blob: 6de7e44452287096f114fe9e65a44e9ac2287bca [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"
rsleevid6de8302016-06-21 01:33:2020#include "net/cert/ct_policy_enforcer.h"
Ryan Sleevi987d2d92017-12-19 19:22:1421#include "net/cert/do_nothing_ct_verifier.h"
22#include "net/cert/mock_cert_verifier.h"
[email protected]f2cb3cf2013-03-21 01:40:5323#include "net/dns/mock_host_resolver.h"
[email protected]e13201d82012-12-12 05:00:3224#include "net/http/http_response_headers.h"
25#include "net/http/http_response_info.h"
rtenneti8332ba52015-09-17 19:33:4126#include "net/http/http_server_properties_impl.h"
[email protected]e13201d82012-12-12 05:00:3227#include "net/http/http_util.h"
[email protected]080b77932014-08-04 01:22:4628#include "net/http/transport_security_state.h"
Matt Mueller230996f12018-10-22 19:39:4429#include "net/http/transport_security_state_test_util.h"
Victor Vasilievbee79ea2019-05-15 01:25:4830#include "net/quic/address_utils.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0831#include "net/quic/crypto/proof_verifier_chromium.h"
32#include "net/quic/mock_crypto_client_stream_factory.h"
33#include "net/quic/mock_quic_data.h"
34#include "net/quic/properties_based_quic_server_info.h"
Renjiea0522f062019-04-29 18:52:2135#include "net/quic/quic_chromium_alarm_factory.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0836#include "net/quic/quic_http_stream.h"
37#include "net/quic/quic_http_utils.h"
38#include "net/quic/quic_server_info.h"
39#include "net/quic/quic_stream_factory_peer.h"
40#include "net/quic/quic_test_packet_maker.h"
41#include "net/quic/test_task_runner.h"
bnc3472afd2016-11-17 15:27:2142#include "net/socket/next_proto.h"
[email protected]e13201d82012-12-12 05:00:3243#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5844#include "net/spdy/spdy_session_test_util.h"
45#include "net/spdy/spdy_test_util_common.h"
[email protected]eed749f92013-12-23 18:57:3846#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0147#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4348#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:0149#include "net/test/test_with_scoped_task_environment.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5150#include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h"
51#include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h"
52#include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
53#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
54#include "net/third_party/quiche/src/quic/core/http/quic_client_promised_info.h"
55#include "net/third_party/quiche/src/quic/core/quic_utils.h"
56#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
57#include "net/third_party/quiche/src/quic/test_tools/mock_clock.h"
58#include "net/third_party/quiche/src/quic/test_tools/mock_random.h"
59#include "net/third_party/quiche/src/quic/test_tools/quic_config_peer.h"
60#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h"
61#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
Victor Vasiliev27cc7712019-01-24 11:50:1462#include "net/third_party/quiche/src/spdy/core/spdy_test_utils.h"
Ramin Halavati683bcaa92018-02-14 08:42:3963#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
robpercival214763f2016-07-01 23:27:0164#include "testing/gmock/include/gmock/gmock.h"
[email protected]e13201d82012-12-12 05:00:3265#include "testing/gtest/include/gtest/gtest.h"
msramek992625ec2016-08-04 18:33:5866#include "url/gurl.h"
[email protected]e13201d82012-12-12 05:00:3267
[email protected]6e12d702013-11-13 00:17:1768using std::string;
[email protected]6e12d702013-11-13 00:17:1769
[email protected]e13201d82012-12-12 05:00:3270namespace net {
jri7e636642016-01-14 06:57:0871
nharper642ae4b2016-06-30 00:40:3672namespace {
73
74class MockSSLConfigService : public SSLConfigService {
75 public:
76 MockSSLConfigService() {}
Ryan Sleevib8449e02018-07-15 04:31:0777 ~MockSSLConfigService() override {}
nharper642ae4b2016-06-30 00:40:3678
79 void GetSSLConfig(SSLConfig* config) override { *config = config_; }
80
Nick Harper89bc7212018-07-31 19:07:5781 bool CanShareConnectionWithClientCerts(
82 const std::string& hostname) const override {
83 return false;
84 }
85
nharper642ae4b2016-06-30 00:40:3686 private:
nharper642ae4b2016-06-30 00:40:3687 SSLConfig config_;
88};
89
90} // namespace
91
[email protected]e13201d82012-12-12 05:00:3292namespace test {
93
[email protected]3c772402013-12-18 21:38:1194namespace {
bnc359ed2a2016-04-29 20:43:4595
96enum DestinationType {
97 // In pooling tests with two requests for different origins to the same
98 // destination, the destination should be
99 SAME_AS_FIRST, // the same as the first origin,
100 SAME_AS_SECOND, // the same as the second origin, or
101 DIFFERENT, // different from both.
102};
103
rch6faa4d42016-01-05 20:48:43104const char kDefaultServerHostName[] = "www.example.org";
105const char kServer2HostName[] = "mail.example.org";
bnc359ed2a2016-04-29 20:43:45106const char kDifferentHostname[] = "different.example.com";
[email protected]3c772402013-12-18 21:38:11107const int kDefaultServerPort = 443;
ckrasic3865ee0f2016-02-29 22:04:56108const char kDefaultUrl[] = "https://www.example.org/";
109const char kServer2Url[] = "https://mail.example.org/";
110const char kServer3Url[] = "https://docs.example.org/";
111const char kServer4Url[] = "https://images.example.org/";
Zhongyi Shic4823bd2018-04-27 00:49:19112const int kDefaultRTTMilliSecs = 300;
113const size_t kMinRetryTimeForDefaultNetworkSecs = 1;
Zhongyi Shib1b1fa42018-06-19 23:13:47114const size_t kWaitTimeForNewNetworkSecs = 10;
Renjiea0cb4a2c2018-09-26 23:37:30115const IPAddress kCachedIPAddress = IPAddress(192, 168, 0, 2);
116const char kNonCachedIPAddress[] = "192.168.0.1";
rtenneti14abd312015-02-06 21:56:01117
bnc359ed2a2016-04-29 20:43:45118// Run QuicStreamFactoryTest instances with all value combinations of version
119// and enable_connection_racting.
rtenneti14abd312015-02-06 21:56:01120struct TestParams {
bnc359ed2a2016-04-29 20:43:45121 friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
Nick Harper23290b82019-05-02 00:02:56122 os << "{ version: " << ParsedQuicVersionToString(p.version)
Yixin Wang079ad542018-01-11 04:06:05123 << ", client_headers_include_h2_stream_dependency: "
124 << p.client_headers_include_h2_stream_dependency << " }";
rtenneti14abd312015-02-06 21:56:01125 return os;
126 }
127
Nick Harper23290b82019-05-02 00:02:56128 quic::ParsedQuicVersion version;
Yixin Wang079ad542018-01-11 04:06:05129 bool client_headers_include_h2_stream_dependency;
rtenneti14abd312015-02-06 21:56:01130};
131
rch872e00e2016-12-02 02:48:18132std::vector<TestParams> GetTestParams() {
133 std::vector<TestParams> params;
Nick Harper23290b82019-05-02 00:02:56134 quic::ParsedQuicVersionVector all_supported_versions =
135 quic::AllSupportedVersions();
Yixin Wang079ad542018-01-11 04:06:05136 for (const auto& version : all_supported_versions) {
137 params.push_back(TestParams{version, false});
138 params.push_back(TestParams{version, true});
139 }
bnc359ed2a2016-04-29 20:43:45140 return params;
141}
142
143// Run QuicStreamFactoryWithDestinationTest instances with all value
144// combinations of version, enable_connection_racting, and destination_type.
145struct PoolingTestParams {
146 friend std::ostream& operator<<(std::ostream& os,
147 const PoolingTestParams& p) {
Nick Harper23290b82019-05-02 00:02:56148 os << "{ version: " << ParsedQuicVersionToString(p.version)
bnc359ed2a2016-04-29 20:43:45149 << ", destination_type: ";
150 switch (p.destination_type) {
151 case SAME_AS_FIRST:
152 os << "SAME_AS_FIRST";
153 break;
154 case SAME_AS_SECOND:
155 os << "SAME_AS_SECOND";
156 break;
157 case DIFFERENT:
158 os << "DIFFERENT";
159 break;
160 }
Yixin Wang079ad542018-01-11 04:06:05161 os << ", client_headers_include_h2_stream_dependency: "
162 << p.client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45163 os << " }";
164 return os;
165 }
166
Nick Harper23290b82019-05-02 00:02:56167 quic::ParsedQuicVersion version;
bnc359ed2a2016-04-29 20:43:45168 DestinationType destination_type;
Yixin Wang079ad542018-01-11 04:06:05169 bool client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45170};
171
rch872e00e2016-12-02 02:48:18172std::vector<PoolingTestParams> GetPoolingTestParams() {
173 std::vector<PoolingTestParams> params;
Nick Harper23290b82019-05-02 00:02:56174 quic::ParsedQuicVersionVector all_supported_versions =
175 quic::AllSupportedVersions();
176 for (const quic::ParsedQuicVersion version : all_supported_versions) {
Yixin Wang079ad542018-01-11 04:06:05177 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, false});
178 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, true});
179 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, false});
180 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, true});
181 params.push_back(PoolingTestParams{version, DIFFERENT, false});
182 params.push_back(PoolingTestParams{version, DIFFERENT, true});
rtenneti14abd312015-02-06 21:56:01183 }
184 return params;
185}
186
bnc912a04b2016-04-20 14:19:50187} // namespace
[email protected]3c772402013-12-18 21:38:11188
bnc359ed2a2016-04-29 20:43:45189class QuicHttpStreamPeer {
190 public:
rchf0b18c8a2017-05-05 19:31:57191 static QuicChromiumClientSession::Handle* GetSessionHandle(
192 HttpStream* stream) {
193 return static_cast<QuicHttpStream*>(stream)->quic_session();
bnc359ed2a2016-04-29 20:43:45194 }
195};
196
Zhongyi Shi5f587cc2017-11-21 23:24:17197// TestConnectionMigrationSocketFactory will vend sockets with incremental port
198// number.
199class TestConnectionMigrationSocketFactory : public MockClientSocketFactory {
200 public:
201 TestConnectionMigrationSocketFactory() : next_source_port_num_(1u) {}
202 ~TestConnectionMigrationSocketFactory() override {}
203
204 std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
205 DatagramSocket::BindType bind_type,
Zhongyi Shi5f587cc2017-11-21 23:24:17206 NetLog* net_log,
207 const NetLogSource& source) override {
208 SocketDataProvider* data_provider = mock_data().GetNext();
209 std::unique_ptr<MockUDPClientSocket> socket(
210 new MockUDPClientSocket(data_provider, net_log));
211 socket->set_source_port(next_source_port_num_++);
212 return std::move(socket);
213 }
214
215 private:
216 uint16_t next_source_port_num_;
217
218 DISALLOW_COPY_AND_ASSIGN(TestConnectionMigrationSocketFactory);
219};
220
Bence Béky98447b12018-05-08 03:14:01221class QuicStreamFactoryTestBase : public WithScopedTaskEnvironment {
[email protected]e13201d82012-12-12 05:00:32222 protected:
Nick Harper23290b82019-05-02 00:02:56223 QuicStreamFactoryTestBase(quic::ParsedQuicVersion version,
Yixin Wang079ad542018-01-11 04:06:05224 bool client_headers_include_h2_stream_dependency)
Renjiea0cb4a2c2018-09-26 23:37:30225 : host_resolver_(new MockHostResolver),
226 ssl_config_service_(new MockSSLConfigService),
Zhongyi Shi5f587cc2017-11-21 23:24:17227 socket_factory_(new MockClientSocketFactory),
nharper642ae4b2016-06-30 00:40:36228 random_generator_(0),
rchbf4c26d2017-04-16 23:17:55229 runner_(new TestTaskRunner(&clock_)),
bnc359ed2a2016-04-29 20:43:45230 version_(version),
David Schinazic8281052019-01-24 06:14:17231 client_maker_(
232 version_,
233 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
234 &clock_,
235 kDefaultServerHostName,
236 quic::Perspective::IS_CLIENT,
Zhongyi Shi967d2f12019-02-08 20:58:53237 client_headers_include_h2_stream_dependency),
David Schinazic8281052019-01-24 06:14:17238 server_maker_(
239 version_,
240 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
241 &clock_,
242 kDefaultServerHostName,
243 quic::Perspective::IS_SERVER,
244 false),
Ryan Sleevi987d2d92017-12-19 19:22:14245 cert_verifier_(std::make_unique<MockCertVerifier>()),
Ryan Sleevi987d2d92017-12-19 19:22:14246 cert_transparency_verifier_(std::make_unique<DoNothingCTVerifier>()),
jri7e636642016-01-14 06:57:08247 scoped_mock_network_change_notifier_(nullptr),
jri7046038f2015-10-22 00:29:26248 factory_(nullptr),
[email protected]bf4ea2f2014-03-10 22:57:53249 host_port_pair_(kDefaultServerHostName, kDefaultServerPort),
ckrasic3865ee0f2016-02-29 22:04:56250 url_(kDefaultUrl),
251 url2_(kServer2Url),
252 url3_(kServer3Url),
253 url4_(kServer4Url),
jri7046038f2015-10-22 00:29:26254 privacy_mode_(PRIVACY_MODE_DISABLED),
Zhongyi Shia6b68d112018-09-24 07:49:03255 failed_on_default_network_callback_(base::BindRepeating(
256 &QuicStreamFactoryTestBase::OnFailedOnDefaultNetwork,
257 base::Unretained(this))),
258 failed_on_default_network_(false),
Zhongyi Shi967d2f12019-02-08 20:58:53259 store_server_configs_in_properties_(false) {
260 test_params_.quic_headers_include_h2_stream_dependency =
261 client_headers_include_h2_stream_dependency;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52262 clock_.AdvanceTime(quic::QuicTime::Delta::FromSeconds(1));
bnc359ed2a2016-04-29 20:43:45263 }
264
jri7046038f2015-10-22 00:29:26265 void Initialize() {
bnc359ed2a2016-04-29 20:43:45266 DCHECK(!factory_);
jri7046038f2015-10-22 00:29:26267 factory_.reset(new QuicStreamFactory(
Renjiea0cb4a2c2018-09-26 23:37:30268 net_log_.net_log(), host_resolver_.get(), ssl_config_service_.get(),
Zhongyi Shi5f587cc2017-11-21 23:24:17269 socket_factory_.get(), &http_server_properties_, cert_verifier_.get(),
Nick Harperecf319d2018-10-16 07:58:54270 &ct_policy_enforcer_, &transport_security_state_,
271 cert_transparency_verifier_.get(),
jri7046038f2015-10-22 00:29:26272 /*SocketPerformanceWatcherFactory*/ nullptr,
rchbf4c26d2017-04-16 23:17:55273 &crypto_client_stream_factory_, &random_generator_, &clock_,
Zhongyi Shi967d2f12019-02-08 20:58:53274 test_params_.quic_max_packet_length, test_params_.quic_user_agent_id,
275 store_server_configs_in_properties_,
276 test_params_.quic_close_sessions_on_ip_change,
277 test_params_.quic_goaway_sessions_on_ip_change,
278 test_params_.mark_quic_broken_when_network_blackholes,
279 test_params_.quic_idle_connection_timeout_seconds,
280 test_params_.quic_reduced_ping_timeout_seconds,
Zhongyi Shie01f2db2019-02-22 19:53:23281 test_params_.quic_retransmittable_on_wire_timeout_milliseconds,
Zhongyi Shi967d2f12019-02-08 20:58:53282 test_params_.quic_max_time_before_crypto_handshake_seconds,
283 test_params_.quic_max_idle_time_before_crypto_handshake_seconds,
284 test_params_.quic_migrate_sessions_on_network_change_v2,
285 test_params_.quic_migrate_sessions_early_v2,
286 test_params_.quic_retry_on_alternate_network_before_handshake,
Zhongyi Shi32fe14d42019-02-28 00:25:36287 test_params_.quic_migrate_idle_sessions,
Zhongyi Shic16b4102019-02-12 00:37:40288 test_params_.quic_idle_session_migration_period,
Zhongyi Shi967d2f12019-02-08 20:58:53289 test_params_.quic_max_time_on_non_default_network,
290 test_params_.quic_max_migrations_to_non_default_network_on_write_error,
291 test_params_
292 .quic_max_migrations_to_non_default_network_on_path_degrading,
293 test_params_.quic_allow_server_migration,
294 test_params_.quic_race_stale_dns_on_connection,
295 test_params_.quic_go_away_on_path_degrading,
296 test_params_.quic_race_cert_verification,
297 test_params_.quic_estimate_initial_rtt,
298 test_params_.quic_headers_include_h2_stream_dependency,
299 test_params_.quic_connection_options,
300 test_params_.quic_client_connection_options,
Renjiea0522f062019-04-29 18:52:21301 test_params_.quic_enable_socket_recv_optimization,
302 test_params_.quic_initial_rtt_for_handshake_milliseconds));
[email protected]e13201d82012-12-12 05:00:32303 }
304
Zhongyi Shi5f587cc2017-11-21 23:24:17305 void InitializeConnectionMigrationV2Test(
306 NetworkChangeNotifier::NetworkList connected_networks) {
307 scoped_mock_network_change_notifier_.reset(
308 new ScopedMockNetworkChangeNotifier());
309 MockNetworkChangeNotifier* mock_ncn =
310 scoped_mock_network_change_notifier_->mock_network_change_notifier();
311 mock_ncn->ForceNetworkHandlesSupported();
312 mock_ncn->SetConnectedNetworksList(connected_networks);
Zhongyi Shi967d2f12019-02-08 20:58:53313 test_params_.quic_migrate_sessions_on_network_change_v2 = true;
314 test_params_.quic_migrate_sessions_early_v2 = true;
Zhongyi Shi5f587cc2017-11-21 23:24:17315 socket_factory_.reset(new TestConnectionMigrationSocketFactory);
316 Initialize();
317 }
318
Yixin Wang7891a39d2017-11-08 20:59:24319 std::unique_ptr<HttpStream> CreateStream(QuicStreamRequest* request) {
320 std::unique_ptr<QuicChromiumClientSession::Handle> session =
321 request->ReleaseSessionHandle();
322 if (!session || !session->IsConnected())
323 return nullptr;
324
325 return std::make_unique<QuicHttpStream>(std::move(session));
326 }
327
bnccb7ff3c2015-05-21 20:51:55328 bool HasActiveSession(const HostPortPair& host_port_pair) {
Ryan Hamilton4f0b26e2018-06-27 23:52:32329 quic::QuicServerId server_id(host_port_pair.host(), host_port_pair.port(),
330 false);
bnc5fdc07162016-05-23 17:36:03331 return QuicStreamFactoryPeer::HasActiveSession(factory_.get(), server_id);
bnccb7ff3c2015-05-21 20:51:55332 }
333
Renjiea0cb4a2c2018-09-26 23:37:30334 bool HasLiveSession(const HostPortPair& host_port_pair) {
335 quic::QuicServerId server_id(host_port_pair.host(), host_port_pair.port(),
336 false);
337 return QuicStreamFactoryPeer::HasLiveSession(factory_.get(), host_port_pair,
338 server_id);
339 }
340
zhongyi363c91c2017-03-23 23:16:08341 bool HasActiveJob(const HostPortPair& host_port_pair,
342 const PrivacyMode privacy_mode) {
Ryan Hamilton4f0b26e2018-06-27 23:52:32343 quic::QuicServerId server_id(host_port_pair.host(), host_port_pair.port(),
344 privacy_mode == PRIVACY_MODE_ENABLED);
zhongyi363c91c2017-03-23 23:16:08345 return QuicStreamFactoryPeer::HasActiveJob(factory_.get(), server_id);
346 }
347
Ryan Hamilton8d9ee76e2018-05-29 23:52:52348 bool HasActiveCertVerifierJob(const quic::QuicServerId& server_id) {
rtennetid073dd22016-08-04 01:58:33349 return QuicStreamFactoryPeer::HasActiveCertVerifierJob(factory_.get(),
350 server_id);
351 }
352
Zhongyi Shic1449372018-08-09 09:58:58353 // Get the pending, not activated session, if there is only one session alive.
354 QuicChromiumClientSession* GetPendingSession(
355 const HostPortPair& host_port_pair) {
356 quic::QuicServerId server_id(host_port_pair.host(), host_port_pair.port(),
357 false);
358 return QuicStreamFactoryPeer::GetPendingSession(factory_.get(), server_id,
359 host_port_pair);
360 }
361
bnc912a04b2016-04-20 14:19:50362 QuicChromiumClientSession* GetActiveSession(
363 const HostPortPair& host_port_pair) {
Ryan Hamilton4f0b26e2018-06-27 23:52:32364 quic::QuicServerId server_id(host_port_pair.host(), host_port_pair.port(),
365 false);
bnc5fdc07162016-05-23 17:36:03366 return QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server_id);
bnc912a04b2016-04-20 14:19:50367 }
368
[email protected]bf4ea2f2014-03-10 22:57:53369 int GetSourcePortForNewSession(const HostPortPair& destination) {
[email protected]d8e2abf82014-03-06 10:30:10370 return GetSourcePortForNewSessionInner(destination, false);
371 }
372
rjshaded5ced072015-12-18 19:26:02373 int GetSourcePortForNewSessionAndGoAway(const HostPortPair& destination) {
[email protected]d8e2abf82014-03-06 10:30:10374 return GetSourcePortForNewSessionInner(destination, true);
375 }
376
[email protected]bf4ea2f2014-03-10 22:57:53377 int GetSourcePortForNewSessionInner(const HostPortPair& destination,
[email protected]d8e2abf82014-03-06 10:30:10378 bool goaway_received) {
[email protected]3c772402013-12-18 21:38:11379 // Should only be called if there is no active session for this destination.
bnccb7ff3c2015-05-21 20:51:55380 EXPECT_FALSE(HasActiveSession(destination));
Zhongyi Shi5f587cc2017-11-21 23:24:17381 size_t socket_count = socket_factory_->udp_client_socket_ports().size();
[email protected]3c772402013-12-18 21:38:11382
rcha00569732016-08-27 11:09:36383 MockQuicData socket_data;
384 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:43385 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:17386 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]3c772402013-12-18 21:38:11387
zhongyi98d6a9262017-05-19 02:47:45388 QuicStreamRequest request(factory_.get());
ckrasic3865ee0f2016-02-29 22:04:56389 GURL url("https://" + destination.host() + "/");
Nick Harper23290b82019-05-02 00:02:56390 EXPECT_EQ(ERR_IO_PENDING,
391 request.Request(
392 destination, version_.transport_version, privacy_mode_,
393 DEFAULT_PRIORITY, SocketTag(),
394 /*cert_verify_flags=*/0, url, net_log_, &net_error_details_,
395 failed_on_default_network_callback_, callback_.callback()));
[email protected]3c772402013-12-18 21:38:11396
robpercival214763f2016-07-01 23:27:01397 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:24398 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]3c772402013-12-18 21:38:11399 EXPECT_TRUE(stream.get());
400 stream.reset();
401
bnc912a04b2016-04-20 14:19:50402 QuicChromiumClientSession* session = GetActiveSession(destination);
[email protected]3c772402013-12-18 21:38:11403
Zhongyi Shi5f587cc2017-11-21 23:24:17404 if (socket_count + 1 != socket_factory_->udp_client_socket_ports().size()) {
mmenke651bae7f2015-12-18 21:26:45405 ADD_FAILURE();
[email protected]3c772402013-12-18 21:38:11406 return 0;
407 }
408
[email protected]d8e2abf82014-03-06 10:30:10409 if (goaway_received) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:52410 quic::QuicGoAwayFrame goaway(quic::kInvalidControlFrameId,
411 quic::QUIC_NO_ERROR, 1, "");
rtenneti9bd5d4b2015-08-21 05:44:52412 session->connection()->OnGoAwayFrame(goaway);
[email protected]d8e2abf82014-03-06 10:30:10413 }
[email protected]3c772402013-12-18 21:38:11414
jri7046038f2015-10-22 00:29:26415 factory_->OnSessionClosed(session);
bnccb7ff3c2015-05-21 20:51:55416 EXPECT_FALSE(HasActiveSession(destination));
rch37de576c2015-05-17 20:28:17417 EXPECT_TRUE(socket_data.AllReadDataConsumed());
418 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
Zhongyi Shi5f587cc2017-11-21 23:24:17419 return socket_factory_->udp_client_socket_ports()[socket_count];
[email protected]3c772402013-12-18 21:38:11420 }
421
Ryan Hamilton8d9ee76e2018-05-29 23:52:52422 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23423 ConstructClientConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03424 return client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52425 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
rtenneti1cd3b162015-09-29 02:58:28426 }
427
Ryan Hamilton8d9ee76e2018-05-29 23:52:52428 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
Fan Yangac867502019-01-28 21:10:23429 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52430 quic::QuicRstStreamErrorCode error_code) {
Fan Yang32c5a112018-12-10 20:06:33431 quic::QuicStreamId stream_id =
432 GetNthClientInitiatedBidirectionalStreamId(0);
fayang3bcb8b502016-12-07 21:44:37433 return client_maker_.MakeRstPacket(packet_number, true, stream_id,
Jana Iyengarba355772017-09-21 22:03:21434 error_code);
fayang3bcb8b502016-12-07 21:44:37435 }
436
bncf8bf0722015-05-19 20:04:13437 static ProofVerifyDetailsChromium DefaultProofVerifyDetails() {
rch6faa4d42016-01-05 20:48:43438 // Load a certificate that is valid for *.example.org
bncf8bf0722015-05-19 20:04:13439 scoped_refptr<X509Certificate> test_cert(
rch6faa4d42016-01-05 20:48:43440 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bncf8bf0722015-05-19 20:04:13441 EXPECT_TRUE(test_cert.get());
442 ProofVerifyDetailsChromium verify_details;
443 verify_details.cert_verify_result.verified_cert = test_cert;
444 verify_details.cert_verify_result.is_issued_by_known_root = true;
445 return verify_details;
446 }
447
jri8c44d692015-10-23 23:53:41448 void NotifyIPAddressChanged() {
449 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
jri7e636642016-01-14 06:57:08450 // Spin the message loop so the notification is delivered.
fdoray92e35a72016-06-10 15:54:55451 base::RunLoop().RunUntilIdle();
jri8c44d692015-10-23 23:53:41452 }
453
Ryan Hamilton8d9ee76e2018-05-29 23:52:52454 std::unique_ptr<quic::QuicEncryptedPacket> ConstructGetRequestPacket(
Fan Yangac867502019-01-28 21:10:23455 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52456 quic::QuicStreamId stream_id,
jri7e636642016-01-14 06:57:08457 bool should_include_version,
458 bool fin) {
Ryan Hamilton0239aac2018-05-19 00:03:13459 spdy::SpdyHeaderBlock headers =
alyssar2adf3ac2016-05-03 17:12:58460 client_maker_.GetRequestHeaders("GET", "https", "/");
Ryan Hamilton0239aac2018-05-19 00:03:13461 spdy::SpdyPriority priority =
jri7e636642016-01-14 06:57:08462 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
463 size_t spdy_headers_frame_len;
alyssar2adf3ac2016-05-03 17:12:58464 return client_maker_.MakeRequestHeadersPacket(
jri7e636642016-01-14 06:57:08465 packet_number, stream_id, should_include_version, fin, priority,
Yixin Wang7a3f1b8d2018-01-17 21:40:48466 std::move(headers), 0, &spdy_headers_frame_len);
jri7e636642016-01-14 06:57:08467 }
468
Ryan Hamilton8d9ee76e2018-05-29 23:52:52469 std::unique_ptr<quic::QuicEncryptedPacket> ConstructGetRequestPacket(
Fan Yangac867502019-01-28 21:10:23470 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52471 quic::QuicStreamId stream_id,
Zhongyi Shi3c4c9e92018-07-02 23:16:23472 quic::QuicStreamId parent_stream_id,
fayang3bcb8b502016-12-07 21:44:37473 bool should_include_version,
474 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52475 quic::QuicStreamOffset* offset) {
Ryan Hamilton0239aac2018-05-19 00:03:13476 spdy::SpdyHeaderBlock headers =
fayang3bcb8b502016-12-07 21:44:37477 client_maker_.GetRequestHeaders("GET", "https", "/");
Ryan Hamilton0239aac2018-05-19 00:03:13478 spdy::SpdyPriority priority =
fayang3bcb8b502016-12-07 21:44:37479 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
480 size_t spdy_headers_frame_len;
481 return client_maker_.MakeRequestHeadersPacket(
482 packet_number, stream_id, should_include_version, fin, priority,
Zhongyi Shi3c4c9e92018-07-02 23:16:23483 std::move(headers), parent_stream_id, &spdy_headers_frame_len, offset);
484 }
485
486 std::unique_ptr<quic::QuicEncryptedPacket> ConstructGetRequestPacket(
Fan Yangac867502019-01-28 21:10:23487 uint64_t packet_number,
Zhongyi Shi3c4c9e92018-07-02 23:16:23488 quic::QuicStreamId stream_id,
489 bool should_include_version,
490 bool fin,
491 quic::QuicStreamOffset* offset) {
492 return ConstructGetRequestPacket(packet_number, stream_id,
493 /*parent_stream_id=*/0,
494 should_include_version, fin, offset);
fayang3bcb8b502016-12-07 21:44:37495 }
496
Ryan Hamilton8d9ee76e2018-05-29 23:52:52497 std::unique_ptr<quic::QuicEncryptedPacket> ConstructOkResponsePacket(
Fan Yangac867502019-01-28 21:10:23498 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52499 quic::QuicStreamId stream_id,
jri7e636642016-01-14 06:57:08500 bool should_include_version,
501 bool fin) {
Ryan Hamilton0239aac2018-05-19 00:03:13502 spdy::SpdyHeaderBlock headers = server_maker_.GetResponseHeaders("200 OK");
jri7e636642016-01-14 06:57:08503 size_t spdy_headers_frame_len;
alyssar2adf3ac2016-05-03 17:12:58504 return server_maker_.MakeResponseHeadersPacket(
bnc086b39e12016-06-24 13:05:26505 packet_number, stream_id, should_include_version, fin,
506 std::move(headers), &spdy_headers_frame_len);
jri7e636642016-01-14 06:57:08507 }
508
Ryan Hamilton8d9ee76e2018-05-29 23:52:52509 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket() {
rch5cb522462017-04-25 20:18:36510 return client_maker_.MakeInitialSettingsPacket(1, nullptr);
511 }
512
Ryan Hamilton8d9ee76e2018-05-29 23:52:52513 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:23514 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52515 quic::QuicStreamOffset* offset) {
rch5cb522462017-04-25 20:18:36516 return client_maker_.MakeInitialSettingsPacket(packet_number, offset);
fayang3bcb8b502016-12-07 21:44:37517 }
518
jri053fdbd2016-08-19 02:33:05519 // Helper method for server migration tests.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52520 void VerifyServerMigration(const quic::QuicConfig& config,
bnc6a0348c2017-05-22 18:56:19521 IPEndPoint expected_address) {
Zhongyi Shi967d2f12019-02-08 20:58:53522 test_params_.quic_allow_server_migration = true;
jri053fdbd2016-08-19 02:33:05523 Initialize();
524
525 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
526 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri053fdbd2016-08-19 02:33:05527 crypto_client_stream_factory_.SetConfig(config);
528
529 // Set up first socket data provider.
rcha00569732016-08-27 11:09:36530 MockQuicData socket_data1;
531 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:17532 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri053fdbd2016-08-19 02:33:05533
rcha00569732016-08-27 11:09:36534 // Set up second socket data provider that is used after
535 // migration.
536 MockQuicData socket_data2;
537 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:43538 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
fayang3bcb8b502016-12-07 21:44:37539 socket_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:43540 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
541 socket_data2.AddWrite(
Fan Yang32c5a112018-12-10 20:06:33542 SYNCHRONOUS, client_maker_.MakeRstPacket(
543 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
544 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:17545 socket_data2.AddSocketDataToFactory(socket_factory_.get());
jri053fdbd2016-08-19 02:33:05546
547 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:45548 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:33549 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:03550 request.Request(
Nick Harper23290b82019-05-02 00:02:56551 host_port_pair_, version_.transport_version, privacy_mode_,
552 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:03553 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
554 failed_on_default_network_callback_, callback_.callback()));
jri053fdbd2016-08-19 02:33:05555 EXPECT_EQ(OK, callback_.WaitForResult());
bnceb9aa7112017-01-05 01:03:46556
557 // Run QuicChromiumClientSession::WriteToNewSocket()
558 // posted by QuicChromiumClientSession::MigrateToSocket().
559 base::RunLoop().RunUntilIdle();
560
Yixin Wang7891a39d2017-11-08 20:59:24561 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri053fdbd2016-08-19 02:33:05562 EXPECT_TRUE(stream.get());
563
564 // Cause QUIC stream to be created.
565 HttpRequestInfo request_info;
566 request_info.method = "GET";
567 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:39568 request_info.traffic_annotation =
569 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:27570 EXPECT_EQ(OK,
571 stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:39572 net_log_, CompletionOnceCallback()));
jri053fdbd2016-08-19 02:33:05573 // Ensure that session is alive and active.
574 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
575 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
576 EXPECT_TRUE(HasActiveSession(host_port_pair_));
577
578 IPEndPoint actual_address;
579 session->GetDefaultSocket()->GetPeerAddress(&actual_address);
580 EXPECT_EQ(actual_address, expected_address);
581 DVLOG(1) << "Socket connected to: " << actual_address.address().ToString()
582 << " " << actual_address.port();
583 DVLOG(1) << "Expected address: " << expected_address.address().ToString()
584 << " " << expected_address.port();
585
586 stream.reset();
587 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
588 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
589 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
590 }
591
tbansal3b966952016-10-25 23:25:14592 // Verifies that the QUIC stream factory is initialized correctly.
tbansal9b1cdf32017-05-10 17:28:39593 void VerifyInitialization() {
rch431dd4452017-04-19 15:22:35594 store_server_configs_in_properties_ = true;
Zhongyi Shi967d2f12019-02-08 20:58:53595 test_params_.quic_idle_connection_timeout_seconds = 500;
tbansal3b966952016-10-25 23:25:14596 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:20597 factory_->set_require_confirmation(false);
tbansal3b966952016-10-25 23:25:14598 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
599 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rch431dd4452017-04-19 15:22:35600 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
601 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:27602 MockCryptoClientStream::ZERO_RTT);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52603 const quic::QuicConfig* config =
604 QuicStreamFactoryPeer::GetConfig(factory_.get());
ckrasic32b17dcd2016-10-31 06:15:35605 EXPECT_EQ(500, config->IdleNetworkTimeout().ToSeconds());
tbansal3b966952016-10-25 23:25:14606
607 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
608
bnc3472afd2016-11-17 15:27:21609 const AlternativeService alternative_service1(
610 kProtoQUIC, host_port_pair_.host(), host_port_pair_.port());
tbansal3b966952016-10-25 23:25:14611 AlternativeServiceInfoVector alternative_service_info_vector;
612 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
613 alternative_service_info_vector.push_back(
zhongyie537a002017-06-27 16:48:21614 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
615 alternative_service1, expiration, {version_}));
tbansal3b966952016-10-25 23:25:14616 http_server_properties_.SetAlternativeServices(
617 url::SchemeHostPort(url_), alternative_service_info_vector);
618
619 HostPortPair host_port_pair2(kServer2HostName, kDefaultServerPort);
620 url::SchemeHostPort server2("https", kServer2HostName, kDefaultServerPort);
bnc3472afd2016-11-17 15:27:21621 const AlternativeService alternative_service2(
622 kProtoQUIC, host_port_pair2.host(), host_port_pair2.port());
tbansal3b966952016-10-25 23:25:14623 AlternativeServiceInfoVector alternative_service_info_vector2;
624 alternative_service_info_vector2.push_back(
zhongyie537a002017-06-27 16:48:21625 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
626 alternative_service2, expiration, {version_}));
tbansal9b1cdf32017-05-10 17:28:39627
628 http_server_properties_.SetAlternativeServices(
629 server2, alternative_service_info_vector2);
630 // Verify that the properties of both QUIC servers are stored in the
631 // HTTP properties map.
632 EXPECT_EQ(2U, http_server_properties_.alternative_service_map().size());
tbansal3b966952016-10-25 23:25:14633
634 http_server_properties_.SetMaxServerConfigsStoredInProperties(
Yixin Wang4a227aa22017-11-30 21:33:01635 kDefaultMaxQuicServerEntries);
tbansal3b966952016-10-25 23:25:14636
Ryan Hamilton8d9ee76e2018-05-29 23:52:52637 quic::QuicServerId quic_server_id(kDefaultServerHostName, 443,
638 PRIVACY_MODE_DISABLED);
rch431dd4452017-04-19 15:22:35639 std::unique_ptr<QuicServerInfo> quic_server_info =
Jeremy Roman0579ed62017-08-29 15:56:19640 std::make_unique<PropertiesBasedQuicServerInfo>(
rch431dd4452017-04-19 15:22:35641 quic_server_id, &http_server_properties_);
tbansal3b966952016-10-25 23:25:14642
643 // Update quic_server_info's server_config and persist it.
644 QuicServerInfo::State* state = quic_server_info->mutable_state();
645 // Minimum SCFG that passes config validation checks.
646 const char scfg[] = {// SCFG
647 0x53, 0x43, 0x46, 0x47,
648 // num entries
649 0x01, 0x00,
650 // padding
651 0x00, 0x00,
652 // EXPY
653 0x45, 0x58, 0x50, 0x59,
654 // EXPY end offset
655 0x08, 0x00, 0x00, 0x00,
656 // Value
657 '1', '2', '3', '4', '5', '6', '7', '8'};
658
659 // Create temporary strings becasue Persist() clears string data in |state|.
660 string server_config(reinterpret_cast<const char*>(&scfg), sizeof(scfg));
661 string source_address_token("test_source_address_token");
662 string cert_sct("test_cert_sct");
663 string chlo_hash("test_chlo_hash");
664 string signature("test_signature");
665 string test_cert("test_cert");
rch872e00e2016-12-02 02:48:18666 std::vector<string> certs;
tbansal3b966952016-10-25 23:25:14667 certs.push_back(test_cert);
668 state->server_config = server_config;
669 state->source_address_token = source_address_token;
670 state->cert_sct = cert_sct;
671 state->chlo_hash = chlo_hash;
672 state->server_config_sig = signature;
673 state->certs = certs;
674
675 quic_server_info->Persist();
676
Ryan Hamilton8d9ee76e2018-05-29 23:52:52677 quic::QuicServerId quic_server_id2(kServer2HostName, 443,
678 PRIVACY_MODE_DISABLED);
rch431dd4452017-04-19 15:22:35679 std::unique_ptr<QuicServerInfo> quic_server_info2 =
Jeremy Roman0579ed62017-08-29 15:56:19680 std::make_unique<PropertiesBasedQuicServerInfo>(
rch431dd4452017-04-19 15:22:35681 quic_server_id2, &http_server_properties_);
tbansal3b966952016-10-25 23:25:14682 // Update quic_server_info2's server_config and persist it.
683 QuicServerInfo::State* state2 = quic_server_info2->mutable_state();
684
685 // Minimum SCFG that passes config validation checks.
686 const char scfg2[] = {// SCFG
687 0x53, 0x43, 0x46, 0x47,
688 // num entries
689 0x01, 0x00,
690 // padding
691 0x00, 0x00,
692 // EXPY
693 0x45, 0x58, 0x50, 0x59,
694 // EXPY end offset
695 0x08, 0x00, 0x00, 0x00,
696 // Value
697 '8', '7', '3', '4', '5', '6', '2', '1'};
698
699 // Create temporary strings becasue Persist() clears string data in
700 // |state2|.
701 string server_config2(reinterpret_cast<const char*>(&scfg2), sizeof(scfg2));
702 string source_address_token2("test_source_address_token2");
703 string cert_sct2("test_cert_sct2");
704 string chlo_hash2("test_chlo_hash2");
705 string signature2("test_signature2");
706 string test_cert2("test_cert2");
rch872e00e2016-12-02 02:48:18707 std::vector<string> certs2;
tbansal3b966952016-10-25 23:25:14708 certs2.push_back(test_cert2);
709 state2->server_config = server_config2;
710 state2->source_address_token = source_address_token2;
711 state2->cert_sct = cert_sct2;
712 state2->chlo_hash = chlo_hash2;
713 state2->server_config_sig = signature2;
714 state2->certs = certs2;
715
716 quic_server_info2->Persist();
717
tbansal3b966952016-10-25 23:25:14718 // Verify the MRU order is maintained.
719 const QuicServerInfoMap& quic_server_info_map =
720 http_server_properties_.quic_server_info_map();
721 EXPECT_EQ(2u, quic_server_info_map.size());
jdoerrie22a91d8b92018-10-05 08:43:26722 auto quic_server_info_map_it = quic_server_info_map.begin();
tbansal3b966952016-10-25 23:25:14723 EXPECT_EQ(quic_server_info_map_it->first, quic_server_id2);
724 ++quic_server_info_map_it;
725 EXPECT_EQ(quic_server_info_map_it->first, quic_server_id);
726
Renjiea0cb4a2c2018-09-26 23:37:30727 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
728 "192.168.0.1", "");
rch431dd4452017-04-19 15:22:35729
730 // Create a session and verify that the cached state is loaded.
731 MockQuicData socket_data;
732 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:17733 socket_data.AddSocketDataToFactory(socket_factory_.get());
rch431dd4452017-04-19 15:22:35734
zhongyi98d6a9262017-05-19 02:47:45735 QuicStreamRequest request(factory_.get());
Yixin Wang247ea642017-11-15 01:15:50736 EXPECT_EQ(ERR_IO_PENDING,
Ryan Hamilton4f0b26e2018-06-27 23:52:32737 request.Request(
738 HostPortPair(quic_server_id.host(), quic_server_id.port()),
Nick Harper23290b82019-05-02 00:02:56739 version_.transport_version, privacy_mode_, DEFAULT_PRIORITY,
740 SocketTag(),
Ryan Hamilton4f0b26e2018-06-27 23:52:32741 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
Zhongyi Shia6b68d112018-09-24 07:49:03742 failed_on_default_network_callback_, callback_.callback()));
rch431dd4452017-04-19 15:22:35743 EXPECT_THAT(callback_.WaitForResult(), IsOk());
744
tbansal3b966952016-10-25 23:25:14745 EXPECT_FALSE(QuicStreamFactoryPeer::CryptoConfigCacheIsEmpty(
746 factory_.get(), quic_server_id));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52747 quic::QuicCryptoClientConfig* crypto_config =
tbansal3b966952016-10-25 23:25:14748 QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
Ryan Hamilton8d9ee76e2018-05-29 23:52:52749 quic::QuicCryptoClientConfig::CachedState* cached =
tbansal3b966952016-10-25 23:25:14750 crypto_config->LookupOrCreate(quic_server_id);
751 EXPECT_FALSE(cached->server_config().empty());
752 EXPECT_TRUE(cached->GetServerConfig());
753 EXPECT_EQ(server_config, cached->server_config());
754 EXPECT_EQ(source_address_token, cached->source_address_token());
755 EXPECT_EQ(cert_sct, cached->cert_sct());
756 EXPECT_EQ(chlo_hash, cached->chlo_hash());
757 EXPECT_EQ(signature, cached->signature());
758 ASSERT_EQ(1U, cached->certs().size());
759 EXPECT_EQ(test_cert, cached->certs()[0]);
760
rch431dd4452017-04-19 15:22:35761 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
762
763 // Create a session and verify that the cached state is loaded.
764 MockQuicData socket_data2;
765 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:17766 socket_data2.AddSocketDataToFactory(socket_factory_.get());
rch431dd4452017-04-19 15:22:35767
Renjiea0cb4a2c2018-09-26 23:37:30768 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
769 "192.168.0.2", "");
rch431dd4452017-04-19 15:22:35770
zhongyi98d6a9262017-05-19 02:47:45771 QuicStreamRequest request2(factory_.get());
rch431dd4452017-04-19 15:22:35772 EXPECT_EQ(ERR_IO_PENDING,
Ryan Hamilton4f0b26e2018-06-27 23:52:32773 request2.Request(
774 HostPortPair(quic_server_id2.host(), quic_server_id2.port()),
Nick Harper23290b82019-05-02 00:02:56775 version_.transport_version, privacy_mode_, DEFAULT_PRIORITY,
776 SocketTag(),
Ryan Hamilton4f0b26e2018-06-27 23:52:32777 /*cert_verify_flags=*/0, GURL("https://mail.example.org/"),
Zhongyi Shia6b68d112018-09-24 07:49:03778 net_log_, &net_error_details_,
779 failed_on_default_network_callback_, callback_.callback()));
rch431dd4452017-04-19 15:22:35780 EXPECT_THAT(callback_.WaitForResult(), IsOk());
781
tbansal3b966952016-10-25 23:25:14782 EXPECT_FALSE(QuicStreamFactoryPeer::CryptoConfigCacheIsEmpty(
783 factory_.get(), quic_server_id2));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52784 quic::QuicCryptoClientConfig::CachedState* cached2 =
tbansal3b966952016-10-25 23:25:14785 crypto_config->LookupOrCreate(quic_server_id2);
786 EXPECT_FALSE(cached2->server_config().empty());
787 EXPECT_TRUE(cached2->GetServerConfig());
788 EXPECT_EQ(server_config2, cached2->server_config());
789 EXPECT_EQ(source_address_token2, cached2->source_address_token());
790 EXPECT_EQ(cert_sct2, cached2->cert_sct());
791 EXPECT_EQ(chlo_hash2, cached2->chlo_hash());
792 EXPECT_EQ(signature2, cached2->signature());
793 ASSERT_EQ(1U, cached->certs().size());
794 EXPECT_EQ(test_cert2, cached2->certs()[0]);
795 }
796
jri5b785512016-09-13 04:29:11797 void RunTestLoopUntilIdle() {
798 while (!runner_->GetPostedTasks().empty())
799 runner_->RunNextTask();
800 }
801
Fan Yang32c5a112018-12-10 20:06:33802 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56803 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
804 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36805 }
806
Fan Yang32c5a112018-12-10 20:06:33807 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56808 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
809 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36810 }
811
Zhongyi Shia6b68d112018-09-24 07:49:03812 void OnFailedOnDefaultNetwork(int rv) { failed_on_default_network_ = true; }
813
jri9f303712016-09-13 01:10:22814 // Helper methods for tests of connection migration on write error.
Zhongyi Shi32fe14d42019-02-28 00:25:36815 void TestMigrationOnWriteErrorNonMigratableStream(IoMode write_error_mode,
816 bool migrate_idle_sessions);
Zhongyi Shi0439ecc72018-07-11 04:41:26817 // Migratable stream triggers write error.
818 void TestMigrationOnWriteErrorMixedStreams(IoMode write_error_mode);
819 // Non-migratable stream triggers write error.
820 void TestMigrationOnWriteErrorMixedStreams2(IoMode write_error_mode);
jri9f303712016-09-13 01:10:22821 void TestMigrationOnWriteErrorMigrationDisabled(IoMode write_error_mode);
822 void TestMigrationOnWriteError(IoMode write_error_mode);
Zhongyi Shi0439ecc72018-07-11 04:41:26823 void TestMigrationOnWriteErrorWithMultipleRequests(IoMode write_error_mode);
jri9f303712016-09-13 01:10:22824 void TestMigrationOnWriteErrorNoNewNetwork(IoMode write_error_mode);
Zhongyi Shi7f1d9212018-06-22 23:24:36825 void TestMigrationOnMultipleWriteErrors(
826 IoMode write_error_mode_on_old_network,
827 IoMode write_error_mode_on_new_network);
Zhongyi Shib24001c02018-06-18 20:01:52828 void TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
829 bool disconnected);
Zhongyi Shi1e2bc742018-06-16 02:06:07830 void TestMigrationOnWriteErrorWithNotificationQueuedLater(bool disconnected);
Zhongyi Shi9f316b262018-06-18 22:01:16831 void TestMigrationOnNetworkDisconnected(bool async_write_before);
Zhongyi Shia0644e32018-06-21 05:19:52832 void TestMigrationOnNetworkMadeDefault(IoMode write_mode);
Zhongyi Shi22fd5f52018-06-20 17:39:09833 void TestMigrationOnPathDegrading(bool async_write_before);
Zhongyi Shib3bc982c2018-07-10 19:59:24834 void TestMigrateSessionWithDrainingStream(
835 IoMode write_mode_for_queued_packet);
jri5b785512016-09-13 04:29:11836 void TestMigrationOnWriteErrorPauseBeforeConnected(IoMode write_error_mode);
Zhongyi Shi4ac9e1f2018-06-21 05:21:47837 void TestMigrationOnWriteErrorWithMultipleNotifications(
jri5b785512016-09-13 04:29:11838 IoMode write_error_mode,
Zhongyi Shi4ac9e1f2018-06-21 05:21:47839 bool disconnect_before_connect);
Zhongyi Shi634c1882018-08-16 04:05:59840 void TestNoAlternateNetworkBeforeHandshake(quic::QuicErrorCode error);
Zhongyi Shi8de43832018-08-15 23:40:00841 void TestNewConnectionOnAlternateNetworkBeforeHandshake(
842 quic::QuicErrorCode error);
Zhongyi Shi32fe14d42019-02-28 00:25:36843 void TestOnNetworkMadeDefaultNonMigratableStream(bool migrate_idle_sessions);
844 void TestMigrateSessionEarlyNonMigratableStream(bool migrate_idle_sessions);
845 void TestOnNetworkDisconnectedNoOpenStreams(bool migrate_idle_sessions);
846 void TestOnNetworkMadeDefaultNoOpenStreams(bool migrate_idle_sessions);
847 void TestOnNetworkDisconnectedNonMigratableStream(bool migrate_idle_sessions);
jri9f303712016-09-13 01:10:22848
Jana Iyengarf6b13d82017-09-04 02:09:10849 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Renjiea0cb4a2c2018-09-26 23:37:30850 std::unique_ptr<MockHostResolverBase> host_resolver_;
Ryan Sleevib8449e02018-07-15 04:31:07851 std::unique_ptr<SSLConfigService> ssl_config_service_;
Zhongyi Shi5f587cc2017-11-21 23:24:17852 std::unique_ptr<MockClientSocketFactory> socket_factory_;
[email protected]e8ff26842013-03-22 21:02:05853 MockCryptoClientStreamFactory crypto_client_stream_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52854 quic::test::MockRandom random_generator_;
855 quic::MockClock clock_;
rtenneti38f5cd52014-10-28 20:28:28856 scoped_refptr<TestTaskRunner> runner_;
Nick Harper23290b82019-05-02 00:02:56857 const quic::ParsedQuicVersion version_;
alyssar2adf3ac2016-05-03 17:12:58858 QuicTestPacketMaker client_maker_;
859 QuicTestPacketMaker server_maker_;
rtenneticcab42b2015-10-09 06:38:16860 HttpServerPropertiesImpl http_server_properties_;
danakjad1777e2016-04-16 00:56:42861 std::unique_ptr<CertVerifier> cert_verifier_;
[email protected]080b77932014-08-04 01:22:46862 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42863 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:23864 DefaultCTPolicyEnforcer ct_policy_enforcer_;
danakjad1777e2016-04-16 00:56:42865 std::unique_ptr<ScopedMockNetworkChangeNotifier>
jri7e636642016-01-14 06:57:08866 scoped_mock_network_change_notifier_;
danakjad1777e2016-04-16 00:56:42867 std::unique_ptr<QuicStreamFactory> factory_;
[email protected]bf4ea2f2014-03-10 22:57:53868 HostPortPair host_port_pair_;
ckrasic3865ee0f2016-02-29 22:04:56869 GURL url_;
870 GURL url2_;
871 GURL url3_;
872 GURL url4_;
873
[email protected]9dd3ff0f2014-03-26 09:51:28874 PrivacyMode privacy_mode_;
tfarina42834112016-09-22 13:38:20875 NetLogWithSource net_log_;
[email protected]e13201d82012-12-12 05:00:32876 TestCompletionCallback callback_;
Zhongyi Shia6b68d112018-09-24 07:49:03877 const CompletionRepeatingCallback failed_on_default_network_callback_;
878 bool failed_on_default_network_;
Ryan Hamilton75f197262017-08-17 14:00:07879 NetErrorDetails net_error_details_;
jri7046038f2015-10-22 00:29:26880
881 // Variables to configure QuicStreamFactory.
Zhongyi Shi967d2f12019-02-08 20:58:53882 HttpNetworkSession::Params test_params_;
rch431dd4452017-04-19 15:22:35883 bool store_server_configs_in_properties_;
[email protected]e13201d82012-12-12 05:00:32884};
885
bnc359ed2a2016-04-29 20:43:45886class QuicStreamFactoryTest : public QuicStreamFactoryTestBase,
887 public ::testing::TestWithParam<TestParams> {
888 protected:
Yixin Wang079ad542018-01-11 04:06:05889 QuicStreamFactoryTest()
890 : QuicStreamFactoryTestBase(
891 GetParam().version,
892 GetParam().client_headers_include_h2_stream_dependency) {}
bnc359ed2a2016-04-29 20:43:45893};
894
Victor Costane635086f2019-01-27 05:20:30895INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
896 QuicStreamFactoryTest,
897 ::testing::ValuesIn(GetTestParams()));
[email protected]1e960032013-12-20 19:00:20898
[email protected]1e960032013-12-20 19:00:20899TEST_P(QuicStreamFactoryTest, Create) {
jri7046038f2015-10-22 00:29:26900 Initialize();
rch6faa4d42016-01-05 20:48:43901 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
902 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:26903
rcha00569732016-08-27 11:09:36904 MockQuicData socket_data;
905 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:43906 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:17907 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]e13201d82012-12-12 05:00:32908
zhongyi98d6a9262017-05-19 02:47:45909 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:33910 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:03911 request.Request(
Nick Harper23290b82019-05-02 00:02:56912 host_port_pair_, version_.transport_version, privacy_mode_,
913 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:03914 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
915 failed_on_default_network_callback_, callback_.callback()));
[email protected]e13201d82012-12-12 05:00:32916
robpercival214763f2016-07-01 23:27:01917 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:24918 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0edce6a2013-05-08 18:02:40919 EXPECT_TRUE(stream.get());
[email protected]e13201d82012-12-12 05:00:32920
Renjiea0cb4a2c2018-09-26 23:37:30921 EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_->last_request_priority());
Yixin Wang247ea642017-11-15 01:15:50922
zhongyi98d6a9262017-05-19 02:47:45923 QuicStreamRequest request2(factory_.get());
Nick Harper23290b82019-05-02 00:02:56924 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_.transport_version,
925 privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
Paul Jensen8e3c5d32018-02-19 17:06:33926 /*cert_verify_flags=*/0, url_, net_log_,
Zhongyi Shia6b68d112018-09-24 07:49:03927 &net_error_details_,
928 failed_on_default_network_callback_,
929 callback_.callback()));
rch68a80eb2017-04-25 05:24:24930 // Will reset stream 3.
Yixin Wang7891a39d2017-11-08 20:59:24931 stream = CreateStream(&request2);
rch68a80eb2017-04-25 05:24:24932
933 EXPECT_TRUE(stream.get());
934
935 // TODO(rtenneti): We should probably have a tests that HTTP and HTTPS result
936 // in streams on different sessions.
zhongyi98d6a9262017-05-19 02:47:45937 QuicStreamRequest request3(factory_.get());
Nick Harper23290b82019-05-02 00:02:56938 EXPECT_EQ(OK, request3.Request(host_port_pair_, version_.transport_version,
939 privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
Paul Jensen8e3c5d32018-02-19 17:06:33940 /*cert_verify_flags=*/0, url_, net_log_,
Zhongyi Shia6b68d112018-09-24 07:49:03941 &net_error_details_,
942 failed_on_default_network_callback_,
943 callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:24944 stream = CreateStream(&request3); // Will reset stream 5.
Ryan Hamiltona12722b2017-08-12 02:23:20945 stream.reset(); // Will reset stream 7.
[email protected]e13201d82012-12-12 05:00:32946
rch37de576c2015-05-17 20:28:17947 EXPECT_TRUE(socket_data.AllReadDataConsumed());
948 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]e13201d82012-12-12 05:00:32949}
950
[email protected]8bd2b812014-03-26 04:01:17951TEST_P(QuicStreamFactoryTest, CreateZeroRtt) {
jri7046038f2015-10-22 00:29:26952 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:20953 factory_->set_require_confirmation(false);
rch6faa4d42016-01-05 20:48:43954 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
955 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:26956
rcha00569732016-08-27 11:09:36957 MockQuicData socket_data;
958 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:17959 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]8bd2b812014-03-26 04:01:17960
961 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:27962 MockCryptoClientStream::ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:30963 host_resolver_->set_synchronous_mode(true);
964 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
965 "192.168.0.1", "");
[email protected]8bd2b812014-03-26 04:01:17966
zhongyi98d6a9262017-05-19 02:47:45967 QuicStreamRequest request(factory_.get());
Nick Harper23290b82019-05-02 00:02:56968 EXPECT_EQ(OK, request.Request(host_port_pair_, version_.transport_version,
969 privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
Paul Jensen8e3c5d32018-02-19 17:06:33970 /*cert_verify_flags=*/0, url_, net_log_,
Zhongyi Shia6b68d112018-09-24 07:49:03971 &net_error_details_,
972 failed_on_default_network_callback_,
973 callback_.callback()));
[email protected]8bd2b812014-03-26 04:01:17974
Yixin Wang7891a39d2017-11-08 20:59:24975 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]8bd2b812014-03-26 04:01:17976 EXPECT_TRUE(stream.get());
rch37de576c2015-05-17 20:28:17977 EXPECT_TRUE(socket_data.AllReadDataConsumed());
978 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]8bd2b812014-03-26 04:01:17979}
980
rchd6163f32017-01-30 23:50:38981TEST_P(QuicStreamFactoryTest, DefaultInitialRtt) {
982 Initialize();
983 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
984 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
985
986 MockQuicData socket_data;
987 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:43988 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:17989 socket_data.AddSocketDataToFactory(socket_factory_.get());
rchd6163f32017-01-30 23:50:38990
zhongyi98d6a9262017-05-19 02:47:45991 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:33992 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:03993 request.Request(
Nick Harper23290b82019-05-02 00:02:56994 host_port_pair_, version_.transport_version, privacy_mode_,
995 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:03996 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
997 failed_on_default_network_callback_, callback_.callback()));
rchd6163f32017-01-30 23:50:38998
999 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241000 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rchd6163f32017-01-30 23:50:381001 EXPECT_TRUE(stream.get());
1002
1003 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Ryan Hamiltona12722b2017-08-12 02:23:201004 EXPECT_TRUE(session->require_confirmation());
rchd6163f32017-01-30 23:50:381005 EXPECT_EQ(100000u, session->connection()->GetStats().srtt_us);
1006 ASSERT_FALSE(session->config()->HasInitialRoundTripTimeUsToSend());
1007}
1008
Helen Li0e823912017-09-25 19:48:301009TEST_P(QuicStreamFactoryTest, FactoryDestroyedWhenJobPending) {
1010 Initialize();
1011 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1012 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1013
1014 MockQuicData socket_data;
1015 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431016 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171017 socket_data.AddSocketDataToFactory(socket_factory_.get());
Helen Li0e823912017-09-25 19:48:301018
1019 auto request = std::make_unique<QuicStreamRequest>(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331020 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031021 request->Request(
Nick Harper23290b82019-05-02 00:02:561022 host_port_pair_, version_.transport_version, privacy_mode_,
1023 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:031024 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1025 failed_on_default_network_callback_, callback_.callback()));
Helen Li0e823912017-09-25 19:48:301026 request.reset();
1027 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
1028 // Tearing down a QuicStreamFactory with a pending Job should not cause any
1029 // crash. crbug.com/768343.
1030 factory_.reset();
1031}
1032
Ryan Hamiltona12722b2017-08-12 02:23:201033TEST_P(QuicStreamFactoryTest, RequireConfirmation) {
1034 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271035 MockCryptoClientStream::ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:301036 host_resolver_->set_synchronous_mode(true);
1037 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
1038 "192.168.0.1", "");
Ryan Hamiltona12722b2017-08-12 02:23:201039 Initialize();
1040 factory_->set_require_confirmation(true);
1041 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1042 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1043
1044 MockQuicData socket_data;
1045 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431046 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171047 socket_data.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamiltona12722b2017-08-12 02:23:201048
1049 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331050 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031051 request.Request(
Nick Harper23290b82019-05-02 00:02:561052 host_port_pair_, version_.transport_version, privacy_mode_,
1053 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:031054 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1055 failed_on_default_network_callback_, callback_.callback()));
Ryan Hamiltona12722b2017-08-12 02:23:201056
Ryan Hamilton8e32a2b2017-08-28 20:06:521057 IPAddress last_address;
1058 EXPECT_FALSE(http_server_properties_.GetSupportsQuic(&last_address));
1059
Ryan Hamiltona12722b2017-08-12 02:23:201060 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521061 quic::QuicSession::HANDSHAKE_CONFIRMED);
Ryan Hamiltona12722b2017-08-12 02:23:201062
Ryan Hamilton8e32a2b2017-08-28 20:06:521063 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
1064
Ryan Hamiltona12722b2017-08-12 02:23:201065 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241066 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Ryan Hamiltona12722b2017-08-12 02:23:201067 EXPECT_TRUE(stream.get());
1068
1069 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1070 EXPECT_TRUE(session->require_confirmation());
1071}
1072
1073TEST_P(QuicStreamFactoryTest, DontRequireConfirmationFromSameIP) {
1074 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271075 MockCryptoClientStream::ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:301076 host_resolver_->set_synchronous_mode(true);
1077 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
1078 "192.168.0.1", "");
Ryan Hamiltona12722b2017-08-12 02:23:201079 Initialize();
1080 factory_->set_require_confirmation(true);
1081 http_server_properties_.SetSupportsQuic(IPAddress(192, 0, 2, 33));
1082
1083 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1084 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1085
1086 MockQuicData socket_data;
1087 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431088 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171089 socket_data.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamiltona12722b2017-08-12 02:23:201090
1091 QuicStreamRequest request(factory_.get());
Zhongyi Shia6b68d112018-09-24 07:49:031092 EXPECT_THAT(request.Request(
Nick Harper23290b82019-05-02 00:02:561093 host_port_pair_, version_.transport_version, privacy_mode_,
1094 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:031095 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1096 failed_on_default_network_callback_, callback_.callback()),
Paul Jensen8e3c5d32018-02-19 17:06:331097 IsOk());
Ryan Hamiltona12722b2017-08-12 02:23:201098
Ryan Hamilton8e32a2b2017-08-28 20:06:521099 IPAddress last_address;
1100 EXPECT_FALSE(http_server_properties_.GetSupportsQuic(&last_address));
1101
Yixin Wang7891a39d2017-11-08 20:59:241102 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Ryan Hamiltona12722b2017-08-12 02:23:201103 EXPECT_TRUE(stream.get());
1104
1105 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1106 EXPECT_FALSE(session->require_confirmation());
Ryan Hamilton8e32a2b2017-08-28 20:06:521107
1108 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521109 quic::QuicSession::HANDSHAKE_CONFIRMED);
Ryan Hamilton8e32a2b2017-08-28 20:06:521110
1111 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
Ryan Hamiltona12722b2017-08-12 02:23:201112}
1113
rchd6163f32017-01-30 23:50:381114TEST_P(QuicStreamFactoryTest, CachedInitialRtt) {
1115 ServerNetworkStats stats;
1116 stats.srtt = base::TimeDelta::FromMilliseconds(10);
1117 http_server_properties_.SetServerNetworkStats(url::SchemeHostPort(url_),
1118 stats);
Zhongyi Shi967d2f12019-02-08 20:58:531119 test_params_.quic_estimate_initial_rtt = true;
rchd6163f32017-01-30 23:50:381120
1121 Initialize();
1122 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1123 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1124
1125 MockQuicData socket_data;
1126 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431127 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171128 socket_data.AddSocketDataToFactory(socket_factory_.get());
rchd6163f32017-01-30 23:50:381129
zhongyi98d6a9262017-05-19 02:47:451130 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331131 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031132 request.Request(
Nick Harper23290b82019-05-02 00:02:561133 host_port_pair_, version_.transport_version, privacy_mode_,
1134 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:031135 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1136 failed_on_default_network_callback_, callback_.callback()));
rchd6163f32017-01-30 23:50:381137
1138 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241139 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rchd6163f32017-01-30 23:50:381140 EXPECT_TRUE(stream.get());
1141
1142 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1143 EXPECT_EQ(10000u, session->connection()->GetStats().srtt_us);
1144 ASSERT_TRUE(session->config()->HasInitialRoundTripTimeUsToSend());
1145 EXPECT_EQ(10000u, session->config()->GetInitialRoundTripTimeUsToSend());
1146}
1147
1148TEST_P(QuicStreamFactoryTest, 2gInitialRtt) {
1149 ScopedMockNetworkChangeNotifier notifier;
1150 notifier.mock_network_change_notifier()->SetConnectionType(
1151 NetworkChangeNotifier::CONNECTION_2G);
Zhongyi Shi967d2f12019-02-08 20:58:531152 test_params_.quic_estimate_initial_rtt = true;
rchd6163f32017-01-30 23:50:381153
1154 Initialize();
1155 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1156 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1157
1158 MockQuicData socket_data;
1159 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431160 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171161 socket_data.AddSocketDataToFactory(socket_factory_.get());
rchd6163f32017-01-30 23:50:381162
zhongyi98d6a9262017-05-19 02:47:451163 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331164 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031165 request.Request(
Nick Harper23290b82019-05-02 00:02:561166 host_port_pair_, version_.transport_version, privacy_mode_,
1167 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:031168 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1169 failed_on_default_network_callback_, callback_.callback()));
rchd6163f32017-01-30 23:50:381170
1171 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241172 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rchd6163f32017-01-30 23:50:381173 EXPECT_TRUE(stream.get());
1174
1175 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1176 EXPECT_EQ(1200000u, session->connection()->GetStats().srtt_us);
1177 ASSERT_TRUE(session->config()->HasInitialRoundTripTimeUsToSend());
1178 EXPECT_EQ(1200000u, session->config()->GetInitialRoundTripTimeUsToSend());
1179}
1180
1181TEST_P(QuicStreamFactoryTest, 3gInitialRtt) {
1182 ScopedMockNetworkChangeNotifier notifier;
1183 notifier.mock_network_change_notifier()->SetConnectionType(
1184 NetworkChangeNotifier::CONNECTION_3G);
Zhongyi Shi967d2f12019-02-08 20:58:531185 test_params_.quic_estimate_initial_rtt = true;
rchd6163f32017-01-30 23:50:381186
1187 Initialize();
1188 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1189 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1190
1191 MockQuicData socket_data;
1192 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431193 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171194 socket_data.AddSocketDataToFactory(socket_factory_.get());
rchd6163f32017-01-30 23:50:381195
zhongyi98d6a9262017-05-19 02:47:451196 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331197 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031198 request.Request(
Nick Harper23290b82019-05-02 00:02:561199 host_port_pair_, version_.transport_version, privacy_mode_,
1200 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:031201 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1202 failed_on_default_network_callback_, callback_.callback()));
rchd6163f32017-01-30 23:50:381203
1204 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241205 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rchd6163f32017-01-30 23:50:381206 EXPECT_TRUE(stream.get());
1207
1208 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1209 EXPECT_EQ(400000u, session->connection()->GetStats().srtt_us);
1210 ASSERT_TRUE(session->config()->HasInitialRoundTripTimeUsToSend());
1211 EXPECT_EQ(400000u, session->config()->GetInitialRoundTripTimeUsToSend());
1212}
1213
rch68955482015-09-24 00:14:391214TEST_P(QuicStreamFactoryTest, GoAway) {
jri7046038f2015-10-22 00:29:261215 Initialize();
rch6faa4d42016-01-05 20:48:431216 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1217 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:261218
rcha00569732016-08-27 11:09:361219 MockQuicData socket_data;
1220 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431221 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171222 socket_data.AddSocketDataToFactory(socket_factory_.get());
rch68955482015-09-24 00:14:391223
zhongyi98d6a9262017-05-19 02:47:451224 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331225 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031226 request.Request(
Nick Harper23290b82019-05-02 00:02:561227 host_port_pair_, version_.transport_version, privacy_mode_,
1228 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:031229 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1230 failed_on_default_network_callback_, callback_.callback()));
rch68955482015-09-24 00:14:391231
robpercival214763f2016-07-01 23:27:011232 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241233 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rch68955482015-09-24 00:14:391234 EXPECT_TRUE(stream.get());
1235
bnc912a04b2016-04-20 14:19:501236 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
rch68955482015-09-24 00:14:391237
Ryan Hamilton8d9ee76e2018-05-29 23:52:521238 session->OnGoAway(quic::QuicGoAwayFrame());
rch68955482015-09-24 00:14:391239
bnc912a04b2016-04-20 14:19:501240 EXPECT_FALSE(HasActiveSession(host_port_pair_));
rch68955482015-09-24 00:14:391241
1242 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1243 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1244}
1245
zhongyi6b5a3892016-03-12 04:46:201246TEST_P(QuicStreamFactoryTest, GoAwayForConnectionMigrationWithPortOnly) {
1247 Initialize();
1248 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1249 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1250
rcha00569732016-08-27 11:09:361251 MockQuicData socket_data;
1252 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431253 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171254 socket_data.AddSocketDataToFactory(socket_factory_.get());
zhongyi6b5a3892016-03-12 04:46:201255
zhongyi98d6a9262017-05-19 02:47:451256 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331257 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031258 request.Request(
Nick Harper23290b82019-05-02 00:02:561259 host_port_pair_, version_.transport_version, privacy_mode_,
1260 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:031261 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1262 failed_on_default_network_callback_, callback_.callback()));
zhongyi6b5a3892016-03-12 04:46:201263
robpercival214763f2016-07-01 23:27:011264 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241265 std::unique_ptr<HttpStream> stream = CreateStream(&request);
zhongyi6b5a3892016-03-12 04:46:201266 EXPECT_TRUE(stream.get());
1267
bnc912a04b2016-04-20 14:19:501268 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
zhongyi6b5a3892016-03-12 04:46:201269
Ryan Hamilton8d9ee76e2018-05-29 23:52:521270 session->OnGoAway(quic::QuicGoAwayFrame(
1271 quic::kInvalidControlFrameId, quic::QUIC_ERROR_MIGRATING_PORT, 0,
1272 "peer connection migration due to port change only"));
zhongyi6b5a3892016-03-12 04:46:201273 NetErrorDetails details;
1274 EXPECT_FALSE(details.quic_port_migration_detected);
1275 session->PopulateNetErrorDetails(&details);
1276 EXPECT_TRUE(details.quic_port_migration_detected);
1277 details.quic_port_migration_detected = false;
1278 stream->PopulateNetErrorDetails(&details);
1279 EXPECT_TRUE(details.quic_port_migration_detected);
1280
bnc912a04b2016-04-20 14:19:501281 EXPECT_FALSE(HasActiveSession(host_port_pair_));
zhongyi6b5a3892016-03-12 04:46:201282
1283 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1284 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1285}
1286
[email protected]5db452202014-08-19 05:22:151287TEST_P(QuicStreamFactoryTest, Pooling) {
jri7046038f2015-10-22 00:29:261288 Initialize();
rch6faa4d42016-01-05 20:48:431289 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1290 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:261291
rcha00569732016-08-27 11:09:361292 MockQuicData socket_data;
1293 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431294 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171295 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]eed749f92013-12-23 18:57:381296
rch6faa4d42016-01-05 20:48:431297 HostPortPair server2(kServer2HostName, kDefaultServerPort);
Renjiea0cb4a2c2018-09-26 23:37:301298 host_resolver_->set_synchronous_mode(true);
1299 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
1300 "192.168.0.1", "");
1301 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]eed749f92013-12-23 18:57:381302
zhongyi98d6a9262017-05-19 02:47:451303 QuicStreamRequest request(factory_.get());
Nick Harper23290b82019-05-02 00:02:561304 EXPECT_EQ(OK, request.Request(host_port_pair_, version_.transport_version,
1305 privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
Paul Jensen8e3c5d32018-02-19 17:06:331306 /*cert_verify_flags=*/0, url_, net_log_,
Zhongyi Shia6b68d112018-09-24 07:49:031307 &net_error_details_,
1308 failed_on_default_network_callback_,
1309 callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241310 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]eed749f92013-12-23 18:57:381311 EXPECT_TRUE(stream.get());
1312
1313 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451314 QuicStreamRequest request2(factory_.get());
Nick Harper23290b82019-05-02 00:02:561315 EXPECT_EQ(OK, request2.Request(server2, version_.transport_version,
1316 privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
1317 /*cert_verify_flags=*/0, url2_, net_log_,
1318 &net_error_details_,
1319 failed_on_default_network_callback_,
1320 callback.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241321 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]eed749f92013-12-23 18:57:381322 EXPECT_TRUE(stream2.get());
1323
bnc912a04b2016-04-20 14:19:501324 EXPECT_EQ(GetActiveSession(host_port_pair_), GetActiveSession(server2));
[email protected]eed749f92013-12-23 18:57:381325
rch37de576c2015-05-17 20:28:171326 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1327 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]eed749f92013-12-23 18:57:381328}
1329
jri94ddc3142016-08-26 01:32:431330TEST_P(QuicStreamFactoryTest, PoolingWithServerMigration) {
1331 // Set up session to migrate.
Renjiea0cb4a2c2018-09-26 23:37:301332 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
1333 "192.168.0.1", "");
jri94ddc3142016-08-26 01:32:431334 IPEndPoint alt_address = IPEndPoint(IPAddress(1, 2, 3, 4), 443);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521335 quic::QuicConfig config;
fayang91ca2012016-11-22 07:42:461336 config.SetAlternateServerAddressToSend(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521337 quic::QuicSocketAddress(quic::QuicSocketAddressImpl(alt_address)));
jri94ddc3142016-08-26 01:32:431338
1339 VerifyServerMigration(config, alt_address);
1340
1341 // Close server-migrated session.
1342 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Renjieba55fae2018-09-20 03:05:161343 session->CloseSessionOnError(0u, quic::QUIC_NO_ERROR,
1344 quic::ConnectionCloseBehavior::SILENT_CLOSE);
jri94ddc3142016-08-26 01:32:431345
1346 // Set up server IP, socket, proof, and config for new session.
1347 HostPortPair server2(kServer2HostName, kDefaultServerPort);
Renjiea0cb4a2c2018-09-26 23:37:301348 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
jri94ddc3142016-08-26 01:32:431349
1350 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521351 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361352 client_maker_.MakeInitialSettingsPacket(1, nullptr));
bnceb9aa7112017-01-05 01:03:461353 MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(),
1354 settings_packet->length(), 1)};
fayang3bcb8b502016-12-07 21:44:371355
Ryan Sleevib8d7ea02018-05-07 20:01:011356 SequencedSocketData socket_data(reads, writes);
Zhongyi Shi5f587cc2017-11-21 23:24:171357 socket_factory_->AddSocketDataProvider(&socket_data);
jri94ddc3142016-08-26 01:32:431358
1359 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1360 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521361 quic::QuicConfig config2;
jri94ddc3142016-08-26 01:32:431362 crypto_client_stream_factory_.SetConfig(config2);
1363
1364 // Create new request to cause new session creation.
1365 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451366 QuicStreamRequest request2(factory_.get());
jri94ddc3142016-08-26 01:32:431367 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031368 request2.Request(
Nick Harper23290b82019-05-02 00:02:561369 server2, version_.transport_version, privacy_mode_,
1370 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:031371 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
1372 failed_on_default_network_callback_, callback.callback()));
jri94ddc3142016-08-26 01:32:431373 EXPECT_EQ(OK, callback.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:241374 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
jri94ddc3142016-08-26 01:32:431375 EXPECT_TRUE(stream2.get());
1376
1377 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1378 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1379 // EXPECT_EQ(GetActiveSession(host_port_pair_), GetActiveSession(server2));
1380}
1381
[email protected]eed749f92013-12-23 18:57:381382TEST_P(QuicStreamFactoryTest, NoPoolingAfterGoAway) {
jri7046038f2015-10-22 00:29:261383 Initialize();
rch6faa4d42016-01-05 20:48:431384 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1385 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1386 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:261387
rcha00569732016-08-27 11:09:361388 MockQuicData socket_data1;
1389 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431390 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171391 socket_data1.AddSocketDataToFactory(socket_factory_.get());
rcha00569732016-08-27 11:09:361392 MockQuicData socket_data2;
1393 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431394 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171395 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]eed749f92013-12-23 18:57:381396
rch6faa4d42016-01-05 20:48:431397 HostPortPair server2(kServer2HostName, kDefaultServerPort);
Renjiea0cb4a2c2018-09-26 23:37:301398 host_resolver_->set_synchronous_mode(true);
1399 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
1400 "192.168.0.1", "");
1401 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]eed749f92013-12-23 18:57:381402
zhongyi98d6a9262017-05-19 02:47:451403 QuicStreamRequest request(factory_.get());
Nick Harper23290b82019-05-02 00:02:561404 EXPECT_EQ(OK, request.Request(host_port_pair_, version_.transport_version,
1405 privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
Paul Jensen8e3c5d32018-02-19 17:06:331406 /*cert_verify_flags=*/0, url_, net_log_,
Zhongyi Shia6b68d112018-09-24 07:49:031407 &net_error_details_,
1408 failed_on_default_network_callback_,
1409 callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241410 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]eed749f92013-12-23 18:57:381411 EXPECT_TRUE(stream.get());
1412
1413 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451414 QuicStreamRequest request2(factory_.get());
Nick Harper23290b82019-05-02 00:02:561415 EXPECT_EQ(OK, request2.Request(server2, version_.transport_version,
1416 privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
1417 /*cert_verify_flags=*/0, url2_, net_log_,
1418 &net_error_details_,
1419 failed_on_default_network_callback_,
1420 callback.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241421 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]eed749f92013-12-23 18:57:381422 EXPECT_TRUE(stream2.get());
1423
bnc912a04b2016-04-20 14:19:501424 factory_->OnSessionGoingAway(GetActiveSession(host_port_pair_));
1425 EXPECT_FALSE(HasActiveSession(host_port_pair_));
1426 EXPECT_FALSE(HasActiveSession(server2));
[email protected]eed749f92013-12-23 18:57:381427
1428 TestCompletionCallback callback3;
zhongyi98d6a9262017-05-19 02:47:451429 QuicStreamRequest request3(factory_.get());
Nick Harper23290b82019-05-02 00:02:561430 EXPECT_EQ(OK, request3.Request(server2, version_.transport_version,
1431 privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
1432 /*cert_verify_flags=*/0, url2_, net_log_,
1433 &net_error_details_,
1434 failed_on_default_network_callback_,
1435 callback3.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241436 std::unique_ptr<HttpStream> stream3 = CreateStream(&request3);
[email protected]eed749f92013-12-23 18:57:381437 EXPECT_TRUE(stream3.get());
1438
bnc912a04b2016-04-20 14:19:501439 EXPECT_TRUE(HasActiveSession(server2));
[email protected]eed749f92013-12-23 18:57:381440
rch37de576c2015-05-17 20:28:171441 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
1442 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
1443 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1444 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]eed749f92013-12-23 18:57:381445}
1446
[email protected]5db452202014-08-19 05:22:151447TEST_P(QuicStreamFactoryTest, HttpsPooling) {
jri7046038f2015-10-22 00:29:261448 Initialize();
rch6faa4d42016-01-05 20:48:431449
rcha00569732016-08-27 11:09:361450 MockQuicData socket_data;
1451 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431452 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171453 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]eed749f92013-12-23 18:57:381454
rch6faa4d42016-01-05 20:48:431455 HostPortPair server1(kDefaultServerHostName, 443);
1456 HostPortPair server2(kServer2HostName, 443);
[email protected]eed749f92013-12-23 18:57:381457
bncf8bf0722015-05-19 20:04:131458 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
bnc20daf9a2015-05-15 17:11:011459 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
[email protected]eed749f92013-12-23 18:57:381460
Renjiea0cb4a2c2018-09-26 23:37:301461 host_resolver_->set_synchronous_mode(true);
1462 host_resolver_->rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
1463 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]eed749f92013-12-23 18:57:381464
zhongyi98d6a9262017-05-19 02:47:451465 QuicStreamRequest request(factory_.get());
Nick Harper23290b82019-05-02 00:02:561466 EXPECT_EQ(OK, request.Request(server1, version_.transport_version,
1467 privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
1468 /*cert_verify_flags=*/0, url_, net_log_,
1469 &net_error_details_,
1470 failed_on_default_network_callback_,
1471 callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241472 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]eed749f92013-12-23 18:57:381473 EXPECT_TRUE(stream.get());
1474
1475 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451476 QuicStreamRequest request2(factory_.get());
Nick Harper23290b82019-05-02 00:02:561477 EXPECT_EQ(OK, request2.Request(server2, version_.transport_version,
1478 privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
1479 /*cert_verify_flags=*/0, url2_, net_log_,
1480 &net_error_details_,
1481 failed_on_default_network_callback_,
1482 callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241483 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]eed749f92013-12-23 18:57:381484 EXPECT_TRUE(stream2.get());
1485
bnc912a04b2016-04-20 14:19:501486 EXPECT_EQ(GetActiveSession(server1), GetActiveSession(server2));
[email protected]eed749f92013-12-23 18:57:381487
rch37de576c2015-05-17 20:28:171488 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1489 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]eed749f92013-12-23 18:57:381490}
1491
[email protected]5db452202014-08-19 05:22:151492TEST_P(QuicStreamFactoryTest, HttpsPoolingWithMatchingPins) {
jri7046038f2015-10-22 00:29:261493 Initialize();
rcha00569732016-08-27 11:09:361494 MockQuicData socket_data;
1495 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431496 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171497 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]5db452202014-08-19 05:22:151498
rch6faa4d42016-01-05 20:48:431499 HostPortPair server1(kDefaultServerHostName, 443);
1500 HostPortPair server2(kServer2HostName, 443);
Matt Mueller230996f12018-10-22 19:39:441501 transport_security_state_.EnableStaticPinsForTesting();
1502 ScopedTransportSecurityStateSource scoped_security_state_source;
[email protected]5db452202014-08-19 05:22:151503
Matt Mueller230996f12018-10-22 19:39:441504 HashValue primary_pin(HASH_VALUE_SHA256);
1505 EXPECT_TRUE(primary_pin.FromString(
1506 "sha256/Nn8jk5By4Vkq6BeOVZ7R7AC6XUUBZsWmUbJR1f1Y5FY="));
bncf8bf0722015-05-19 20:04:131507 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
Matt Mueller230996f12018-10-22 19:39:441508 verify_details.cert_verify_result.public_key_hashes.push_back(primary_pin);
bnc20daf9a2015-05-15 17:11:011509 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
[email protected]5db452202014-08-19 05:22:151510
Renjiea0cb4a2c2018-09-26 23:37:301511 host_resolver_->set_synchronous_mode(true);
1512 host_resolver_->rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
1513 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]5db452202014-08-19 05:22:151514
zhongyi98d6a9262017-05-19 02:47:451515 QuicStreamRequest request(factory_.get());
Nick Harper23290b82019-05-02 00:02:561516 EXPECT_EQ(OK, request.Request(server1, version_.transport_version,
1517 privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
1518 /*cert_verify_flags=*/0, url_, net_log_,
1519 &net_error_details_,
1520 failed_on_default_network_callback_,
1521 callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241522 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]5db452202014-08-19 05:22:151523 EXPECT_TRUE(stream.get());
1524
1525 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451526 QuicStreamRequest request2(factory_.get());
Nick Harper23290b82019-05-02 00:02:561527 EXPECT_EQ(OK, request2.Request(server2, version_.transport_version,
1528 privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
1529 /*cert_verify_flags=*/0, url2_, net_log_,
1530 &net_error_details_,
1531 failed_on_default_network_callback_,
1532 callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241533 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]5db452202014-08-19 05:22:151534 EXPECT_TRUE(stream2.get());
1535
bnc912a04b2016-04-20 14:19:501536 EXPECT_EQ(GetActiveSession(server1), GetActiveSession(server2));
[email protected]5db452202014-08-19 05:22:151537
rch37de576c2015-05-17 20:28:171538 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1539 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]5db452202014-08-19 05:22:151540}
1541
1542TEST_P(QuicStreamFactoryTest, NoHttpsPoolingWithDifferentPins) {
jri7046038f2015-10-22 00:29:261543 Initialize();
rcha00569732016-08-27 11:09:361544
1545 MockQuicData socket_data1;
1546 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431547 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171548 socket_data1.AddSocketDataToFactory(socket_factory_.get());
rcha00569732016-08-27 11:09:361549 MockQuicData socket_data2;
1550 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431551 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171552 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]5db452202014-08-19 05:22:151553
rch6faa4d42016-01-05 20:48:431554 HostPortPair server1(kDefaultServerHostName, 443);
1555 HostPortPair server2(kServer2HostName, 443);
Matt Mueller230996f12018-10-22 19:39:441556 transport_security_state_.EnableStaticPinsForTesting();
1557 ScopedTransportSecurityStateSource scoped_security_state_source;
[email protected]5db452202014-08-19 05:22:151558
bncf8bf0722015-05-19 20:04:131559 ProofVerifyDetailsChromium verify_details1 = DefaultProofVerifyDetails();
Matt Mueller230996f12018-10-22 19:39:441560 uint8_t bad_pin = 3;
bnc20daf9a2015-05-15 17:11:011561 verify_details1.cert_verify_result.public_key_hashes.push_back(
1562 test::GetTestHashValue(bad_pin));
1563 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
1564
Matt Mueller230996f12018-10-22 19:39:441565 HashValue primary_pin(HASH_VALUE_SHA256);
1566 EXPECT_TRUE(primary_pin.FromString(
1567 "sha256/Nn8jk5By4Vkq6BeOVZ7R7AC6XUUBZsWmUbJR1f1Y5FY="));
bncf8bf0722015-05-19 20:04:131568 ProofVerifyDetailsChromium verify_details2 = DefaultProofVerifyDetails();
Matt Mueller230996f12018-10-22 19:39:441569 verify_details2.cert_verify_result.public_key_hashes.push_back(primary_pin);
bnc20daf9a2015-05-15 17:11:011570 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
[email protected]5db452202014-08-19 05:22:151571
Renjiea0cb4a2c2018-09-26 23:37:301572 host_resolver_->set_synchronous_mode(true);
1573 host_resolver_->rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
1574 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]5db452202014-08-19 05:22:151575
zhongyi98d6a9262017-05-19 02:47:451576 QuicStreamRequest request(factory_.get());
Nick Harper23290b82019-05-02 00:02:561577 EXPECT_EQ(OK, request.Request(server1, version_.transport_version,
1578 privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
1579 /*cert_verify_flags=*/0, url_, net_log_,
1580 &net_error_details_,
1581 failed_on_default_network_callback_,
1582 callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241583 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]5db452202014-08-19 05:22:151584 EXPECT_TRUE(stream.get());
1585
1586 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451587 QuicStreamRequest request2(factory_.get());
Nick Harper23290b82019-05-02 00:02:561588 EXPECT_EQ(OK, request2.Request(server2, version_.transport_version,
1589 privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
1590 /*cert_verify_flags=*/0, url2_, net_log_,
1591 &net_error_details_,
1592 failed_on_default_network_callback_,
1593 callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241594 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]5db452202014-08-19 05:22:151595 EXPECT_TRUE(stream2.get());
1596
bnc912a04b2016-04-20 14:19:501597 EXPECT_NE(GetActiveSession(server1), GetActiveSession(server2));
[email protected]5db452202014-08-19 05:22:151598
rch37de576c2015-05-17 20:28:171599 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
1600 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
1601 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1602 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]5db452202014-08-19 05:22:151603}
1604
[email protected]1e960032013-12-20 19:00:201605TEST_P(QuicStreamFactoryTest, Goaway) {
jri7046038f2015-10-22 00:29:261606 Initialize();
rch6faa4d42016-01-05 20:48:431607 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1608 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1609 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1610
rcha00569732016-08-27 11:09:361611 MockQuicData socket_data;
1612 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431613 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171614 socket_data.AddSocketDataToFactory(socket_factory_.get());
rcha00569732016-08-27 11:09:361615 MockQuicData socket_data2;
1616 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431617 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171618 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]4d283b32013-10-17 12:57:271619
zhongyi98d6a9262017-05-19 02:47:451620 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331621 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031622 request.Request(
Nick Harper23290b82019-05-02 00:02:561623 host_port_pair_, version_.transport_version, privacy_mode_,
1624 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:031625 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1626 failed_on_default_network_callback_, callback_.callback()));
[email protected]4d283b32013-10-17 12:57:271627
robpercival214763f2016-07-01 23:27:011628 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241629 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]4d283b32013-10-17 12:57:271630 EXPECT_TRUE(stream.get());
1631
1632 // Mark the session as going away. Ensure that while it is still alive
1633 // that it is no longer active.
bnc912a04b2016-04-20 14:19:501634 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri7046038f2015-10-22 00:29:261635 factory_->OnSessionGoingAway(session);
1636 EXPECT_EQ(true,
1637 QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
bnc912a04b2016-04-20 14:19:501638 EXPECT_FALSE(HasActiveSession(host_port_pair_));
[email protected]4d283b32013-10-17 12:57:271639
1640 // Create a new request for the same destination and verify that a
1641 // new session is created.
zhongyi98d6a9262017-05-19 02:47:451642 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331643 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031644 request2.Request(
Nick Harper23290b82019-05-02 00:02:561645 host_port_pair_, version_.transport_version, privacy_mode_,
1646 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:031647 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1648 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:011649 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241650 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]4d283b32013-10-17 12:57:271651 EXPECT_TRUE(stream2.get());
1652
bnc912a04b2016-04-20 14:19:501653 EXPECT_TRUE(HasActiveSession(host_port_pair_));
1654 EXPECT_NE(session, GetActiveSession(host_port_pair_));
jri7046038f2015-10-22 00:29:261655 EXPECT_EQ(true,
1656 QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
[email protected]4d283b32013-10-17 12:57:271657
1658 stream2.reset();
1659 stream.reset();
1660
rch37de576c2015-05-17 20:28:171661 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1662 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1663 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1664 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]4d283b32013-10-17 12:57:271665}
1666
[email protected]1e960032013-12-20 19:00:201667TEST_P(QuicStreamFactoryTest, MaxOpenStream) {
jri7046038f2015-10-22 00:29:261668 Initialize();
rch6faa4d42016-01-05 20:48:431669 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1670 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1671
Fan Yang32c5a112018-12-10 20:06:331672 quic::QuicStreamId stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
rcha00569732016-08-27 11:09:361673 MockQuicData socket_data;
Zhongyi Shi32f2fd02018-04-16 18:23:431674 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Nick Harper23290b82019-05-02 00:02:561675 if (version_.transport_version == quic::QUIC_VERSION_99) {
David Schinazicc1bc592019-04-24 19:40:311676 socket_data.AddWrite(SYNCHRONOUS, client_maker_.MakeStreamsBlockedPacket(
1677 2, true, 52,
1678 /*unidirectional=*/false));
Frank Kastenholzc9b9bea2018-12-03 20:13:471679 socket_data.AddWrite(
1680 SYNCHRONOUS, client_maker_.MakeRstPacket(3, true, stream_id,
1681 quic::QUIC_STREAM_CANCELLED));
1682 socket_data.AddRead(
1683 ASYNC, server_maker_.MakeRstPacket(1, false, stream_id,
1684 quic::QUIC_STREAM_CANCELLED));
Fan Yang32c5a112018-12-10 20:06:331685 socket_data.AddRead(
David Schinazicc1bc592019-04-24 19:40:311686 ASYNC, server_maker_.MakeMaxStreamsPacket(4, true, 53,
1687 /*unidirectional=*/false));
Frank Kastenholzc9b9bea2018-12-03 20:13:471688 } else {
1689 socket_data.AddWrite(
1690 SYNCHRONOUS, client_maker_.MakeRstPacket(2, true, stream_id,
1691 quic::QUIC_STREAM_CANCELLED));
1692 socket_data.AddRead(
1693 ASYNC, server_maker_.MakeRstPacket(1, false, stream_id,
1694 quic::QUIC_STREAM_CANCELLED));
Frank Kastenholz878763bf2018-11-28 19:14:481695 }
rcha00569732016-08-27 11:09:361696 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:171697 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]0b2294d32013-08-02 00:46:361698
1699 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:391700 request_info.traffic_annotation =
1701 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1702
xunjieli1d2b4272017-04-25 22:37:171703 std::vector<std::unique_ptr<HttpStream>> streams;
Ryan Hamilton9835e662018-08-02 05:36:271704 // The MockCryptoClientStream sets max_open_streams to be
Ryan Hamilton8d9ee76e2018-05-29 23:52:521705 // quic::kDefaultMaxStreamsPerConnection / 2.
1706 for (size_t i = 0; i < quic::kDefaultMaxStreamsPerConnection / 2; i++) {
zhongyi98d6a9262017-05-19 02:47:451707 QuicStreamRequest request(factory_.get());
Zhongyi Shia6b68d112018-09-24 07:49:031708 int rv = request.Request(
Nick Harper23290b82019-05-02 00:02:561709 host_port_pair_, version_.transport_version, privacy_mode_,
1710 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:031711 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1712 failed_on_default_network_callback_, callback_.callback());
[email protected]0b2294d32013-08-02 00:46:361713 if (i == 0) {
robpercival214763f2016-07-01 23:27:011714 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1715 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]0b2294d32013-08-02 00:46:361716 } else {
robpercival214763f2016-07-01 23:27:011717 EXPECT_THAT(rv, IsOk());
[email protected]0b2294d32013-08-02 00:46:361718 }
Yixin Wang7891a39d2017-11-08 20:59:241719 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0b2294d32013-08-02 00:46:361720 EXPECT_TRUE(stream);
Steven Valdezb4ff0412018-01-18 22:39:271721 EXPECT_EQ(OK,
1722 stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:391723 net_log_, CompletionOnceCallback()));
avib3635452016-10-21 18:33:531724 streams.push_back(std::move(stream));
[email protected]0b2294d32013-08-02 00:46:361725 }
1726
zhongyi98d6a9262017-05-19 02:47:451727 QuicStreamRequest request(factory_.get());
Nick Harper23290b82019-05-02 00:02:561728 EXPECT_EQ(OK, request.Request(host_port_pair_, version_.transport_version,
1729 privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
Paul Jensen8e3c5d32018-02-19 17:06:331730 /*cert_verify_flags=*/0, url_, net_log_,
Zhongyi Shia6b68d112018-09-24 07:49:031731 &net_error_details_,
1732 failed_on_default_network_callback_,
1733 CompletionOnceCallback()));
Yixin Wang7891a39d2017-11-08 20:59:241734 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0b2294d32013-08-02 00:46:361735 EXPECT_TRUE(stream);
rjshaded5ced072015-12-18 19:26:021736 EXPECT_EQ(ERR_IO_PENDING,
Steven Valdezb4ff0412018-01-18 22:39:271737 stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
1738 net_log_, callback_.callback()));
[email protected]0b2294d32013-08-02 00:46:361739
1740 // Close the first stream.
1741 streams.front()->Close(false);
ckrasicea295fe2015-10-31 05:03:271742 // Trigger exchange of RSTs that in turn allow progress for the last
1743 // stream.
Frank Kastenholz878763bf2018-11-28 19:14:481744 base::RunLoop().RunUntilIdle();
robpercival214763f2016-07-01 23:27:011745 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]0b2294d32013-08-02 00:46:361746
rch37de576c2015-05-17 20:28:171747 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1748 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
ckrasicea295fe2015-10-31 05:03:271749
1750 // Force close of the connection to suppress the generation of RST
1751 // packets when streams are torn down, which wouldn't be relevant to
1752 // this test anyway.
bnc912a04b2016-04-20 14:19:501753 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521754 session->connection()->CloseConnection(
1755 quic::QUIC_PUBLIC_RESET, "test",
1756 quic::ConnectionCloseBehavior::SILENT_CLOSE);
[email protected]0b2294d32013-08-02 00:46:361757}
1758
[email protected]1e960032013-12-20 19:00:201759TEST_P(QuicStreamFactoryTest, ResolutionErrorInCreate) {
jri7046038f2015-10-22 00:29:261760 Initialize();
rcha00569732016-08-27 11:09:361761 MockQuicData socket_data;
Zhongyi Shi5f587cc2017-11-21 23:24:171762 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]e13201d82012-12-12 05:00:321763
Renjiea0cb4a2c2018-09-26 23:37:301764 host_resolver_->rules()->AddSimulatedFailure(kDefaultServerHostName);
[email protected]e13201d82012-12-12 05:00:321765
zhongyi98d6a9262017-05-19 02:47:451766 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331767 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031768 request.Request(
Nick Harper23290b82019-05-02 00:02:561769 host_port_pair_, version_.transport_version, privacy_mode_,
1770 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:031771 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1772 failed_on_default_network_callback_, callback_.callback()));
[email protected]e13201d82012-12-12 05:00:321773
robpercival214763f2016-07-01 23:27:011774 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
[email protected]e13201d82012-12-12 05:00:321775
rch37de576c2015-05-17 20:28:171776 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1777 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]e13201d82012-12-12 05:00:321778}
1779
[email protected]1e960032013-12-20 19:00:201780TEST_P(QuicStreamFactoryTest, ConnectErrorInCreate) {
jri7046038f2015-10-22 00:29:261781 Initialize();
rcha00569732016-08-27 11:09:361782
1783 MockQuicData socket_data;
1784 socket_data.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
Zhongyi Shi5f587cc2017-11-21 23:24:171785 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]3c772402013-12-18 21:38:111786
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_,
1791 DEFAULT_PRIORITY, SocketTag(),
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]3c772402013-12-18 21:38:111794
robpercival214763f2016-07-01 23:27:011795 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_ADDRESS_IN_USE));
[email protected]3c772402013-12-18 21:38:111796
rch37de576c2015-05-17 20:28:171797 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1798 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]3c772402013-12-18 21:38:111799}
1800
[email protected]1e960032013-12-20 19:00:201801TEST_P(QuicStreamFactoryTest, CancelCreate) {
jri7046038f2015-10-22 00:29:261802 Initialize();
rcha00569732016-08-27 11:09:361803 MockQuicData socket_data;
1804 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431805 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171806 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]e13201d82012-12-12 05:00:321807 {
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_,
1812 DEFAULT_PRIORITY, SocketTag(),
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]e13201d82012-12-12 05:00:321815 }
1816
mmenke651bae7f2015-12-18 21:26:451817 base::RunLoop().RunUntilIdle();
[email protected]e13201d82012-12-12 05:00:321818
zhongyi98d6a9262017-05-19 02:47:451819 QuicStreamRequest request2(factory_.get());
Nick Harper23290b82019-05-02 00:02:561820 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_.transport_version,
1821 privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
Paul Jensen8e3c5d32018-02-19 17:06:331822 /*cert_verify_flags=*/0, url_, net_log_,
Zhongyi Shia6b68d112018-09-24 07:49:031823 &net_error_details_,
1824 failed_on_default_network_callback_,
1825 callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241826 std::unique_ptr<HttpStream> stream = CreateStream(&request2);
rch68a80eb2017-04-25 05:24:241827
[email protected]e13201d82012-12-12 05:00:321828 EXPECT_TRUE(stream.get());
1829 stream.reset();
1830
rch37de576c2015-05-17 20:28:171831 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1832 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]e13201d82012-12-12 05:00:321833}
1834
[email protected]1e960032013-12-20 19:00:201835TEST_P(QuicStreamFactoryTest, CloseAllSessions) {
jri7046038f2015-10-22 00:29:261836 Initialize();
rch6faa4d42016-01-05 20:48:431837 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1838 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1839 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1840
rcha00569732016-08-27 11:09:361841 MockQuicData socket_data;
1842 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431843 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Ryan Hamilton8d9ee76e2018-05-29 23:52:521844 socket_data.AddWrite(
1845 SYNCHRONOUS, ConstructClientRstPacket(2, quic::QUIC_RST_ACKNOWLEDGEMENT));
Renjieba55fae2018-09-20 03:05:161846 socket_data.AddWrite(SYNCHRONOUS,
1847 client_maker_.MakeConnectionClosePacket(
1848 3, true, quic::QUIC_INTERNAL_ERROR, "net error"));
Zhongyi Shi5f587cc2017-11-21 23:24:171849 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]56dfb902013-01-03 23:17:551850
rcha00569732016-08-27 11:09:361851 MockQuicData socket_data2;
1852 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431853 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171854 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]56dfb902013-01-03 23:17:551855
zhongyi98d6a9262017-05-19 02:47:451856 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331857 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031858 request.Request(
Nick Harper23290b82019-05-02 00:02:561859 host_port_pair_, version_.transport_version, privacy_mode_,
1860 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:031861 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1862 failed_on_default_network_callback_, callback_.callback()));
[email protected]56dfb902013-01-03 23:17:551863
robpercival214763f2016-07-01 23:27:011864 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241865 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0b2294d32013-08-02 00:46:361866 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:391867 request_info.traffic_annotation =
1868 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:271869 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:391870 net_log_, CompletionOnceCallback()));
[email protected]56dfb902013-01-03 23:17:551871
1872 // Close the session and verify that stream saw the error.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521873 factory_->CloseAllSessions(ERR_INTERNET_DISCONNECTED,
1874 quic::QUIC_INTERNAL_ERROR);
[email protected]56dfb902013-01-03 23:17:551875 EXPECT_EQ(ERR_INTERNET_DISCONNECTED,
1876 stream->ReadResponseHeaders(callback_.callback()));
1877
1878 // Now attempting to request a stream to the same origin should create
1879 // a new session.
1880
zhongyi98d6a9262017-05-19 02:47:451881 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331882 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031883 request2.Request(
Nick Harper23290b82019-05-02 00:02:561884 host_port_pair_, version_.transport_version, privacy_mode_,
1885 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:031886 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1887 failed_on_default_network_callback_, callback_.callback()));
[email protected]56dfb902013-01-03 23:17:551888
robpercival214763f2016-07-01 23:27:011889 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241890 stream = CreateStream(&request2);
[email protected]56dfb902013-01-03 23:17:551891 stream.reset(); // Will reset stream 3.
1892
rch37de576c2015-05-17 20:28:171893 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1894 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1895 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1896 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]56dfb902013-01-03 23:17:551897}
1898
zhongyi363c91c2017-03-23 23:16:081899// Regression test for crbug.com/700617. Test a write error during the
1900// crypto handshake will not hang QuicStreamFactory::Job and should
1901// report QUIC_HANDSHAKE_FAILED to upper layers. Subsequent
1902// QuicStreamRequest should succeed without hanging.
1903TEST_P(QuicStreamFactoryTest,
1904 WriteErrorInCryptoConnectWithAsyncHostResolution) {
1905 Initialize();
1906 // Use unmocked crypto stream to do crypto connect.
1907 crypto_client_stream_factory_.set_handshake_mode(
Zhongyi Shi879659422018-08-02 17:58:251908 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
zhongyi363c91c2017-03-23 23:16:081909
1910 MockQuicData socket_data;
1911 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1912 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
1913 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:171914 socket_data.AddSocketDataToFactory(socket_factory_.get());
zhongyi363c91c2017-03-23 23:16:081915
1916 // Create request, should fail after the write of the CHLO fails.
zhongyi98d6a9262017-05-19 02:47:451917 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331918 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031919 request.Request(
Nick Harper23290b82019-05-02 00:02:561920 host_port_pair_, version_.transport_version, privacy_mode_,
1921 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:031922 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1923 failed_on_default_network_callback_, callback_.callback()));
zhongyi363c91c2017-03-23 23:16:081924 EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED, callback_.WaitForResult());
1925 EXPECT_FALSE(HasActiveSession(host_port_pair_));
1926 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
1927
1928 // Verify new requests can be sent normally without hanging.
1929 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271930 MockCryptoClientStream::COLD_START);
zhongyi363c91c2017-03-23 23:16:081931 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1932 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1933 MockQuicData socket_data2;
1934 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431935 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171936 socket_data2.AddSocketDataToFactory(socket_factory_.get());
zhongyi363c91c2017-03-23 23:16:081937
zhongyi98d6a9262017-05-19 02:47:451938 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331939 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031940 request2.Request(
Nick Harper23290b82019-05-02 00:02:561941 host_port_pair_, version_.transport_version, privacy_mode_,
1942 DEFAULT_PRIORITY, SocketTag(),
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_FALSE(HasActiveSession(host_port_pair_));
1946 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
1947 // Run the message loop to complete host resolution.
1948 base::RunLoop().RunUntilIdle();
1949
1950 // Complete handshake. QuicStreamFactory::Job should complete and succeed.
1951 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521952 quic::QuicSession::HANDSHAKE_CONFIRMED);
zhongyi363c91c2017-03-23 23:16:081953 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1954 EXPECT_TRUE(HasActiveSession(host_port_pair_));
1955 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
1956
1957 // Create QuicHttpStream.
Yixin Wang7891a39d2017-11-08 20:59:241958 std::unique_ptr<HttpStream> stream = CreateStream(&request2);
zhongyi363c91c2017-03-23 23:16:081959 EXPECT_TRUE(stream.get());
1960 stream.reset();
1961 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1962 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1963 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1964 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
1965}
1966
1967TEST_P(QuicStreamFactoryTest, WriteErrorInCryptoConnectWithSyncHostResolution) {
1968 Initialize();
1969 // Use unmocked crypto stream to do crypto connect.
1970 crypto_client_stream_factory_.set_handshake_mode(
Zhongyi Shi879659422018-08-02 17:58:251971 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
Renjiea0cb4a2c2018-09-26 23:37:301972 host_resolver_->set_synchronous_mode(true);
1973 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
1974 "192.168.0.1", "");
zhongyi363c91c2017-03-23 23:16:081975
1976 MockQuicData socket_data;
1977 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1978 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
1979 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:171980 socket_data.AddSocketDataToFactory(socket_factory_.get());
zhongyi363c91c2017-03-23 23:16:081981
1982 // Create request, should fail immediately.
zhongyi98d6a9262017-05-19 02:47:451983 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331984 EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED,
Zhongyi Shia6b68d112018-09-24 07:49:031985 request.Request(
Nick Harper23290b82019-05-02 00:02:561986 host_port_pair_, version_.transport_version, privacy_mode_,
1987 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:031988 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1989 failed_on_default_network_callback_, callback_.callback()));
zhongyi363c91c2017-03-23 23:16:081990 // Check no active session, or active jobs left for this server.
1991 EXPECT_FALSE(HasActiveSession(host_port_pair_));
1992 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
1993
1994 // Verify new requests can be sent normally without hanging.
1995 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271996 MockCryptoClientStream::COLD_START);
zhongyi363c91c2017-03-23 23:16:081997 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1998 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1999 MockQuicData socket_data2;
2000 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432001 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:172002 socket_data2.AddSocketDataToFactory(socket_factory_.get());
zhongyi363c91c2017-03-23 23:16:082003
zhongyi98d6a9262017-05-19 02:47:452004 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332005 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032006 request2.Request(
Nick Harper23290b82019-05-02 00:02:562007 host_port_pair_, version_.transport_version, privacy_mode_,
2008 DEFAULT_PRIORITY, SocketTag(),
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 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2012 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
2013
2014 // Complete handshake.
2015 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522016 quic::QuicSession::HANDSHAKE_CONFIRMED);
zhongyi363c91c2017-03-23 23:16:082017 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2018 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2019 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
2020
2021 // Create QuicHttpStream.
Yixin Wang7891a39d2017-11-08 20:59:242022 std::unique_ptr<HttpStream> stream = CreateStream(&request2);
zhongyi363c91c2017-03-23 23:16:082023 EXPECT_TRUE(stream.get());
2024 stream.reset();
2025 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2026 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2027 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
2028 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
2029}
2030
Zhongyi Shi63574b72018-06-01 20:22:252031TEST_P(QuicStreamFactoryTest, CloseSessionsOnIPAddressChanged) {
Zhongyi Shi967d2f12019-02-08 20:58:532032 test_params_.quic_close_sessions_on_ip_change = true;
jri7046038f2015-10-22 00:29:262033 Initialize();
rch6faa4d42016-01-05 20:48:432034 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2035 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2036 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri8c44d692015-10-23 23:53:412037
rcha00569732016-08-27 11:09:362038 MockQuicData socket_data;
2039 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432040 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Ryan Hamilton8d9ee76e2018-05-29 23:52:522041 socket_data.AddWrite(
2042 SYNCHRONOUS, ConstructClientRstPacket(2, quic::QUIC_RST_ACKNOWLEDGEMENT));
Renjieba55fae2018-09-20 03:05:162043 socket_data.AddWrite(
2044 SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
2045 3, true, quic::QUIC_IP_ADDRESS_CHANGED, "net error"));
Zhongyi Shi5f587cc2017-11-21 23:24:172046 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]f698a012013-05-06 20:18:592047
rcha00569732016-08-27 11:09:362048 MockQuicData socket_data2;
2049 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432050 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:172051 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]f698a012013-05-06 20:18:592052
zhongyi98d6a9262017-05-19 02:47:452053 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332054 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032055 request.Request(
Nick Harper23290b82019-05-02 00:02:562056 host_port_pair_, version_.transport_version, privacy_mode_,
2057 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:032058 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2059 failed_on_default_network_callback_, callback_.callback()));
[email protected]f698a012013-05-06 20:18:592060
robpercival214763f2016-07-01 23:27:012061 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242062 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0b2294d32013-08-02 00:46:362063 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392064 request_info.traffic_annotation =
2065 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272066 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392067 net_log_, CompletionOnceCallback()));
[email protected]f698a012013-05-06 20:18:592068
Zhongyi Shi63574b72018-06-01 20:22:252069 // Check an active session exisits for the destination.
2070 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2071 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
2072 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2073
Ryan Hamilton8e32a2b2017-08-28 20:06:522074 IPAddress last_address;
2075 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
Zhongyi Shi63574b72018-06-01 20:22:252076 // Change the IP address and verify that stream saw the error and the active
2077 // session is closed.
jri8c44d692015-10-23 23:53:412078 NotifyIPAddressChanged();
[email protected]f698a012013-05-06 20:18:592079 EXPECT_EQ(ERR_NETWORK_CHANGED,
2080 stream->ReadResponseHeaders(callback_.callback()));
jri7046038f2015-10-22 00:29:262081 EXPECT_TRUE(factory_->require_confirmation());
Ryan Hamilton8e32a2b2017-08-28 20:06:522082 EXPECT_FALSE(http_server_properties_.GetSupportsQuic(&last_address));
Zhongyi Shi63574b72018-06-01 20:22:252083 // Check no active session exists for the destination.
2084 EXPECT_FALSE(HasActiveSession(host_port_pair_));
[email protected]f698a012013-05-06 20:18:592085
2086 // Now attempting to request a stream to the same origin should create
2087 // a new session.
zhongyi98d6a9262017-05-19 02:47:452088 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332089 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032090 request2.Request(
Nick Harper23290b82019-05-02 00:02:562091 host_port_pair_, version_.transport_version, privacy_mode_,
2092 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:032093 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2094 failed_on_default_network_callback_, callback_.callback()));
[email protected]f698a012013-05-06 20:18:592095
robpercival214763f2016-07-01 23:27:012096 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242097 stream = CreateStream(&request2);
[email protected]f698a012013-05-06 20:18:592098
Zhongyi Shi63574b72018-06-01 20:22:252099 // Check a new active session exisits for the destination and the old session
2100 // is no longer live.
2101 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2102 QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
2103 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
2104
2105 stream.reset(); // Will reset stream 3.
rch37de576c2015-05-17 20:28:172106 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2107 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2108 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
2109 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]f698a012013-05-06 20:18:592110}
2111
Zhongyi Shi63574b72018-06-01 20:22:252112// Test that if goaway_session_on_ip_change is set, old sessions will be marked
2113// as going away on IP address change instead of being closed. New requests will
2114// go to a new connection.
2115TEST_P(QuicStreamFactoryTest, GoAwaySessionsOnIPAddressChanged) {
Zhongyi Shi967d2f12019-02-08 20:58:532116 test_params_.quic_goaway_sessions_on_ip_change = true;
Zhongyi Shi63574b72018-06-01 20:22:252117 Initialize();
2118 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2119 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2120 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2121
2122 MockQuicData quic_data1;
2123 quic::QuicStreamOffset header_stream_offset = 0;
2124 quic_data1.AddWrite(SYNCHRONOUS,
2125 ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:332126 quic_data1.AddWrite(
2127 SYNCHRONOUS, ConstructGetRequestPacket(
2128 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
2129 true, &header_stream_offset));
Zhongyi Shi63574b72018-06-01 20:22:252130 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
2131 quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:332132 ASYNC,
2133 ConstructOkResponsePacket(
2134 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true));
Zhongyi Shi63574b72018-06-01 20:22:252135 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
2136 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2137
2138 MockQuicData quic_data2;
2139 quic::QuicStreamOffset header_stream_offset2 = 0;
2140 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
2141 quic_data2.AddWrite(
2142 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset2));
2143 quic_data2.AddSocketDataToFactory(socket_factory_.get());
2144
2145 // Create request and QuicHttpStream.
2146 QuicStreamRequest request(factory_.get());
2147 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032148 request.Request(
Nick Harper23290b82019-05-02 00:02:562149 host_port_pair_, version_.transport_version, privacy_mode_,
2150 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:032151 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2152 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi63574b72018-06-01 20:22:252153 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2154 std::unique_ptr<HttpStream> stream = CreateStream(&request);
2155 EXPECT_TRUE(stream.get());
2156
2157 // Cause QUIC stream to be created.
2158 HttpRequestInfo request_info;
2159 request_info.method = "GET";
2160 request_info.url = url_;
2161 request_info.traffic_annotation =
2162 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2163 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
2164 net_log_, CompletionOnceCallback()));
2165
2166 // Ensure that session is alive and active.
2167 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
2168 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2169 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2170
2171 // Send GET request on stream.
2172 HttpResponseInfo response;
2173 HttpRequestHeaders request_headers;
2174 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
2175 callback_.callback()));
2176
2177 // Receive an IP address change notification.
2178 NotifyIPAddressChanged();
2179
2180 // The connection should still be alive, but marked as going away.
2181 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2182 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2183 EXPECT_EQ(1u, session->GetNumActiveStreams());
2184
2185 // Resume the data, response should be read from the original connection.
2186 quic_data1.Resume();
2187 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
2188 EXPECT_EQ(200, response.headers->response_code());
2189 EXPECT_EQ(0u, session->GetNumActiveStreams());
2190
2191 // Second request should be sent on a new connection.
2192 QuicStreamRequest request2(factory_.get());
2193 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032194 request2.Request(
Nick Harper23290b82019-05-02 00:02:562195 host_port_pair_, version_.transport_version, privacy_mode_,
2196 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:032197 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2198 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi63574b72018-06-01 20:22:252199 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2200 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
2201 EXPECT_TRUE(stream2.get());
2202
2203 // Check an active session exisits for the destination.
2204 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2205 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2206 QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
2207 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
2208
2209 stream.reset();
2210 stream2.reset();
2211 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
2212 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
2213 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
2214 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
2215}
2216
Jana Iyengarba355772017-09-21 22:03:212217TEST_P(QuicStreamFactoryTest, OnIPAddressChangedWithConnectionMigration) {
Zhongyi Shi1a054612018-06-14 04:59:082218 InitializeConnectionMigrationV2Test(
Jana Iyengarba355772017-09-21 22:03:212219 {kDefaultNetworkForTests, kNewNetworkForTests});
2220 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2221 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2222 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2223
2224 MockQuicData socket_data;
2225 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432226 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Ryan Hamilton8d9ee76e2018-05-29 23:52:522227 socket_data.AddWrite(
2228 SYNCHRONOUS, ConstructClientRstPacket(2, quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:172229 socket_data.AddSocketDataToFactory(socket_factory_.get());
Jana Iyengarba355772017-09-21 22:03:212230
2231 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332232 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032233 request.Request(
Nick Harper23290b82019-05-02 00:02:562234 host_port_pair_, version_.transport_version, privacy_mode_,
2235 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:032236 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2237 failed_on_default_network_callback_, callback_.callback()));
Jana Iyengarba355772017-09-21 22:03:212238
2239 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242240 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Jana Iyengarba355772017-09-21 22:03:212241 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392242 request_info.traffic_annotation =
2243 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272244 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392245 net_log_, CompletionOnceCallback()));
Jana Iyengarba355772017-09-21 22:03:212246
2247 IPAddress last_address;
2248 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
2249
2250 // Change the IP address and verify that the connection is unaffected.
2251 NotifyIPAddressChanged();
2252 EXPECT_FALSE(factory_->require_confirmation());
2253 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
2254
2255 // Attempting a new request to the same origin uses the same connection.
2256 QuicStreamRequest request2(factory_.get());
Nick Harper23290b82019-05-02 00:02:562257 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_.transport_version,
2258 privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
Paul Jensen8e3c5d32018-02-19 17:06:332259 /*cert_verify_flags=*/0, url_, net_log_,
Zhongyi Shia6b68d112018-09-24 07:49:032260 &net_error_details_,
2261 failed_on_default_network_callback_,
2262 callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:242263 stream = CreateStream(&request2);
Jana Iyengarba355772017-09-21 22:03:212264
2265 stream.reset();
2266 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2267 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2268}
2269
Zhongyi Shia0644e32018-06-21 05:19:522270TEST_P(QuicStreamFactoryTest, MigrateOnNetworkMadeDefaultWithSynchronousWrite) {
2271 TestMigrationOnNetworkMadeDefault(SYNCHRONOUS);
jri9f303712016-09-13 01:10:222272}
2273
Zhongyi Shia0644e32018-06-21 05:19:522274TEST_P(QuicStreamFactoryTest, MigrateOnNetworkMadeDefaultWithAsyncWrite) {
2275 TestMigrationOnNetworkMadeDefault(ASYNC);
jri9f303712016-09-13 01:10:222276}
2277
Zhongyi Shia0644e32018-06-21 05:19:522278// Sets up a test which attempts connection migration successfully after probing
2279// when a new network is made as default and the old default is still available.
2280// |write_mode| specifies the write mode for the last write before
2281// OnNetworkMadeDefault is delivered to session.
2282void QuicStreamFactoryTestBase::TestMigrationOnNetworkMadeDefault(
2283 IoMode write_mode) {
2284 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri7e636642016-01-14 06:57:082285 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2286 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2287 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2288
Zhongyi Shia0644e32018-06-21 05:19:522289 // Using a testing task runner so that we can control time.
2290 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
2291 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
2292
2293 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2294 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
2295
2296 MockQuicData quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522297 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shia0644e32018-06-21 05:19:522298 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
2299 quic_data1.AddWrite(SYNCHRONOUS,
2300 ConstructInitialSettingsPacket(1, &header_stream_offset));
2301 quic_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:332302 write_mode, ConstructGetRequestPacket(
2303 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
2304 true, &header_stream_offset));
Zhongyi Shia0644e32018-06-21 05:19:522305 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2306
2307 // Set up the second socket data provider that is used after migration.
2308 // The response to the earlier request is read on the new socket.
2309 MockQuicData quic_data2;
2310 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:252311 quic_data2.AddWrite(SYNCHRONOUS,
2312 client_maker_.MakeConnectivityProbingPacket(3, true));
Zhongyi Shia0644e32018-06-21 05:19:522313 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
2314 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:252315 quic_data2.AddRead(ASYNC,
2316 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shia0644e32018-06-21 05:19:522317 // Ping packet to send after migration is completed.
2318 quic_data2.AddWrite(ASYNC,
2319 client_maker_.MakeAckAndPingPacket(4, false, 1, 1, 1));
2320 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:332321 ASYNC,
2322 ConstructOkResponsePacket(
2323 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shia0644e32018-06-21 05:19:522324 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:332325 quic_data2.AddWrite(
2326 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
2327 5, false, GetNthClientInitiatedBidirectionalStreamId(0),
2328 quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true));
Zhongyi Shia0644e32018-06-21 05:19:522329 quic_data2.AddSocketDataToFactory(socket_factory_.get());
jri7e636642016-01-14 06:57:082330
2331 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452332 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332333 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032334 request.Request(
Nick Harper23290b82019-05-02 00:02:562335 host_port_pair_, version_.transport_version, privacy_mode_,
2336 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:032337 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2338 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012339 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242340 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri7e636642016-01-14 06:57:082341 EXPECT_TRUE(stream.get());
2342
2343 // Cause QUIC stream to be created.
2344 HttpRequestInfo request_info;
2345 request_info.method = "GET";
bnc3d9035b32016-06-30 18:18:482346 request_info.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:392347 request_info.traffic_annotation =
2348 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272349 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392350 net_log_, CompletionOnceCallback()));
jri7e636642016-01-14 06:57:082351
2352 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502353 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri7e636642016-01-14 06:57:082354 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2355 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2356
2357 // Send GET request on stream.
2358 HttpResponseInfo response;
2359 HttpRequestHeaders request_headers;
2360 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
2361 callback_.callback()));
2362
Zhongyi Shia0644e32018-06-21 05:19:522363 // Deliver a signal that a alternate network is connected now, this should
2364 // cause the connection to start early migration on path degrading.
2365 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2366 ->SetConnectedNetworksList(
2367 {kDefaultNetworkForTests, kNewNetworkForTests});
2368 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2369 ->NotifyNetworkConnected(kNewNetworkForTests);
jri9f303712016-09-13 01:10:222370
Zhongyi Shia0644e32018-06-21 05:19:522371 // Cause the connection to report path degrading to the session.
2372 // Due to lack of alternate network, session will not mgirate connection.
2373 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
jri7e636642016-01-14 06:57:082374 scoped_mock_network_change_notifier_->mock_network_change_notifier()
jrie2661982016-08-20 08:24:342375 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri7e636642016-01-14 06:57:082376
Zhongyi Shia0644e32018-06-21 05:19:522377 // A task will be posted to migrate to the new default network.
2378 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2379 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
2380
2381 // Execute the posted task to migrate back to the default network.
2382 task_runner->RunUntilIdle();
2383 // Another task to try send a new connectivity probe is posted. And a task to
2384 // retry migrate back to default network is scheduled.
2385 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
2386 // Next connectivity probe is scheduled to be sent in 2 *
2387 // kDefaultRTTMilliSecs.
2388 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
2389 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
2390 next_task_delay);
2391
2392 // The connection should still be alive, and not marked as going away.
jri7e636642016-01-14 06:57:082393 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia0644e32018-06-21 05:19:522394 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2395 EXPECT_EQ(1u, session->GetNumActiveStreams());
2396 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
2397
2398 // Resume quic data and a connectivity probe response will be read on the new
2399 // socket, declare probing as successful. And a new task to WriteToNewSocket
2400 // will be posted to complete migration.
2401 quic_data2.Resume();
2402
2403 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2404 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri7e636642016-01-14 06:57:082405 EXPECT_EQ(1u, session->GetNumActiveStreams());
2406
Zhongyi Shia0644e32018-06-21 05:19:522407 // There should be three pending tasks, the nearest one will complete
2408 // migration to the new network.
2409 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
2410 next_task_delay = task_runner->NextPendingTaskDelay();
2411 EXPECT_EQ(base::TimeDelta(), next_task_delay);
2412 task_runner->FastForwardBy(next_task_delay);
2413
2414 // Response headers are received over the new network.
2415 EXPECT_THAT(callback_.WaitForResult(), IsOk());
jri7e636642016-01-14 06:57:082416 EXPECT_EQ(200, response.headers->response_code());
2417
Zhongyi Shia0644e32018-06-21 05:19:522418 // Now there are two pending tasks, the nearest one was to send connectivity
2419 // probe and has been cancelled due to successful migration.
2420 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
2421 next_task_delay = task_runner->NextPendingTaskDelay();
2422 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
2423 next_task_delay);
2424 task_runner->FastForwardBy(next_task_delay);
jri7e636642016-01-14 06:57:082425
Zhongyi Shia0644e32018-06-21 05:19:522426 // There's one more task to mgirate back to the default network in 0.4s, which
2427 // is also cancelled due to the success migration on the previous trial.
2428 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2429 next_task_delay = task_runner->NextPendingTaskDelay();
2430 base::TimeDelta expected_delay =
2431 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
2432 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
2433 EXPECT_EQ(expected_delay, next_task_delay);
2434 task_runner->FastForwardBy(next_task_delay);
2435 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
jri7e636642016-01-14 06:57:082436
Zhongyi Shia0644e32018-06-21 05:19:522437 // Verify that the session is still alive.
jri7e636642016-01-14 06:57:082438 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia0644e32018-06-21 05:19:522439 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri7e636642016-01-14 06:57:082440
Zhongyi Shia0644e32018-06-21 05:19:522441 stream.reset();
2442 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
2443 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
2444 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
2445 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
jri7e636642016-01-14 06:57:082446}
2447
Zhongyi Shib3bc982c2018-07-10 19:59:242448// Regression test for http://859674.
2449// This test veries that a writer will not attempt to write packets until being
2450// unblocked on both socket level and network level. In this test, a probing
2451// writer is used to send two connectivity probes to the peer: where the first
2452// one completes successfully, while a connectivity response is received before
2453// completes sending the second one. The connection migration attempt will
2454// proceed while the probing writer is blocked at the socket level, which will
2455// block the writer on the network level. Once connection migration completes
2456// successfully, the probing writer will be unblocked on the network level, it
2457// will not attempt to write new packets until the socket level is unblocked.
2458TEST_P(QuicStreamFactoryTest, MigratedToBlockedSocketAfterProbing) {
2459 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
2460 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2461 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2462 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2463
2464 // Using a testing task runner so that we can control time.
2465 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
2466 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
2467
2468 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2469 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
2470
2471 MockQuicData quic_data1;
2472 quic::QuicStreamOffset header_stream_offset = 0;
2473 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
2474 quic_data1.AddWrite(SYNCHRONOUS,
2475 ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:332476 quic_data1.AddWrite(
2477 SYNCHRONOUS, ConstructGetRequestPacket(
2478 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
2479 true, &header_stream_offset));
Zhongyi Shib3bc982c2018-07-10 19:59:242480 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2481
2482 // Set up the second socket data provider that is used after migration.
2483 // The response to the earlier request is read on the new socket.
2484 MockQuicData quic_data2;
2485 // First connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:252486 quic_data2.AddWrite(SYNCHRONOUS,
2487 client_maker_.MakeConnectivityProbingPacket(3, true));
Zhongyi Shib3bc982c2018-07-10 19:59:242488 quic_data2.AddRead(ASYNC,
2489 ERR_IO_PENDING); // Pause so that we can control time.
2490 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:252491 quic_data2.AddRead(ASYNC,
2492 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shib3bc982c2018-07-10 19:59:242493 // Second connectivity probe which will complete asynchronously.
Zhongyi Shi879659422018-08-02 17:58:252494 quic_data2.AddWrite(ASYNC,
2495 client_maker_.MakeConnectivityProbingPacket(4, true));
Zhongyi Shib3bc982c2018-07-10 19:59:242496 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:332497 ASYNC,
2498 ConstructOkResponsePacket(
2499 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shib3bc982c2018-07-10 19:59:242500 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2501 quic_data2.AddWrite(ASYNC,
2502 client_maker_.MakeAckAndPingPacket(5, false, 1, 1, 1));
Fan Yang32c5a112018-12-10 20:06:332503 quic_data2.AddWrite(
2504 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
2505 6, false, GetNthClientInitiatedBidirectionalStreamId(0),
2506 quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true));
Zhongyi Shib3bc982c2018-07-10 19:59:242507
2508 quic_data2.AddSocketDataToFactory(socket_factory_.get());
2509
2510 // Create request and QuicHttpStream.
2511 QuicStreamRequest request(factory_.get());
2512 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032513 request.Request(
Nick Harper23290b82019-05-02 00:02:562514 host_port_pair_, version_.transport_version, privacy_mode_,
2515 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:032516 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2517 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shib3bc982c2018-07-10 19:59:242518 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2519 std::unique_ptr<HttpStream> stream = CreateStream(&request);
2520 EXPECT_TRUE(stream.get());
2521
2522 // Cause QUIC stream to be created.
2523 HttpRequestInfo request_info;
2524 request_info.method = "GET";
2525 request_info.url = url_;
2526 request_info.traffic_annotation =
2527 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2528 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
2529 net_log_, CompletionOnceCallback()));
2530
2531 // Ensure that session is alive and active.
2532 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
2533 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2534 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2535
2536 // Send GET request on stream.
2537 HttpResponseInfo response;
2538 HttpRequestHeaders request_headers;
2539 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
2540 callback_.callback()));
2541
2542 // Deliver a signal that a alternate network is connected now, this should
2543 // cause the connection to start early migration on path degrading.
2544 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2545 ->SetConnectedNetworksList(
2546 {kDefaultNetworkForTests, kNewNetworkForTests});
2547 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2548 ->NotifyNetworkConnected(kNewNetworkForTests);
2549
2550 // Cause the connection to report path degrading to the session.
2551 // Due to lack of alternate network, session will not mgirate connection.
2552 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
2553 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2554 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2555
2556 // A task will be posted to migrate to the new default network.
2557 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2558 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
2559
2560 // Execute the posted task to migrate back to the default network.
2561 task_runner->RunUntilIdle();
2562 // Another task to resend a new connectivity probe is posted. And a task to
2563 // retry migrate back to default network is scheduled.
2564 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
2565 // Next connectivity probe is scheduled to be sent in 2 *
2566 // kDefaultRTTMilliSecs.
2567 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
2568 base::TimeDelta expected_delay =
2569 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
2570 EXPECT_EQ(expected_delay, next_task_delay);
2571
2572 // Fast forward to send the second connectivity probe. The write will be
2573 // asynchronous and complete after the read completes.
2574 task_runner->FastForwardBy(next_task_delay);
2575
2576 // Resume quic data and a connectivity probe response will be read on the new
2577 // socket, declare probing as successful.
2578 quic_data2.Resume();
2579
2580 // The connection should still be alive, and not marked as going away.
2581 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2582 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2583 EXPECT_EQ(1u, session->GetNumActiveStreams());
2584 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
2585
2586 // There should be three pending tasks, the nearest one will complete
2587 // migration to the new network. Second task will retry migrate back to
2588 // default but cancelled, and the third task will retry send connectivity
2589 // probe but also cancelled.
2590 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
2591 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
2592 task_runner->RunUntilIdle();
2593
2594 // Response headers are received over the new network.
2595 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2596 EXPECT_EQ(200, response.headers->response_code());
2597
2598 // Run the message loop to complete the asynchronous write of ack and ping.
2599 base::RunLoop().RunUntilIdle();
2600
2601 // Now there are two pending tasks, the nearest one was to retry migrate back
2602 // to default network and has been cancelled due to successful migration.
2603 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
2604 expected_delay =
2605 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
2606 expected_delay;
2607 next_task_delay = task_runner->NextPendingTaskDelay();
2608 EXPECT_EQ(expected_delay, next_task_delay);
2609 task_runner->FastForwardBy(next_task_delay);
2610
2611 // There's one more task to retry sending connectivity probe in 0.4s and has
2612 // also been cancelled due to the successful probing.
2613 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2614 next_task_delay = task_runner->NextPendingTaskDelay();
2615 expected_delay =
2616 base::TimeDelta::FromMilliseconds(3 * 2 * kDefaultRTTMilliSecs) -
2617 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs);
2618 EXPECT_EQ(expected_delay, next_task_delay);
2619 task_runner->FastForwardBy(next_task_delay);
2620 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
2621
2622 // Verify that the session is still alive.
2623 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2624 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2625
2626 stream.reset();
2627 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
2628 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
2629 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
2630 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
2631}
2632
Zhongyi Shib1b1fa42018-06-19 23:13:472633// This test verifies that session times out connection migration attempt
2634// with signals delivered in the following order (no alternate network is
2635// available):
2636// - default network disconnected is delivered: session attempts connection
2637// migration but found not alternate network. Session waits for a new network
Zhongyi Shie01f2db2019-02-22 19:53:232638// comes up in the next kWaitTimeForNewNetworkSecs seconds.
Zhongyi Shib1b1fa42018-06-19 23:13:472639// - no new network is connected, migration times out. Session is closed.
2640TEST_P(QuicStreamFactoryTest, MigrationTimeoutWithNoNewNetwork) {
2641 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri7e636642016-01-14 06:57:082642 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2643 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2644
Zhongyi Shib1b1fa42018-06-19 23:13:472645 // Using a testing task runner so that we can control time.
2646 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
2647 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
jri5b785512016-09-13 04:29:112648
rcha00569732016-08-27 11:09:362649 MockQuicData socket_data;
2650 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432651 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:172652 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri7e636642016-01-14 06:57:082653
2654 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452655 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332656 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032657 request.Request(
Nick Harper23290b82019-05-02 00:02:562658 host_port_pair_, version_.transport_version, privacy_mode_,
2659 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:032660 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2661 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012662 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242663 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri7e636642016-01-14 06:57:082664 EXPECT_TRUE(stream.get());
2665
2666 // Cause QUIC stream to be created.
2667 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392668 request_info.traffic_annotation =
2669 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272670 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392671 net_log_, CompletionOnceCallback()));
jri7e636642016-01-14 06:57:082672
2673 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502674 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri7e636642016-01-14 06:57:082675 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2676 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2677
2678 // Trigger connection migration. Since there are no networks
jri5b785512016-09-13 04:29:112679 // to migrate to, this should cause the session to wait for a new network.
jri7e636642016-01-14 06:57:082680 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2681 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
2682
jri5b785512016-09-13 04:29:112683 // The migration will not fail until the migration alarm timeout.
2684 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shib1b1fa42018-06-19 23:13:472685 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:112686 EXPECT_EQ(1u, session->GetNumActiveStreams());
2687 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
2688 EXPECT_EQ(true, session->connection()->writer()->IsWriteBlocked());
2689
Zhongyi Shib1b1fa42018-06-19 23:13:472690 // Migration will be timed out after kWaitTimeForNewNetwokSecs.
2691 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2692 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
2693 EXPECT_EQ(base::TimeDelta::FromSeconds(kWaitTimeForNewNetworkSecs),
2694 next_task_delay);
2695 task_runner->FastForwardBy(next_task_delay);
jri5b785512016-09-13 04:29:112696
2697 // The connection should now be closed. A request for response
2698 // headers should fail.
jri7e636642016-01-14 06:57:082699 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2700 EXPECT_FALSE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:112701 EXPECT_EQ(ERR_NETWORK_CHANGED, callback_.WaitForResult());
jri7e636642016-01-14 06:57:082702
2703 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2704 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2705}
2706
Zhongyi Shi21e99532018-07-17 22:23:072707// This test verifies that connectivity probes will be sent even if there is
2708// a non-migratable stream. However, when connection migrates to the
Zhongyi Shic16b4102019-02-12 00:37:402709// successfully probed path, any non-migratable streams will be reset.
Zhongyi Shi32fe14d42019-02-28 00:25:362710TEST_P(QuicStreamFactoryTest,
2711 OnNetworkMadeDefaultNonMigratableStream_MigrateIdleSessions) {
2712 TestOnNetworkMadeDefaultNonMigratableStream(true);
2713}
2714
2715// This test verifies that connectivity probes will be sent even if there is
2716// a non-migratable stream. However, when connection migrates to the
2717// successfully probed path, any non-migratable stream will be reset. And if
2718// the connection becomes idle then, close the connection.
2719TEST_P(QuicStreamFactoryTest,
2720 OnNetworkMadeDefaultNonMigratableStream_DoNotMigrateIdleSessions) {
2721 TestOnNetworkMadeDefaultNonMigratableStream(false);
2722}
2723
2724void QuicStreamFactoryTestBase::TestOnNetworkMadeDefaultNonMigratableStream(
2725 bool migrate_idle_sessions) {
2726 test_params_.quic_migrate_idle_sessions = migrate_idle_sessions;
Zhongyi Shi5f587cc2017-11-21 23:24:172727 InitializeConnectionMigrationV2Test(
2728 {kDefaultNetworkForTests, kNewNetworkForTests});
2729 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2730 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2731
2732 MockQuicData socket_data;
2733 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432734 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi32fe14d42019-02-28 00:25:362735 if (!migrate_idle_sessions) {
2736 socket_data.AddWrite(
2737 SYNCHRONOUS,
2738 client_maker_.MakeRstAckAndConnectionClosePacket(
2739 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
2740 quic::QUIC_STREAM_CANCELLED,
2741 quic::QuicTime::Delta::FromMilliseconds(0), 1, 1, 1,
2742 quic::QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS,
2743 "net error"));
2744 }
Renjieba55fae2018-09-20 03:05:162745
Zhongyi Shi5f587cc2017-11-21 23:24:172746 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri231c2972016-03-08 19:50:112747
Zhongyi Shi21e99532018-07-17 22:23:072748 // Set up the second socket data provider that is used for probing.
2749 MockQuicData quic_data1;
2750 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:252751 quic_data1.AddWrite(SYNCHRONOUS,
2752 client_maker_.MakeConnectivityProbingPacket(2, true));
Zhongyi Shi21e99532018-07-17 22:23:072753 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
2754 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:252755 quic_data1.AddRead(ASYNC,
2756 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shi32fe14d42019-02-28 00:25:362757 if (migrate_idle_sessions) {
2758 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
2759 // A RESET will be sent to the peer to cancel the non-migratable stream.
2760 quic_data1.AddWrite(
2761 SYNCHRONOUS,
2762 client_maker_.MakeRstPacket(
2763 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
2764 quic::QUIC_STREAM_CANCELLED));
2765 // Ping packet to send after migration is completed.
2766 quic_data1.AddWrite(SYNCHRONOUS,
2767 client_maker_.MakeAckAndPingPacket(4, false, 1, 1, 1));
2768 }
Zhongyi Shi21e99532018-07-17 22:23:072769 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2770
jri231c2972016-03-08 19:50:112771 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452772 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332773 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032774 request.Request(
Nick Harper23290b82019-05-02 00:02:562775 host_port_pair_, version_.transport_version, privacy_mode_,
2776 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:032777 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2778 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012779 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242780 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri231c2972016-03-08 19:50:112781 EXPECT_TRUE(stream.get());
2782
2783 // Cause QUIC stream to be created, but marked as non-migratable.
2784 HttpRequestInfo request_info;
Zhongyi Shibb28b1f2018-07-18 02:41:262785 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Ramin Halavati683bcaa92018-02-14 08:42:392786 request_info.traffic_annotation =
2787 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272788 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392789 net_log_, CompletionOnceCallback()));
jri231c2972016-03-08 19:50:112790
2791 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502792 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri231c2972016-03-08 19:50:112793 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2794 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2795
Zhongyi Shi21e99532018-07-17 22:23:072796 // Trigger connection migration. Session will start to probe the alternative
2797 // network. Although there is a non-migratable stream, session will still be
2798 // active until probing is declared as successful.
jri231c2972016-03-08 19:50:112799 scoped_mock_network_change_notifier_->mock_network_change_notifier()
jrie2661982016-08-20 08:24:342800 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri231c2972016-03-08 19:50:112801
2802 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shi21e99532018-07-17 22:23:072803 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri231c2972016-03-08 19:50:112804 EXPECT_EQ(1u, session->GetNumActiveStreams());
2805
Zhongyi Shi21e99532018-07-17 22:23:072806 // Resume data to read a connectivity probing response, which will cause
Zhongyi Shic16b4102019-02-12 00:37:402807 // non-migtable streams to be closed.
Zhongyi Shi21e99532018-07-17 22:23:072808 quic_data1.Resume();
2809 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shi32fe14d42019-02-28 00:25:362810 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(host_port_pair_));
Zhongyi Shi21e99532018-07-17 22:23:072811 EXPECT_EQ(0u, session->GetNumActiveStreams());
jri231c2972016-03-08 19:50:112812
Zhongyi Shic16b4102019-02-12 00:37:402813 base::RunLoop().RunUntilIdle();
2814
Zhongyi Shi21e99532018-07-17 22:23:072815 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
2816 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
jri231c2972016-03-08 19:50:112817 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2818 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2819}
2820
jri9f303712016-09-13 01:10:222821TEST_P(QuicStreamFactoryTest, OnNetworkMadeDefaultConnectionMigrationDisabled) {
Zhongyi Shi5f587cc2017-11-21 23:24:172822 InitializeConnectionMigrationV2Test(
2823 {kDefaultNetworkForTests, kNewNetworkForTests});
2824 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2825 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2826
2827 MockQuicData socket_data;
2828 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432829 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
2830 socket_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:332831 SYNCHRONOUS, client_maker_.MakeRstPacket(
2832 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
2833 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:172834 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9c541572016-03-29 17:51:482835
2836 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452837 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332838 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032839 request.Request(
Nick Harper23290b82019-05-02 00:02:562840 host_port_pair_, version_.transport_version, privacy_mode_,
2841 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:032842 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2843 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012844 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242845 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9c541572016-03-29 17:51:482846 EXPECT_TRUE(stream.get());
2847
2848 // Cause QUIC stream to be created.
2849 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392850 request_info.traffic_annotation =
2851 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272852 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392853 net_log_, CompletionOnceCallback()));
jri9c541572016-03-29 17:51:482854
2855 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502856 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri9c541572016-03-29 17:51:482857 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2858 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2859
2860 // Set session config to have connection migration disabled.
Ryan Hamilton8d9ee76e2018-05-29 23:52:522861 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
2862 session->config());
jri9c541572016-03-29 17:51:482863 EXPECT_TRUE(session->config()->DisableConnectionMigration());
2864
2865 // Trigger connection migration. Since there is a non-migratable stream,
2866 // this should cause session to continue but be marked as going away.
2867 scoped_mock_network_change_notifier_->mock_network_change_notifier()
jrie2661982016-08-20 08:24:342868 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri9c541572016-03-29 17:51:482869
2870 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2871 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2872 EXPECT_EQ(1u, session->GetNumActiveStreams());
2873
2874 stream.reset();
2875
2876 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2877 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2878}
2879
Zhongyi Shi32fe14d42019-02-28 00:25:362880TEST_P(QuicStreamFactoryTest,
2881 OnNetworkDisconnectedNonMigratableStream_DoNotMigrateIdleSessions) {
2882 TestOnNetworkDisconnectedNonMigratableStream(false);
2883}
2884
2885TEST_P(QuicStreamFactoryTest,
2886 OnNetworkDisconnectedNonMigratableStream_MigrateIdleSessions) {
2887 TestOnNetworkDisconnectedNonMigratableStream(true);
2888}
2889
2890void QuicStreamFactoryTestBase::TestOnNetworkDisconnectedNonMigratableStream(
2891 bool migrate_idle_sessions) {
2892 test_params_.quic_migrate_idle_sessions = migrate_idle_sessions;
Zhongyi Shi5f587cc2017-11-21 23:24:172893 InitializeConnectionMigrationV2Test(
2894 {kDefaultNetworkForTests, kNewNetworkForTests});
2895 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2896 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2897
Zhongyi Shic16b4102019-02-12 00:37:402898 MockQuicData failed_socket_data;
Zhongyi Shic16b4102019-02-12 00:37:402899 MockQuicData socket_data;
Zhongyi Shi32fe14d42019-02-28 00:25:362900 if (migrate_idle_sessions) {
2901 quic::QuicStreamOffset header_stream_offset = 0;
2902 failed_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2903 failed_socket_data.AddWrite(
2904 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2905 // A RESET will be sent to the peer to cancel the non-migratable stream.
2906 failed_socket_data.AddWrite(
2907 SYNCHRONOUS, client_maker_.MakeRstPacket(
2908 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
2909 quic::QUIC_STREAM_CANCELLED));
2910 failed_socket_data.AddSocketDataToFactory(socket_factory_.get());
2911
2912 // Set up second socket data provider that is used after migration.
2913 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
2914 // Ping packet to send after migration.
2915 socket_data.AddWrite(
2916 SYNCHRONOUS, client_maker_.MakePingPacket(3, /*include_version=*/true));
2917 socket_data.AddSocketDataToFactory(socket_factory_.get());
2918 } else {
2919 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2920 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
2921 socket_data.AddWrite(
2922 SYNCHRONOUS, client_maker_.MakeRstPacket(
2923 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
2924 quic::QUIC_STREAM_CANCELLED));
2925 socket_data.AddSocketDataToFactory(socket_factory_.get());
2926 }
jri231c2972016-03-08 19:50:112927
2928 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452929 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332930 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032931 request.Request(
Nick Harper23290b82019-05-02 00:02:562932 host_port_pair_, version_.transport_version, privacy_mode_,
2933 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:032934 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2935 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012936 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242937 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri231c2972016-03-08 19:50:112938 EXPECT_TRUE(stream.get());
2939
2940 // Cause QUIC stream to be created, but marked as non-migratable.
2941 HttpRequestInfo request_info;
Zhongyi Shibb28b1f2018-07-18 02:41:262942 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Ramin Halavati683bcaa92018-02-14 08:42:392943 request_info.traffic_annotation =
2944 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272945 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392946 net_log_, CompletionOnceCallback()));
jri231c2972016-03-08 19:50:112947
2948 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502949 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri231c2972016-03-08 19:50:112950 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2951 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2952
2953 // Trigger connection migration. Since there is a non-migratable stream,
2954 // this should cause a RST_STREAM frame to be emitted with
Zhongyi Shic16b4102019-02-12 00:37:402955 // quic::QUIC_STREAM_CANCELLED error code.
Zhongyi Shi32fe14d42019-02-28 00:25:362956 // If migate idle session, the connection will then be migrated to the
2957 // alternate network. Otherwise, the connection will be closed.
jri231c2972016-03-08 19:50:112958 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2959 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
2960
Zhongyi Shi32fe14d42019-02-28 00:25:362961 EXPECT_EQ(migrate_idle_sessions,
2962 QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2963 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(host_port_pair_));
jri231c2972016-03-08 19:50:112964
Zhongyi Shi32fe14d42019-02-28 00:25:362965 if (migrate_idle_sessions) {
2966 EXPECT_EQ(0u, session->GetNumActiveStreams());
2967 base::RunLoop().RunUntilIdle();
Zhongyi Shic16b4102019-02-12 00:37:402968
Zhongyi Shi32fe14d42019-02-28 00:25:362969 EXPECT_TRUE(failed_socket_data.AllReadDataConsumed());
2970 EXPECT_TRUE(failed_socket_data.AllWriteDataConsumed());
2971 }
jri231c2972016-03-08 19:50:112972 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2973 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2974}
2975
jri9c541572016-03-29 17:51:482976TEST_P(QuicStreamFactoryTest,
jri9f303712016-09-13 01:10:222977 OnNetworkDisconnectedConnectionMigrationDisabled) {
Zhongyi Shi5f587cc2017-11-21 23:24:172978 InitializeConnectionMigrationV2Test(
2979 {kDefaultNetworkForTests, kNewNetworkForTests});
2980 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2981 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2982
2983 MockQuicData socket_data;
2984 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432985 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
2986 socket_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:332987 SYNCHRONOUS, client_maker_.MakeRstPacket(
2988 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
2989 quic::QUIC_RST_ACKNOWLEDGEMENT));
Zhongyi Shi5f587cc2017-11-21 23:24:172990 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9c541572016-03-29 17:51:482991
2992 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452993 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332994 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032995 request.Request(
Nick Harper23290b82019-05-02 00:02:562996 host_port_pair_, version_.transport_version, privacy_mode_,
2997 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:032998 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2999 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:013000 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:243001 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9c541572016-03-29 17:51:483002 EXPECT_TRUE(stream.get());
3003
3004 // Cause QUIC stream to be created.
3005 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:393006 request_info.traffic_annotation =
3007 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:273008 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:393009 net_log_, CompletionOnceCallback()));
jri9c541572016-03-29 17:51:483010
3011 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:503012 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri9c541572016-03-29 17:51:483013 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3014 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3015
3016 // Set session config to have connection migration disabled.
Ryan Hamilton8d9ee76e2018-05-29 23:52:523017 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
3018 session->config());
jri9c541572016-03-29 17:51:483019 EXPECT_TRUE(session->config()->DisableConnectionMigration());
3020
3021 // Trigger connection migration. Since there is a non-migratable stream,
3022 // this should cause a RST_STREAM frame to be emitted with
Ryan Hamilton8d9ee76e2018-05-29 23:52:523023 // quic::QUIC_RST_ACKNOWLEDGEMENT error code, and the session will be closed.
jri9c541572016-03-29 17:51:483024 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3025 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
3026
3027 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3028 EXPECT_FALSE(HasActiveSession(host_port_pair_));
3029
3030 EXPECT_TRUE(socket_data.AllReadDataConsumed());
3031 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
3032}
3033
Zhongyi Shi32fe14d42019-02-28 00:25:363034TEST_P(QuicStreamFactoryTest,
3035 OnNetworkMadeDefaultNoOpenStreams_DoNotMigrateIdleSessions) {
3036 TestOnNetworkMadeDefaultNoOpenStreams(false);
3037}
3038
3039TEST_P(QuicStreamFactoryTest,
3040 OnNetworkMadeDefaultNoOpenStreams_MigrateIdleSessions) {
3041 TestOnNetworkMadeDefaultNoOpenStreams(true);
3042}
3043
3044void QuicStreamFactoryTestBase::TestOnNetworkMadeDefaultNoOpenStreams(
3045 bool migrate_idle_sessions) {
3046 test_params_.quic_migrate_idle_sessions = migrate_idle_sessions;
Zhongyi Shi5f587cc2017-11-21 23:24:173047 InitializeConnectionMigrationV2Test(
3048 {kDefaultNetworkForTests, kNewNetworkForTests});
3049 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3050 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3051
3052 MockQuicData socket_data;
3053 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:433054 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi32fe14d42019-02-28 00:25:363055 if (!migrate_idle_sessions) {
3056 socket_data.AddWrite(
3057 SYNCHRONOUS,
3058 client_maker_.MakeConnectionClosePacket(
3059 2, true, quic::QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS,
3060 "net error"));
3061 }
Zhongyi Shi5f587cc2017-11-21 23:24:173062 socket_data.AddSocketDataToFactory(socket_factory_.get());
3063
Zhongyi Shic16b4102019-02-12 00:37:403064 MockQuicData quic_data1;
Zhongyi Shi32fe14d42019-02-28 00:25:363065 if (migrate_idle_sessions) {
3066 // Set up the second socket data provider that is used for probing.
3067 // Connectivity probe to be sent on the new path.
3068 quic_data1.AddWrite(SYNCHRONOUS,
3069 client_maker_.MakeConnectivityProbingPacket(2, true));
3070 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3071 // Connectivity probe to receive from the server.
3072 quic_data1.AddRead(ASYNC,
3073 server_maker_.MakeConnectivityProbingPacket(1, false));
3074 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
3075 // Ping packet to send after migration is completed.
3076 quic_data1.AddWrite(SYNCHRONOUS,
3077 client_maker_.MakeAckAndPingPacket(3, false, 1, 1, 1));
3078 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3079 }
Zhongyi Shic16b4102019-02-12 00:37:403080
Zhongyi Shi5f587cc2017-11-21 23:24:173081 // Create request and QuicHttpStream.
3082 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:333083 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033084 request.Request(
Nick Harper23290b82019-05-02 00:02:563085 host_port_pair_, version_.transport_version, privacy_mode_,
3086 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:033087 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3088 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi5f587cc2017-11-21 23:24:173089 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3090 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3091 EXPECT_TRUE(stream.get());
3092
3093 // Ensure that session is alive and active.
3094 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3095 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3096 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shic16b4102019-02-12 00:37:403097 EXPECT_EQ(0u, session->GetNumActiveStreams());
3098 EXPECT_EQ(0u, session->GetNumDrainingStreams());
Zhongyi Shi5f587cc2017-11-21 23:24:173099
3100 // Trigger connection migration.
3101 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3102 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
Zhongyi Shi32fe14d42019-02-28 00:25:363103 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(host_port_pair_));
Zhongyi Shi5f587cc2017-11-21 23:24:173104
Zhongyi Shi32fe14d42019-02-28 00:25:363105 if (migrate_idle_sessions) {
3106 quic_data1.Resume();
3107 base::RunLoop().RunUntilIdle();
3108 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
3109 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
3110 }
Zhongyi Shi5f587cc2017-11-21 23:24:173111 EXPECT_TRUE(socket_data.AllReadDataConsumed());
3112 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
3113}
3114
Zhongyi Shi32fe14d42019-02-28 00:25:363115TEST_P(QuicStreamFactoryTest,
3116 OnNetworkDisconnectedNoOpenStreams_DoNotMigateIdleSessions) {
3117 TestOnNetworkDisconnectedNoOpenStreams(false);
3118}
3119
3120TEST_P(QuicStreamFactoryTest,
3121 OnNetworkDisconnectedNoOpenStreams_MigateIdleSessions) {
3122 TestOnNetworkDisconnectedNoOpenStreams(true);
3123}
3124
3125void QuicStreamFactoryTestBase::TestOnNetworkDisconnectedNoOpenStreams(
3126 bool migrate_idle_sessions) {
3127 test_params_.quic_migrate_idle_sessions = migrate_idle_sessions;
Zhongyi Shi5f587cc2017-11-21 23:24:173128 InitializeConnectionMigrationV2Test(
3129 {kDefaultNetworkForTests, kNewNetworkForTests});
3130 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3131 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3132
Zhongyi Shic16b4102019-02-12 00:37:403133 MockQuicData default_socket_data;
3134 default_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3135 default_socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
3136 default_socket_data.AddSocketDataToFactory(socket_factory_.get());
3137
Zhongyi Shic16b4102019-02-12 00:37:403138 MockQuicData alternate_socket_data;
Zhongyi Shi32fe14d42019-02-28 00:25:363139 if (migrate_idle_sessions) {
3140 // Set up second socket data provider that is used after migration.
3141 alternate_socket_data.AddRead(SYNCHRONOUS,
3142 ERR_IO_PENDING); // Hanging read.
3143 // Ping packet to send after migration.
3144 alternate_socket_data.AddWrite(
3145 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
3146 alternate_socket_data.AddSocketDataToFactory(socket_factory_.get());
3147 }
Zhongyi Shi5f587cc2017-11-21 23:24:173148
3149 // Create request and QuicHttpStream.
3150 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:333151 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033152 request.Request(
Nick Harper23290b82019-05-02 00:02:563153 host_port_pair_, version_.transport_version, privacy_mode_,
3154 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:033155 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3156 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi5f587cc2017-11-21 23:24:173157 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3158 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3159 EXPECT_TRUE(stream.get());
3160
Zhongyi Shic16b4102019-02-12 00:37:403161 // Ensure that session is active.
Zhongyi Shi5f587cc2017-11-21 23:24:173162 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3163
3164 // Trigger connection migration. Since there are no active streams,
3165 // the session will be closed.
3166 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3167 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
3168
Zhongyi Shi32fe14d42019-02-28 00:25:363169 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(host_port_pair_));
Zhongyi Shi5f587cc2017-11-21 23:24:173170
Zhongyi Shic16b4102019-02-12 00:37:403171 EXPECT_TRUE(default_socket_data.AllReadDataConsumed());
3172 EXPECT_TRUE(default_socket_data.AllWriteDataConsumed());
Zhongyi Shi32fe14d42019-02-28 00:25:363173 if (migrate_idle_sessions) {
3174 EXPECT_TRUE(alternate_socket_data.AllReadDataConsumed());
3175 EXPECT_TRUE(alternate_socket_data.AllWriteDataConsumed());
3176 }
Zhongyi Shi5f587cc2017-11-21 23:24:173177}
3178
Zhongyi Shi9f316b262018-06-18 22:01:163179// This test verifies session migrates to the alternate network immediately when
3180// default network disconnects with a synchronous write before migration.
3181TEST_P(QuicStreamFactoryTest, MigrateOnDefaultNetworkDisconnectedSync) {
3182 TestMigrationOnNetworkDisconnected(/*async_write_before*/ false);
3183}
3184
3185// This test verifies session migrates to the alternate network immediately when
3186// default network disconnects with an asynchronously write before migration.
3187TEST_P(QuicStreamFactoryTest, MigrateOnDefaultNetworkDisconnectedAsync) {
3188 TestMigrationOnNetworkDisconnected(/*async_write_before*/ true);
3189}
3190
3191void QuicStreamFactoryTestBase::TestMigrationOnNetworkDisconnected(
3192 bool async_write_before) {
3193 InitializeConnectionMigrationV2Test(
3194 {kDefaultNetworkForTests, kNewNetworkForTests});
3195 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3196 ->NotifyNetworkMadeDefault(kDefaultNetworkForTests);
3197 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3198 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3199 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3200
3201 // Use the test task runner.
3202 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
3203
3204 int packet_number = 1;
3205 MockQuicData socket_data;
3206 quic::QuicStreamOffset header_stream_offset = 0;
3207 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3208 socket_data.AddWrite(
3209 SYNCHRONOUS,
3210 ConstructInitialSettingsPacket(packet_number++, &header_stream_offset));
3211 socket_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333212 SYNCHRONOUS,
3213 ConstructGetRequestPacket(packet_number++,
3214 GetNthClientInitiatedBidirectionalStreamId(0),
3215 true, true, &header_stream_offset));
Zhongyi Shi9f316b262018-06-18 22:01:163216 if (async_write_before) {
3217 socket_data.AddWrite(ASYNC, OK);
3218 packet_number++;
3219 }
3220 socket_data.AddSocketDataToFactory(socket_factory_.get());
3221
3222 // Create request and QuicHttpStream.
3223 QuicStreamRequest request(factory_.get());
3224 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033225 request.Request(
Nick Harper23290b82019-05-02 00:02:563226 host_port_pair_, version_.transport_version, privacy_mode_,
3227 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:033228 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3229 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi9f316b262018-06-18 22:01:163230 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3231 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3232 EXPECT_TRUE(stream.get());
3233
3234 // Cause QUIC stream to be created.
3235 HttpRequestInfo request_info;
3236 request_info.method = "GET";
3237 request_info.url = url_;
3238 request_info.traffic_annotation =
3239 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3240 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3241 net_log_, CompletionOnceCallback()));
3242
3243 // Ensure that session is alive and active.
3244 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3245 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3246 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3247
3248 // Send GET request on stream.
3249 HttpResponseInfo response;
3250 HttpRequestHeaders request_headers;
3251 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3252 callback_.callback()));
3253
Zhongyi Shi22fd5f52018-06-20 17:39:093254 if (async_write_before)
Zhongyi Shi9f316b262018-06-18 22:01:163255 session->SendPing();
Zhongyi Shi9f316b262018-06-18 22:01:163256
3257 // Set up second socket data provider that is used after migration.
3258 // The response to the earlier request is read on this new socket.
3259 MockQuicData socket_data1;
3260 socket_data1.AddWrite(
3261 SYNCHRONOUS,
3262 client_maker_.MakePingPacket(packet_number++, /*include_version=*/true));
3263 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:333264 ASYNC,
3265 ConstructOkResponsePacket(
3266 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shi9f316b262018-06-18 22:01:163267 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3268 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333269 SYNCHRONOUS,
3270 client_maker_.MakeAckAndRstPacket(
3271 packet_number++, false, GetNthClientInitiatedBidirectionalStreamId(0),
3272 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi9f316b262018-06-18 22:01:163273 socket_data1.AddSocketDataToFactory(socket_factory_.get());
3274
3275 // Trigger connection migration.
3276 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3277 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
3278
3279 // The connection should still be alive, not marked as going away.
3280 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3281 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3282 EXPECT_EQ(1u, session->GetNumActiveStreams());
3283 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3284
3285 // Ensure that the session is still alive.
3286 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3287 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3288 EXPECT_EQ(1u, session->GetNumActiveStreams());
3289
3290 // Run the message loop so that data queued in the new socket is read by the
3291 // packet reader.
3292 runner_->RunNextTask();
3293
3294 // Response headers are received over the new network.
3295 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3296 EXPECT_EQ(200, response.headers->response_code());
3297
3298 // Check that the session is still alive.
3299 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3300 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3301
3302 // There should be posted tasks not executed, which is to migrate back to
3303 // default network.
3304 EXPECT_FALSE(runner_->GetPostedTasks().empty());
3305
3306 // Receive signal to mark new network as default.
3307 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3308 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3309
3310 stream.reset();
3311 EXPECT_TRUE(socket_data.AllReadDataConsumed());
3312 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
3313 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
3314 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
3315}
3316
Zhongyi Shi5f587cc2017-11-21 23:24:173317// This test receives NCN signals in the following order:
3318// - default network disconnected
3319// - after a pause, new network is connected.
3320// - new network is made default.
3321TEST_P(QuicStreamFactoryTest, NewNetworkConnectedAfterNoNetwork) {
3322 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
3323 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3324 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3325 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3326
3327 // Use the test task runner.
3328 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
3329
3330 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523331 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shi5f587cc2017-11-21 23:24:173332 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3333 socket_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433334 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:333335 socket_data.AddWrite(
3336 SYNCHRONOUS, ConstructGetRequestPacket(
3337 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
3338 true, &header_stream_offset));
Zhongyi Shi5f587cc2017-11-21 23:24:173339 socket_data.AddSocketDataToFactory(socket_factory_.get());
3340
3341 // Create request and QuicHttpStream.
3342 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:333343 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033344 request.Request(
Nick Harper23290b82019-05-02 00:02:563345 host_port_pair_, version_.transport_version, privacy_mode_,
3346 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:033347 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3348 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi5f587cc2017-11-21 23:24:173349 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3350 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3351 EXPECT_TRUE(stream.get());
3352
3353 // Cause QUIC stream to be created.
3354 HttpRequestInfo request_info;
3355 request_info.method = "GET";
3356 request_info.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:393357 request_info.traffic_annotation =
3358 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:273359 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:393360 net_log_, CompletionOnceCallback()));
Zhongyi Shi5f587cc2017-11-21 23:24:173361
3362 // Ensure that session is alive and active.
3363 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3364 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3365 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3366
3367 // Send GET request on stream.
3368 HttpResponseInfo response;
3369 HttpRequestHeaders request_headers;
3370 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3371 callback_.callback()));
3372
3373 // Trigger connection migration. Since there are no networks
3374 // to migrate to, this should cause the session to wait for a new network.
3375 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3376 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
3377
3378 // The connection should still be alive, not marked as going away.
3379 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3380 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3381 EXPECT_EQ(1u, session->GetNumActiveStreams());
3382 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3383
3384 // Set up second socket data provider that is used after migration.
3385 // The response to the earlier request is read on this new socket.
3386 MockQuicData socket_data1;
3387 socket_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433388 SYNCHRONOUS, client_maker_.MakePingPacket(3, /*include_version=*/true));
3389 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:333390 ASYNC,
3391 ConstructOkResponsePacket(
3392 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shi5f587cc2017-11-21 23:24:173393 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:333394 socket_data1.AddWrite(
3395 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
3396 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
3397 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:173398 socket_data1.AddSocketDataToFactory(socket_factory_.get());
3399
3400 // Add a new network and notify the stream factory of a new connected network.
3401 // This causes a PING packet to be sent over the new network.
3402 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3403 ->SetConnectedNetworksList({kNewNetworkForTests});
3404 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3405 ->NotifyNetworkConnected(kNewNetworkForTests);
3406
3407 // Ensure that the session is still alive.
3408 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3409 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3410 EXPECT_EQ(1u, session->GetNumActiveStreams());
3411
3412 // Run the message loop so that data queued in the new socket is read by the
3413 // packet reader.
3414 runner_->RunNextTask();
3415
3416 // Response headers are received over the new network.
3417 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3418 EXPECT_EQ(200, response.headers->response_code());
3419
3420 // Check that the session is still alive.
3421 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3422 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3423
3424 // There should posted tasks not executed, which is to migrate back to default
3425 // network.
3426 EXPECT_FALSE(runner_->GetPostedTasks().empty());
3427
3428 // Receive signal to mark new network as default.
3429 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3430 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3431
3432 stream.reset();
3433 EXPECT_TRUE(socket_data.AllReadDataConsumed());
3434 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
3435 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
3436 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
3437}
3438
Zhongyi Shid3d5f502018-08-10 00:22:223439// Regression test for http://crbug.com/872011.
3440// This test verifies that migrate to the probing socket will not trigger
3441// new packets being read synchronously and generate ACK frame while
3442// processing the initial connectivity probe response, which may cause a
3443// connection being closed with INTERNAL_ERROR as pending ACK frame is not
3444// allowed when processing a new packet.
Zhongyi Shi6a7323b2018-12-07 01:26:323445TEST_P(QuicStreamFactoryTest, MigrateToProbingSocket) {
Zhongyi Shid3d5f502018-08-10 00:22:223446 InitializeConnectionMigrationV2Test(
3447 {kDefaultNetworkForTests, kNewNetworkForTests});
3448 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3449 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3450 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3451
3452 // Using a testing task runner so that we can control time.
3453 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3454 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
3455
3456 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3457 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3458
3459 int packet_number = 1;
3460 MockQuicData quic_data1;
3461 quic::QuicStreamOffset header_stream_offset = 0;
3462 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
3463 quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
3464 packet_number++, &header_stream_offset));
3465 quic_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333466 SYNCHRONOUS,
3467 ConstructGetRequestPacket(packet_number++,
3468 GetNthClientInitiatedBidirectionalStreamId(0),
3469 true, true, &header_stream_offset));
Zhongyi Shid3d5f502018-08-10 00:22:223470 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3471
3472 // Set up the second socket data provider that is used for probing on the
3473 // alternate network.
3474 MockQuicData quic_data2;
3475 // Connectivity probe to be sent on the new path.
3476 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(
3477 packet_number++, true));
3478 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3479 // First connectivity probe to receive from the server, which will complete
3480 // connection migraiton on path degrading.
3481 quic_data2.AddRead(ASYNC,
3482 server_maker_.MakeConnectivityProbingPacket(1, false));
3483 // Read multiple connectivity probes synchronously.
3484 quic_data2.AddRead(SYNCHRONOUS,
3485 server_maker_.MakeConnectivityProbingPacket(2, false));
3486 quic_data2.AddRead(SYNCHRONOUS,
3487 server_maker_.MakeConnectivityProbingPacket(3, false));
3488 quic_data2.AddRead(SYNCHRONOUS,
3489 server_maker_.MakeConnectivityProbingPacket(4, false));
3490 quic_data2.AddWrite(
3491 ASYNC, client_maker_.MakeAckPacket(packet_number++, 1, 4, 1, 1, true));
3492 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:333493 ASYNC,
3494 ConstructOkResponsePacket(
3495 5, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shid3d5f502018-08-10 00:22:223496 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3497 quic_data2.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333498 SYNCHRONOUS,
3499 client_maker_.MakeAckAndRstPacket(
3500 packet_number++, false, GetNthClientInitiatedBidirectionalStreamId(0),
3501 quic::QUIC_STREAM_CANCELLED, 5, 1, 1, true));
Zhongyi Shid3d5f502018-08-10 00:22:223502 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3503
3504 // Create request and QuicHttpStream.
3505 QuicStreamRequest request(factory_.get());
3506 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033507 request.Request(
Nick Harper23290b82019-05-02 00:02:563508 host_port_pair_, version_.transport_version, privacy_mode_,
3509 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:033510 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3511 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shid3d5f502018-08-10 00:22:223512 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3513 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3514 EXPECT_TRUE(stream.get());
3515
3516 // Cause QUIC stream to be created.
3517 HttpRequestInfo request_info;
3518 request_info.method = "GET";
3519 request_info.url = url_;
3520 request_info.traffic_annotation =
3521 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3522 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3523 net_log_, CompletionOnceCallback()));
3524
3525 // Ensure that session is alive and active.
3526 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3527 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3528 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3529
3530 // Send GET request on stream.
3531 HttpResponseInfo response;
3532 HttpRequestHeaders request_headers;
3533 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3534 callback_.callback()));
3535
3536 // Cause the connection to report path degrading to the session.
3537 // Session will start to probe the alternate network.
3538 session->connection()->OnPathDegradingTimeout();
3539
3540 // Next connectivity probe is scheduled to be sent in 2 *
3541 // kDefaultRTTMilliSecs.
3542 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3543 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
3544 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3545 next_task_delay);
3546
3547 // The connection should still be alive, and not marked as going away.
3548 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3549 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3550 EXPECT_EQ(1u, session->GetNumActiveStreams());
3551 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3552
3553 // Resume quic data and a connectivity probe response will be read on the new
3554 // socket.
3555 quic_data2.Resume();
3556
3557 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3558 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3559 EXPECT_EQ(1u, session->GetNumActiveStreams());
3560
3561 // There should be three pending tasks, the nearest one will complete
3562 // migration to the new network.
3563 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
3564 next_task_delay = task_runner->NextPendingTaskDelay();
3565 EXPECT_EQ(base::TimeDelta(), next_task_delay);
3566 task_runner->FastForwardBy(next_task_delay);
3567
3568 // Response headers are received over the new network.
3569 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3570 EXPECT_EQ(200, response.headers->response_code());
3571
3572 // Now there are two pending tasks, the nearest one was to send connectivity
3573 // probe and has been cancelled due to successful migration.
3574 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
3575 next_task_delay = task_runner->NextPendingTaskDelay();
3576 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3577 next_task_delay);
3578 task_runner->FastForwardBy(next_task_delay);
3579
3580 // There's one more task to mgirate back to the default network in 0.4s.
3581 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3582 next_task_delay = task_runner->NextPendingTaskDelay();
3583 base::TimeDelta expected_delay =
3584 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
3585 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
3586 EXPECT_EQ(expected_delay, next_task_delay);
3587
3588 // Deliver a signal that the alternate network now becomes default to session,
3589 // this will cancel mgirate back to default network timer.
3590 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3591 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3592
3593 task_runner->FastForwardBy(next_task_delay);
3594 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
3595
3596 // Verify that the session is still alive.
3597 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3598 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3599
3600 stream.reset();
3601 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
3602 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
3603 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
3604 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
3605}
3606
Zhongyi Shic4823bd2018-04-27 00:49:193607// This test verifies that the connection migrates to the alternate network
Zhongyi Shi22fd5f52018-06-20 17:39:093608// early when path degrading is detected with an ASYNCHRONOUS write before
3609// migration.
3610TEST_P(QuicStreamFactoryTest, MigrateEarlyOnPathDegradingAysnc) {
3611 TestMigrationOnPathDegrading(/*async_write_before_migration*/ true);
3612}
3613
3614// This test verifies that the connection migrates to the alternate network
3615// early when path degrading is detected with a SYNCHRONOUS write before
3616// migration.
3617TEST_P(QuicStreamFactoryTest, MigrateEarlyOnPathDegradingSync) {
3618 TestMigrationOnPathDegrading(/*async_write_before_migration*/ false);
3619}
3620
3621void QuicStreamFactoryTestBase::TestMigrationOnPathDegrading(
3622 bool async_write_before) {
Zhongyi Shic4823bd2018-04-27 00:49:193623 InitializeConnectionMigrationV2Test(
3624 {kDefaultNetworkForTests, kNewNetworkForTests});
3625 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3626 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3627 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3628
3629 // Using a testing task runner so that we can control time.
3630 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3631 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
3632
3633 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3634 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3635
Zhongyi Shi22fd5f52018-06-20 17:39:093636 int packet_number = 1;
Zhongyi Shic4823bd2018-04-27 00:49:193637 MockQuicData quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523638 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shic4823bd2018-04-27 00:49:193639 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
Zhongyi Shi22fd5f52018-06-20 17:39:093640 quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
3641 packet_number++, &header_stream_offset));
3642 quic_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333643 SYNCHRONOUS,
3644 ConstructGetRequestPacket(packet_number++,
3645 GetNthClientInitiatedBidirectionalStreamId(0),
3646 true, true, &header_stream_offset));
Zhongyi Shi22fd5f52018-06-20 17:39:093647 if (async_write_before) {
3648 quic_data1.AddWrite(ASYNC, OK);
3649 packet_number++;
3650 }
Zhongyi Shic4823bd2018-04-27 00:49:193651 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3652
3653 // Set up the second socket data provider that is used after migration.
3654 // The response to the earlier request is read on the new socket.
3655 MockQuicData quic_data2;
3656 // Connectivity probe to be sent on the new path.
Zhongyi Shi22fd5f52018-06-20 17:39:093657 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(
Zhongyi Shi879659422018-08-02 17:58:253658 packet_number++, true));
Zhongyi Shic4823bd2018-04-27 00:49:193659 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3660 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:253661 quic_data2.AddRead(ASYNC,
3662 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shic4823bd2018-04-27 00:49:193663 // Ping packet to send after migration is completed.
Zhongyi Shi22fd5f52018-06-20 17:39:093664 quic_data2.AddWrite(ASYNC, client_maker_.MakeAckAndPingPacket(
3665 packet_number++, false, 1, 1, 1));
Ryan Hamiltona3ee93a72018-08-01 22:03:083666 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:333667 ASYNC,
3668 ConstructOkResponsePacket(
3669 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shic4823bd2018-04-27 00:49:193670 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi22fd5f52018-06-20 17:39:093671 quic_data2.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333672 SYNCHRONOUS,
3673 client_maker_.MakeAckAndRstPacket(
3674 packet_number++, false, GetNthClientInitiatedBidirectionalStreamId(0),
3675 quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true));
Zhongyi Shic4823bd2018-04-27 00:49:193676 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3677
3678 // Create request and QuicHttpStream.
3679 QuicStreamRequest request(factory_.get());
3680 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033681 request.Request(
Nick Harper23290b82019-05-02 00:02:563682 host_port_pair_, version_.transport_version, privacy_mode_,
3683 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:033684 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3685 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shic4823bd2018-04-27 00:49:193686 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3687 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3688 EXPECT_TRUE(stream.get());
3689
3690 // Cause QUIC stream to be created.
3691 HttpRequestInfo request_info;
3692 request_info.method = "GET";
3693 request_info.url = url_;
3694 request_info.traffic_annotation =
3695 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3696 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3697 net_log_, CompletionOnceCallback()));
3698
3699 // Ensure that session is alive and active.
3700 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3701 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3702 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3703
3704 // Send GET request on stream.
3705 HttpResponseInfo response;
3706 HttpRequestHeaders request_headers;
3707 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3708 callback_.callback()));
3709
Zhongyi Shi22fd5f52018-06-20 17:39:093710 if (async_write_before)
3711 session->SendPing();
3712
Zhongyi Shiaba4a832018-04-30 20:29:083713 // Cause the connection to report path degrading to the session.
3714 // Session will start to probe the alternate network.
3715 session->connection()->OnPathDegradingTimeout();
3716
3717 // Next connectivity probe is scheduled to be sent in 2 *
3718 // kDefaultRTTMilliSecs.
3719 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3720 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
3721 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3722 next_task_delay);
3723
3724 // The connection should still be alive, and not marked as going away.
3725 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3726 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3727 EXPECT_EQ(1u, session->GetNumActiveStreams());
3728 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3729
3730 // Resume quic data and a connectivity probe response will be read on the new
3731 // socket.
3732 quic_data2.Resume();
3733
3734 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3735 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3736 EXPECT_EQ(1u, session->GetNumActiveStreams());
3737
3738 // There should be three pending tasks, the nearest one will complete
3739 // migration to the new network.
3740 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
3741 next_task_delay = task_runner->NextPendingTaskDelay();
3742 EXPECT_EQ(base::TimeDelta(), next_task_delay);
3743 task_runner->FastForwardBy(next_task_delay);
3744
3745 // Response headers are received over the new network.
3746 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3747 EXPECT_EQ(200, response.headers->response_code());
3748
3749 // Now there are two pending tasks, the nearest one was to send connectivity
3750 // probe and has been cancelled due to successful migration.
3751 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
3752 next_task_delay = task_runner->NextPendingTaskDelay();
3753 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3754 next_task_delay);
3755 task_runner->FastForwardBy(next_task_delay);
3756
3757 // There's one more task to mgirate back to the default network in 0.4s.
3758 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3759 next_task_delay = task_runner->NextPendingTaskDelay();
3760 base::TimeDelta expected_delay =
3761 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
3762 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
3763 EXPECT_EQ(expected_delay, next_task_delay);
3764
3765 // Deliver a signal that the alternate network now becomes default to session,
3766 // this will cancel mgirate back to default network timer.
3767 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3768 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3769
3770 task_runner->FastForwardBy(next_task_delay);
3771 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
3772
3773 // Verify that the session is still alive.
3774 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3775 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3776
3777 stream.reset();
3778 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
3779 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
3780 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
3781 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
3782}
3783
Renjiea5722ccf2018-08-10 00:18:493784// This test verifies that the session marks itself GOAWAY on path degrading
3785// and it does not receive any new request
3786TEST_P(QuicStreamFactoryTest, GoawayOnPathDegrading) {
Zhongyi Shi967d2f12019-02-08 20:58:533787 test_params_.quic_go_away_on_path_degrading = true;
Renjiea5722ccf2018-08-10 00:18:493788 Initialize();
3789 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3790 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3791 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3792
3793 MockQuicData quic_data1;
3794 quic::QuicStreamOffset header_stream_offset = 0;
3795 quic_data1.AddWrite(SYNCHRONOUS,
3796 ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:333797 quic_data1.AddWrite(
3798 SYNCHRONOUS, ConstructGetRequestPacket(
3799 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
3800 true, &header_stream_offset));
Renjiea5722ccf2018-08-10 00:18:493801 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3802 quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:333803 ASYNC,
3804 ConstructOkResponsePacket(
3805 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true));
Renjiea5722ccf2018-08-10 00:18:493806 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
3807 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3808
3809 MockQuicData quic_data2;
3810 quic::QuicStreamOffset header_stream_offset2 = 0;
3811 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
3812 quic_data2.AddWrite(
3813 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset2));
3814 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3815
3816 // Creat request and QuicHttpStream.
3817 QuicStreamRequest request(factory_.get());
3818 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033819 request.Request(
Nick Harper23290b82019-05-02 00:02:563820 host_port_pair_, version_.transport_version, privacy_mode_,
3821 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:033822 /*cerf_verify_flags=*/0, url_, net_log_, &net_error_details_,
3823 failed_on_default_network_callback_, callback_.callback()));
Renjiea5722ccf2018-08-10 00:18:493824 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3825 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3826 EXPECT_TRUE(stream.get());
3827
3828 // Cause QUIC stream to be created.
3829 HttpRequestInfo request_info;
3830 request_info.method = "GET";
3831 request_info.url = url_;
3832 request_info.traffic_annotation =
3833 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3834 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3835 net_log_, CompletionOnceCallback()));
3836
3837 // Ensure that session is alive and active.
3838 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3839 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3840 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3841
3842 // Send GET request on stream.
3843 HttpResponseInfo response;
3844 HttpRequestHeaders request_headers;
3845 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3846 callback_.callback()));
3847
3848 // Trigger the connection to report path degrading to the session.
3849 // Session will mark itself GOAWAY.
3850 session->connection()->OnPathDegradingTimeout();
3851
3852 // The connection should still be alive, but marked as going away.
3853 EXPECT_FALSE(HasActiveSession(host_port_pair_));
3854 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3855 EXPECT_EQ(1u, session->GetNumActiveStreams());
3856
3857 // Second request should be sent on a new connection.
3858 QuicStreamRequest request2(factory_.get());
3859 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033860 request2.Request(
Nick Harper23290b82019-05-02 00:02:563861 host_port_pair_, version_.transport_version, privacy_mode_,
3862 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:033863 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3864 failed_on_default_network_callback_, callback_.callback()));
Renjiea5722ccf2018-08-10 00:18:493865 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3866 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
3867 EXPECT_TRUE(stream2.get());
3868
3869 // Resume the data, verify old request can read response on the old session
3870 // successfully.
3871 quic_data1.Resume();
3872 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
3873 EXPECT_EQ(200, response.headers->response_code());
3874 EXPECT_EQ(0U, session->GetNumActiveStreams());
3875
3876 // Check an active session exists for the destination.
3877 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3878 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3879 QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
3880 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
3881 EXPECT_NE(session, session2);
3882
3883 stream.reset();
3884 stream2.reset();
3885 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
3886 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
3887 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
3888 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
3889}
3890
Zhongyi Shibb770d92018-06-16 02:07:003891// This test verifies that the connection will not migrate to a bad socket
3892// when path degrading is detected.
3893TEST_P(QuicStreamFactoryTest, DoNotMigrateToBadSocketOnPathDegrading) {
3894 InitializeConnectionMigrationV2Test(
3895 {kDefaultNetworkForTests, kNewNetworkForTests});
3896 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3897 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3898 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3899
3900 // Using a testing task runner so that we can control time.
3901 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3902 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
3903
3904 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3905 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3906
3907 MockQuicData quic_data;
3908 quic::QuicStreamOffset header_stream_offset = 0;
3909 quic_data.AddWrite(SYNCHRONOUS,
3910 ConstructInitialSettingsPacket(1, &header_stream_offset));
Zhongyi Shibb770d92018-06-16 02:07:003911 quic_data.AddWrite(SYNCHRONOUS,
Fan Yang32c5a112018-12-10 20:06:333912 ConstructGetRequestPacket(
3913 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
3914 true, &header_stream_offset));
3915 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3916 quic_data.AddRead(ASYNC, ConstructOkResponsePacket(
3917 1, GetNthClientInitiatedBidirectionalStreamId(0),
3918 false, false));
3919 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3920 quic_data.AddWrite(
3921 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
3922 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
3923 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shibb770d92018-06-16 02:07:003924 quic_data.AddSocketDataToFactory(socket_factory_.get());
3925
3926 // Set up second socket that will immediately return disconnected.
3927 // The stream factory will abort probe the alternate network.
3928 MockConnect bad_connect = MockConnect(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
3929 SequencedSocketData socket_data(bad_connect, base::span<MockRead>(),
3930 base::span<MockWrite>());
3931 socket_factory_->AddSocketDataProvider(&socket_data);
3932
3933 // Create request and QuicHttpStream.
3934 QuicStreamRequest request(factory_.get());
3935 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033936 request.Request(
Nick Harper23290b82019-05-02 00:02:563937 host_port_pair_, version_.transport_version, privacy_mode_,
3938 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:033939 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3940 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shibb770d92018-06-16 02:07:003941 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3942 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3943 EXPECT_TRUE(stream.get());
3944
3945 // Cause QUIC stream to be created.
3946 HttpRequestInfo request_info;
3947 request_info.method = "GET";
3948 request_info.url = url_;
3949 request_info.traffic_annotation =
3950 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3951 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3952 net_log_, CompletionOnceCallback()));
3953
3954 // Ensure that session is alive and active.
3955 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3956 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3957 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3958
3959 // Send GET request on stream.
3960 HttpResponseInfo response;
3961 HttpRequestHeaders request_headers;
3962 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3963 callback_.callback()));
3964
3965 // Cause the connection to report path degrading to the session.
3966 // Session will start to probe the alternate network.
3967 session->connection()->OnPathDegradingTimeout();
3968
3969 // The connection should still be alive, and not marked as going away.
3970 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3971 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3972 EXPECT_EQ(1u, session->GetNumActiveStreams());
3973 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3974
3975 // Resume the data, and response header is received over the original network.
3976 quic_data.Resume();
3977 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3978 EXPECT_EQ(200, response.headers->response_code());
3979
3980 // Verify there is no pending task as probing alternate network is halted.
3981 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
3982
3983 // Verify that the session is still alive.
3984 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3985 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3986
3987 stream.reset();
3988 EXPECT_TRUE(quic_data.AllReadDataConsumed());
3989 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
3990}
3991
Zhongyi Shif5cc30392018-05-30 18:25:153992// Regression test for http://crbug.com/847569.
3993// This test verifies that the connection migrates to the alternate network
3994// early when there is no active stream but a draining stream.
Zhongyi Shib3bc982c2018-07-10 19:59:243995// The first packet being written after migration is a synchrnous write, which
3996// will cause a PING packet being sent.
3997TEST_P(QuicStreamFactoryTest, MigrateSessionWithDrainingStreamSync) {
3998 TestMigrateSessionWithDrainingStream(SYNCHRONOUS);
3999}
4000
4001// Regression test for http://crbug.com/847569.
4002// This test verifies that the connection migrates to the alternate network
4003// early when there is no active stream but a draining stream.
4004// The first packet being written after migration is an asynchronous write, no
4005// PING packet will be sent.
4006TEST_P(QuicStreamFactoryTest, MigrateSessionWithDrainingStreamAsync) {
4007 TestMigrateSessionWithDrainingStream(ASYNC);
4008}
4009
4010void QuicStreamFactoryTestBase::TestMigrateSessionWithDrainingStream(
4011 IoMode write_mode_for_queued_packet) {
Zhongyi Shif5cc30392018-05-30 18:25:154012 InitializeConnectionMigrationV2Test(
4013 {kDefaultNetworkForTests, kNewNetworkForTests});
4014 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4015 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4016 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4017
4018 // Using a testing task runner so that we can control time.
4019 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4020 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4021
4022 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4023 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
4024
Zhongyi Shib3bc982c2018-07-10 19:59:244025 int packet_number = 1;
Zhongyi Shif5cc30392018-05-30 18:25:154026 MockQuicData quic_data1;
4027 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shib3bc982c2018-07-10 19:59:244028 quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
4029 packet_number++, &header_stream_offset));
4030 quic_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334031 SYNCHRONOUS,
4032 ConstructGetRequestPacket(packet_number++,
4033 GetNthClientInitiatedBidirectionalStreamId(0),
4034 true, true, &header_stream_offset));
Zhongyi Shif5cc30392018-05-30 18:25:154035 // Read an out of order packet with FIN to drain the stream.
4036 quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:334037 ASYNC, ConstructOkResponsePacket(
4038 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
4039 true)); // keep sending version.
Fan Yang0da2282f72019-04-25 21:06:574040 if (!GetQuicRestartFlag(quic_enable_accept_random_ipn)) {
4041 // Packet 2 is considered as out of order packet and an ACK will be sent
4042 // immediately.
4043 quic_data1.AddWrite(SYNCHRONOUS, client_maker_.MakeAckPacket(
4044 packet_number++, 2, 2, 2, 1, true));
4045 }
Zhongyi Shif5cc30392018-05-30 18:25:154046 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4047 quic_data1.AddSocketDataToFactory(socket_factory_.get());
4048
4049 // Set up the second socket data provider that is used after migration.
4050 MockQuicData quic_data2;
4051 // Connectivity probe to be sent on the new path.
Zhongyi Shib3bc982c2018-07-10 19:59:244052 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(
Zhongyi Shi879659422018-08-02 17:58:254053 packet_number++, false));
Zhongyi Shif5cc30392018-05-30 18:25:154054 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
4055 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:254056 quic_data2.AddRead(ASYNC,
4057 server_maker_.MakeConnectivityProbingPacket(3, false));
Zhongyi Shif5cc30392018-05-30 18:25:154058 // Ping packet to send after migration is completed.
Zhongyi Shib3bc982c2018-07-10 19:59:244059 quic_data2.AddWrite(
4060 write_mode_for_queued_packet,
4061 client_maker_.MakeAckPacket(packet_number++, 2, 3, 3, 1, true));
4062 if (write_mode_for_queued_packet == SYNCHRONOUS) {
4063 quic_data2.AddWrite(ASYNC,
4064 client_maker_.MakePingPacket(packet_number++, false));
4065 }
Zhongyi Shif5cc30392018-05-30 18:25:154066 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:334067 ASYNC,
4068 ConstructOkResponsePacket(
4069 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shib3bc982c2018-07-10 19:59:244070 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeAckPacket(
4071 packet_number++, 1, 3, 1, 1, true));
Zhongyi Shif5cc30392018-05-30 18:25:154072 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4073 quic_data2.AddSocketDataToFactory(socket_factory_.get());
4074
4075 // Create request and QuicHttpStream.
4076 QuicStreamRequest request(factory_.get());
4077 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034078 request.Request(
Nick Harper23290b82019-05-02 00:02:564079 host_port_pair_, version_.transport_version, privacy_mode_,
4080 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:034081 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4082 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shif5cc30392018-05-30 18:25:154083 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4084 std::unique_ptr<HttpStream> stream = CreateStream(&request);
4085 EXPECT_TRUE(stream.get());
4086
4087 // Cause QUIC stream to be created.
4088 HttpRequestInfo request_info;
4089 request_info.method = "GET";
4090 request_info.url = url_;
4091 request_info.traffic_annotation =
4092 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4093 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
4094 net_log_, CompletionOnceCallback()));
4095
4096 // Ensure that session is alive and active.
4097 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
4098 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4099 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4100
4101 // Send GET request on stream.
4102 HttpResponseInfo response;
4103 HttpRequestHeaders request_headers;
4104 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
4105 callback_.callback()));
4106
4107 // Run the message loop to receive the out of order packet which contains a
4108 // FIN and drains the stream.
4109 base::RunLoop().RunUntilIdle();
4110 EXPECT_EQ(0u, session->GetNumActiveStreams());
4111
4112 // Cause the connection to report path degrading to the session.
4113 // Session should still start to probe the alternate network.
4114 session->connection()->OnPathDegradingTimeout();
4115 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4116
4117 // Next connectivity probe is scheduled to be sent in 2 *
4118 // kDefaultRTTMilliSecs.
4119 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4120 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
4121 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
4122 next_task_delay);
4123
4124 // The connection should still be alive, and not marked as going away.
4125 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shif5cc30392018-05-30 18:25:154126
4127 // Resume quic data and a connectivity probe response will be read on the new
4128 // socket.
4129 quic_data2.Resume();
4130
4131 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4132 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:264133 EXPECT_EQ(0u, session->GetNumActiveStreams());
4134 EXPECT_EQ(1u, session->GetNumDrainingStreams());
Zhongyi Shif5cc30392018-05-30 18:25:154135
4136 // There should be three pending tasks, the nearest one will complete
4137 // migration to the new network.
4138 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
4139 next_task_delay = task_runner->NextPendingTaskDelay();
4140 EXPECT_EQ(base::TimeDelta(), next_task_delay);
4141 task_runner->FastForwardBy(next_task_delay);
4142
4143 // Now there are two pending tasks, the nearest one was to send connectivity
4144 // probe and has been cancelled due to successful migration.
4145 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
4146 next_task_delay = task_runner->NextPendingTaskDelay();
4147 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
4148 next_task_delay);
4149 task_runner->FastForwardBy(next_task_delay);
4150
4151 // There's one more task to mgirate back to the default network in 0.4s.
4152 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4153 next_task_delay = task_runner->NextPendingTaskDelay();
4154 base::TimeDelta expected_delay =
4155 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
4156 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
4157 EXPECT_EQ(expected_delay, next_task_delay);
4158
Zhongyi Shib3bc982c2018-07-10 19:59:244159 base::RunLoop().RunUntilIdle();
4160
Zhongyi Shif5cc30392018-05-30 18:25:154161 // Deliver a signal that the alternate network now becomes default to session,
4162 // this will cancel mgirate back to default network timer.
4163 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4164 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
4165
4166 task_runner->FastForwardBy(next_task_delay);
4167 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4168
4169 // Verify that the session is still alive.
4170 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4171 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:264172 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
Zhongyi Shif5cc30392018-05-30 18:25:154173
4174 stream.reset();
4175 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
4176 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
4177 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
4178 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
4179}
4180
Zhongyi Shiaba4a832018-04-30 20:29:084181// Regression test for http://crbug.com/835444.
4182// This test verifies that the connection migrates to the alternate network
4183// when the alternate network is connected after path has been degrading.
4184TEST_P(QuicStreamFactoryTest, MigrateOnNewNetworkConnectAfterPathDegrading) {
4185 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
4186 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4187 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4188 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4189
4190 // Using a testing task runner so that we can control time.
4191 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4192 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4193
4194 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4195 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
4196
4197 MockQuicData quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524198 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shiaba4a832018-04-30 20:29:084199 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
4200 quic_data1.AddWrite(SYNCHRONOUS,
4201 ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:334202 quic_data1.AddWrite(
4203 SYNCHRONOUS, ConstructGetRequestPacket(
4204 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
4205 true, &header_stream_offset));
Zhongyi Shiaba4a832018-04-30 20:29:084206 quic_data1.AddSocketDataToFactory(socket_factory_.get());
4207
4208 // Set up the second socket data provider that is used after migration.
4209 // The response to the earlier request is read on the new socket.
4210 MockQuicData quic_data2;
4211 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:254212 quic_data2.AddWrite(SYNCHRONOUS,
4213 client_maker_.MakeConnectivityProbingPacket(3, true));
Zhongyi Shiaba4a832018-04-30 20:29:084214 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
4215 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:254216 quic_data2.AddRead(ASYNC,
4217 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shiaba4a832018-04-30 20:29:084218 // Ping packet to send after migration is completed.
4219 quic_data2.AddWrite(ASYNC,
4220 client_maker_.MakeAckAndPingPacket(4, false, 1, 1, 1));
4221 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:334222 ASYNC,
4223 ConstructOkResponsePacket(
4224 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shiaba4a832018-04-30 20:29:084225 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:334226 quic_data2.AddWrite(
4227 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
4228 5, false, GetNthClientInitiatedBidirectionalStreamId(0),
4229 quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true));
Zhongyi Shiaba4a832018-04-30 20:29:084230 quic_data2.AddSocketDataToFactory(socket_factory_.get());
4231
4232 // Create request and QuicHttpStream.
4233 QuicStreamRequest request(factory_.get());
4234 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034235 request.Request(
Nick Harper23290b82019-05-02 00:02:564236 host_port_pair_, version_.transport_version, privacy_mode_,
4237 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:034238 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4239 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shiaba4a832018-04-30 20:29:084240 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4241 std::unique_ptr<HttpStream> stream = CreateStream(&request);
4242 EXPECT_TRUE(stream.get());
4243
4244 // Cause QUIC stream to be created.
4245 HttpRequestInfo request_info;
4246 request_info.method = "GET";
4247 request_info.url = url_;
4248 request_info.traffic_annotation =
4249 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4250 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
4251 net_log_, CompletionOnceCallback()));
4252
4253 // Ensure that session is alive and active.
4254 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
4255 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4256 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4257
4258 // Send GET request on stream.
4259 HttpResponseInfo response;
4260 HttpRequestHeaders request_headers;
4261 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
4262 callback_.callback()));
4263
4264 // Cause the connection to report path degrading to the session.
4265 // Due to lack of alternate network, session will not mgirate connection.
4266 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4267 session->connection()->OnPathDegradingTimeout();
4268 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4269
4270 // Deliver a signal that a alternate network is connected now, this should
4271 // cause the connection to start early migration on path degrading.
4272 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4273 ->SetConnectedNetworksList(
4274 {kDefaultNetworkForTests, kNewNetworkForTests});
4275 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4276 ->NotifyNetworkConnected(kNewNetworkForTests);
Zhongyi Shic4823bd2018-04-27 00:49:194277
4278 // Next connectivity probe is scheduled to be sent in 2 *
4279 // kDefaultRTTMilliSecs.
4280 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4281 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
4282 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
4283 next_task_delay);
4284
4285 // The connection should still be alive, and not marked as going away.
4286 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4287 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4288 EXPECT_EQ(1u, session->GetNumActiveStreams());
4289 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
4290
4291 // Resume quic data and a connectivity probe response will be read on the new
4292 // socket.
4293 quic_data2.Resume();
4294
4295 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4296 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4297 EXPECT_EQ(1u, session->GetNumActiveStreams());
4298
4299 // There should be three pending tasks, the nearest one will complete
4300 // migration to the new network.
4301 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
4302 next_task_delay = task_runner->NextPendingTaskDelay();
4303 EXPECT_EQ(base::TimeDelta(), next_task_delay);
4304 task_runner->FastForwardBy(next_task_delay);
4305
4306 // Response headers are received over the new network.
4307 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4308 EXPECT_EQ(200, response.headers->response_code());
4309
4310 // Now there are two pending tasks, the nearest one was to send connectivity
4311 // probe and has been cancelled due to successful migration.
4312 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
4313 next_task_delay = task_runner->NextPendingTaskDelay();
4314 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
4315 next_task_delay);
4316 task_runner->FastForwardBy(next_task_delay);
4317
4318 // There's one more task to mgirate back to the default network in 0.4s.
4319 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4320 next_task_delay = task_runner->NextPendingTaskDelay();
4321 base::TimeDelta expected_delay =
4322 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
4323 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
4324 EXPECT_EQ(expected_delay, next_task_delay);
4325
4326 // Deliver a signal that the alternate network now becomes default to session,
4327 // this will cancel mgirate back to default network timer.
4328 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4329 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
4330
4331 task_runner->FastForwardBy(next_task_delay);
4332 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4333
4334 // Verify that the session is still alive.
4335 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4336 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4337
4338 stream.reset();
4339 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
4340 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
4341 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
4342 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
4343}
4344
Zhongyi Shi28f6e352018-06-20 21:15:434345// This test verifies that multiple sessions are migrated on connection
4346// migration signal.
jrie3d187c2016-09-16 14:29:174347TEST_P(QuicStreamFactoryTest,
Zhongyi Shi28f6e352018-06-20 21:15:434348 MigrateMultipleSessionsToBadSocketsAfterDisconnected) {
4349 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jrie3d187c2016-09-16 14:29:174350
4351 MockQuicData socket_data1;
4352 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434353 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jrie3d187c2016-09-16 14:29:174354 socket_data1.AddWrite(ASYNC, OK);
Zhongyi Shi5f587cc2017-11-21 23:24:174355 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jrie3d187c2016-09-16 14:29:174356 MockQuicData socket_data2;
4357 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434358 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jrie3d187c2016-09-16 14:29:174359 socket_data2.AddWrite(ASYNC, OK);
Zhongyi Shi5f587cc2017-11-21 23:24:174360 socket_data2.AddSocketDataToFactory(socket_factory_.get());
jrie3d187c2016-09-16 14:29:174361
4362 HostPortPair server1(kDefaultServerHostName, 443);
4363 HostPortPair server2(kServer2HostName, 443);
4364
4365 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4366 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4367 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4368
Renjiea0cb4a2c2018-09-26 23:37:304369 host_resolver_->set_synchronous_mode(true);
4370 host_resolver_->rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
4371 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.2", "");
jrie3d187c2016-09-16 14:29:174372
4373 // Create request and QuicHttpStream to create session1.
zhongyi98d6a9262017-05-19 02:47:454374 QuicStreamRequest request1(factory_.get());
Nick Harper23290b82019-05-02 00:02:564375 EXPECT_EQ(OK, request1.Request(server1, version_.transport_version,
4376 privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
4377 /*cert_verify_flags=*/0, url_, net_log_,
4378 &net_error_details_,
4379 failed_on_default_network_callback_,
4380 callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:244381 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
jrie3d187c2016-09-16 14:29:174382 EXPECT_TRUE(stream1.get());
4383
4384 // Create request and QuicHttpStream to create session2.
zhongyi98d6a9262017-05-19 02:47:454385 QuicStreamRequest request2(factory_.get());
Nick Harper23290b82019-05-02 00:02:564386 EXPECT_EQ(OK, request2.Request(server2, version_.transport_version,
4387 privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
4388 /*cert_verify_flags=*/0, url2_, net_log_,
4389 &net_error_details_,
4390 failed_on_default_network_callback_,
4391 callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:244392 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
jrie3d187c2016-09-16 14:29:174393 EXPECT_TRUE(stream2.get());
4394
4395 QuicChromiumClientSession* session1 = GetActiveSession(server1);
4396 QuicChromiumClientSession* session2 = GetActiveSession(server2);
4397 EXPECT_NE(session1, session2);
4398
4399 // Cause QUIC stream to be created and send GET so session1 has an open
4400 // stream.
4401 HttpRequestInfo request_info1;
4402 request_info1.method = "GET";
4403 request_info1.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:394404 request_info1.traffic_annotation =
4405 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274406 EXPECT_EQ(OK,
4407 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394408 net_log_, CompletionOnceCallback()));
jrie3d187c2016-09-16 14:29:174409 HttpResponseInfo response1;
4410 HttpRequestHeaders request_headers1;
4411 EXPECT_EQ(OK, stream1->SendRequest(request_headers1, &response1,
4412 callback_.callback()));
4413
4414 // Cause QUIC stream to be created and send GET so session2 has an open
4415 // stream.
4416 HttpRequestInfo request_info2;
4417 request_info2.method = "GET";
4418 request_info2.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:394419 request_info2.traffic_annotation =
4420 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274421 EXPECT_EQ(OK,
4422 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394423 net_log_, CompletionOnceCallback()));
jrie3d187c2016-09-16 14:29:174424 HttpResponseInfo response2;
4425 HttpRequestHeaders request_headers2;
4426 EXPECT_EQ(OK, stream2->SendRequest(request_headers2, &response2,
4427 callback_.callback()));
4428
4429 // Cause both sessions to be paused due to DISCONNECTED.
4430 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4431 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
4432
4433 // Ensure that both sessions are paused but alive.
4434 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session1));
4435 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
4436
Zhongyi Shi28f6e352018-06-20 21:15:434437 // Add new sockets to use post migration. Those are bad sockets and will cause
4438 // migration to fail.
jrie3d187c2016-09-16 14:29:174439 MockConnect connect_result =
4440 MockConnect(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
Ryan Sleevib8d7ea02018-05-07 20:01:014441 SequencedSocketData socket_data3(connect_result, base::span<MockRead>(),
4442 base::span<MockWrite>());
Zhongyi Shi5f587cc2017-11-21 23:24:174443 socket_factory_->AddSocketDataProvider(&socket_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:014444 SequencedSocketData socket_data4(connect_result, base::span<MockRead>(),
4445 base::span<MockWrite>());
Zhongyi Shi5f587cc2017-11-21 23:24:174446 socket_factory_->AddSocketDataProvider(&socket_data4);
jrie3d187c2016-09-16 14:29:174447
Zhongyi Shi28f6e352018-06-20 21:15:434448 // Connect the new network and cause migration to bad sockets, causing
4449 // sessions to close.
jrie3d187c2016-09-16 14:29:174450 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4451 ->SetConnectedNetworksList({kNewNetworkForTests});
4452 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4453 ->NotifyNetworkConnected(kNewNetworkForTests);
4454
4455 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session1));
4456 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
4457
4458 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
4459 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
4460 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
4461 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
4462}
4463
Zhongyi Shi6ec9b36e2018-06-20 20:32:544464// This test verifies that session attempts connection migration with signals
4465// delivered in the following order (no alternate network is available):
4466// - path degrading is detected: session attempts connection migration but no
4467// alternate network is available, session caches path degrading signal in
4468// connection and stays on the original network.
4469// - original network backs up, request is served in the orignal network,
4470// session is not marked as going away.
4471TEST_P(QuicStreamFactoryTest, MigrateOnPathDegradingWithNoNewNetwork) {
4472 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jrid36ada62016-02-06 02:42:084473 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4474 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4475
Zhongyi Shi6ec9b36e2018-06-20 20:32:544476 MockQuicData quic_data;
4477 quic::QuicStreamOffset header_stream_offset = 0;
4478 quic_data.AddWrite(SYNCHRONOUS,
4479 ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:334480 quic_data.AddWrite(SYNCHRONOUS,
4481 ConstructGetRequestPacket(
4482 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
4483 true, &header_stream_offset));
Zhongyi Shi6ec9b36e2018-06-20 20:32:544484 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause for path degrading signal.
4485
4486 // The rest of the data will still flow in the original socket as there is no
4487 // new network after path degrading.
Fan Yang32c5a112018-12-10 20:06:334488 quic_data.AddRead(ASYNC, ConstructOkResponsePacket(
4489 1, GetNthClientInitiatedBidirectionalStreamId(0),
4490 false, false));
Zhongyi Shi6ec9b36e2018-06-20 20:32:544491 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:334492 quic_data.AddWrite(
4493 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
4494 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
4495 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi6ec9b36e2018-06-20 20:32:544496 quic_data.AddSocketDataToFactory(socket_factory_.get());
jrid36ada62016-02-06 02:42:084497
4498 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:454499 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:334500 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034501 request.Request(
Nick Harper23290b82019-05-02 00:02:564502 host_port_pair_, version_.transport_version, privacy_mode_,
4503 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:034504 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4505 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:014506 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:244507 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jrid36ada62016-02-06 02:42:084508 EXPECT_TRUE(stream.get());
4509
4510 // Cause QUIC stream to be created.
4511 HttpRequestInfo request_info;
Zhongyi Shi6ec9b36e2018-06-20 20:32:544512 request_info.method = "GET";
4513 request_info.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:394514 request_info.traffic_annotation =
4515 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Zhongyi Shi6ec9b36e2018-06-20 20:32:544516 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394517 net_log_, CompletionOnceCallback()));
jrid36ada62016-02-06 02:42:084518
4519 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:504520 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jrid36ada62016-02-06 02:42:084521 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4522 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4523
Zhongyi Shi6ec9b36e2018-06-20 20:32:544524 // Send GET request on stream.
4525 HttpResponseInfo response;
4526 HttpRequestHeaders request_headers;
4527 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
4528 callback_.callback()));
jrid36ada62016-02-06 02:42:084529
Zhongyi Shi6ec9b36e2018-06-20 20:32:544530 // Trigger connection migration on path degrading. Since there are no networks
4531 // to migrate to, the session will remain on the original network, not marked
4532 // as going away.
4533 session->connection()->OnPathDegradingTimeout();
4534 EXPECT_TRUE(session->connection()->IsPathDegrading());
4535
4536 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4537 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4538 EXPECT_EQ(1u, session->GetNumActiveStreams());
4539 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
4540
4541 // Resume so that rest of the data will flow in the original socket.
4542 quic_data.Resume();
jrid36ada62016-02-06 02:42:084543
4544 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4545 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4546 EXPECT_EQ(1u, session->GetNumActiveStreams());
4547
4548 stream.reset();
Zhongyi Shi6ec9b36e2018-06-20 20:32:544549 EXPECT_TRUE(quic_data.AllReadDataConsumed());
4550 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
jrid36ada62016-02-06 02:42:084551}
4552
Zhongyi Shi21e99532018-07-17 22:23:074553// This test verifies that session with non-migratable stream will probe the
4554// alternate network on path degrading, and close the non-migratable streams
4555// when probe is successful.
Zhongyi Shi32fe14d42019-02-28 00:25:364556TEST_P(QuicStreamFactoryTest,
4557 MigrateSessionEarlyNonMigratableStream_DoNotMigrateIdleSessions) {
4558 TestMigrateSessionEarlyNonMigratableStream(false);
4559}
4560
4561TEST_P(QuicStreamFactoryTest,
4562 MigrateSessionEarlyNonMigratableStream_MigrateIdleSessions) {
4563 TestMigrateSessionEarlyNonMigratableStream(true);
4564}
4565
4566void QuicStreamFactoryTestBase::TestMigrateSessionEarlyNonMigratableStream(
4567 bool migrate_idle_sessions) {
4568 test_params_.quic_migrate_idle_sessions = migrate_idle_sessions;
Zhongyi Shi1a054612018-06-14 04:59:084569 InitializeConnectionMigrationV2Test(
jri231c2972016-03-08 19:50:114570 {kDefaultNetworkForTests, kNewNetworkForTests});
4571 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4572 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4573
rcha00569732016-08-27 11:09:364574 MockQuicData socket_data;
4575 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434576 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi32fe14d42019-02-28 00:25:364577 if (!migrate_idle_sessions) {
4578 socket_data.AddWrite(
4579 SYNCHRONOUS,
4580 client_maker_.MakeRstAckAndConnectionClosePacket(
4581 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
4582 quic::QUIC_STREAM_CANCELLED,
4583 quic::QuicTime::Delta::FromMilliseconds(0), 1, 1, 1,
4584 quic::QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS,
4585 "net error"));
4586 }
Zhongyi Shi5f587cc2017-11-21 23:24:174587 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri231c2972016-03-08 19:50:114588
Zhongyi Shi21e99532018-07-17 22:23:074589 // Set up the second socket data provider that is used for probing.
4590 MockQuicData quic_data1;
4591 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:254592 quic_data1.AddWrite(SYNCHRONOUS,
4593 client_maker_.MakeConnectivityProbingPacket(2, true));
Zhongyi Shi21e99532018-07-17 22:23:074594 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
4595 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:254596 quic_data1.AddRead(ASYNC,
4597 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shi32fe14d42019-02-28 00:25:364598 if (migrate_idle_sessions) {
4599 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
4600 // A RESET will be sent to the peer to cancel the non-migratable stream.
4601 quic_data1.AddWrite(
4602 SYNCHRONOUS,
4603 client_maker_.MakeRstPacket(
4604 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
4605 quic::QUIC_STREAM_CANCELLED));
4606 // Ping packet to send after migration is completed.
4607 quic_data1.AddWrite(SYNCHRONOUS,
4608 client_maker_.MakeAckAndPingPacket(4, false, 1, 1, 1));
4609 }
Zhongyi Shi21e99532018-07-17 22:23:074610 quic_data1.AddSocketDataToFactory(socket_factory_.get());
4611
jri231c2972016-03-08 19:50:114612 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:454613 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:334614 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034615 request.Request(
Nick Harper23290b82019-05-02 00:02:564616 host_port_pair_, version_.transport_version, privacy_mode_,
4617 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:034618 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4619 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:014620 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:244621 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri231c2972016-03-08 19:50:114622 EXPECT_TRUE(stream.get());
4623
4624 // Cause QUIC stream to be created, but marked as non-migratable.
4625 HttpRequestInfo request_info;
Zhongyi Shibb28b1f2018-07-18 02:41:264626 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Ramin Halavati683bcaa92018-02-14 08:42:394627 request_info.traffic_annotation =
4628 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274629 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394630 net_log_, CompletionOnceCallback()));
jri231c2972016-03-08 19:50:114631
4632 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:504633 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri231c2972016-03-08 19:50:114634 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4635 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4636
4637 // Trigger connection migration. Since there is a non-migratable stream,
Zhongyi Shic16b4102019-02-12 00:37:404638 // this should cause session to migrate.
jri231c2972016-03-08 19:50:114639 session->OnPathDegrading();
4640
4641 // Run the message loop so that data queued in the new socket is read by the
4642 // packet reader.
4643 base::RunLoop().RunUntilIdle();
4644
jri231c2972016-03-08 19:50:114645 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4646 EXPECT_EQ(1u, session->GetNumActiveStreams());
4647
Zhongyi Shi21e99532018-07-17 22:23:074648 // Resume the data to read the connectivity probing response to declare probe
4649 // as successful. Non-migratable streams will be closed.
4650 quic_data1.Resume();
Zhongyi Shi32fe14d42019-02-28 00:25:364651 if (migrate_idle_sessions)
4652 base::RunLoop().RunUntilIdle();
Zhongyi Shic16b4102019-02-12 00:37:404653
Zhongyi Shi32fe14d42019-02-28 00:25:364654 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(host_port_pair_));
Zhongyi Shi21e99532018-07-17 22:23:074655 EXPECT_EQ(0u, session->GetNumActiveStreams());
jri231c2972016-03-08 19:50:114656
Zhongyi Shi21e99532018-07-17 22:23:074657 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
4658 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
jri231c2972016-03-08 19:50:114659 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4660 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4661}
4662
jri9c541572016-03-29 17:51:484663TEST_P(QuicStreamFactoryTest, MigrateSessionEarlyConnectionMigrationDisabled) {
Zhongyi Shi1a054612018-06-14 04:59:084664 InitializeConnectionMigrationV2Test(
jri9c541572016-03-29 17:51:484665 {kDefaultNetworkForTests, kNewNetworkForTests});
4666 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4667 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4668
rcha00569732016-08-27 11:09:364669 MockQuicData socket_data;
4670 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434671 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
4672 socket_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334673 SYNCHRONOUS, client_maker_.MakeRstPacket(
4674 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
4675 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:174676 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9c541572016-03-29 17:51:484677
4678 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:454679 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:334680 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034681 request.Request(
Nick Harper23290b82019-05-02 00:02:564682 host_port_pair_, version_.transport_version, privacy_mode_,
4683 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:034684 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4685 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:014686 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:244687 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9c541572016-03-29 17:51:484688 EXPECT_TRUE(stream.get());
4689
4690 // Cause QUIC stream to be created.
4691 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:394692 request_info.traffic_annotation =
4693 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274694 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394695 net_log_, CompletionOnceCallback()));
jri9c541572016-03-29 17:51:484696
4697 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:504698 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri9c541572016-03-29 17:51:484699 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4700 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4701
4702 // Set session config to have connection migration disabled.
Ryan Hamilton8d9ee76e2018-05-29 23:52:524703 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
4704 session->config());
jri9c541572016-03-29 17:51:484705 EXPECT_TRUE(session->config()->DisableConnectionMigration());
4706
4707 // Trigger connection migration. Since there is a non-migratable stream,
4708 // this should cause session to be continue without migrating.
4709 session->OnPathDegrading();
4710
4711 // Run the message loop so that data queued in the new socket is read by the
4712 // packet reader.
4713 base::RunLoop().RunUntilIdle();
4714
4715 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4716 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4717 EXPECT_EQ(1u, session->GetNumActiveStreams());
4718
4719 stream.reset();
4720
4721 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4722 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4723}
4724
Zhongyi Shi3c4c9e92018-07-02 23:16:234725// Regression test for http://crbug.com/791886.
4726// This test verifies that the old packet writer which encountered an
4727// asynchronous write error will be blocked during migration on write error. New
4728// packets would not be written until the one with write error is rewritten on
4729// the new network.
4730TEST_P(QuicStreamFactoryTest, MigrateSessionOnAysncWriteError) {
4731 InitializeConnectionMigrationV2Test(
4732 {kDefaultNetworkForTests, kNewNetworkForTests});
4733 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4734 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4735 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4736
4737 // Using a testing task runner so that we can control time.
4738 // base::RunLoop() controls mocked socket writes and reads.
4739 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4740 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4741
4742 MockQuicData socket_data;
4743 quic::QuicStreamOffset header_stream_offset = 0;
4744 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4745 socket_data.AddWrite(
4746 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4747 socket_data.AddWrite(ASYNC, ERR_ADDRESS_UNREACHABLE);
4748 socket_data.AddSocketDataToFactory(socket_factory_.get());
4749
4750 // Set up second socket data provider that is used after
4751 // migration. The request is rewritten to this new socket, and the
4752 // response to the request is read on this new socket.
4753 MockQuicData socket_data1;
Zhongyi Shi3c4c9e92018-07-02 23:16:234754 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334755 SYNCHRONOUS, ConstructGetRequestPacket(
4756 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
4757 true, &header_stream_offset));
4758 socket_data1.AddWrite(SYNCHRONOUS,
4759 ConstructGetRequestPacket(
4760 3, GetNthClientInitiatedBidirectionalStreamId(1),
4761 GetNthClientInitiatedBidirectionalStreamId(0), true,
4762 true, &header_stream_offset));
4763 socket_data1.AddRead(
4764 ASYNC,
4765 ConstructOkResponsePacket(
4766 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
4767 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4768 socket_data1.AddWrite(
4769 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
4770 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
4771 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
4772 socket_data1.AddWrite(
4773 SYNCHRONOUS, client_maker_.MakeRstPacket(
4774 5, false, GetNthClientInitiatedBidirectionalStreamId(1),
Frank Kastenholz684ea412019-02-13 18:48:184775 quic::QUIC_STREAM_CANCELLED, 0,
4776 /*include_stop_sending_if_v99=*/true));
Zhongyi Shi3c4c9e92018-07-02 23:16:234777
4778 socket_data1.AddSocketDataToFactory(socket_factory_.get());
4779
4780 // Create request #1 and QuicHttpStream.
4781 QuicStreamRequest request1(factory_.get());
4782 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034783 request1.Request(
Nick Harper23290b82019-05-02 00:02:564784 host_port_pair_, version_.transport_version, privacy_mode_,
4785 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:034786 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4787 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi3c4c9e92018-07-02 23:16:234788 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4789 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
4790 EXPECT_TRUE(stream1.get());
4791
4792 HttpRequestInfo request_info1;
4793 request_info1.method = "GET";
4794 request_info1.url = GURL("https://www.example.org/");
4795 request_info1.traffic_annotation =
4796 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4797 EXPECT_EQ(OK,
4798 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
4799 net_log_, CompletionOnceCallback()));
4800
4801 // Request #2 returns synchronously because it pools to existing session.
4802 TestCompletionCallback callback2;
4803 QuicStreamRequest request2(factory_.get());
Nick Harper23290b82019-05-02 00:02:564804 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_.transport_version,
4805 privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shi3c4c9e92018-07-02 23:16:234806 /*cert_verify_flags=*/0, url_, net_log_,
Zhongyi Shia6b68d112018-09-24 07:49:034807 &net_error_details_,
4808 failed_on_default_network_callback_,
4809 callback2.callback()));
Zhongyi Shi3c4c9e92018-07-02 23:16:234810 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
4811 EXPECT_TRUE(stream2.get());
4812
4813 HttpRequestInfo request_info2;
4814 request_info2.method = "GET";
4815 request_info2.url = GURL("https://www.example.org/");
4816 request_info2.traffic_annotation =
4817 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4818 EXPECT_EQ(OK,
4819 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
4820 net_log_, CompletionOnceCallback()));
4821
4822 // Ensure that session is alive and active.
4823 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
4824 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4825 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4826 EXPECT_EQ(2u, session->GetNumActiveStreams());
4827
4828 // Send GET request on stream1. This should cause an async write error.
4829 HttpResponseInfo response;
4830 HttpRequestHeaders request_headers;
4831 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
4832 callback_.callback()));
4833 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4834
4835 // Run the message loop so that asynchronous write completes and a connection
4836 // migration on write error attempt is posted in QuicStreamFactory's task
4837 // runner.
4838 base::RunLoop().RunUntilIdle();
4839 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4840
4841 // Send GET request on stream. This will cause another write attempt before
4842 // migration on write error is exectued.
4843 HttpResponseInfo response2;
4844 HttpRequestHeaders request_headers2;
4845 EXPECT_EQ(OK, stream2->SendRequest(request_headers2, &response2,
4846 callback2.callback()));
4847
4848 // Run the task runner so that migration on write error is finally executed.
4849 task_runner->RunUntilIdle();
4850
Zhongyi Shia7dd46b2018-07-12 22:59:294851 // Verify the session is still alive and not marked as going away.
Zhongyi Shi3c4c9e92018-07-02 23:16:234852 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:294853 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi3c4c9e92018-07-02 23:16:234854 EXPECT_EQ(2u, session->GetNumActiveStreams());
Zhongyi Shia7dd46b2018-07-12 22:59:294855 // There should be one task posted to migrate back to the default network in
4856 // kMinRetryTimeForDefaultNetworkSecs.
4857 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4858 EXPECT_EQ(base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs),
4859 task_runner->NextPendingTaskDelay());
Zhongyi Shi3c4c9e92018-07-02 23:16:234860
4861 // Verify that response headers on the migrated socket were delivered to the
4862 // stream.
4863 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
4864 EXPECT_EQ(200, response.headers->response_code());
4865
4866 stream1.reset();
4867 stream2.reset();
4868
4869 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4870 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4871 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
4872 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
4873}
4874
Zhongyi Shia7dd46b2018-07-12 22:59:294875// Verify session is not marked as going away after connection migration on
4876// write error and migrate back to default network logic is applied to bring the
4877// migrated session back to the default network. Migration singals delivered
4878// in the following order (alternate network is always availabe):
4879// - session on the default network encountered a write error;
4880// - session successfully migrated to the non-default network;
4881// - session attempts to migrate back to default network post migration;
4882// - migration back to the default network is successful.
4883TEST_P(QuicStreamFactoryTest, MigrateBackToDefaultPostMigrationOnWriteError) {
4884 InitializeConnectionMigrationV2Test(
4885 {kDefaultNetworkForTests, kNewNetworkForTests});
4886 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4887 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4888 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4889
4890 // Using a testing task runner so that we can control time.
4891 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4892 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4893
4894 MockQuicData socket_data;
4895 quic::QuicStreamOffset header_stream_offset = 0;
4896 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4897 socket_data.AddWrite(
4898 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4899 socket_data.AddWrite(ASYNC, ERR_ADDRESS_UNREACHABLE);
4900 socket_data.AddSocketDataToFactory(socket_factory_.get());
4901
4902 // Set up second socket data provider that is used after
4903 // migration. The request is rewritten to this new socket, and the
4904 // response to the request is read on this new socket.
4905 MockQuicData quic_data2;
Fan Yang32c5a112018-12-10 20:06:334906 quic_data2.AddWrite(
4907 SYNCHRONOUS, ConstructGetRequestPacket(
4908 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
4909 true, &header_stream_offset));
Zhongyi Shia7dd46b2018-07-12 22:59:294910 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:334911 ASYNC,
4912 ConstructOkResponsePacket(
4913 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shia7dd46b2018-07-12 22:59:294914 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4915 quic_data2.AddSocketDataToFactory(socket_factory_.get());
4916
4917 // Create request QuicHttpStream.
4918 QuicStreamRequest request1(factory_.get());
4919 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034920 request1.Request(
Nick Harper23290b82019-05-02 00:02:564921 host_port_pair_, version_.transport_version, privacy_mode_,
4922 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:034923 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4924 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shia7dd46b2018-07-12 22:59:294925 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4926 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
4927 EXPECT_TRUE(stream1.get());
4928
4929 HttpRequestInfo request_info1;
4930 request_info1.method = "GET";
4931 request_info1.url = GURL("https://www.example.org/");
4932 request_info1.traffic_annotation =
4933 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4934 EXPECT_EQ(OK,
4935 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
4936 net_log_, CompletionOnceCallback()));
4937
4938 // Ensure that session is alive and active.
4939 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
4940 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4941 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4942 EXPECT_EQ(1u, session->GetNumActiveStreams());
4943
4944 // Send GET request. This should cause an async write error.
4945 HttpResponseInfo response;
4946 HttpRequestHeaders request_headers;
4947 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
4948 callback_.callback()));
4949 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4950
4951 // Run the message loop so that asynchronous write completes and a connection
4952 // migration on write error attempt is posted in QuicStreamFactory's task
4953 // runner.
4954 base::RunLoop().RunUntilIdle();
4955 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4956
4957 // Run the task runner so that migration on write error is finally executed.
4958 task_runner->RunUntilIdle();
4959
4960 // Verify the session is still alive and not marked as going away.
4961 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4962 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4963 EXPECT_EQ(1u, session->GetNumActiveStreams());
4964 // There should be one task posted to migrate back to the default network in
4965 // kMinRetryTimeForDefaultNetworkSecs.
4966 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4967 base::TimeDelta expected_delay =
4968 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs);
4969 EXPECT_EQ(expected_delay, task_runner->NextPendingTaskDelay());
4970
4971 // Verify that response headers on the migrated socket were delivered to the
4972 // stream.
4973 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
4974 EXPECT_EQ(200, response.headers->response_code());
4975
4976 // Set up the third socket data provider for migrate back to default network.
4977 MockQuicData quic_data3;
4978 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:254979 quic_data3.AddWrite(SYNCHRONOUS,
4980 client_maker_.MakeConnectivityProbingPacket(3, false));
Zhongyi Shia7dd46b2018-07-12 22:59:294981 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:254982 quic_data3.AddRead(ASYNC,
4983 server_maker_.MakeConnectivityProbingPacket(2, false));
Zhongyi Shia7dd46b2018-07-12 22:59:294984 quic_data3.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4985 quic_data3.AddWrite(ASYNC, client_maker_.MakeAckPacket(4, 1, 2, 1, 1, true));
4986 quic_data3.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334987 SYNCHRONOUS, client_maker_.MakeRstPacket(
4988 5, false, GetNthClientInitiatedBidirectionalStreamId(0),
Frank Kastenholz684ea412019-02-13 18:48:184989 quic::QUIC_STREAM_CANCELLED, 0,
4990 /*include_stop_sending_if_v99=*/true));
Zhongyi Shia7dd46b2018-07-12 22:59:294991 quic_data3.AddSocketDataToFactory(socket_factory_.get());
4992
4993 // Fast forward to fire the migrate back timer and verify the session
4994 // successfully migrates back to the default network.
4995 task_runner->FastForwardBy(expected_delay);
4996
4997 // Verify the session is still alive and not marked as going away.
4998 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4999 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5000 EXPECT_EQ(1u, session->GetNumActiveStreams());
5001
5002 // There should be one task posted to one will resend a connectivity probe and
5003 // the other will retry migrate back, both are cancelled.
5004 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
5005 task_runner->FastForwardBy(
5006 base::TimeDelta::FromSeconds(2 * kMinRetryTimeForDefaultNetworkSecs));
5007 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
5008
5009 stream1.reset();
5010 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5011 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5012 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
5013 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
5014 EXPECT_TRUE(quic_data3.AllReadDataConsumed());
5015 EXPECT_TRUE(quic_data3.AllWriteDataConsumed());
5016}
5017
Zhongyi Shic1449372018-08-09 09:58:585018// This test verifies that the connection will not attempt connection migration
5019// (send connectivity probes on alternate path) when path degrading is detected
5020// and handshake is not confirmed.
5021TEST_P(QuicStreamFactoryTest,
5022 NoMigrationOnPathDegradingBeforeHandshakeConfirmed) {
5023 InitializeConnectionMigrationV2Test(
5024 {kDefaultNetworkForTests, kNewNetworkForTests});
5025
5026 // Using a testing task runner.
5027 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
5028 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
5029
5030 // Use cold start mode to send crypto message for handshake.
5031 crypto_client_stream_factory_.set_handshake_mode(
5032 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
5033
5034 MockQuicData socket_data;
5035 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5036 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
5037 socket_data.AddSocketDataToFactory(socket_factory_.get());
5038
5039 // Create request and QuicHttpStream.
5040 QuicStreamRequest request(factory_.get());
5041 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035042 request.Request(
Nick Harper23290b82019-05-02 00:02:565043 host_port_pair_, version_.transport_version, privacy_mode_,
5044 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:035045 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5046 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shic1449372018-08-09 09:58:585047
5048 base::RunLoop().RunUntilIdle();
5049
5050 // Ensure that session is alive but not active.
5051 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5052 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5053 QuicChromiumClientSession* session = GetPendingSession(host_port_pair_);
5054 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5055 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
5056
5057 // Cause the connection to report path degrading to the session.
5058 // Session will ignore the signal as handshake is not completed.
5059 session->connection()->OnPathDegradingTimeout();
5060 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
5061
5062 EXPECT_FALSE(HasActiveSession(host_port_pair_));
Zhongyi Shi8de43832018-08-15 23:40:005063 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
Zhongyi Shic1449372018-08-09 09:58:585064 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5065 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5066}
5067
Zhongyi Shi634c1882018-08-16 04:05:595068// This test verifies that if a connection is closed with
5069// QUIC_NETWORK_IDLE_TIMEOUT before handshake is completed and there is no
5070// alternate network, no new connection will be created.
5071TEST_P(QuicStreamFactoryTest, NoAlternateNetworkBeforeHandshakeOnIdleTimeout) {
5072 TestNoAlternateNetworkBeforeHandshake(quic::QUIC_NETWORK_IDLE_TIMEOUT);
5073}
5074
5075// This test verifies that if a connection is closed with QUIC_HANDSHAKE_TIMEOUT
5076// and there is no alternate network, no new connection will be created.
5077TEST_P(QuicStreamFactoryTest, NoAlternateNetworkOnHandshakeTimeout) {
5078 TestNoAlternateNetworkBeforeHandshake(quic::QUIC_HANDSHAKE_TIMEOUT);
5079}
5080
5081void QuicStreamFactoryTestBase::TestNoAlternateNetworkBeforeHandshake(
5082 quic::QuicErrorCode quic_error) {
5083 DCHECK(quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT ||
5084 quic_error == quic::QUIC_HANDSHAKE_TIMEOUT);
5085 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
5086
5087 // Using a testing task runner.
5088 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
5089 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
5090
5091 // Use cold start mode to send crypto message for handshake.
5092 crypto_client_stream_factory_.set_handshake_mode(
5093 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
5094
5095 MockQuicData socket_data;
5096 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5097 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
5098 socket_data.AddSocketDataToFactory(socket_factory_.get());
5099
5100 // Create request.
5101 QuicStreamRequest request(factory_.get());
5102 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035103 request.Request(
Nick Harper23290b82019-05-02 00:02:565104 host_port_pair_, version_.transport_version, privacy_mode_,
5105 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:035106 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5107 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi634c1882018-08-16 04:05:595108
5109 base::RunLoop().RunUntilIdle();
5110
5111 // Ensure that session is alive but not active.
5112 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5113 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5114 QuicChromiumClientSession* session = GetPendingSession(host_port_pair_);
5115 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5116 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
5117
5118 // Cause the connection to report path degrading to the session.
5119 // Session will ignore the signal as handshake is not completed.
5120 session->connection()->OnPathDegradingTimeout();
5121 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
5122 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5123 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5124
5125 // Cause the connection to close due to |quic_error| before handshake.
Victor Vasiliev076657c2019-03-12 02:46:435126 std::string error_details;
Zhongyi Shi634c1882018-08-16 04:05:595127 if (quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT) {
5128 error_details = "No recent network activity.";
5129 } else {
5130 error_details = "Handshake timeout expired.";
5131 }
5132 session->connection()->CloseConnection(
5133 quic_error, error_details, quic::ConnectionCloseBehavior::SILENT_CLOSE);
5134
5135 // A task will be posted to clean up the session in the factory.
5136 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
5137 task_runner->FastForwardUntilNoTasksRemain();
5138
5139 // No new session should be created as there is no alternate network.
5140 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5141 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
5142 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5143 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5144}
5145
Zhongyi Shi8de43832018-08-15 23:40:005146TEST_P(QuicStreamFactoryTest, NewConnectionBeforeHandshakeAfterIdleTimeout) {
5147 TestNewConnectionOnAlternateNetworkBeforeHandshake(
5148 quic::QUIC_NETWORK_IDLE_TIMEOUT);
5149}
5150
5151TEST_P(QuicStreamFactoryTest, NewConnectionAfterHandshakeTimeout) {
5152 TestNewConnectionOnAlternateNetworkBeforeHandshake(
5153 quic::QUIC_HANDSHAKE_TIMEOUT);
5154}
5155
Zhongyi Shif3fcbbe62018-08-16 22:52:085156// Sets up a test to verify that a new connection will be created on the
5157// alternate network after the initial connection fails before handshake with
5158// signals delivered in the following order (alternate network is available):
5159// - the default network is not able to complete crypto handshake;
5160// - the original connection is closed with |quic_error|;
5161// - a new connection is created on the alternate network and is able to finish
5162// crypto handshake;
5163// - the new session on the alternate network attempts to migrate back to the
5164// default network by sending probes;
5165// - default network being disconnected is delivered: session will stop probing
5166// the original network.
5167// - alternate network is made by default.
Zhongyi Shi8de43832018-08-15 23:40:005168void QuicStreamFactoryTestBase::
5169 TestNewConnectionOnAlternateNetworkBeforeHandshake(
5170 quic::QuicErrorCode quic_error) {
5171 DCHECK(quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT ||
5172 quic_error == quic::QUIC_HANDSHAKE_TIMEOUT);
Zhongyi Shi967d2f12019-02-08 20:58:535173 test_params_.quic_retry_on_alternate_network_before_handshake = true;
Zhongyi Shi8de43832018-08-15 23:40:005174 InitializeConnectionMigrationV2Test(
5175 {kDefaultNetworkForTests, kNewNetworkForTests});
5176
5177 // Using a testing task runner.
5178 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
5179 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
5180
5181 // Use cold start mode to send crypto message for handshake.
5182 crypto_client_stream_factory_.set_handshake_mode(
5183 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
5184
5185 // Socket data for connection on the default network.
5186 MockQuicData socket_data;
5187 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5188 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
5189 socket_data.AddSocketDataToFactory(socket_factory_.get());
5190
5191 // Socket data for connection on the alternate network.
5192 MockQuicData socket_data2;
5193 quic::QuicStreamOffset header_stream_offset = 0;
5194 socket_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5195 socket_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
5196 // Change the encryption level after handshake is confirmed.
5197 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5198 socket_data2.AddWrite(
5199 ASYNC, ConstructInitialSettingsPacket(2, &header_stream_offset));
5200 socket_data2.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335201 ASYNC, ConstructGetRequestPacket(
5202 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
5203 &header_stream_offset));
Zhongyi Shi8de43832018-08-15 23:40:005204 socket_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:335205 ASYNC,
5206 ConstructOkResponsePacket(
5207 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shi8de43832018-08-15 23:40:005208 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:335209 socket_data2.AddWrite(
5210 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
5211 5, false, GetNthClientInitiatedBidirectionalStreamId(0),
5212 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi8de43832018-08-15 23:40:005213 socket_data2.AddSocketDataToFactory(socket_factory_.get());
5214
Zhongyi Shif3fcbbe62018-08-16 22:52:085215 // Socket data for probing on the default network.
5216 MockQuicData probing_data;
5217 probing_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
5218 probing_data.AddWrite(SYNCHRONOUS,
5219 client_maker_.MakeConnectivityProbingPacket(4, false));
5220 probing_data.AddSocketDataToFactory(socket_factory_.get());
5221
Zhongyi Shi8de43832018-08-15 23:40:005222 // Create request and QuicHttpStream.
5223 QuicStreamRequest request(factory_.get());
5224 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035225 request.Request(
Nick Harper23290b82019-05-02 00:02:565226 host_port_pair_, version_.transport_version, privacy_mode_,
5227 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:035228 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5229 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi8de43832018-08-15 23:40:005230
5231 base::RunLoop().RunUntilIdle();
5232
5233 // Ensure that session is alive but not active.
5234 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5235 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5236 QuicChromiumClientSession* session = GetPendingSession(host_port_pair_);
5237 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5238 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
Zhongyi Shia6b68d112018-09-24 07:49:035239 EXPECT_FALSE(failed_on_default_network_);
Zhongyi Shi8de43832018-08-15 23:40:005240
Victor Vasiliev076657c2019-03-12 02:46:435241 std::string error_details;
Zhongyi Shi8de43832018-08-15 23:40:005242 if (quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT) {
5243 error_details = "No recent network activity.";
5244 } else {
5245 error_details = "Handshake timeout expired.";
5246 }
5247 session->connection()->CloseConnection(
5248 quic_error, error_details, quic::ConnectionCloseBehavior::SILENT_CLOSE);
5249
5250 // A task will be posted to clean up the session in the factory.
5251 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
5252 task_runner->FastForwardUntilNoTasksRemain();
5253
5254 // Verify a new session is created on the alternate network.
5255 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5256 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5257 QuicChromiumClientSession* session2 = GetPendingSession(host_port_pair_);
5258 EXPECT_NE(session, session2);
Zhongyi Shia6b68d112018-09-24 07:49:035259 EXPECT_TRUE(failed_on_default_network_);
Zhongyi Shi8de43832018-08-15 23:40:005260
5261 // Confirm the handshake on the alternate network.
5262 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5263 quic::QuicSession::HANDSHAKE_CONFIRMED);
5264 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5265 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5266 // Resume the data now so that data can be sent and read.
5267 socket_data2.Resume();
5268
5269 // Create the stream.
5270 std::unique_ptr<HttpStream> stream = CreateStream(&request);
5271 EXPECT_TRUE(stream.get());
5272 HttpRequestInfo request_info;
5273 request_info.method = "GET";
5274 request_info.url = GURL("https://www.example.org/");
5275 request_info.traffic_annotation =
5276 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5277 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
5278 net_log_, CompletionOnceCallback()));
5279 // Send the request.
5280 HttpResponseInfo response;
5281 HttpRequestHeaders request_headers;
5282 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5283 callback_.callback()));
5284 // Run the message loop to finish asynchronous mock write.
5285 base::RunLoop().RunUntilIdle();
5286 // Read the response.
5287 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
5288 EXPECT_EQ(200, response.headers->response_code());
5289
Zhongyi Shif3fcbbe62018-08-16 22:52:085290 // There should be a new task posted to migrate back to the default network.
5291 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
5292 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
5293 EXPECT_EQ(base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs),
5294 next_task_delay);
5295 task_runner->FastForwardBy(next_task_delay);
5296
5297 // There should be two tasks posted. One will retry probing and the other
5298 // will retry migrate back.
5299 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
5300 next_task_delay = task_runner->NextPendingTaskDelay();
5301 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
5302 next_task_delay);
5303
5304 // Deliver the signal that the default network is disconnected.
5305 scoped_mock_network_change_notifier_->mock_network_change_notifier()
5306 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
5307 // Verify no connectivity probes will be sent as probing will be cancelled.
5308 task_runner->FastForwardUntilNoTasksRemain();
5309 // Deliver the signal that the alternate network is made default.
5310 scoped_mock_network_change_notifier_->mock_network_change_notifier()
5311 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
5312 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
5313
Zhongyi Shi8de43832018-08-15 23:40:005314 stream.reset();
5315 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5316 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5317 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
5318 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
5319}
5320
Zhongyi Shi247d6322018-07-24 07:03:355321// Test that connection will be closed with PACKET_WRITE_ERROR if a write error
5322// is triggered before handshake is confirmed and connection migration is turned
5323// on.
5324TEST_P(QuicStreamFactoryTest, MigrationOnWriteErrorBeforeHandshakeConfirmed) {
Zhongyi Shi967d2f12019-02-08 20:58:535325 DCHECK(!test_params_.quic_retry_on_alternate_network_before_handshake);
Zhongyi Shi247d6322018-07-24 07:03:355326 InitializeConnectionMigrationV2Test(
5327 {kDefaultNetworkForTests, kNewNetworkForTests});
5328
5329 // Use unmocked crypto stream to do crypto connect.
5330 crypto_client_stream_factory_.set_handshake_mode(
Zhongyi Shi879659422018-08-02 17:58:255331 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
Zhongyi Shi247d6322018-07-24 07:03:355332
5333 MockQuicData socket_data;
5334 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5335 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
5336 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
5337 socket_data.AddSocketDataToFactory(socket_factory_.get());
5338
5339 // Create request, should fail after the write of the CHLO fails.
5340 QuicStreamRequest request(factory_.get());
5341 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035342 request.Request(
Nick Harper23290b82019-05-02 00:02:565343 host_port_pair_, version_.transport_version, privacy_mode_,
5344 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:035345 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5346 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi247d6322018-07-24 07:03:355347 EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED, callback_.WaitForResult());
5348 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5349 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
5350
5351 // Verify new requests can be sent normally.
5352 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:275353 MockCryptoClientStream::COLD_START);
Zhongyi Shi247d6322018-07-24 07:03:355354 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5355 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5356 MockQuicData socket_data2;
5357 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5358 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
5359 socket_data2.AddSocketDataToFactory(socket_factory_.get());
5360
5361 QuicStreamRequest request2(factory_.get());
5362 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035363 request2.Request(
Nick Harper23290b82019-05-02 00:02:565364 host_port_pair_, version_.transport_version, privacy_mode_,
5365 DEFAULT_PRIORITY, SocketTag(),
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_FALSE(HasActiveSession(host_port_pair_));
5369 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5370 // Run the message loop to complete host resolution.
5371 base::RunLoop().RunUntilIdle();
5372
5373 // Complete handshake. QuicStreamFactory::Job should complete and succeed.
5374 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5375 quic::QuicSession::HANDSHAKE_CONFIRMED);
5376 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5377 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5378 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
5379
5380 // Create QuicHttpStream.
5381 std::unique_ptr<HttpStream> stream = CreateStream(&request2);
5382 EXPECT_TRUE(stream.get());
5383 stream.reset();
5384 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5385 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5386 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
5387 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
5388}
5389
Zhongyi Shif2524bf2019-01-27 07:44:035390// Test that if the original connection is closed with QUIC_PACKET_WRITE_ERROR
5391// before handshake is confirmed and new connection before handshake is turned
5392// on, a new connection will be retried on the alternate network.
5393TEST_P(QuicStreamFactoryTest,
5394 RetryConnectionOnWriteErrorBeforeHandshakeConfirmed) {
Zhongyi Shi967d2f12019-02-08 20:58:535395 test_params_.quic_retry_on_alternate_network_before_handshake = true;
Zhongyi Shif2524bf2019-01-27 07:44:035396 InitializeConnectionMigrationV2Test(
5397 {kDefaultNetworkForTests, kNewNetworkForTests});
5398
5399 // Use unmocked crypto stream to do crypto connect.
5400 crypto_client_stream_factory_.set_handshake_mode(
5401 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
5402
5403 // Socket data for connection on the default network.
5404 MockQuicData socket_data;
5405 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5406 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
5407 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
5408 socket_data.AddSocketDataToFactory(socket_factory_.get());
5409
5410 // Socket data for connection on the alternate network.
5411 MockQuicData socket_data2;
5412 quic::QuicStreamOffset header_stream_offset = 0;
5413 socket_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5414 socket_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
5415 // Change the encryption level after handshake is confirmed.
5416 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5417 socket_data2.AddWrite(
5418 ASYNC, ConstructInitialSettingsPacket(2, &header_stream_offset));
5419 socket_data2.AddWrite(
5420 ASYNC, ConstructGetRequestPacket(
5421 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
5422 &header_stream_offset));
5423 socket_data2.AddRead(
5424 ASYNC,
5425 ConstructOkResponsePacket(
5426 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
5427 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5428 socket_data2.AddWrite(
5429 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
5430 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
5431 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
5432 socket_data2.AddSocketDataToFactory(socket_factory_.get());
5433
5434 // Create request, should fail after the write of the CHLO fails.
5435 QuicStreamRequest request(factory_.get());
5436 EXPECT_EQ(ERR_IO_PENDING,
5437 request.Request(
Nick Harper23290b82019-05-02 00:02:565438 host_port_pair_, version_.transport_version, privacy_mode_,
5439 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shif2524bf2019-01-27 07:44:035440 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5441 failed_on_default_network_callback_, callback_.callback()));
5442 // Ensure that the session is alive but not active.
5443 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5444 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5445 base::RunLoop().RunUntilIdle();
5446 QuicChromiumClientSession* session = GetPendingSession(host_port_pair_);
5447 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5448
5449 // Confirm the handshake on the alternate network.
5450 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5451 quic::QuicSession::HANDSHAKE_CONFIRMED);
5452 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5453 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5454
5455 // Resume the data now so that data can be sent and read.
5456 socket_data2.Resume();
5457
5458 // Create the stream.
5459 std::unique_ptr<HttpStream> stream = CreateStream(&request);
5460 EXPECT_TRUE(stream.get());
5461 HttpRequestInfo request_info;
5462 request_info.method = "GET";
5463 request_info.url = GURL("https://www.example.org/");
5464 request_info.traffic_annotation =
5465 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5466 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
5467 net_log_, CompletionOnceCallback()));
5468 // Send the request.
5469 HttpResponseInfo response;
5470 HttpRequestHeaders request_headers;
5471 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5472 callback_.callback()));
5473 // Run the message loop to finish asynchronous mock write.
5474 base::RunLoop().RunUntilIdle();
5475 // Read the response.
5476 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
5477 EXPECT_EQ(200, response.headers->response_code());
5478
5479 stream.reset();
5480 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5481 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5482 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
5483 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
5484}
5485
jri9f303712016-09-13 01:10:225486void QuicStreamFactoryTestBase::TestMigrationOnWriteError(
5487 IoMode write_error_mode) {
Zhongyi Shi1a054612018-06-14 04:59:085488 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:225489 {kDefaultNetworkForTests, kNewNetworkForTests});
5490 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5491 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5492 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5493
Zhongyi Shi3c4c9e92018-07-02 23:16:235494 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
5495
jri9f303712016-09-13 01:10:225496 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525497 quic::QuicStreamOffset header_stream_offset = 0;
jri9f303712016-09-13 01:10:225498 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
rch5cb522462017-04-25 20:18:365499 socket_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435500 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
jri9f303712016-09-13 01:10:225501 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:175502 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:225503
5504 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:455505 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:335506 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035507 request.Request(
Nick Harper23290b82019-05-02 00:02:565508 host_port_pair_, version_.transport_version, privacy_mode_,
5509 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:035510 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5511 failed_on_default_network_callback_, callback_.callback()));
jri9f303712016-09-13 01:10:225512 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:245513 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:225514 EXPECT_TRUE(stream.get());
5515
5516 // Cause QUIC stream to be created.
5517 HttpRequestInfo request_info;
5518 request_info.method = "GET";
5519 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:395520 request_info.traffic_annotation =
5521 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:275522 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:395523 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:225524
5525 // Ensure that session is alive and active.
5526 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5527 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5528 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5529
5530 // Set up second socket data provider that is used after
5531 // migration. The request is rewritten to this new socket, and the
5532 // response to the request is read on this new socket.
5533 MockQuicData socket_data1;
Fan Yang32c5a112018-12-10 20:06:335534 socket_data1.AddWrite(
5535 SYNCHRONOUS, ConstructGetRequestPacket(
5536 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
5537 true, &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435538 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:335539 ASYNC,
5540 ConstructOkResponsePacket(
5541 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
jri9f303712016-09-13 01:10:225542 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:335543 socket_data1.AddWrite(
5544 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
5545 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
5546 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:175547 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:225548
5549 // Send GET request on stream. This should cause a write error, which triggers
5550 // a connection migration attempt.
5551 HttpResponseInfo response;
5552 HttpRequestHeaders request_headers;
5553 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5554 callback_.callback()));
5555
5556 // Run the message loop so that the migration attempt is executed and
5557 // data queued in the new socket is read by the packet reader.
5558 base::RunLoop().RunUntilIdle();
5559
Zhongyi Shia7dd46b2018-07-12 22:59:295560 // Verify that session is alive and not marked as going awya.
jri9f303712016-09-13 01:10:225561 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:295562 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri9f303712016-09-13 01:10:225563 EXPECT_EQ(1u, session->GetNumActiveStreams());
5564
5565 // Verify that response headers on the migrated socket were delivered to the
5566 // stream.
5567 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
5568 EXPECT_EQ(200, response.headers->response_code());
5569
5570 stream.reset();
5571
5572 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5573 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5574 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
5575 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
5576}
5577
5578TEST_P(QuicStreamFactoryTest, MigrateSessionOnWriteErrorSynchronous) {
5579 TestMigrationOnWriteError(SYNCHRONOUS);
5580}
5581
5582TEST_P(QuicStreamFactoryTest, MigrateSessionOnWriteErrorAsync) {
5583 TestMigrationOnWriteError(ASYNC);
5584}
5585
5586void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorNoNewNetwork(
5587 IoMode write_error_mode) {
Zhongyi Shi1a054612018-06-14 04:59:085588 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri9f303712016-09-13 01:10:225589 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5590 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5591
jri5b785512016-09-13 04:29:115592 // Use the test task runner, to force the migration alarm timeout later.
5593 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
5594
jri9f303712016-09-13 01:10:225595 MockQuicData socket_data;
5596 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:435597 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jri9f303712016-09-13 01:10:225598 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:175599 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:225600
5601 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:455602 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:335603 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035604 request.Request(
Nick Harper23290b82019-05-02 00:02:565605 host_port_pair_, version_.transport_version, privacy_mode_,
5606 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:035607 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5608 failed_on_default_network_callback_, callback_.callback()));
jri9f303712016-09-13 01:10:225609 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:245610 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:225611 EXPECT_TRUE(stream.get());
5612
5613 // Cause QUIC stream to be created.
5614 HttpRequestInfo request_info;
5615 request_info.method = "GET";
5616 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:395617 request_info.traffic_annotation =
5618 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:275619 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:395620 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:225621
5622 // Ensure that session is alive and active.
5623 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5624 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5625 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5626
jri5b785512016-09-13 04:29:115627 // Send GET request on stream. This causes a write error, which triggers
5628 // a connection migration attempt. Since there are no networks
5629 // to migrate to, this causes the session to wait for a new network.
jri9f303712016-09-13 01:10:225630 HttpResponseInfo response;
5631 HttpRequestHeaders request_headers;
5632 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5633 callback_.callback()));
jri5b785512016-09-13 04:29:115634
5635 // Complete any pending writes. Pending async MockQuicData writes
5636 // are run on the message loop, not on the test runner.
jri9f303712016-09-13 01:10:225637 base::RunLoop().RunUntilIdle();
jri5b785512016-09-13 04:29:115638
5639 // Write error causes migration task to be posted. Spin the loop.
5640 if (write_error_mode == ASYNC)
5641 runner_->RunNextTask();
5642
5643 // Migration has not yet failed. The session should be alive and active.
5644 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5645 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5646 EXPECT_EQ(1u, session->GetNumActiveStreams());
5647 EXPECT_TRUE(session->connection()->writer()->IsWriteBlocked());
5648
5649 // The migration will not fail until the migration alarm timeout.
5650 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5651 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5652 EXPECT_EQ(1u, session->GetNumActiveStreams());
5653 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
5654
5655 // Force migration alarm timeout to run.
5656 RunTestLoopUntilIdle();
5657
5658 // The connection should be closed. A request for response headers
5659 // should fail.
jri9f303712016-09-13 01:10:225660 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5661 EXPECT_FALSE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:115662 EXPECT_EQ(ERR_NETWORK_CHANGED, callback_.WaitForResult());
5663 EXPECT_EQ(ERR_NETWORK_CHANGED,
5664 stream->ReadResponseHeaders(callback_.callback()));
jri9f303712016-09-13 01:10:225665
Zhongyi Shi59aaf072019-01-17 03:32:135666 NetErrorDetails error_details;
5667 stream->PopulateNetErrorDetails(&error_details);
5668 EXPECT_EQ(error_details.quic_connection_error,
5669 quic::QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK);
5670
jri9f303712016-09-13 01:10:225671 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5672 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5673}
5674
5675TEST_P(QuicStreamFactoryTest,
5676 MigrateSessionOnWriteErrorNoNewNetworkSynchronous) {
5677 TestMigrationOnWriteErrorNoNewNetwork(SYNCHRONOUS);
5678}
5679
5680TEST_P(QuicStreamFactoryTest, MigrateSessionOnWriteErrorNoNewNetworkAsync) {
5681 TestMigrationOnWriteErrorNoNewNetwork(ASYNC);
5682}
5683
Zhongyi Shi0439ecc72018-07-11 04:41:265684TEST_P(QuicStreamFactoryTest,
5685 MigrateSessionOnWriteErrorWithMultipleRequestsSync) {
5686 TestMigrationOnWriteErrorWithMultipleRequests(SYNCHRONOUS);
5687}
5688
5689TEST_P(QuicStreamFactoryTest,
5690 MigrateSessionOnWriteErrorWithMultipleRequestsAsync) {
5691 TestMigrationOnWriteErrorWithMultipleRequests(ASYNC);
5692}
5693
5694// Sets up a test which verifies that connection migration on write error can
5695// eventually succeed and rewrite the packet on the new network with *multiple*
5696// migratable streams.
5697void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorWithMultipleRequests(
5698 IoMode write_error_mode) {
5699 InitializeConnectionMigrationV2Test(
5700 {kDefaultNetworkForTests, kNewNetworkForTests});
5701 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5702 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5703 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5704
5705 MockQuicData socket_data;
5706 quic::QuicStreamOffset header_stream_offset = 0;
5707 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5708 socket_data.AddWrite(
5709 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5710 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
5711 socket_data.AddSocketDataToFactory(socket_factory_.get());
5712
5713 // Set up second socket data provider that is used after
5714 // migration. The request is rewritten to this new socket, and the
5715 // response to the request is read on this new socket.
5716 MockQuicData socket_data1;
Zhongyi Shi0439ecc72018-07-11 04:41:265717 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335718 SYNCHRONOUS, ConstructGetRequestPacket(
5719 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
5720 true, &header_stream_offset));
5721 socket_data1.AddRead(
5722 ASYNC,
5723 ConstructOkResponsePacket(
5724 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
5725 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5726 socket_data1.AddWrite(
5727 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
5728 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
5729 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
5730 socket_data1.AddWrite(
5731 SYNCHRONOUS, client_maker_.MakeRstPacket(
5732 4, false, GetNthClientInitiatedBidirectionalStreamId(1),
Frank Kastenholz684ea412019-02-13 18:48:185733 quic::QUIC_STREAM_CANCELLED, 0,
5734 /*include_stop_sending_if_v99=*/true));
Zhongyi Shi0439ecc72018-07-11 04:41:265735
5736 socket_data1.AddSocketDataToFactory(socket_factory_.get());
5737
5738 // Create request #1 and QuicHttpStream.
5739 QuicStreamRequest request1(factory_.get());
5740 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035741 request1.Request(
Nick Harper23290b82019-05-02 00:02:565742 host_port_pair_, version_.transport_version, privacy_mode_,
5743 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:035744 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5745 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi0439ecc72018-07-11 04:41:265746 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5747 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
5748 EXPECT_TRUE(stream1.get());
5749
5750 HttpRequestInfo request_info1;
5751 request_info1.method = "GET";
5752 request_info1.url = GURL("https://www.example.org/");
5753 request_info1.traffic_annotation =
5754 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5755 EXPECT_EQ(OK,
5756 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
5757 net_log_, CompletionOnceCallback()));
5758
5759 // Second request returns synchronously because it pools to existing session.
5760 TestCompletionCallback callback2;
5761 QuicStreamRequest request2(factory_.get());
Nick Harper23290b82019-05-02 00:02:565762 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_.transport_version,
5763 privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shi0439ecc72018-07-11 04:41:265764 /*cert_verify_flags=*/0, url_, net_log_,
Zhongyi Shia6b68d112018-09-24 07:49:035765 &net_error_details_,
5766 failed_on_default_network_callback_,
5767 callback2.callback()));
Zhongyi Shi0439ecc72018-07-11 04:41:265768 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
5769 EXPECT_TRUE(stream2.get());
5770 HttpRequestInfo request_info2;
5771 request_info2.method = "GET";
5772 request_info2.url = GURL("https://www.example.org/");
5773 request_info2.traffic_annotation =
5774 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5775 EXPECT_EQ(OK,
5776 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
5777 net_log_, CompletionOnceCallback()));
5778
5779 // Ensure that session is alive and active.
5780 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5781 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5782 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5783 EXPECT_EQ(2u, session->GetNumActiveStreams());
5784
5785 // Send GET request on stream. This should cause a write error, which triggers
5786 // a connection migration attempt.
5787 HttpResponseInfo response;
5788 HttpRequestHeaders request_headers;
5789 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
5790 callback_.callback()));
5791
5792 // Run the message loop so that the migration attempt is executed and
5793 // data queued in the new socket is read by the packet reader.
5794 base::RunLoop().RunUntilIdle();
5795
Zhongyi Shia7dd46b2018-07-12 22:59:295796 // Verify session is still alive and not marked as going away.
Zhongyi Shi0439ecc72018-07-11 04:41:265797 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:295798 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:265799 EXPECT_EQ(2u, session->GetNumActiveStreams());
5800
5801 // Verify that response headers on the migrated socket were delivered to the
5802 // stream.
5803 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
5804 EXPECT_EQ(200, response.headers->response_code());
5805
5806 stream1.reset();
5807 stream2.reset();
5808
5809 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5810 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5811 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
5812 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
5813}
5814
5815TEST_P(QuicStreamFactoryTest, MigrateOnWriteErrorWithMixedRequestsSync) {
5816 TestMigrationOnWriteErrorMixedStreams(SYNCHRONOUS);
5817}
5818
5819TEST_P(QuicStreamFactoryTest, MigrateOnWriteErrorWithMixedRequestsAsync) {
5820 TestMigrationOnWriteErrorMixedStreams(ASYNC);
5821}
5822
5823// Sets up a test that verifies connection migration manages to migrate to
5824// alternate network after encountering a SYNC/ASYNC write error based on
5825// |write_error_mode| on the original network.
5826// Note there are mixed types of unfinished requests before migration: one
5827// migratable and one non-migratable. The *migratable* one triggers write
5828// error.
5829void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorMixedStreams(
5830 IoMode write_error_mode) {
5831 InitializeConnectionMigrationV2Test(
5832 {kDefaultNetworkForTests, kNewNetworkForTests});
5833 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5834 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5835 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5836
5837 int packet_number = 1;
5838 MockQuicData socket_data;
5839 quic::QuicStreamOffset header_stream_offset = 0;
5840 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5841 socket_data.AddWrite(
5842 SYNCHRONOUS,
5843 ConstructInitialSettingsPacket(packet_number++, &header_stream_offset));
5844 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
5845 socket_data.AddSocketDataToFactory(socket_factory_.get());
5846
5847 // Set up second socket data provider that is used after
5848 // migration. The request is rewritten to this new socket, and the
5849 // response to the request is read on this new socket.
5850 MockQuicData socket_data1;
5851 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335852 SYNCHRONOUS,
5853 ConstructGetRequestPacket(packet_number++,
5854 GetNthClientInitiatedBidirectionalStreamId(0),
5855 true, true, &header_stream_offset));
Zhongyi Shi0439ecc72018-07-11 04:41:265856 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335857 SYNCHRONOUS,
5858 client_maker_.MakeRstPacket(packet_number++, true,
5859 GetNthClientInitiatedBidirectionalStreamId(1),
Frank Kastenholz684ea412019-02-13 18:48:185860 quic::QUIC_STREAM_CANCELLED, 0,
5861 /*include_stop_sending_if_v99=*/true));
Zhongyi Shi0439ecc72018-07-11 04:41:265862 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:335863 ASYNC,
5864 ConstructOkResponsePacket(
5865 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shi0439ecc72018-07-11 04:41:265866 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5867 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335868 SYNCHRONOUS,
5869 client_maker_.MakeAckAndRstPacket(
5870 packet_number++, false, GetNthClientInitiatedBidirectionalStreamId(0),
5871 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi0439ecc72018-07-11 04:41:265872 socket_data1.AddSocketDataToFactory(socket_factory_.get());
5873
5874 // Create request #1 and QuicHttpStream.
5875 QuicStreamRequest request1(factory_.get());
5876 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035877 request1.Request(
Nick Harper23290b82019-05-02 00:02:565878 host_port_pair_, version_.transport_version, privacy_mode_,
5879 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:035880 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5881 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi0439ecc72018-07-11 04:41:265882 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5883 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
5884 EXPECT_TRUE(stream1.get());
5885
5886 HttpRequestInfo request_info1;
5887 request_info1.method = "GET";
5888 request_info1.url = GURL("https://www.example.org/");
5889 request_info1.traffic_annotation =
5890 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5891 EXPECT_EQ(OK,
5892 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
5893 net_log_, CompletionOnceCallback()));
5894
5895 // Second request returns synchronously because it pools to existing session.
5896 TestCompletionCallback callback2;
5897 QuicStreamRequest request2(factory_.get());
Nick Harper23290b82019-05-02 00:02:565898 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_.transport_version,
5899 privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shi0439ecc72018-07-11 04:41:265900 /*cert_verify_flags=*/0, url_, net_log_,
Zhongyi Shia6b68d112018-09-24 07:49:035901 &net_error_details_,
5902 failed_on_default_network_callback_,
5903 callback2.callback()));
Zhongyi Shi0439ecc72018-07-11 04:41:265904 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
5905 EXPECT_TRUE(stream2.get());
5906
5907 HttpRequestInfo request_info2;
5908 request_info2.method = "GET";
Zhongyi Shibb28b1f2018-07-18 02:41:265909 request_info2.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Zhongyi Shi0439ecc72018-07-11 04:41:265910 request_info2.url = GURL("https://www.example.org/");
5911 request_info2.traffic_annotation =
5912 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5913 EXPECT_EQ(OK,
5914 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
5915 net_log_, CompletionOnceCallback()));
5916
5917 // Ensure that session is alive and active.
5918 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5919 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5920 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5921 EXPECT_EQ(2u, session->GetNumActiveStreams());
5922
5923 // Send GET request on stream 1. This should cause a write error, which
5924 // triggers a connection migration attempt.
5925 HttpResponseInfo response;
5926 HttpRequestHeaders request_headers;
5927 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
5928 callback_.callback()));
5929
5930 // Run the message loop so that the migration attempt is executed and
5931 // data queued in the new socket is read by the packet reader.
5932 base::RunLoop().RunUntilIdle();
5933
Zhongyi Shia7dd46b2018-07-12 22:59:295934 // Verify that the session is still alive and not marked as going away.
5935 // Non-migratable stream should be closed due to migration.
Zhongyi Shi0439ecc72018-07-11 04:41:265936 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:295937 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:265938 EXPECT_EQ(1u, session->GetNumActiveStreams());
5939
5940 // Verify that response headers on the migrated socket were delivered to the
5941 // stream.
5942 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
5943 EXPECT_EQ(200, response.headers->response_code());
5944
5945 stream1.reset();
5946
5947 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5948 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5949 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
5950 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
5951}
5952
5953TEST_P(QuicStreamFactoryTest, MigrateOnWriteErrorWithMixedRequests2Sync) {
5954 TestMigrationOnWriteErrorMixedStreams2(SYNCHRONOUS);
5955}
5956
5957TEST_P(QuicStreamFactoryTest, MigrateOnWriteErrorWithMixedRequests2Async) {
5958 TestMigrationOnWriteErrorMixedStreams2(ASYNC);
5959}
5960
5961// The one triggers write error is a non-migratable stream.
5962// Sets up a test that verifies connection migration manages to migrate to
5963// alternate network after encountering a SYNC/ASYNC write error based on
5964// |write_error_mode| on the original network.
5965// Note there are mixed types of unfinished requests before migration: one
5966// migratable and one non-migratable. The *non-migratable* one triggers write
5967// error.
5968void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorMixedStreams2(
5969 IoMode write_error_mode) {
5970 InitializeConnectionMigrationV2Test(
5971 {kDefaultNetworkForTests, kNewNetworkForTests});
5972 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5973 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5974 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5975
5976 int packet_number = 1;
5977 MockQuicData socket_data;
5978 quic::QuicStreamOffset header_stream_offset = 0;
5979 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5980 socket_data.AddWrite(
5981 SYNCHRONOUS,
5982 ConstructInitialSettingsPacket(packet_number++, &header_stream_offset));
5983 socket_data.AddWrite(write_error_mode,
5984 ERR_ADDRESS_UNREACHABLE); // Write error.
5985 socket_data.AddSocketDataToFactory(socket_factory_.get());
5986
5987 // Set up second socket data provider that is used after
5988 // migration. The request is rewritten to this new socket, and the
5989 // response to the request is read on this new socket.
5990 MockQuicData socket_data1;
5991 // The packet triggered writer error will be sent anyway even if the stream
5992 // will be cancelled later.
5993 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335994 SYNCHRONOUS,
5995 ConstructGetRequestPacket(packet_number++,
5996 GetNthClientInitiatedBidirectionalStreamId(1),
5997 true, true, &header_stream_offset));
Zhongyi Shi0439ecc72018-07-11 04:41:265998 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335999 SYNCHRONOUS,
6000 client_maker_.MakeRstPacket(packet_number++, true,
6001 GetNthClientInitiatedBidirectionalStreamId(1),
Frank Kastenholz684ea412019-02-13 18:48:186002 quic::QUIC_STREAM_CANCELLED, 0,
6003 /*include_stop_sending_if_v99=*/true));
Zhongyi Shi0439ecc72018-07-11 04:41:266004 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:336005 SYNCHRONOUS,
6006 ConstructGetRequestPacket(packet_number++,
6007 GetNthClientInitiatedBidirectionalStreamId(0),
6008 true, true, &header_stream_offset));
Zhongyi Shi0439ecc72018-07-11 04:41:266009 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:336010 ASYNC,
6011 ConstructOkResponsePacket(
6012 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shi0439ecc72018-07-11 04:41:266013 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6014 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:336015 SYNCHRONOUS,
6016 client_maker_.MakeAckAndRstPacket(
6017 packet_number++, false, GetNthClientInitiatedBidirectionalStreamId(0),
6018 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi0439ecc72018-07-11 04:41:266019 socket_data1.AddSocketDataToFactory(socket_factory_.get());
6020
6021 // Create request #1 and QuicHttpStream.
6022 QuicStreamRequest request1(factory_.get());
6023 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036024 request1.Request(
Nick Harper23290b82019-05-02 00:02:566025 host_port_pair_, version_.transport_version, privacy_mode_,
6026 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:036027 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6028 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi0439ecc72018-07-11 04:41:266029 EXPECT_THAT(callback_.WaitForResult(), IsOk());
6030 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
6031 EXPECT_TRUE(stream1.get());
6032
6033 HttpRequestInfo request_info1;
6034 request_info1.method = "GET";
6035 request_info1.url = GURL("https://www.example.org/");
6036 request_info1.traffic_annotation =
6037 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6038 EXPECT_EQ(OK,
6039 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
6040 net_log_, CompletionOnceCallback()));
6041
6042 // Second request returns synchronously because it pools to existing session.
6043 TestCompletionCallback callback2;
6044 QuicStreamRequest request2(factory_.get());
Nick Harper23290b82019-05-02 00:02:566045 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_.transport_version,
6046 privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shi0439ecc72018-07-11 04:41:266047 /*cert_verify_flags=*/0, url_, net_log_,
Zhongyi Shia6b68d112018-09-24 07:49:036048 &net_error_details_,
6049 failed_on_default_network_callback_,
6050 callback2.callback()));
Zhongyi Shi0439ecc72018-07-11 04:41:266051 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
6052 EXPECT_TRUE(stream2.get());
6053
6054 HttpRequestInfo request_info2;
6055 request_info2.method = "GET";
Zhongyi Shibb28b1f2018-07-18 02:41:266056 request_info2.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Zhongyi Shi0439ecc72018-07-11 04:41:266057 request_info2.url = GURL("https://www.example.org/");
6058 request_info2.traffic_annotation =
6059 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6060 EXPECT_EQ(OK,
6061 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
6062 net_log_, CompletionOnceCallback()));
6063
6064 // Ensure that session is alive and active.
6065 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6066 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6067 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6068 EXPECT_EQ(2u, session->GetNumActiveStreams());
6069
6070 // Send GET request on stream 2 which is non-migratable. This should cause a
6071 // write error, which triggers a connection migration attempt.
6072 HttpResponseInfo response2;
6073 HttpRequestHeaders request_headers2;
6074 EXPECT_EQ(OK, stream2->SendRequest(request_headers2, &response2,
6075 callback2.callback()));
6076
6077 // Run the message loop so that the migration attempt is executed and
Zhongyi Shia7dd46b2018-07-12 22:59:296078 // data queued in the new socket is read by the packet reader. Session is
6079 // still alive and not marked as going away, non-migratable stream will be
6080 // closed.
Zhongyi Shi0439ecc72018-07-11 04:41:266081 base::RunLoop().RunUntilIdle();
6082 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:296083 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:266084 EXPECT_EQ(1u, session->GetNumActiveStreams());
6085
6086 // Send GET request on stream 1.
6087 HttpResponseInfo response;
6088 HttpRequestHeaders request_headers;
6089 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
6090 callback_.callback()));
6091
6092 base::RunLoop().RunUntilIdle();
6093
6094 // Verify that response headers on the migrated socket were delivered to the
6095 // stream.
6096 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
6097 EXPECT_EQ(200, response.headers->response_code());
6098
6099 stream1.reset();
6100
6101 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6102 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6103 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6104 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6105}
6106
Zhongyi Shic16b4102019-02-12 00:37:406107// This test verifies that when a connection encounters a packet write error, it
6108// will cancel non-migratable streams, and migrate to the alternate network.
jri9f303712016-09-13 01:10:226109void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorNonMigratableStream(
Zhongyi Shi32fe14d42019-02-28 00:25:366110 IoMode write_error_mode,
6111 bool migrate_idle_sessions) {
Zhongyi Shic16b4102019-02-12 00:37:406112 DVLOG(1) << "Write error mode: "
jri9f303712016-09-13 01:10:226113 << ((write_error_mode == SYNCHRONOUS) ? "SYNCHRONOUS" : "ASYNC");
Zhongyi Shi32fe14d42019-02-28 00:25:366114 DVLOG(1) << "Migrate idle sessions: " << migrate_idle_sessions;
6115 test_params_.quic_migrate_idle_sessions = migrate_idle_sessions;
Zhongyi Shi1a054612018-06-14 04:59:086116 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:226117 {kDefaultNetworkForTests, kNewNetworkForTests});
6118 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6119 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6120
Zhongyi Shic16b4102019-02-12 00:37:406121 MockQuicData failed_socket_data;
jri9f303712016-09-13 01:10:226122 MockQuicData socket_data;
Zhongyi Shi32fe14d42019-02-28 00:25:366123 if (migrate_idle_sessions) {
6124 quic::QuicStreamOffset header_stream_offset = 0;
6125 // The socket data provider for the original socket before migration.
6126 failed_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6127 failed_socket_data.AddWrite(
6128 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6129 failed_socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
6130 failed_socket_data.AddSocketDataToFactory(socket_factory_.get());
6131
6132 // Set up second socket data provider that is used after migration.
6133 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
6134 // Although the write error occurs when writing a packet for the
6135 // non-migratable stream and the stream will be cancelled during migration,
6136 // the packet will still be retransimitted at the connection level.
6137 socket_data.AddWrite(
6138 SYNCHRONOUS, ConstructGetRequestPacket(
6139 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6140 true, &header_stream_offset));
6141 // A RESET will be sent to the peer to cancel the non-migratable stream.
6142 socket_data.AddWrite(
6143 SYNCHRONOUS, client_maker_.MakeRstPacket(
6144 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
6145 quic::QUIC_STREAM_CANCELLED));
6146 socket_data.AddSocketDataToFactory(socket_factory_.get());
6147 } else {
6148 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6149 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
6150 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
6151 socket_data.AddSocketDataToFactory(socket_factory_.get());
6152 }
jri9f303712016-09-13 01:10:226153
6154 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456155 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336156 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036157 request.Request(
Nick Harper23290b82019-05-02 00:02:566158 host_port_pair_, version_.transport_version, privacy_mode_,
6159 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:036160 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6161 failed_on_default_network_callback_, callback_.callback()));
jri9f303712016-09-13 01:10:226162 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246163 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:226164 EXPECT_TRUE(stream.get());
6165
6166 // Cause QUIC stream to be created, but marked as non-migratable.
6167 HttpRequestInfo request_info;
Zhongyi Shibb28b1f2018-07-18 02:41:266168 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
jri9f303712016-09-13 01:10:226169 request_info.method = "GET";
6170 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396171 request_info.traffic_annotation =
6172 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276173 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396174 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:226175
6176 // Ensure that session is alive and active.
6177 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6178 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6179 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6180
6181 // Send GET request on stream. This should cause a write error, which triggers
6182 // a connection migration attempt.
6183 HttpResponseInfo response;
6184 HttpRequestHeaders request_headers;
6185 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6186 callback_.callback()));
6187
6188 // Run message loop to execute migration attempt.
6189 base::RunLoop().RunUntilIdle();
6190
Zhongyi Shi32fe14d42019-02-28 00:25:366191 // Migration closes the non-migratable stream and:
6192 // if migrate idle session is enabled, it migrates to the alternate network
6193 // successfully; otherwise the connection is closed.
6194 EXPECT_EQ(migrate_idle_sessions,
6195 QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6196 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(host_port_pair_));
jri9f303712016-09-13 01:10:226197
Zhongyi Shi32fe14d42019-02-28 00:25:366198 if (migrate_idle_sessions) {
6199 EXPECT_TRUE(failed_socket_data.AllReadDataConsumed());
6200 EXPECT_TRUE(failed_socket_data.AllWriteDataConsumed());
6201 }
jri9f303712016-09-13 01:10:226202 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6203 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6204}
6205
Zhongyi Shi32fe14d42019-02-28 00:25:366206TEST_P(
6207 QuicStreamFactoryTest,
6208 MigrateSessionOnWriteErrorNonMigratableStreamSync_DoNotMigrateIdleSessions) {
6209 TestMigrationOnWriteErrorNonMigratableStream(SYNCHRONOUS, false);
6210}
6211
6212TEST_P(
6213 QuicStreamFactoryTest,
6214 MigrateSessionOnWriteErrorNonMigratableStreamAsync_DoNotMigrateIdleSessions) {
6215 TestMigrationOnWriteErrorNonMigratableStream(ASYNC, false);
jri9f303712016-09-13 01:10:226216}
6217
6218TEST_P(QuicStreamFactoryTest,
Zhongyi Shi32fe14d42019-02-28 00:25:366219 MigrateSessionOnWriteErrorNonMigratableStreamSync_MigrateIdleSessions) {
6220 TestMigrationOnWriteErrorNonMigratableStream(SYNCHRONOUS, true);
6221}
6222
6223TEST_P(QuicStreamFactoryTest,
6224 MigrateSessionOnWriteErrorNonMigratableStreamAsync_MigrateIdleSessions) {
6225 TestMigrationOnWriteErrorNonMigratableStream(ASYNC, true);
jri9f303712016-09-13 01:10:226226}
6227
6228void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorMigrationDisabled(
6229 IoMode write_error_mode) {
Zhongyi Shi1a054612018-06-14 04:59:086230 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:226231 {kDefaultNetworkForTests, kNewNetworkForTests});
6232 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6233 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6234
6235 MockQuicData socket_data;
6236 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436237 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jri9f303712016-09-13 01:10:226238 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:176239 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:226240
6241 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456242 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336243 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036244 request.Request(
Nick Harper23290b82019-05-02 00:02:566245 host_port_pair_, version_.transport_version, privacy_mode_,
6246 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:036247 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6248 failed_on_default_network_callback_, callback_.callback()));
jri9f303712016-09-13 01:10:226249 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246250 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:226251 EXPECT_TRUE(stream.get());
6252
6253 // Cause QUIC stream to be created.
6254 HttpRequestInfo request_info;
6255 request_info.method = "GET";
6256 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396257 request_info.traffic_annotation =
6258 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276259 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396260 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:226261
6262 // Ensure that session is alive and active.
6263 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6264 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6265 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6266
6267 // Set session config to have connection migration disabled.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526268 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
6269 session->config());
jri9f303712016-09-13 01:10:226270 EXPECT_TRUE(session->config()->DisableConnectionMigration());
6271
6272 // Send GET request on stream. This should cause a write error, which triggers
6273 // a connection migration attempt.
6274 HttpResponseInfo response;
6275 HttpRequestHeaders request_headers;
6276 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6277 callback_.callback()));
6278 // Run message loop to execute migration attempt.
6279 base::RunLoop().RunUntilIdle();
6280 // Migration fails, and session is closed and deleted.
6281 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6282 EXPECT_FALSE(HasActiveSession(host_port_pair_));
6283 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6284 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6285}
6286
6287TEST_P(QuicStreamFactoryTest,
6288 MigrateSessionOnWriteErrorMigrationDisabledSynchronous) {
6289 TestMigrationOnWriteErrorMigrationDisabled(SYNCHRONOUS);
6290}
6291
6292TEST_P(QuicStreamFactoryTest,
6293 MigrateSessionOnWriteErrorMigrationDisabledAsync) {
6294 TestMigrationOnWriteErrorMigrationDisabled(ASYNC);
6295}
6296
Zhongyi Shi7f1d9212018-06-22 23:24:366297// Sets up a test which verifies that connection migration on write error can
6298// eventually succeed and rewrite the packet on the new network with singals
6299// delivered in the following order (alternate network is always availabe):
6300// - original network encounters a SYNC/ASYNC write error based on
6301// |write_error_mode_on_old_network|, the packet failed to be written is
6302// cached, session migrates immediately to the alternate network.
6303// - an immediate SYNC/ASYNC write error based on
6304// |write_error_mode_on_new_network| is encountered after migration to the
6305// alternate network, session migrates immediately to the original network.
6306// - an immediate SYNC/ASYNC write error based on
6307// |write_error_mode_on_old_network| is encountered after migration to the
6308// original network, session migrates immediately to the alternate network.
6309// - finally, session successfully sends the packet and reads the response on
6310// the alternate network.
6311// TODO(zhongyi): once https://crbug.com/855666 is fixed, this test should be
6312// modified to test that session is closed early if hopping between networks
6313// with consecutive write errors is detected.
jri9f303712016-09-13 01:10:226314void QuicStreamFactoryTestBase::TestMigrationOnMultipleWriteErrors(
Zhongyi Shi7f1d9212018-06-22 23:24:366315 IoMode write_error_mode_on_old_network,
6316 IoMode write_error_mode_on_new_network) {
6317 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:226318 {kDefaultNetworkForTests, kNewNetworkForTests});
6319 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6320 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6321 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6322
Zhongyi Shi7f1d9212018-06-22 23:24:366323 // Set up the socket data used by the original network, which encounters a
6324 // write erorr.
6325 MockQuicData socket_data1;
6326 quic::QuicStreamOffset header_stream_offset = 0;
6327 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6328 socket_data1.AddWrite(
6329 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6330 socket_data1.AddWrite(write_error_mode_on_old_network,
6331 ERR_ADDRESS_UNREACHABLE); // Write Error
6332 socket_data1.AddSocketDataToFactory(socket_factory_.get());
6333
6334 // Set up the socket data used by the alternate network, which also
6335 // encounters a write error.
6336 MockQuicData failed_quic_data2;
6337 failed_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6338 failed_quic_data2.AddWrite(write_error_mode_on_new_network, ERR_FAILED);
6339 failed_quic_data2.AddSocketDataToFactory(socket_factory_.get());
6340
6341 // Set up the third socket data used by original network, which encounters a
6342 // write error again.
6343 MockQuicData failed_quic_data1;
6344 failed_quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6345 failed_quic_data1.AddWrite(write_error_mode_on_old_network, ERR_FAILED);
6346 failed_quic_data1.AddSocketDataToFactory(socket_factory_.get());
6347
6348 // Set up the last socket data used by the alternate network, which will
6349 // finish migration successfully. The request is rewritten to this new socket,
6350 // and the response to the request is read on this socket.
6351 MockQuicData socket_data2;
Fan Yang32c5a112018-12-10 20:06:336352 socket_data2.AddWrite(
6353 SYNCHRONOUS, ConstructGetRequestPacket(
6354 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6355 true, &header_stream_offset));
Zhongyi Shi7f1d9212018-06-22 23:24:366356 socket_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:336357 ASYNC,
6358 ConstructOkResponsePacket(
6359 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shi7f1d9212018-06-22 23:24:366360 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:336361 socket_data2.AddWrite(
6362 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
6363 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
6364 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi7f1d9212018-06-22 23:24:366365 socket_data2.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:226366
6367 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456368 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336369 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036370 request.Request(
Nick Harper23290b82019-05-02 00:02:566371 host_port_pair_, version_.transport_version, privacy_mode_,
6372 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:036373 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6374 failed_on_default_network_callback_, callback_.callback()));
jri9f303712016-09-13 01:10:226375 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246376 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:226377 EXPECT_TRUE(stream.get());
6378
6379 // Cause QUIC stream to be created.
6380 HttpRequestInfo request_info;
6381 request_info.method = "GET";
6382 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396383 request_info.traffic_annotation =
6384 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276385 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396386 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:226387
6388 // Ensure that session is alive and active.
6389 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6390 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6391 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6392
Zhongyi Shi7f1d9212018-06-22 23:24:366393 // Send GET request on stream.
6394 // This should encounter a write error on network 1,
6395 // then migrate to network 2, which encounters another write error,
6396 // and migrate again to network 1, which encoutners one more write error.
6397 // Finally the session migrates to network 2 successfully.
jri9f303712016-09-13 01:10:226398 HttpResponseInfo response;
6399 HttpRequestHeaders request_headers;
6400 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6401 callback_.callback()));
jri9f303712016-09-13 01:10:226402
jri9f303712016-09-13 01:10:226403 base::RunLoop().RunUntilIdle();
Zhongyi Shi7f1d9212018-06-22 23:24:366404 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6405 EXPECT_EQ(1u, session->GetNumActiveStreams());
jri9f303712016-09-13 01:10:226406
Zhongyi Shi7f1d9212018-06-22 23:24:366407 // Verify that response headers on the migrated socket were delivered to the
6408 // stream.
6409 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6410 EXPECT_EQ(200, response.headers->response_code());
jri9f303712016-09-13 01:10:226411
6412 stream.reset();
Zhongyi Shi7f1d9212018-06-22 23:24:366413 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6414 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6415 EXPECT_TRUE(failed_quic_data2.AllReadDataConsumed());
6416 EXPECT_TRUE(failed_quic_data2.AllWriteDataConsumed());
6417 EXPECT_TRUE(failed_quic_data1.AllReadDataConsumed());
6418 EXPECT_TRUE(failed_quic_data1.AllWriteDataConsumed());
6419 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
6420 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
jri9f303712016-09-13 01:10:226421}
6422
6423TEST_P(QuicStreamFactoryTest, MigrateSessionOnMultipleWriteErrorsSyncSync) {
Zhongyi Shi7f1d9212018-06-22 23:24:366424 TestMigrationOnMultipleWriteErrors(
6425 /*write_error_mode_on_old_network*/ SYNCHRONOUS,
6426 /*write_error_mode_on_new_network*/ SYNCHRONOUS);
jri9f303712016-09-13 01:10:226427}
6428
6429TEST_P(QuicStreamFactoryTest, MigrateSessionOnMultipleWriteErrorsSyncAsync) {
Zhongyi Shi7f1d9212018-06-22 23:24:366430 TestMigrationOnMultipleWriteErrors(
6431 /*write_error_mode_on_old_network*/ SYNCHRONOUS,
6432 /*write_error_mode_on_new_network*/ ASYNC);
jri9f303712016-09-13 01:10:226433}
6434
6435TEST_P(QuicStreamFactoryTest, MigrateSessionOnMultipleWriteErrorsAsyncSync) {
Zhongyi Shi7f1d9212018-06-22 23:24:366436 TestMigrationOnMultipleWriteErrors(
6437 /*write_error_mode_on_old_network*/ ASYNC,
6438 /*write_error_mode_on_new_network*/ SYNCHRONOUS);
jri9f303712016-09-13 01:10:226439}
6440
6441TEST_P(QuicStreamFactoryTest, MigrateSessionOnMultipleWriteErrorsAsyncAsync) {
Zhongyi Shi7f1d9212018-06-22 23:24:366442 TestMigrationOnMultipleWriteErrors(
6443 /*write_error_mode_on_old_network*/ ASYNC,
6444 /*write_error_mode_on_new_network*/ ASYNC);
jri9f303712016-09-13 01:10:226445}
6446
Zhongyi Shi6abe33812018-07-24 19:43:116447// Verifies that a connection is closed when connection migration is triggered
6448// on network being disconnected and the handshake is not confirmed.
6449TEST_P(QuicStreamFactoryTest, NoMigrationBeforeHandshakeOnNetworkDisconnected) {
6450 InitializeConnectionMigrationV2Test(
6451 {kDefaultNetworkForTests, kNewNetworkForTests});
6452
Zhongyi Shi879659422018-08-02 17:58:256453 // Use cold start mode to do crypto connect, and send CHLO packet on wire.
Zhongyi Shi6abe33812018-07-24 19:43:116454 crypto_client_stream_factory_.set_handshake_mode(
Zhongyi Shi879659422018-08-02 17:58:256455 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
Zhongyi Shi6abe33812018-07-24 19:43:116456
Zhongyi Shi6abe33812018-07-24 19:43:116457 MockQuicData socket_data;
Zhongyi Shi879659422018-08-02 17:58:256458 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5068bb02018-08-03 02:44:096459 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
Zhongyi Shi6abe33812018-07-24 19:43:116460 socket_data.AddSocketDataToFactory(socket_factory_.get());
6461
6462 // Create request and QuicHttpStream.
6463 QuicStreamRequest request(factory_.get());
6464 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036465 request.Request(
Nick Harper23290b82019-05-02 00:02:566466 host_port_pair_, version_.transport_version, privacy_mode_,
6467 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:036468 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6469 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi6abe33812018-07-24 19:43:116470 // Deliver the network notification, which should cause the connection to be
6471 // closed.
6472 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6473 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
6474 EXPECT_EQ(ERR_NETWORK_CHANGED, callback_.WaitForResult());
Zhongyi Shi4293b142018-07-25 00:33:576475
Zhongyi Shi6abe33812018-07-24 19:43:116476 EXPECT_FALSE(HasActiveSession(host_port_pair_));
6477 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
Zhongyi Shi4293b142018-07-25 00:33:576478 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6479 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
Zhongyi Shi6abe33812018-07-24 19:43:116480}
6481
Zhongyi Shib24001c02018-06-18 20:01:526482// Sets up the connection migration test where network change notification is
6483// queued BEFORE connection migration attempt on write error is posted.
6484void QuicStreamFactoryTestBase::
6485 TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
6486 bool disconnected) {
6487 InitializeConnectionMigrationV2Test(
jried79618b2016-07-02 03:18:526488 {kDefaultNetworkForTests, kNewNetworkForTests});
6489 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6490 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6491 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6492
rcha00569732016-08-27 11:09:366493 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526494 quic::QuicStreamOffset header_stream_offset = 0;
rcha00569732016-08-27 11:09:366495 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
rch5cb522462017-04-25 20:18:366496 socket_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436497 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
rcha00569732016-08-27 11:09:366498 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:176499 socket_data.AddSocketDataToFactory(socket_factory_.get());
jried79618b2016-07-02 03:18:526500
6501 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456502 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336503 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036504 request.Request(
Nick Harper23290b82019-05-02 00:02:566505 host_port_pair_, version_.transport_version, privacy_mode_,
6506 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:036507 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6508 failed_on_default_network_callback_, callback_.callback()));
jried79618b2016-07-02 03:18:526509 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246510 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jried79618b2016-07-02 03:18:526511 EXPECT_TRUE(stream.get());
6512
6513 // Cause QUIC stream to be created.
6514 HttpRequestInfo request_info;
6515 request_info.method = "GET";
6516 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396517 request_info.traffic_annotation =
6518 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276519 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396520 net_log_, CompletionOnceCallback()));
jried79618b2016-07-02 03:18:526521
6522 // Ensure that session is alive and active.
6523 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6524 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6525 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6526
6527 // Set up second socket data provider that is used after
6528 // migration. The request is rewritten to this new socket, and the
6529 // response to the request is read on this new socket.
rcha00569732016-08-27 11:09:366530 MockQuicData socket_data1;
Fan Yang32c5a112018-12-10 20:06:336531 socket_data1.AddWrite(
6532 SYNCHRONOUS, ConstructGetRequestPacket(
6533 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6534 true, &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436535 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:336536 ASYNC,
6537 ConstructOkResponsePacket(
6538 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
rcha00569732016-08-27 11:09:366539 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:336540 socket_data1.AddWrite(
6541 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
6542 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
6543 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:176544 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jried79618b2016-07-02 03:18:526545
jri9f303712016-09-13 01:10:226546 // First queue a network change notification in the message loop.
6547 if (disconnected) {
6548 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6549 ->QueueNetworkDisconnected(kDefaultNetworkForTests);
6550 } else {
6551 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6552 ->QueueNetworkMadeDefault(kNewNetworkForTests);
6553 }
6554 // Send GET request on stream. This should cause a write error,
6555 // which triggers a connection migration attempt. This will queue a
6556 // migration attempt behind the notification in the message loop.
jried79618b2016-07-02 03:18:526557 HttpResponseInfo response;
6558 HttpRequestHeaders request_headers;
6559 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6560 callback_.callback()));
6561
jried79618b2016-07-02 03:18:526562 base::RunLoop().RunUntilIdle();
Zhongyi Shia7dd46b2018-07-12 22:59:296563 // Verify the session is still alive and not marked as going away post
6564 // migration.
jried79618b2016-07-02 03:18:526565 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:296566 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jried79618b2016-07-02 03:18:526567 EXPECT_EQ(1u, session->GetNumActiveStreams());
6568
6569 // Verify that response headers on the migrated socket were delivered to the
6570 // stream.
6571 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6572 EXPECT_EQ(200, response.headers->response_code());
6573
6574 stream.reset();
6575
6576 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6577 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6578 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6579 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6580}
6581
Zhongyi Shib24001c02018-06-18 20:01:526582// This test verifies that session attempts connection migration successfully
6583// with signals delivered in the following order (alternate network is always
6584// available):
6585// - a notification that default network is disconnected is queued.
6586// - write error is triggered: session posts a task to attempt connection
6587// migration, |migration_pending_| set to true.
6588// - default network disconnected is delivered: session immediately migrates to
6589// the alternate network, |migration_pending_| set to false.
Zhongyi Shif3d6cddb2018-07-11 03:30:026590// - connection migration on write error attempt aborts: writer encountered
6591// error is no longer in active use.
jri9f303712016-09-13 01:10:226592TEST_P(QuicStreamFactoryTest,
Zhongyi Shib24001c02018-06-18 20:01:526593 MigrateOnNetworkDisconnectedWithWriteErrorQueuedLater) {
6594 TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
6595 /*disconnected=*/true);
jri9f303712016-09-13 01:10:226596}
6597
Zhongyi Shib24001c02018-06-18 20:01:526598// This test verifies that session attempts connection migration successfully
6599// with signals delivered in the following order (alternate network is always
6600// available):
6601// - a notification that alternate network is made default is queued.
6602// - write error is triggered: session posts a task to attempt connection
6603// migration, block future migrations.
6604// - new default notification is delivered: migrate back timer spins and task is
6605// posted to migrate to the new default network.
6606// - connection migration on write error attempt proceeds successfully: session
6607// is
6608// marked as going away, future migrations unblocked.
6609// - migrate back to default network task executed: session is already on the
6610// default network, no-op.
jri9f303712016-09-13 01:10:226611TEST_P(QuicStreamFactoryTest,
Zhongyi Shib24001c02018-06-18 20:01:526612 MigrateOnWriteErrorWithNetworkMadeDefaultQueuedEarlier) {
6613 TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
6614 /*disconnected=*/false);
jri9f303712016-09-13 01:10:226615}
6616
Zhongyi Shi1e2bc742018-06-16 02:06:076617// Sets up the connection migration test where network change notification is
6618// queued AFTER connection migration attempt on write error is posted.
6619void QuicStreamFactoryTestBase::
6620 TestMigrationOnWriteErrorWithNotificationQueuedLater(bool disconnected) {
Zhongyi Shi1a054612018-06-14 04:59:086621 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:226622 {kDefaultNetworkForTests, kNewNetworkForTests});
jried79618b2016-07-02 03:18:526623 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6624 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri9f303712016-09-13 01:10:226625 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jried79618b2016-07-02 03:18:526626
rcha00569732016-08-27 11:09:366627 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526628 quic::QuicStreamOffset header_stream_offset = 0;
rcha00569732016-08-27 11:09:366629 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
rch5cb522462017-04-25 20:18:366630 socket_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436631 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
rcha00569732016-08-27 11:09:366632 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:176633 socket_data.AddSocketDataToFactory(socket_factory_.get());
jried79618b2016-07-02 03:18:526634
6635 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456636 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336637 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036638 request.Request(
Nick Harper23290b82019-05-02 00:02:566639 host_port_pair_, version_.transport_version, privacy_mode_,
6640 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:036641 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6642 failed_on_default_network_callback_, callback_.callback()));
jried79618b2016-07-02 03:18:526643 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246644 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jried79618b2016-07-02 03:18:526645 EXPECT_TRUE(stream.get());
6646
6647 // Cause QUIC stream to be created.
6648 HttpRequestInfo request_info;
6649 request_info.method = "GET";
6650 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396651 request_info.traffic_annotation =
6652 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276653 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396654 net_log_, CompletionOnceCallback()));
jried79618b2016-07-02 03:18:526655
6656 // Ensure that session is alive and active.
6657 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6658 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6659 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6660
jri9f303712016-09-13 01:10:226661 // Set up second socket data provider that is used after
6662 // migration. The request is rewritten to this new socket, and the
6663 // response to the request is read on this new socket.
6664 MockQuicData socket_data1;
Fan Yang32c5a112018-12-10 20:06:336665 socket_data1.AddWrite(
6666 SYNCHRONOUS, ConstructGetRequestPacket(
6667 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6668 true, &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436669 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:336670 ASYNC,
6671 ConstructOkResponsePacket(
6672 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
jri9f303712016-09-13 01:10:226673 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:336674 socket_data1.AddWrite(
6675 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
6676 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
6677 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:176678 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:226679
6680 // Send GET request on stream. This should cause a write error,
6681 // which triggers a connection migration attempt. This will queue a
6682 // migration attempt in the message loop.
jried79618b2016-07-02 03:18:526683 HttpResponseInfo response;
6684 HttpRequestHeaders request_headers;
jri9f303712016-09-13 01:10:226685 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6686 callback_.callback()));
jried79618b2016-07-02 03:18:526687
jri9f303712016-09-13 01:10:226688 // Now queue a network change notification in the message loop behind
6689 // the migration attempt.
6690 if (disconnected) {
6691 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6692 ->QueueNetworkDisconnected(kDefaultNetworkForTests);
6693 } else {
6694 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6695 ->QueueNetworkMadeDefault(kNewNetworkForTests);
6696 }
6697
6698 base::RunLoop().RunUntilIdle();
Zhongyi Shia7dd46b2018-07-12 22:59:296699 // Verify session is still alive and not marked as going away.
jri9f303712016-09-13 01:10:226700 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:296701 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri9f303712016-09-13 01:10:226702 EXPECT_EQ(1u, session->GetNumActiveStreams());
6703
6704 // Verify that response headers on the migrated socket were delivered to the
6705 // stream.
6706 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6707 EXPECT_EQ(200, response.headers->response_code());
6708
6709 stream.reset();
jried79618b2016-07-02 03:18:526710
6711 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6712 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
jri9f303712016-09-13 01:10:226713 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6714 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
jried79618b2016-07-02 03:18:526715}
6716
Zhongyi Shi1e2bc742018-06-16 02:06:076717// This test verifies that session attempts connection migration successfully
6718// with signals delivered in the following order (alternate network is always
6719// available):
6720// - write error is triggered: session posts a task to complete connection
6721// migration.
6722// - a notification that alternate network is made default is queued.
6723// - connection migration attempt proceeds successfully, session is marked as
6724// going away.
6725// - new default notification is delivered after connection migration has been
6726// completed.
jri9f303712016-09-13 01:10:226727TEST_P(QuicStreamFactoryTest,
Zhongyi Shi1e2bc742018-06-16 02:06:076728 MigrateOnWriteErrorWithNetworkMadeDefaultQueuedLater) {
6729 TestMigrationOnWriteErrorWithNotificationQueuedLater(/*disconnected=*/false);
jried79618b2016-07-02 03:18:526730}
6731
Zhongyi Shi1e2bc742018-06-16 02:06:076732// This test verifies that session attempts connection migration successfully
6733// with signals delivered in the following order (alternate network is always
6734// available):
6735// - write error is triggered: session posts a task to complete connection
6736// migration.
6737// - a notification that default network is diconnected is queued.
6738// - connection migration attempt proceeds successfully, session is marked as
6739// going away.
6740// - disconnect notification is delivered after connection migration has been
6741// completed.
jri9f303712016-09-13 01:10:226742TEST_P(QuicStreamFactoryTest,
Zhongyi Shi1e2bc742018-06-16 02:06:076743 MigrateOnWriteErrorWithNetworkDisconnectedQueuedLater) {
6744 TestMigrationOnWriteErrorWithNotificationQueuedLater(/*disconnected=*/true);
jried79618b2016-07-02 03:18:526745}
6746
Zhongyi Shia3810c52018-06-15 23:07:196747// This tests connection migration on write error with signals delivered in the
6748// following order:
6749// - a synchronous/asynchronous write error is triggered base on
Zhongyi Shif3d6cddb2018-07-11 03:30:026750// |write_error_mode|: connection migration attempt is posted.
6751// - old default network disconnects, migration waits for a new network.
Zhongyi Shia3810c52018-06-15 23:07:196752// - after a pause, new network is connected: session will migrate to new
6753// network immediately.
Zhongyi Shif3d6cddb2018-07-11 03:30:026754// - migration on writer error is exectued and aborts as writer passed in is no
6755// longer active in use.
Zhongyi Shia3810c52018-06-15 23:07:196756// - new network is made default.
jri5b785512016-09-13 04:29:116757void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorPauseBeforeConnected(
6758 IoMode write_error_mode) {
Zhongyi Shia3810c52018-06-15 23:07:196759 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri5b785512016-09-13 04:29:116760 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6761 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6762 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6763
Zhongyi Shia3810c52018-06-15 23:07:196764 // Use the test task runner.
6765 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
6766
jri5b785512016-09-13 04:29:116767 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526768 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shia3810c52018-06-15 23:07:196769 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
rch5cb522462017-04-25 20:18:366770 socket_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436771 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Zhongyi Shia3810c52018-06-15 23:07:196772 socket_data.AddWrite(write_error_mode, ERR_FAILED);
Zhongyi Shi5f587cc2017-11-21 23:24:176773 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri5b785512016-09-13 04:29:116774
6775 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456776 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336777 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036778 request.Request(
Nick Harper23290b82019-05-02 00:02:566779 host_port_pair_, version_.transport_version, privacy_mode_,
6780 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:036781 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6782 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shia3810c52018-06-15 23:07:196783 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:246784 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri5b785512016-09-13 04:29:116785 EXPECT_TRUE(stream.get());
6786
6787 // Cause QUIC stream to be created.
6788 HttpRequestInfo request_info;
6789 request_info.method = "GET";
Zhongyi Shia3810c52018-06-15 23:07:196790 request_info.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:396791 request_info.traffic_annotation =
6792 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276793 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396794 net_log_, CompletionOnceCallback()));
jri5b785512016-09-13 04:29:116795
6796 // Ensure that session is alive and active.
6797 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6798 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6799 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6800
Zhongyi Shia3810c52018-06-15 23:07:196801 // Send GET request on stream.
jri5b785512016-09-13 04:29:116802 HttpResponseInfo response;
6803 HttpRequestHeaders request_headers;
6804 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6805 callback_.callback()));
6806
Zhongyi Shia3810c52018-06-15 23:07:196807 // The connection should still be alive, not marked as going away.
jri5b785512016-09-13 04:29:116808 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6809 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6810 EXPECT_EQ(1u, session->GetNumActiveStreams());
6811 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
6812
Zhongyi Shia3810c52018-06-15 23:07:196813 // Set up second socket data provider that is used after migration.
6814 // The response to the earlier request is read on this new socket.
jri5b785512016-09-13 04:29:116815 MockQuicData socket_data1;
Fan Yang32c5a112018-12-10 20:06:336816 socket_data1.AddWrite(
6817 SYNCHRONOUS, ConstructGetRequestPacket(
6818 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6819 true, &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436820 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:336821 ASYNC,
6822 ConstructOkResponsePacket(
6823 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
jri5b785512016-09-13 04:29:116824 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:336825 socket_data1.AddWrite(
6826 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
6827 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
6828 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:176829 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri5b785512016-09-13 04:29:116830
Zhongyi Shia3810c52018-06-15 23:07:196831 // On a DISCONNECTED notification, nothing happens.
6832 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6833 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
6834 // Add a new network and notify the stream factory of a new connected network.
6835 // This causes a PING packet to be sent over the new network.
jri5b785512016-09-13 04:29:116836 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6837 ->SetConnectedNetworksList({kNewNetworkForTests});
6838 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6839 ->NotifyNetworkConnected(kNewNetworkForTests);
6840
Zhongyi Shia3810c52018-06-15 23:07:196841 // Ensure that the session is still alive.
jri5b785512016-09-13 04:29:116842 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia3810c52018-06-15 23:07:196843 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:116844 EXPECT_EQ(1u, session->GetNumActiveStreams());
6845
Zhongyi Shia3810c52018-06-15 23:07:196846 // Run the message loop migration for write error can finish.
6847 runner_->RunUntilIdle();
6848
6849 // Response headers are received over the new network.
jri5b785512016-09-13 04:29:116850 EXPECT_THAT(callback_.WaitForResult(), IsOk());
6851 EXPECT_EQ(200, response.headers->response_code());
6852
Zhongyi Shia3810c52018-06-15 23:07:196853 // Check that the session is still alive.
6854 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
jri5b785512016-09-13 04:29:116855 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shia3810c52018-06-15 23:07:196856
6857 // There should be no posted tasks not executed, no way to migrate back to
6858 // default network.
6859 EXPECT_TRUE(runner_->GetPostedTasks().empty());
6860
6861 // Receive signal to mark new network as default.
6862 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6863 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri5b785512016-09-13 04:29:116864
6865 stream.reset();
jri5b785512016-09-13 04:29:116866 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6867 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6868 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6869 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
jri5b785512016-09-13 04:29:116870}
6871
6872TEST_P(QuicStreamFactoryTest,
Zhongyi Shia3810c52018-06-15 23:07:196873 MigrateSessionOnSyncWriteErrorPauseBeforeConnected) {
jri5b785512016-09-13 04:29:116874 TestMigrationOnWriteErrorPauseBeforeConnected(SYNCHRONOUS);
6875}
6876
6877TEST_P(QuicStreamFactoryTest,
Zhongyi Shia3810c52018-06-15 23:07:196878 MigrateSessionOnAsyncWriteErrorPauseBeforeConnected) {
jri5b785512016-09-13 04:29:116879 TestMigrationOnWriteErrorPauseBeforeConnected(ASYNC);
6880}
6881
Zhongyi Shif3d6cddb2018-07-11 03:30:026882// This test verifies that when session successfully migrate to the alternate
6883// network, packet write error on the old writer will be ignored and will not
6884// trigger connection migration on write error.
6885TEST_P(QuicStreamFactoryTest, IgnoreWriteErrorFromOldWriterAfterMigration) {
6886 InitializeConnectionMigrationV2Test(
6887 {kDefaultNetworkForTests, kNewNetworkForTests});
6888 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6889 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6890 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6891
6892 // Using a testing task runner so that we can verify whether the migrate on
6893 // write error task is posted.
6894 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
6895 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
6896
6897 MockQuicData socket_data;
6898 quic::QuicStreamOffset header_stream_offset = 0;
6899 socket_data.AddWrite(
6900 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6901 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
6902 socket_data.AddWrite(ASYNC, ERR_ADDRESS_UNREACHABLE);
6903 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6904 socket_data.AddSocketDataToFactory(socket_factory_.get());
6905
6906 // Create request and QuicHttpStream.
6907 QuicStreamRequest request(factory_.get());
6908 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036909 request.Request(
Nick Harper23290b82019-05-02 00:02:566910 host_port_pair_, version_.transport_version, privacy_mode_,
6911 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:036912 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6913 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shif3d6cddb2018-07-11 03:30:026914 EXPECT_EQ(OK, callback_.WaitForResult());
6915 std::unique_ptr<HttpStream> stream = CreateStream(&request);
6916 EXPECT_TRUE(stream.get());
6917
6918 // Cause QUIC stream to be created.
6919 HttpRequestInfo request_info;
6920 request_info.method = "GET";
6921 request_info.url = GURL("https://www.example.org/");
6922 request_info.traffic_annotation =
6923 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6924 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
6925 net_log_, CompletionOnceCallback()));
6926
6927 // Ensure that session is alive and active.
6928 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6929 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6930 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6931
6932 // Set up second socket data provider that is used after
6933 // migration. The response to the request is read on this new socket.
6934 MockQuicData socket_data1;
6935 socket_data1.AddWrite(
6936 SYNCHRONOUS, client_maker_.MakePingPacket(3, /*include_version=*/true));
6937 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:336938 ASYNC,
6939 ConstructOkResponsePacket(
6940 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shif3d6cddb2018-07-11 03:30:026941 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:336942 socket_data1.AddWrite(
6943 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
6944 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
6945 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shif3d6cddb2018-07-11 03:30:026946 socket_data1.AddSocketDataToFactory(socket_factory_.get());
6947
6948 // Send GET request on stream.
6949 HttpResponseInfo response;
6950 HttpRequestHeaders request_headers;
6951 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6952 callback_.callback()));
6953
6954 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
6955 // Now notify network is disconnected, cause the migration to complete
6956 // immediately.
6957 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6958 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
6959 // There will be two pending task, one will complete migration with no delay
6960 // and the other will attempt to migrate back to the default network with
6961 // delay.
6962 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
6963
6964 // Complete migration.
6965 task_runner->RunUntilIdle();
6966 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
6967
6968 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6969 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6970 EXPECT_EQ(1u, session->GetNumActiveStreams());
6971
6972 // Verify that response headers on the migrated socket were delivered to the
6973 // stream.
6974 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6975 EXPECT_EQ(200, response.headers->response_code());
6976
6977 // Resume the old socket data, a write error will be delivered to the old
6978 // packet writer. Verify no additional task is posted.
6979 socket_data.Resume();
6980 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
6981
6982 stream.reset();
6983 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6984 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6985 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6986}
6987
6988// This test verifies that when session successfully migrate to the alternate
6989// network, packet read error on the old reader will be ignored and will not
6990// close the connection.
6991TEST_P(QuicStreamFactoryTest, IgnoreReadErrorFromOldReaderAfterMigration) {
6992 InitializeConnectionMigrationV2Test(
6993 {kDefaultNetworkForTests, kNewNetworkForTests});
6994 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6995 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6996 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6997
6998 // Using a testing task runner.
6999 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7000 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7001
7002 MockQuicData socket_data;
7003 quic::QuicStreamOffset header_stream_offset = 0;
7004 socket_data.AddWrite(
7005 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7006 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
7007 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE);
7008 socket_data.AddSocketDataToFactory(socket_factory_.get());
7009
7010 // Create request and QuicHttpStream.
7011 QuicStreamRequest request(factory_.get());
7012 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:037013 request.Request(
Nick Harper23290b82019-05-02 00:02:567014 host_port_pair_, version_.transport_version, privacy_mode_,
7015 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:037016 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7017 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shif3d6cddb2018-07-11 03:30:027018 EXPECT_EQ(OK, callback_.WaitForResult());
7019 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7020 EXPECT_TRUE(stream.get());
7021
7022 // Cause QUIC stream to be created.
7023 HttpRequestInfo request_info;
7024 request_info.method = "GET";
7025 request_info.url = GURL("https://www.example.org/");
7026 request_info.traffic_annotation =
7027 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7028 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7029 net_log_, CompletionOnceCallback()));
7030
7031 // Ensure that session is alive and active.
7032 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7033 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7034 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7035
7036 // Set up second socket data provider that is used after
7037 // migration. The request is written to this new socket, and the
7038 // response to the request is read on this new socket.
7039 MockQuicData socket_data1;
7040 socket_data1.AddWrite(
7041 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
Fan Yang32c5a112018-12-10 20:06:337042 socket_data1.AddWrite(
7043 SYNCHRONOUS, ConstructGetRequestPacket(
7044 3, GetNthClientInitiatedBidirectionalStreamId(0), true,
7045 true, &header_stream_offset));
Zhongyi Shif3d6cddb2018-07-11 03:30:027046 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337047 ASYNC,
7048 ConstructOkResponsePacket(
7049 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shif3d6cddb2018-07-11 03:30:027050 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:337051 socket_data1.AddWrite(
7052 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
7053 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
7054 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shif3d6cddb2018-07-11 03:30:027055 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7056
7057 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
7058 // Now notify network is disconnected, cause the migration to complete
7059 // immediately.
7060 scoped_mock_network_change_notifier_->mock_network_change_notifier()
7061 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
7062 // There will be two pending task, one will complete migration with no delay
7063 // and the other will attempt to migrate back to the default network with
7064 // delay.
7065 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
7066
7067 // Complete migration.
7068 task_runner->RunUntilIdle();
7069 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
7070
7071 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7072 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7073 EXPECT_EQ(1u, session->GetNumActiveStreams());
7074
7075 // Send GET request on stream.
7076 HttpResponseInfo response;
7077 HttpRequestHeaders request_headers;
7078 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7079 callback_.callback()));
7080
7081 // Verify that response headers on the migrated socket were delivered to the
7082 // stream.
7083 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
7084 EXPECT_EQ(OK, callback_.WaitForResult());
7085 EXPECT_EQ(200, response.headers->response_code());
7086
7087 // Resume the old socket data, a read error will be delivered to the old
7088 // packet reader. Verify that the session is not affected.
7089 socket_data.Resume();
7090 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
7091 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7092 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7093 EXPECT_EQ(1u, session->GetNumActiveStreams());
7094
7095 stream.reset();
7096 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7097 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7098 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7099 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7100}
7101
7102// This test verifies that after migration on network is executed, packet
7103// read error on the old reader will be ignored and will not close the
7104// connection.
7105TEST_P(QuicStreamFactoryTest, IgnoreReadErrorOnOldReaderDuringMigration) {
7106 InitializeConnectionMigrationV2Test(
7107 {kDefaultNetworkForTests, kNewNetworkForTests});
7108 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7109 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7110 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7111
7112 // Using a testing task runner.
7113 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7114 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7115
7116 MockQuicData socket_data;
7117 quic::QuicStreamOffset header_stream_offset = 0;
7118 socket_data.AddWrite(
7119 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7120 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
7121 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE);
7122 socket_data.AddSocketDataToFactory(socket_factory_.get());
7123
7124 // Create request and QuicHttpStream.
7125 QuicStreamRequest request(factory_.get());
7126 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:037127 request.Request(
Nick Harper23290b82019-05-02 00:02:567128 host_port_pair_, version_.transport_version, privacy_mode_,
7129 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:037130 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7131 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shif3d6cddb2018-07-11 03:30:027132 EXPECT_EQ(OK, callback_.WaitForResult());
7133 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7134 EXPECT_TRUE(stream.get());
7135
7136 // Cause QUIC stream to be created.
7137 HttpRequestInfo request_info;
7138 request_info.method = "GET";
7139 request_info.url = GURL("https://www.example.org/");
7140 request_info.traffic_annotation =
7141 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7142 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7143 net_log_, CompletionOnceCallback()));
7144
7145 // Ensure that session is alive and active.
7146 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7147 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7148 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7149
7150 // Set up second socket data provider that is used after
7151 // migration. The request is written to this new socket, and the
7152 // response to the request is read on this new socket.
7153 MockQuicData socket_data1;
7154 socket_data1.AddWrite(
7155 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
Fan Yang32c5a112018-12-10 20:06:337156 socket_data1.AddWrite(
7157 SYNCHRONOUS, ConstructGetRequestPacket(
7158 3, GetNthClientInitiatedBidirectionalStreamId(0), true,
7159 true, &header_stream_offset));
Zhongyi Shif3d6cddb2018-07-11 03:30:027160 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337161 ASYNC,
7162 ConstructOkResponsePacket(
7163 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shif3d6cddb2018-07-11 03:30:027164 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:337165 socket_data1.AddWrite(
7166 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
7167 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
7168 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shif3d6cddb2018-07-11 03:30:027169 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7170
7171 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
7172 // Now notify network is disconnected, cause the migration to complete
7173 // immediately.
7174 scoped_mock_network_change_notifier_->mock_network_change_notifier()
7175 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
7176 // There will be two pending task, one will complete migration with no delay
7177 // and the other will attempt to migrate back to the default network with
7178 // delay.
7179 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
7180
7181 // Resume the old socket data, a read error will be delivered to the old
7182 // packet reader. Verify that the session is not affected.
7183 socket_data.Resume();
7184 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
7185 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7186 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7187 EXPECT_EQ(1u, session->GetNumActiveStreams());
7188
7189 // Complete migration.
7190 task_runner->RunUntilIdle();
7191 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
7192
7193 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7194 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7195 EXPECT_EQ(1u, session->GetNumActiveStreams());
7196
7197 // Send GET request on stream.
7198 HttpResponseInfo response;
7199 HttpRequestHeaders request_headers;
7200 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7201 callback_.callback()));
7202
7203 // Verify that response headers on the migrated socket were delivered to the
7204 // stream.
7205 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
7206 EXPECT_EQ(OK, callback_.WaitForResult());
7207 EXPECT_EQ(200, response.headers->response_code());
7208
7209 stream.reset();
7210 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7211 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7212 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7213 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7214}
7215
7216// This test verifies that after migration on write error is posted, packet
7217// read error on the old reader will be ignored and will not close the
7218// connection.
7219TEST_P(QuicStreamFactoryTest,
7220 IgnoreReadErrorOnOldReaderDuringPendingMigrationOnWriteError) {
7221 InitializeConnectionMigrationV2Test(
7222 {kDefaultNetworkForTests, kNewNetworkForTests});
7223 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7224 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7225 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7226
7227 // Using a testing task runner.
7228 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7229 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7230
7231 MockQuicData socket_data;
7232 quic::QuicStreamOffset header_stream_offset = 0;
7233 socket_data.AddWrite(
7234 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7235 socket_data.AddWrite(ASYNC, ERR_FAILED); // Write error.
7236 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE); // Read error.
7237 socket_data.AddSocketDataToFactory(socket_factory_.get());
7238
7239 // Create request and QuicHttpStream.
7240 QuicStreamRequest request(factory_.get());
7241 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:037242 request.Request(
Nick Harper23290b82019-05-02 00:02:567243 host_port_pair_, version_.transport_version, privacy_mode_,
7244 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:037245 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7246 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shif3d6cddb2018-07-11 03:30:027247 EXPECT_EQ(OK, callback_.WaitForResult());
7248 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7249 EXPECT_TRUE(stream.get());
7250
7251 // Cause QUIC stream to be created.
7252 HttpRequestInfo request_info;
7253 request_info.method = "GET";
7254 request_info.url = GURL("https://www.example.org/");
7255 request_info.traffic_annotation =
7256 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7257 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7258 net_log_, CompletionOnceCallback()));
7259
7260 // Ensure that session is alive and active.
7261 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7262 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7263 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7264
7265 // Set up second socket data provider that is used after
7266 // migration. The request is written to this new socket, and the
7267 // response to the request is read on this new socket.
7268 MockQuicData socket_data1;
Fan Yang32c5a112018-12-10 20:06:337269 socket_data1.AddWrite(
7270 SYNCHRONOUS, ConstructGetRequestPacket(
7271 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7272 true, &header_stream_offset));
Zhongyi Shif3d6cddb2018-07-11 03:30:027273 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337274 ASYNC,
7275 ConstructOkResponsePacket(
7276 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shif3d6cddb2018-07-11 03:30:027277
7278 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7279 socket_data1.AddRead(ASYNC, ERR_FAILED); // Read error to close connection.
7280 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7281
7282 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
7283 // Send GET request on stream.
7284 HttpResponseInfo response;
7285 HttpRequestHeaders request_headers;
7286 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7287 callback_.callback()));
7288 // Run the message loop to complete asynchronous write and read with errors.
7289 base::RunLoop().RunUntilIdle();
7290 // There will be one pending task to complete migration on write error.
7291 // Verify session is not closed with read error.
7292 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
7293 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7294 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7295 EXPECT_EQ(1u, session->GetNumActiveStreams());
7296
7297 // Complete migration.
7298 task_runner->RunUntilIdle();
Zhongyi Shia7dd46b2018-07-12 22:59:297299 // There will be one more task posted attempting to migrate back to the
7300 // default network.
7301 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
Zhongyi Shif3d6cddb2018-07-11 03:30:027302 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:297303 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shif3d6cddb2018-07-11 03:30:027304 EXPECT_EQ(1u, session->GetNumActiveStreams());
7305
7306 // Verify that response headers on the migrated socket were delivered to the
7307 // stream.
7308 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
7309 EXPECT_EQ(200, response.headers->response_code());
7310
7311 // Resume to consume the read error on new socket, which will close
7312 // the connection.
7313 socket_data1.Resume();
7314
7315 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7316 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7317 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7318 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7319}
7320
Zhongyi Shi4ac9e1f2018-06-21 05:21:477321// Migrate on asynchronous write error, old network disconnects after alternate
7322// network connects.
7323TEST_P(QuicStreamFactoryTest,
7324 MigrateSessionOnWriteErrorWithDisconnectAfterConnectAysnc) {
7325 TestMigrationOnWriteErrorWithMultipleNotifications(
7326 ASYNC, /*disconnect_before_connect*/ false);
7327}
7328
7329// Migrate on synchronous write error, old network disconnects after alternate
7330// network connects.
7331TEST_P(QuicStreamFactoryTest,
7332 MigrateSessionOnWriteErrorWithDisconnectAfterConnectSync) {
7333 TestMigrationOnWriteErrorWithMultipleNotifications(
7334 SYNCHRONOUS, /*disconnect_before_connect*/ false);
7335}
7336
7337// Migrate on asynchronous write error, old network disconnects before alternate
7338// network connects.
7339TEST_P(QuicStreamFactoryTest,
7340 MigrateSessionOnWriteErrorWithDisconnectBeforeConnectAysnc) {
7341 TestMigrationOnWriteErrorWithMultipleNotifications(
7342 ASYNC, /*disconnect_before_connect*/ true);
7343}
7344
7345// Migrate on synchronous write error, old network disconnects before alternate
7346// network connects.
7347TEST_P(QuicStreamFactoryTest,
7348 MigrateSessionOnWriteErrorWithDisconnectBeforeConnectSync) {
7349 TestMigrationOnWriteErrorWithMultipleNotifications(
7350 SYNCHRONOUS, /*disconnect_before_connect*/ true);
7351}
7352
7353// Setps up test which verifies that session successfully migrate to alternate
7354// network with signals delivered in the following order:
7355// *NOTE* Signal (A) and (B) can reverse order based on
7356// |disconnect_before_connect|.
7357// - (No alternate network is connected) session connects to
7358// kDefaultNetworkForTests.
7359// - An async/sync write error is encountered based on |write_error_mode|:
7360// session posted task to migrate session on write error.
7361// - Posted task is executed, miration moves to pending state due to lack of
7362// alternate network.
7363// - (A) An alternate network is connected, pending migration completes.
7364// - (B) Old default network disconnects, no migration will be attempted as
Zhongyi Shi329f5cbd2018-06-22 23:51:187365// session has already migrate to the alternate network.
Zhongyi Shi4ac9e1f2018-06-21 05:21:477366// - The alternate network is made default.
jri5b785512016-09-13 04:29:117367void QuicStreamFactoryTestBase::
Zhongyi Shi4ac9e1f2018-06-21 05:21:477368 TestMigrationOnWriteErrorWithMultipleNotifications(
jri5b785512016-09-13 04:29:117369 IoMode write_error_mode,
Zhongyi Shi4ac9e1f2018-06-21 05:21:477370 bool disconnect_before_connect) {
Zhongyi Shi329f5cbd2018-06-22 23:51:187371 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri5b785512016-09-13 04:29:117372 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7373 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7374 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7375
7376 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527377 quic::QuicStreamOffset header_stream_offset = 0;
jri5b785512016-09-13 04:29:117378 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
rch5cb522462017-04-25 20:18:367379 socket_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437380 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Zhongyi Shi4ac9e1f2018-06-21 05:21:477381 socket_data.AddWrite(write_error_mode, ERR_FAILED); // Write error.
Zhongyi Shi5f587cc2017-11-21 23:24:177382 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri5b785512016-09-13 04:29:117383
7384 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:457385 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337386 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:037387 request.Request(
Nick Harper23290b82019-05-02 00:02:567388 host_port_pair_, version_.transport_version, privacy_mode_,
7389 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:037390 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7391 failed_on_default_network_callback_, callback_.callback()));
jri5b785512016-09-13 04:29:117392 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:247393 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri5b785512016-09-13 04:29:117394 EXPECT_TRUE(stream.get());
7395
7396 // Cause QUIC stream to be created.
7397 HttpRequestInfo request_info;
7398 request_info.method = "GET";
7399 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:397400 request_info.traffic_annotation =
7401 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:277402 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:397403 net_log_, CompletionOnceCallback()));
jri5b785512016-09-13 04:29:117404
7405 // Ensure that session is alive and active.
7406 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7407 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7408 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7409
7410 // Send GET request on stream. This should cause a write error, which triggers
7411 // a connection migration attempt.
7412 HttpResponseInfo response;
7413 HttpRequestHeaders request_headers;
7414 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7415 callback_.callback()));
Zhongyi Shi4ac9e1f2018-06-21 05:21:477416 // Run the message loop so that posted task to migrate to socket will be
7417 // executed. A new task will be posted to wait for a new network.
jri5b785512016-09-13 04:29:117418 base::RunLoop().RunUntilIdle();
7419
7420 // In this particular code path, the network will not yet be marked
7421 // as going away and the session will still be alive.
7422 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7423 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7424 EXPECT_EQ(1u, session->GetNumActiveStreams());
7425 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
7426
7427 // Set up second socket data provider that is used after
7428 // migration. The request is rewritten to this new socket, and the
7429 // response to the request is read on this new socket.
7430 MockQuicData socket_data1;
Fan Yang32c5a112018-12-10 20:06:337431 socket_data1.AddWrite(
7432 SYNCHRONOUS, ConstructGetRequestPacket(
7433 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7434 true, &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:437435 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337436 ASYNC,
7437 ConstructOkResponsePacket(
7438 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
jri5b785512016-09-13 04:29:117439 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:337440 socket_data1.AddWrite(
7441 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
7442 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
7443 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:177444 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri5b785512016-09-13 04:29:117445
7446 scoped_mock_network_change_notifier_->mock_network_change_notifier()
7447 ->SetConnectedNetworksList(
7448 {kDefaultNetworkForTests, kNewNetworkForTests});
Zhongyi Shi4ac9e1f2018-06-21 05:21:477449 if (disconnect_before_connect) {
7450 // Now deliver a DISCONNECT notification.
jri5b785512016-09-13 04:29:117451 scoped_mock_network_change_notifier_->mock_network_change_notifier()
7452 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
Zhongyi Shi4ac9e1f2018-06-21 05:21:477453
7454 // Now deliver a CONNECTED notification and completes migration.
jri5b785512016-09-13 04:29:117455 scoped_mock_network_change_notifier_->mock_network_change_notifier()
Zhongyi Shi4ac9e1f2018-06-21 05:21:477456 ->NotifyNetworkConnected(kNewNetworkForTests);
7457 } else {
7458 // Now deliver a CONNECTED notification and completes migration.
7459 scoped_mock_network_change_notifier_->mock_network_change_notifier()
7460 ->NotifyNetworkConnected(kNewNetworkForTests);
7461
7462 // Now deliver a DISCONNECT notification.
7463 scoped_mock_network_change_notifier_->mock_network_change_notifier()
7464 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
jri5b785512016-09-13 04:29:117465 }
jri5b785512016-09-13 04:29:117466 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shi329f5cbd2018-06-22 23:51:187467 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:117468 EXPECT_EQ(1u, session->GetNumActiveStreams());
7469
7470 // This is the callback for the response headers that returned
7471 // pending previously, because no result was available. Check that
7472 // the result is now available due to the successful migration.
7473 EXPECT_THAT(callback_.WaitForResult(), IsOk());
7474 EXPECT_EQ(200, response.headers->response_code());
7475
Zhongyi Shi4ac9e1f2018-06-21 05:21:477476 // Deliver a MADEDEFAULT notification.
jri5b785512016-09-13 04:29:117477 scoped_mock_network_change_notifier_->mock_network_change_notifier()
Zhongyi Shi4ac9e1f2018-06-21 05:21:477478 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri5b785512016-09-13 04:29:117479
zhongyi98d6a9262017-05-19 02:47:457480 QuicStreamRequest request2(factory_.get());
Nick Harper23290b82019-05-02 00:02:567481 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_.transport_version,
7482 privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shi329f5cbd2018-06-22 23:51:187483 /*cert_verify_flags=*/0, url_, net_log_,
Zhongyi Shia6b68d112018-09-24 07:49:037484 &net_error_details_,
7485 failed_on_default_network_callback_,
7486 callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:247487 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
jri5b785512016-09-13 04:29:117488 EXPECT_TRUE(stream2.get());
7489
7490 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi329f5cbd2018-06-22 23:51:187491 EXPECT_EQ(session, GetActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:117492
7493 stream.reset();
7494 stream2.reset();
7495
7496 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7497 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7498 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7499 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
jri5b785512016-09-13 04:29:117500}
7501
Zhongyi Shic16b4102019-02-12 00:37:407502// This test verifies after session migrates off the default network, it keeps
7503// retrying migrate back to the default network until successfully gets on the
7504// default network or the idle migration period threshold is exceeded.
7505// The default threshold is 30s.
7506TEST_P(QuicStreamFactoryTest, DefaultIdleMigrationPeriod) {
Zhongyi Shi32fe14d42019-02-28 00:25:367507 test_params_.quic_migrate_idle_sessions = true;
Zhongyi Shic16b4102019-02-12 00:37:407508 InitializeConnectionMigrationV2Test(
7509 {kDefaultNetworkForTests, kNewNetworkForTests});
7510 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7511 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7512
7513 // Using a testing task runner and a test tick tock.
7514 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7515 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7516 QuicStreamFactoryPeer::SetTickClock(factory_.get(),
7517 task_runner->GetMockTickClock());
7518
7519 MockQuicData default_socket_data;
7520 default_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
7521 default_socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
7522 default_socket_data.AddSocketDataToFactory(socket_factory_.get());
7523
7524 // Set up second socket data provider that is used after migration.
7525 MockQuicData alternate_socket_data;
7526 alternate_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
7527 // Ping packet to send after migration.
7528 alternate_socket_data.AddWrite(
7529 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
7530 alternate_socket_data.AddSocketDataToFactory(socket_factory_.get());
7531
7532 // Set up probing socket for migrating back to the default network.
7533 MockQuicData quic_data; // retry count: 0.
7534 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
7535 quic_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
7536 quic_data.AddSocketDataToFactory(socket_factory_.get());
7537
7538 MockQuicData quic_data1; // retry count: 1
7539 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
7540 quic_data1.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
7541 quic_data1.AddSocketDataToFactory(socket_factory_.get());
7542
7543 MockQuicData quic_data2; // retry count: 2
7544 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
7545 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
7546 quic_data2.AddSocketDataToFactory(socket_factory_.get());
7547
7548 MockQuicData quic_data3; // retry count: 3
7549 quic_data3.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
7550 quic_data3.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
7551 quic_data3.AddSocketDataToFactory(socket_factory_.get());
7552
7553 MockQuicData quic_data4; // retry count: 4
7554 quic_data4.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
7555 quic_data4.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
7556 quic_data4.AddSocketDataToFactory(socket_factory_.get());
7557
7558 MockQuicData quic_data5; // retry count: 5
7559 quic_data5.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
7560 quic_data5.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
7561 quic_data5.AddSocketDataToFactory(socket_factory_.get());
7562
7563 // Create request and QuicHttpStream.
7564 QuicStreamRequest request(factory_.get());
7565 EXPECT_EQ(ERR_IO_PENDING,
7566 request.Request(
Nick Harper23290b82019-05-02 00:02:567567 host_port_pair_, version_.transport_version, privacy_mode_,
7568 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shic16b4102019-02-12 00:37:407569 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7570 failed_on_default_network_callback_, callback_.callback()));
7571 EXPECT_THAT(callback_.WaitForResult(), IsOk());
7572 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7573 EXPECT_TRUE(stream.get());
7574
7575 // Ensure that session is active.
7576 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7577
7578 // Trigger connection migration. Since there are no active streams,
7579 // the session will be closed.
7580 scoped_mock_network_change_notifier_->mock_network_change_notifier()
7581 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
7582
7583 // The nearest task will complete migration.
7584 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
7585 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
7586 task_runner->FastForwardBy(base::TimeDelta());
7587
7588 // The migrate back timer will fire. Due to default network
7589 // being disconnected, no attempt will be exercised to migrate back.
7590 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
7591 EXPECT_EQ(base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs),
7592 task_runner->NextPendingTaskDelay());
7593 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7594 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
7595
7596 // Deliver the signal that the old default network now backs up.
7597 scoped_mock_network_change_notifier_->mock_network_change_notifier()
7598 ->NotifyNetworkMadeDefault(kDefaultNetworkForTests);
7599
7600 // A task is posted to migrate back to the default network immediately.
7601 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
7602 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
7603 task_runner->FastForwardBy(base::TimeDelta());
7604
7605 // Retry migrate back in 1, 2, 4, 8, 16s.
7606 // Session will be closed due to idle migration timeout.
7607 for (int i = 0; i < 5; i++) {
7608 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7609 // A task is posted to migrate back to the default network in 2^i seconds.
7610 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
7611 EXPECT_EQ(base::TimeDelta::FromSeconds(UINT64_C(1) << i),
7612 task_runner->NextPendingTaskDelay());
7613 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7614 }
7615
7616 EXPECT_TRUE(default_socket_data.AllReadDataConsumed());
7617 EXPECT_TRUE(default_socket_data.AllWriteDataConsumed());
7618 EXPECT_TRUE(alternate_socket_data.AllReadDataConsumed());
7619 EXPECT_TRUE(alternate_socket_data.AllWriteDataConsumed());
7620}
7621
7622TEST_P(QuicStreamFactoryTest, CustomIdleMigrationPeriod) {
7623 // The customized threshold is 15s.
Zhongyi Shi32fe14d42019-02-28 00:25:367624 test_params_.quic_migrate_idle_sessions = true;
Zhongyi Shic16b4102019-02-12 00:37:407625 test_params_.quic_idle_session_migration_period =
7626 base::TimeDelta::FromSeconds(15);
7627 InitializeConnectionMigrationV2Test(
7628 {kDefaultNetworkForTests, kNewNetworkForTests});
7629 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7630 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7631
7632 // Using a testing task runner and a test tick tock.
7633 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7634 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7635 QuicStreamFactoryPeer::SetTickClock(factory_.get(),
7636 task_runner->GetMockTickClock());
7637
7638 MockQuicData default_socket_data;
7639 default_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
7640 default_socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
7641 default_socket_data.AddSocketDataToFactory(socket_factory_.get());
7642
7643 // Set up second socket data provider that is used after migration.
7644 MockQuicData alternate_socket_data;
7645 alternate_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
7646 // Ping packet to send after migration.
7647 alternate_socket_data.AddWrite(
7648 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
7649 alternate_socket_data.AddSocketDataToFactory(socket_factory_.get());
7650
7651 // Set up probing socket for migrating back to the default network.
7652 MockQuicData quic_data; // retry count: 0.
7653 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
7654 quic_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
7655 quic_data.AddSocketDataToFactory(socket_factory_.get());
7656
7657 MockQuicData quic_data1; // retry count: 1
7658 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
7659 quic_data1.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
7660 quic_data1.AddSocketDataToFactory(socket_factory_.get());
7661
7662 MockQuicData quic_data2; // retry count: 2
7663 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
7664 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
7665 quic_data2.AddSocketDataToFactory(socket_factory_.get());
7666
7667 MockQuicData quic_data3; // retry count: 3
7668 quic_data3.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
7669 quic_data3.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
7670 quic_data3.AddSocketDataToFactory(socket_factory_.get());
7671
7672 MockQuicData quic_data4; // retry count: 4
7673 quic_data4.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
7674 quic_data4.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
7675 quic_data4.AddSocketDataToFactory(socket_factory_.get());
7676
7677 // Create request and QuicHttpStream.
7678 QuicStreamRequest request(factory_.get());
7679 EXPECT_EQ(ERR_IO_PENDING,
7680 request.Request(
Nick Harper23290b82019-05-02 00:02:567681 host_port_pair_, version_.transport_version, privacy_mode_,
7682 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shic16b4102019-02-12 00:37:407683 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7684 failed_on_default_network_callback_, callback_.callback()));
7685 EXPECT_THAT(callback_.WaitForResult(), IsOk());
7686 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7687 EXPECT_TRUE(stream.get());
7688
7689 // Ensure that session is active.
7690 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7691
7692 // Trigger connection migration. Since there are no active streams,
7693 // the session will be closed.
7694 scoped_mock_network_change_notifier_->mock_network_change_notifier()
7695 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
7696
7697 // The nearest task will complete migration.
7698 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
7699 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
7700 task_runner->FastForwardBy(base::TimeDelta());
7701
7702 // The migrate back timer will fire. Due to default network
7703 // being disconnected, no attempt will be exercised to migrate back.
7704 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
7705 EXPECT_EQ(base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs),
7706 task_runner->NextPendingTaskDelay());
7707 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7708 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
7709
7710 // Deliver the signal that the old default network now backs up.
7711 scoped_mock_network_change_notifier_->mock_network_change_notifier()
7712 ->NotifyNetworkMadeDefault(kDefaultNetworkForTests);
7713
7714 // A task is posted to migrate back to the default network immediately.
7715 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
7716 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
7717 task_runner->FastForwardBy(base::TimeDelta());
7718
7719 // Retry migrate back in 1, 2, 4, 8s.
7720 // Session will be closed due to idle migration timeout.
7721 for (int i = 0; i < 4; i++) {
7722 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7723 // A task is posted to migrate back to the default network in 2^i seconds.
7724 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
7725 EXPECT_EQ(base::TimeDelta::FromSeconds(UINT64_C(1) << i),
7726 task_runner->NextPendingTaskDelay());
7727 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7728 }
7729
7730 EXPECT_TRUE(default_socket_data.AllReadDataConsumed());
7731 EXPECT_TRUE(default_socket_data.AllWriteDataConsumed());
7732 EXPECT_TRUE(alternate_socket_data.AllReadDataConsumed());
7733 EXPECT_TRUE(alternate_socket_data.AllWriteDataConsumed());
7734}
7735
jri217455a12016-07-13 20:15:097736TEST_P(QuicStreamFactoryTest, ServerMigration) {
Zhongyi Shi967d2f12019-02-08 20:58:537737 test_params_.quic_allow_server_migration = true;
jri217455a12016-07-13 20:15:097738 Initialize();
7739
7740 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7741 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7742 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7743
rcha00569732016-08-27 11:09:367744 MockQuicData socket_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527745 quic::QuicStreamOffset header_stream_offset = 0;
rcha00569732016-08-27 11:09:367746 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
rch5cb522462017-04-25 20:18:367747 socket_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437748 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337749 socket_data1.AddWrite(
7750 SYNCHRONOUS, ConstructGetRequestPacket(
7751 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7752 true, &header_stream_offset));
Zhongyi Shi5f587cc2017-11-21 23:24:177753 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri217455a12016-07-13 20:15:097754
7755 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:457756 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337757 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:037758 request.Request(
Nick Harper23290b82019-05-02 00:02:567759 host_port_pair_, version_.transport_version, privacy_mode_,
7760 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:037761 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7762 failed_on_default_network_callback_, callback_.callback()));
jri217455a12016-07-13 20:15:097763 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:247764 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri217455a12016-07-13 20:15:097765 EXPECT_TRUE(stream.get());
7766
7767 // Cause QUIC stream to be created.
7768 HttpRequestInfo request_info;
7769 request_info.method = "GET";
7770 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:397771 request_info.traffic_annotation =
7772 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:277773 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:397774 net_log_, CompletionOnceCallback()));
jri217455a12016-07-13 20:15:097775
7776 // Ensure that session is alive and active.
7777 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7778 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7779 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7780
7781 // Send GET request on stream.
7782 HttpResponseInfo response;
7783 HttpRequestHeaders request_headers;
7784 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7785 callback_.callback()));
7786
7787 IPEndPoint ip;
7788 session->GetDefaultSocket()->GetPeerAddress(&ip);
7789 DVLOG(1) << "Socket connected to: " << ip.address().ToString() << " "
7790 << ip.port();
7791
7792 // Set up second socket data provider that is used after
7793 // migration. The request is rewritten to this new socket, and the
7794 // response to the request is read on this new socket.
rcha00569732016-08-27 11:09:367795 MockQuicData socket_data2;
7796 socket_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437797 SYNCHRONOUS, client_maker_.MakePingPacket(3, /*include_version=*/true));
7798 socket_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337799 ASYNC,
7800 ConstructOkResponsePacket(
7801 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
rcha00569732016-08-27 11:09:367802 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:337803 socket_data2.AddWrite(
7804 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
7805 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
7806 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:177807 socket_data2.AddSocketDataToFactory(socket_factory_.get());
jri217455a12016-07-13 20:15:097808
7809 const uint8_t kTestIpAddress[] = {1, 2, 3, 4};
7810 const uint16_t kTestPort = 123;
Zhongyi Shif124a582017-11-02 00:15:047811 session->Migrate(NetworkChangeNotifier::kInvalidNetworkHandle,
7812 IPEndPoint(IPAddress(kTestIpAddress), kTestPort), true,
7813 net_log_);
jri217455a12016-07-13 20:15:097814
7815 session->GetDefaultSocket()->GetPeerAddress(&ip);
7816 DVLOG(1) << "Socket migrated to: " << ip.address().ToString() << " "
7817 << ip.port();
7818
7819 // The session should be alive and active.
7820 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7821 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7822 EXPECT_EQ(1u, session->GetNumActiveStreams());
7823
7824 // Run the message loop so that data queued in the new socket is read by the
7825 // packet reader.
7826 base::RunLoop().RunUntilIdle();
7827
7828 // Verify that response headers on the migrated socket were delivered to the
7829 // stream.
7830 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
7831 EXPECT_EQ(200, response.headers->response_code());
7832
7833 stream.reset();
7834
7835 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7836 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7837 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
7838 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
7839}
7840
jri053fdbd2016-08-19 02:33:057841TEST_P(QuicStreamFactoryTest, ServerMigrationIPv4ToIPv4) {
7842 // Add alternate IPv4 server address to config.
7843 IPEndPoint alt_address = IPEndPoint(IPAddress(1, 2, 3, 4), 123);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527844 quic::QuicConfig config;
fayang91ca2012016-11-22 07:42:467845 config.SetAlternateServerAddressToSend(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527846 quic::QuicSocketAddress(quic::QuicSocketAddressImpl(alt_address)));
jri053fdbd2016-08-19 02:33:057847 VerifyServerMigration(config, alt_address);
7848}
7849
7850TEST_P(QuicStreamFactoryTest, ServerMigrationIPv6ToIPv6) {
7851 // Add a resolver rule to make initial connection to an IPv6 address.
Renjiea0cb4a2c2018-09-26 23:37:307852 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
7853 "fe80::aebc:32ff:febb:1e33", "");
jri053fdbd2016-08-19 02:33:057854 // Add alternate IPv6 server address to config.
7855 IPEndPoint alt_address = IPEndPoint(
7856 IPAddress(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), 123);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527857 quic::QuicConfig config;
fayang91ca2012016-11-22 07:42:467858 config.SetAlternateServerAddressToSend(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527859 quic::QuicSocketAddress(quic::QuicSocketAddressImpl(alt_address)));
jri053fdbd2016-08-19 02:33:057860 VerifyServerMigration(config, alt_address);
7861}
7862
7863TEST_P(QuicStreamFactoryTest, ServerMigrationIPv6ToIPv4) {
7864 // Add a resolver rule to make initial connection to an IPv6 address.
Renjiea0cb4a2c2018-09-26 23:37:307865 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
7866 "fe80::aebc:32ff:febb:1e33", "");
jri053fdbd2016-08-19 02:33:057867 // Add alternate IPv4 server address to config.
7868 IPEndPoint alt_address = IPEndPoint(IPAddress(1, 2, 3, 4), 123);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527869 quic::QuicConfig config;
fayang91ca2012016-11-22 07:42:467870 config.SetAlternateServerAddressToSend(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527871 quic::QuicSocketAddress(quic::QuicSocketAddressImpl(alt_address)));
jri053fdbd2016-08-19 02:33:057872 IPEndPoint expected_address(
7873 ConvertIPv4ToIPv4MappedIPv6(alt_address.address()), alt_address.port());
7874 VerifyServerMigration(config, expected_address);
7875}
7876
7877TEST_P(QuicStreamFactoryTest, ServerMigrationIPv4ToIPv6Fails) {
Zhongyi Shi967d2f12019-02-08 20:58:537878 test_params_.quic_allow_server_migration = true;
jri053fdbd2016-08-19 02:33:057879 Initialize();
7880
7881 // Add a resolver rule to make initial connection to an IPv4 address.
Renjiea0cb4a2c2018-09-26 23:37:307882 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), "1.2.3.4",
7883 "");
jri053fdbd2016-08-19 02:33:057884 // Add alternate IPv6 server address to config.
7885 IPEndPoint alt_address = IPEndPoint(
7886 IPAddress(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), 123);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527887 quic::QuicConfig config;
fayang91ca2012016-11-22 07:42:467888 config.SetAlternateServerAddressToSend(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527889 quic::QuicSocketAddress(quic::QuicSocketAddressImpl(alt_address)));
jri053fdbd2016-08-19 02:33:057890
7891 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7892 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7893 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7894
7895 crypto_client_stream_factory_.SetConfig(config);
7896
7897 // Set up only socket data provider.
rcha00569732016-08-27 11:09:367898 MockQuicData socket_data1;
7899 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437900 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
7901 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:337902 SYNCHRONOUS, client_maker_.MakeRstPacket(
7903 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
7904 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:177905 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri053fdbd2016-08-19 02:33:057906
7907 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:457908 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337909 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:037910 request.Request(
Nick Harper23290b82019-05-02 00:02:567911 host_port_pair_, version_.transport_version, privacy_mode_,
7912 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:037913 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7914 failed_on_default_network_callback_, callback_.callback()));
jri053fdbd2016-08-19 02:33:057915 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:247916 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri053fdbd2016-08-19 02:33:057917 EXPECT_TRUE(stream.get());
7918
7919 // Cause QUIC stream to be created.
7920 HttpRequestInfo request_info;
7921 request_info.method = "GET";
7922 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:397923 request_info.traffic_annotation =
7924 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:277925 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:397926 net_log_, CompletionOnceCallback()));
jri053fdbd2016-08-19 02:33:057927
7928 // Ensure that session is alive and active.
7929 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7930 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7931 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7932
7933 IPEndPoint actual_address;
7934 session->GetDefaultSocket()->GetPeerAddress(&actual_address);
7935 // No migration should have happened.
7936 IPEndPoint expected_address =
7937 IPEndPoint(IPAddress(1, 2, 3, 4), kDefaultServerPort);
7938 EXPECT_EQ(actual_address, expected_address);
7939 DVLOG(1) << "Socket connected to: " << actual_address.address().ToString()
7940 << " " << actual_address.port();
7941 DVLOG(1) << "Expected address: " << expected_address.address().ToString()
7942 << " " << expected_address.port();
7943
7944 stream.reset();
7945 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7946 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7947}
7948
rsleevi17784692016-10-12 01:36:207949TEST_P(QuicStreamFactoryTest, OnCertDBChanged) {
jri7046038f2015-10-22 00:29:267950 Initialize();
rch6faa4d42016-01-05 20:48:437951 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7952 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7953 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7954
rcha00569732016-08-27 11:09:367955 MockQuicData socket_data;
7956 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437957 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:177958 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]d7d1e50b2013-11-25 22:08:097959
rcha00569732016-08-27 11:09:367960 MockQuicData socket_data2;
7961 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437962 socket_data2.AddWrite(SYNCHRONOUS,
7963 ConstructInitialSettingsPacket(1, nullptr));
Zhongyi Shi5f587cc2017-11-21 23:24:177964 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]d7d1e50b2013-11-25 22:08:097965
zhongyi98d6a9262017-05-19 02:47:457966 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337967 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:037968 request.Request(
Nick Harper23290b82019-05-02 00:02:567969 host_port_pair_, version_.transport_version, privacy_mode_,
7970 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:037971 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7972 failed_on_default_network_callback_, callback_.callback()));
[email protected]d7d1e50b2013-11-25 22:08:097973
robpercival214763f2016-07-01 23:27:017974 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:247975 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Charles 'Buck' Krasic71763c9f2018-02-16 02:37:287976 EXPECT_TRUE(stream);
7977 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
[email protected]d7d1e50b2013-11-25 22:08:097978
7979 // Change the CA cert and verify that stream saw the event.
mattmfd05a1f2017-02-18 06:18:447980 factory_->OnCertDBChanged();
Charles 'Buck' Krasic71763c9f2018-02-16 02:37:287981
jri7046038f2015-10-22 00:29:267982 EXPECT_FALSE(factory_->require_confirmation());
Charles 'Buck' Krasic71763c9f2018-02-16 02:37:287983 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7984 EXPECT_FALSE(HasActiveSession(host_port_pair_));
[email protected]d7d1e50b2013-11-25 22:08:097985
7986 // Now attempting to request a stream to the same origin should create
7987 // a new session.
7988
zhongyi98d6a9262017-05-19 02:47:457989 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337990 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:037991 request2.Request(
Nick Harper23290b82019-05-02 00:02:567992 host_port_pair_, version_.transport_version, privacy_mode_,
7993 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:037994 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7995 failed_on_default_network_callback_, callback_.callback()));
[email protected]d7d1e50b2013-11-25 22:08:097996
robpercival214763f2016-07-01 23:27:017997 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Charles 'Buck' Krasic71763c9f2018-02-16 02:37:287998 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
7999 EXPECT_TRUE(stream2);
8000 QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
8001 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8002 EXPECT_NE(session, session2);
8003 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8004 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
8005
8006 stream2.reset();
8007 stream.reset();
[email protected]d7d1e50b2013-11-25 22:08:098008
rch37de576c2015-05-17 20:28:178009 EXPECT_TRUE(socket_data.AllReadDataConsumed());
8010 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
8011 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
8012 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]d7d1e50b2013-11-25 22:08:098013}
8014
[email protected]1e960032013-12-20 19:00:208015TEST_P(QuicStreamFactoryTest, SharedCryptoConfig) {
jri7046038f2015-10-22 00:29:268016 Initialize();
rch6faa4d42016-01-05 20:48:438017
rch872e00e2016-12-02 02:48:188018 std::vector<string> cannoncial_suffixes;
[email protected]6e12d702013-11-13 00:17:178019 cannoncial_suffixes.push_back(string(".c.youtube.com"));
8020 cannoncial_suffixes.push_back(string(".googlevideo.com"));
[email protected]c49ff182013-09-28 08:33:268021
[email protected]6e12d702013-11-13 00:17:178022 for (unsigned i = 0; i < cannoncial_suffixes.size(); ++i) {
8023 string r1_host_name("r1");
8024 string r2_host_name("r2");
8025 r1_host_name.append(cannoncial_suffixes[i]);
8026 r2_host_name.append(cannoncial_suffixes[i]);
[email protected]b70fdb792013-10-25 19:04:148027
[email protected]bf4ea2f2014-03-10 22:57:538028 HostPortPair host_port_pair1(r1_host_name, 80);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528029 quic::QuicCryptoClientConfig* crypto_config =
jri7046038f2015-10-22 00:29:268030 QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
Ryan Hamilton4f0b26e2018-06-27 23:52:328031 quic::QuicServerId server_id1(host_port_pair1.host(),
8032 host_port_pair1.port(), privacy_mode_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528033 quic::QuicCryptoClientConfig::CachedState* cached1 =
[email protected]257f24f2014-04-01 09:15:378034 crypto_config->LookupOrCreate(server_id1);
[email protected]6e12d702013-11-13 00:17:178035 EXPECT_FALSE(cached1->proof_valid());
8036 EXPECT_TRUE(cached1->source_address_token().empty());
8037
8038 // Mutate the cached1 to have different data.
8039 // TODO(rtenneti): mutate other members of CachedState.
8040 cached1->set_source_address_token(r1_host_name);
8041 cached1->SetProofValid();
8042
[email protected]bf4ea2f2014-03-10 22:57:538043 HostPortPair host_port_pair2(r2_host_name, 80);
Ryan Hamilton4f0b26e2018-06-27 23:52:328044 quic::QuicServerId server_id2(host_port_pair2.host(),
8045 host_port_pair2.port(), privacy_mode_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528046 quic::QuicCryptoClientConfig::CachedState* cached2 =
[email protected]257f24f2014-04-01 09:15:378047 crypto_config->LookupOrCreate(server_id2);
[email protected]6e12d702013-11-13 00:17:178048 EXPECT_EQ(cached1->source_address_token(), cached2->source_address_token());
8049 EXPECT_TRUE(cached2->proof_valid());
8050 }
[email protected]b70fdb792013-10-25 19:04:148051}
8052
[email protected]1e960032013-12-20 19:00:208053TEST_P(QuicStreamFactoryTest, CryptoConfigWhenProofIsInvalid) {
jri7046038f2015-10-22 00:29:268054 Initialize();
rch872e00e2016-12-02 02:48:188055 std::vector<string> cannoncial_suffixes;
[email protected]6e12d702013-11-13 00:17:178056 cannoncial_suffixes.push_back(string(".c.youtube.com"));
8057 cannoncial_suffixes.push_back(string(".googlevideo.com"));
[email protected]b70fdb792013-10-25 19:04:148058
[email protected]6e12d702013-11-13 00:17:178059 for (unsigned i = 0; i < cannoncial_suffixes.size(); ++i) {
8060 string r3_host_name("r3");
8061 string r4_host_name("r4");
8062 r3_host_name.append(cannoncial_suffixes[i]);
8063 r4_host_name.append(cannoncial_suffixes[i]);
[email protected]b70fdb792013-10-25 19:04:148064
[email protected]bf4ea2f2014-03-10 22:57:538065 HostPortPair host_port_pair1(r3_host_name, 80);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528066 quic::QuicCryptoClientConfig* crypto_config =
jri7046038f2015-10-22 00:29:268067 QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
Ryan Hamilton4f0b26e2018-06-27 23:52:328068 quic::QuicServerId server_id1(host_port_pair1.host(),
8069 host_port_pair1.port(), privacy_mode_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528070 quic::QuicCryptoClientConfig::CachedState* cached1 =
[email protected]257f24f2014-04-01 09:15:378071 crypto_config->LookupOrCreate(server_id1);
[email protected]6e12d702013-11-13 00:17:178072 EXPECT_FALSE(cached1->proof_valid());
8073 EXPECT_TRUE(cached1->source_address_token().empty());
8074
8075 // Mutate the cached1 to have different data.
8076 // TODO(rtenneti): mutate other members of CachedState.
8077 cached1->set_source_address_token(r3_host_name);
8078 cached1->SetProofInvalid();
8079
[email protected]bf4ea2f2014-03-10 22:57:538080 HostPortPair host_port_pair2(r4_host_name, 80);
Ryan Hamilton4f0b26e2018-06-27 23:52:328081 quic::QuicServerId server_id2(host_port_pair2.host(),
8082 host_port_pair2.port(), privacy_mode_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528083 quic::QuicCryptoClientConfig::CachedState* cached2 =
[email protected]257f24f2014-04-01 09:15:378084 crypto_config->LookupOrCreate(server_id2);
[email protected]6e12d702013-11-13 00:17:178085 EXPECT_NE(cached1->source_address_token(), cached2->source_address_token());
8086 EXPECT_TRUE(cached2->source_address_token().empty());
8087 EXPECT_FALSE(cached2->proof_valid());
8088 }
[email protected]c49ff182013-09-28 08:33:268089}
8090
rtenneti34dffe752015-02-24 23:27:328091TEST_P(QuicStreamFactoryTest, EnableNotLoadFromDiskCache) {
jri7046038f2015-10-22 00:29:268092 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:208093 factory_->set_require_confirmation(false);
rch6faa4d42016-01-05 20:48:438094 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8095 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8096
jri7046038f2015-10-22 00:29:268097 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
rtenneti34dffe752015-02-24 23:27:328098
rcha00569732016-08-27 11:09:368099 MockQuicData socket_data;
8100 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:178101 socket_data.AddSocketDataToFactory(socket_factory_.get());
rtenneti34dffe752015-02-24 23:27:328102
8103 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:278104 MockCryptoClientStream::ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:308105 host_resolver_->set_synchronous_mode(true);
8106 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
8107 "192.168.0.1", "");
rtenneti34dffe752015-02-24 23:27:328108
zhongyi98d6a9262017-05-19 02:47:458109 QuicStreamRequest request(factory_.get());
Nick Harper23290b82019-05-02 00:02:568110 EXPECT_EQ(OK, request.Request(host_port_pair_, version_.transport_version,
8111 privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
Paul Jensen8e3c5d32018-02-19 17:06:338112 /*cert_verify_flags=*/0, url_, net_log_,
Zhongyi Shia6b68d112018-09-24 07:49:038113 &net_error_details_,
8114 failed_on_default_network_callback_,
8115 callback_.callback()));
rtenneti34dffe752015-02-24 23:27:328116
8117 // If we are waiting for disk cache, we would have posted a task. Verify that
8118 // the CancelWaitForDataReady task hasn't been posted.
8119 ASSERT_EQ(0u, runner_->GetPostedTasks().size());
8120
Yixin Wang7891a39d2017-11-08 20:59:248121 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rtenneti34dffe752015-02-24 23:27:328122 EXPECT_TRUE(stream.get());
rch37de576c2015-05-17 20:28:178123 EXPECT_TRUE(socket_data.AllReadDataConsumed());
8124 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
rtenneti34dffe752015-02-24 23:27:328125}
8126
dmurph44ca4f42016-09-09 20:39:098127TEST_P(QuicStreamFactoryTest, ReducePingTimeoutOnConnectionTimeOutOpenStreams) {
Zhongyi Shi967d2f12019-02-08 20:58:538128 test_params_.quic_reduced_ping_timeout_seconds = 10;
dmurph44ca4f42016-09-09 20:39:098129 Initialize();
8130 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8131 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8132 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8133
8134 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
zhongyidd1439f62016-09-02 02:02:268135
8136 MockQuicData socket_data;
8137 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:438138 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:178139 socket_data.AddSocketDataToFactory(socket_factory_.get());
zhongyidd1439f62016-09-02 02:02:268140
8141 MockQuicData socket_data2;
8142 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:438143 socket_data2.AddWrite(SYNCHRONOUS,
8144 ConstructInitialSettingsPacket(1, nullptr));
Zhongyi Shi5f587cc2017-11-21 23:24:178145 socket_data2.AddSocketDataToFactory(socket_factory_.get());
zhongyidd1439f62016-09-02 02:02:268146
8147 HostPortPair server2(kServer2HostName, kDefaultServerPort);
8148
8149 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:278150 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Renjiea0cb4a2c2018-09-26 23:37:308151 host_resolver_->set_synchronous_mode(true);
8152 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
8153 "192.168.0.1", "");
8154 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
zhongyidd1439f62016-09-02 02:02:268155
8156 // Quic should use default PING timeout when no previous connection times out
8157 // with open stream.
Ryan Hamilton8d9ee76e2018-05-29 23:52:528158 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(quic::kPingTimeoutSecs),
zhongyidd1439f62016-09-02 02:02:268159 QuicStreamFactoryPeer::GetPingTimeout(factory_.get()));
zhongyi98d6a9262017-05-19 02:47:458160 QuicStreamRequest request(factory_.get());
Nick Harper23290b82019-05-02 00:02:568161 EXPECT_EQ(OK, request.Request(host_port_pair_, version_.transport_version,
8162 privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
Paul Jensen8e3c5d32018-02-19 17:06:338163 /*cert_verify_flags=*/0, url_, net_log_,
Zhongyi Shia6b68d112018-09-24 07:49:038164 &net_error_details_,
8165 failed_on_default_network_callback_,
8166 callback_.callback()));
zhongyidd1439f62016-09-02 02:02:268167
8168 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528169 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(quic::kPingTimeoutSecs),
zhongyidd1439f62016-09-02 02:02:268170 session->connection()->ping_timeout());
8171
Yixin Wang7891a39d2017-11-08 20:59:248172 std::unique_ptr<HttpStream> stream = CreateStream(&request);
zhongyidd1439f62016-09-02 02:02:268173 EXPECT_TRUE(stream.get());
8174 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:398175 request_info.traffic_annotation =
8176 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:278177 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:398178 net_log_, CompletionOnceCallback()));
zhongyidd1439f62016-09-02 02:02:268179
8180 DVLOG(1)
8181 << "Created 1st session and initialized a stream. Now trigger timeout";
Ryan Hamilton8d9ee76e2018-05-29 23:52:528182 session->connection()->CloseConnection(
8183 quic::QUIC_NETWORK_IDLE_TIMEOUT, "test",
8184 quic::ConnectionCloseBehavior::SILENT_CLOSE);
zhongyidd1439f62016-09-02 02:02:268185 // Need to spin the loop now to ensure that
8186 // QuicStreamFactory::OnSessionClosed() runs.
8187 base::RunLoop run_loop;
8188 run_loop.RunUntilIdle();
8189
zhongyidd1439f62016-09-02 02:02:268190 // The first connection times out with open stream, QUIC should reduce initial
8191 // PING time for subsequent connections.
Ryan Hamilton8d9ee76e2018-05-29 23:52:528192 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(10),
zhongyidd1439f62016-09-02 02:02:268193 QuicStreamFactoryPeer::GetPingTimeout(factory_.get()));
8194
8195 // Test two-in-a-row timeouts with open streams.
8196 DVLOG(1) << "Create 2nd session and timeout with open stream";
8197 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:458198 QuicStreamRequest request2(factory_.get());
Nick Harper23290b82019-05-02 00:02:568199 EXPECT_EQ(OK, request2.Request(server2, version_.transport_version,
8200 privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
8201 /*cert_verify_flags=*/0, url2_, net_log_,
8202 &net_error_details_,
8203 failed_on_default_network_callback_,
8204 callback2.callback()));
zhongyidd1439f62016-09-02 02:02:268205 QuicChromiumClientSession* session2 = GetActiveSession(server2);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528206 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(10),
zhongyidd1439f62016-09-02 02:02:268207 session2->connection()->ping_timeout());
8208
Yixin Wang7891a39d2017-11-08 20:59:248209 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
zhongyidd1439f62016-09-02 02:02:268210 EXPECT_TRUE(stream2.get());
Steven Valdezb4ff0412018-01-18 22:39:278211 EXPECT_EQ(OK,
8212 stream2->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:398213 net_log_, CompletionOnceCallback()));
zhongyidd1439f62016-09-02 02:02:268214 session2->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:528215 quic::QUIC_NETWORK_IDLE_TIMEOUT, "test",
8216 quic::ConnectionCloseBehavior::SILENT_CLOSE);
zhongyidd1439f62016-09-02 02:02:268217 // Need to spin the loop now to ensure that
8218 // QuicStreamFactory::OnSessionClosed() runs.
8219 base::RunLoop run_loop2;
8220 run_loop2.RunUntilIdle();
zhongyidd1439f62016-09-02 02:02:268221
8222 EXPECT_TRUE(socket_data.AllReadDataConsumed());
8223 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
8224 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
8225 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
8226}
8227
tbansal3b966952016-10-25 23:25:148228// Verifies that the QUIC stream factory is initialized correctly.
rtenneticd2aaa15b2015-10-10 20:29:338229TEST_P(QuicStreamFactoryTest, MaybeInitialize) {
tbansal9b1cdf32017-05-10 17:28:398230 VerifyInitialization();
rtenneti8a80a6dc2015-09-21 19:51:138231}
8232
rtennetid073dd22016-08-04 01:58:338233TEST_P(QuicStreamFactoryTest, StartCertVerifyJob) {
8234 Initialize();
8235
rcha00569732016-08-27 11:09:368236 MockQuicData socket_data;
8237 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:438238 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:178239 socket_data.AddSocketDataToFactory(socket_factory_.get());
rtennetid073dd22016-08-04 01:58:338240
8241 // Save current state of |race_cert_verification|.
8242 bool race_cert_verification =
8243 QuicStreamFactoryPeer::GetRaceCertVerification(factory_.get());
8244
8245 // Load server config.
8246 HostPortPair host_port_pair(kDefaultServerHostName, kDefaultServerPort);
Ryan Hamilton4f0b26e2018-06-27 23:52:328247 quic::QuicServerId quic_server_id(host_port_pair_.host(),
8248 host_port_pair_.port(),
8249 privacy_mode_ == PRIVACY_MODE_ENABLED);
rtennetid073dd22016-08-04 01:58:338250 QuicStreamFactoryPeer::CacheDummyServerConfig(factory_.get(), quic_server_id);
8251
8252 QuicStreamFactoryPeer::SetRaceCertVerification(factory_.get(), true);
8253 EXPECT_FALSE(HasActiveCertVerifierJob(quic_server_id));
8254
8255 // Start CertVerifyJob.
Ryan Hamilton8d9ee76e2018-05-29 23:52:528256 quic::QuicAsyncStatus status = QuicStreamFactoryPeer::StartCertVerifyJob(
rtennetid073dd22016-08-04 01:58:338257 factory_.get(), quic_server_id, /*cert_verify_flags=*/0, net_log_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528258 if (status == quic::QUIC_PENDING) {
rtennetid073dd22016-08-04 01:58:338259 // Verify CertVerifierJob has started.
8260 EXPECT_TRUE(HasActiveCertVerifierJob(quic_server_id));
8261
8262 while (HasActiveCertVerifierJob(quic_server_id)) {
8263 base::RunLoop().RunUntilIdle();
8264 }
8265 }
8266 // Verify CertVerifierJob has finished.
8267 EXPECT_FALSE(HasActiveCertVerifierJob(quic_server_id));
8268
8269 // Start a QUIC request.
zhongyi98d6a9262017-05-19 02:47:458270 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338271 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:038272 request.Request(
Nick Harper23290b82019-05-02 00:02:568273 host_port_pair_, version_.transport_version, privacy_mode_,
8274 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:038275 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8276 failed_on_default_network_callback_, callback_.callback()));
rtennetid073dd22016-08-04 01:58:338277
8278 EXPECT_EQ(OK, callback_.WaitForResult());
8279
Yixin Wang7891a39d2017-11-08 20:59:248280 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rtennetid073dd22016-08-04 01:58:338281 EXPECT_TRUE(stream.get());
8282
8283 // Restore |race_cert_verification|.
8284 QuicStreamFactoryPeer::SetRaceCertVerification(factory_.get(),
8285 race_cert_verification);
8286
8287 EXPECT_TRUE(socket_data.AllReadDataConsumed());
8288 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
8289
8290 // Verify there are no outstanding CertVerifierJobs after request has
8291 // finished.
8292 EXPECT_FALSE(HasActiveCertVerifierJob(quic_server_id));
8293}
8294
rtenneti1cd3b162015-09-29 02:58:288295TEST_P(QuicStreamFactoryTest, YieldAfterPackets) {
jri7046038f2015-10-22 00:29:268296 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:208297 factory_->set_require_confirmation(false);
rch6faa4d42016-01-05 20:48:438298 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8299 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:268300 QuicStreamFactoryPeer::SetYieldAfterPackets(factory_.get(), 0);
rtenneti1cd3b162015-09-29 02:58:288301
rcha00569732016-08-27 11:09:368302 MockQuicData socket_data;
Fan Yangac867502019-01-28 21:10:238303 socket_data.AddRead(SYNCHRONOUS, ConstructClientConnectionClosePacket(1));
rcha00569732016-08-27 11:09:368304 socket_data.AddRead(ASYNC, OK);
Zhongyi Shi5f587cc2017-11-21 23:24:178305 socket_data.AddSocketDataToFactory(socket_factory_.get());
rtenneti1cd3b162015-09-29 02:58:288306
8307 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:278308 MockCryptoClientStream::ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:308309 host_resolver_->set_synchronous_mode(true);
8310 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
8311 "192.168.0.1", "");
rtenneti1cd3b162015-09-29 02:58:288312
rcha02807b42016-01-29 21:56:158313 // Set up the TaskObserver to verify QuicChromiumPacketReader::StartReading
8314 // posts a task.
rtenneti1cd3b162015-09-29 02:58:288315 // TODO(rtenneti): Change SpdySessionTestTaskObserver to NetTestTaskObserver??
rcha02807b42016-01-29 21:56:158316 SpdySessionTestTaskObserver observer("quic_chromium_packet_reader.cc",
8317 "StartReading");
rtenneti1cd3b162015-09-29 02:58:288318
zhongyi98d6a9262017-05-19 02:47:458319 QuicStreamRequest request(factory_.get());
Nick Harper23290b82019-05-02 00:02:568320 EXPECT_EQ(OK, request.Request(host_port_pair_, version_.transport_version,
8321 privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
Paul Jensen8e3c5d32018-02-19 17:06:338322 /*cert_verify_flags=*/0, url_, net_log_,
Zhongyi Shia6b68d112018-09-24 07:49:038323 &net_error_details_,
8324 failed_on_default_network_callback_,
8325 callback_.callback()));
rtenneti1cd3b162015-09-29 02:58:288326
rcha02807b42016-01-29 21:56:158327 // Call run_loop so that QuicChromiumPacketReader::OnReadComplete() gets
8328 // called.
rtenneti1cd3b162015-09-29 02:58:288329 base::RunLoop run_loop;
8330 run_loop.RunUntilIdle();
8331
8332 // Verify task that the observer's executed_count is 1, which indicates
rcha02807b42016-01-29 21:56:158333 // QuicChromiumPacketReader::StartReading() has posted only one task and
8334 // yielded the read.
rtenneti1cd3b162015-09-29 02:58:288335 EXPECT_EQ(1u, observer.executed_count());
8336
Yixin Wang7891a39d2017-11-08 20:59:248337 std::unique_ptr<HttpStream> stream = CreateStream(&request);
xunjieli2608f9b2016-03-14 13:39:238338 EXPECT_FALSE(stream.get()); // Session is already closed.
rtenneti1cd3b162015-09-29 02:58:288339 EXPECT_TRUE(socket_data.AllReadDataConsumed());
8340 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
8341}
8342
8343TEST_P(QuicStreamFactoryTest, YieldAfterDuration) {
jri7046038f2015-10-22 00:29:268344 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:208345 factory_->set_require_confirmation(false);
rch6faa4d42016-01-05 20:48:438346 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8347 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rtenneti1cd3b162015-09-29 02:58:288348 QuicStreamFactoryPeer::SetYieldAfterDuration(
Ryan Hamilton8d9ee76e2018-05-29 23:52:528349 factory_.get(), quic::QuicTime::Delta::FromMilliseconds(-1));
rtenneti1cd3b162015-09-29 02:58:288350
rcha00569732016-08-27 11:09:368351 MockQuicData socket_data;
Fan Yangac867502019-01-28 21:10:238352 socket_data.AddRead(SYNCHRONOUS, ConstructClientConnectionClosePacket(1));
rcha00569732016-08-27 11:09:368353 socket_data.AddRead(ASYNC, OK);
Zhongyi Shi5f587cc2017-11-21 23:24:178354 socket_data.AddSocketDataToFactory(socket_factory_.get());
rtenneti1cd3b162015-09-29 02:58:288355
8356 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:278357 MockCryptoClientStream::ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:308358 host_resolver_->set_synchronous_mode(true);
8359 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
8360 "192.168.0.1", "");
rtenneti1cd3b162015-09-29 02:58:288361
rcha02807b42016-01-29 21:56:158362 // Set up the TaskObserver to verify QuicChromiumPacketReader::StartReading
8363 // posts a task.
rtenneti1cd3b162015-09-29 02:58:288364 // TODO(rtenneti): Change SpdySessionTestTaskObserver to NetTestTaskObserver??
rcha02807b42016-01-29 21:56:158365 SpdySessionTestTaskObserver observer("quic_chromium_packet_reader.cc",
8366 "StartReading");
rtenneti1cd3b162015-09-29 02:58:288367
zhongyi98d6a9262017-05-19 02:47:458368 QuicStreamRequest request(factory_.get());
Nick Harper23290b82019-05-02 00:02:568369 EXPECT_EQ(OK, request.Request(host_port_pair_, version_.transport_version,
8370 privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
Paul Jensen8e3c5d32018-02-19 17:06:338371 /*cert_verify_flags=*/0, url_, net_log_,
Zhongyi Shia6b68d112018-09-24 07:49:038372 &net_error_details_,
8373 failed_on_default_network_callback_,
8374 callback_.callback()));
rtenneti1cd3b162015-09-29 02:58:288375
rcha02807b42016-01-29 21:56:158376 // Call run_loop so that QuicChromiumPacketReader::OnReadComplete() gets
8377 // called.
rtenneti1cd3b162015-09-29 02:58:288378 base::RunLoop run_loop;
8379 run_loop.RunUntilIdle();
8380
8381 // Verify task that the observer's executed_count is 1, which indicates
rcha02807b42016-01-29 21:56:158382 // QuicChromiumPacketReader::StartReading() has posted only one task and
8383 // yielded the read.
rtenneti1cd3b162015-09-29 02:58:288384 EXPECT_EQ(1u, observer.executed_count());
8385
Yixin Wang7891a39d2017-11-08 20:59:248386 std::unique_ptr<HttpStream> stream = CreateStream(&request);
xunjieli2608f9b2016-03-14 13:39:238387 EXPECT_FALSE(stream.get()); // Session is already closed.
rtenneti1cd3b162015-09-29 02:58:288388 EXPECT_TRUE(socket_data.AllReadDataConsumed());
8389 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
8390}
8391
ckrasic3865ee0f2016-02-29 22:04:568392TEST_P(QuicStreamFactoryTest, ServerPushSessionAffinity) {
8393 Initialize();
8394 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8395 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8396
rcha00569732016-08-27 11:09:368397 MockQuicData socket_data;
8398 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:438399 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:178400 socket_data.AddSocketDataToFactory(socket_factory_.get());
ckrasic3865ee0f2016-02-29 22:04:568401
zhongyi98d6a9262017-05-19 02:47:458402 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338403 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:038404 request.Request(
Nick Harper23290b82019-05-02 00:02:568405 host_port_pair_, version_.transport_version, privacy_mode_,
8406 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:038407 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8408 failed_on_default_network_callback_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:568409
robpercival214763f2016-07-01 23:27:018410 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:248411 std::unique_ptr<HttpStream> stream = CreateStream(&request);
ckrasic3865ee0f2016-02-29 22:04:568412 EXPECT_TRUE(stream.get());
8413
8414 EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumPushStreamsCreated(factory_.get()));
8415
bnc5fdc07162016-05-23 17:36:038416 string url = "https://www.example.org/";
ckrasic3865ee0f2016-02-29 22:04:568417
bnc912a04b2016-04-20 14:19:508418 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
ckrasic3865ee0f2016-02-29 22:04:568419
Ryan Hamilton8d9ee76e2018-05-29 23:52:528420 quic::QuicClientPromisedInfo promised(
Fan Yang32c5a112018-12-10 20:06:338421 session, GetNthServerInitiatedUnidirectionalStreamId(0), kDefaultUrl);
ckrasic3865ee0f2016-02-29 22:04:568422 (*QuicStreamFactoryPeer::GetPushPromiseIndex(factory_.get())
bnc3d9035b32016-06-30 18:18:488423 ->promised_by_url())[kDefaultUrl] = &promised;
ckrasic3865ee0f2016-02-29 22:04:568424
zhongyi98d6a9262017-05-19 02:47:458425 QuicStreamRequest request2(factory_.get());
Nick Harper23290b82019-05-02 00:02:568426 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_.transport_version,
8427 privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
Paul Jensen8e3c5d32018-02-19 17:06:338428 /*cert_verify_flags=*/0, url_, net_log_,
Zhongyi Shia6b68d112018-09-24 07:49:038429 &net_error_details_,
8430 failed_on_default_network_callback_,
8431 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:568432
8433 EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumPushStreamsCreated(factory_.get()));
8434}
8435
8436TEST_P(QuicStreamFactoryTest, ServerPushPrivacyModeMismatch) {
8437 Initialize();
8438 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8439 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8440 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8441
rcha00569732016-08-27 11:09:368442 MockQuicData socket_data1;
8443 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:438444 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
8445 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338446 SYNCHRONOUS, client_maker_.MakeRstPacket(
8447 2, true, GetNthServerInitiatedUnidirectionalStreamId(0),
8448 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:178449 socket_data1.AddSocketDataToFactory(socket_factory_.get());
ckrasic3865ee0f2016-02-29 22:04:568450
rcha00569732016-08-27 11:09:368451 MockQuicData socket_data2;
8452 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:438453 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:178454 socket_data2.AddSocketDataToFactory(socket_factory_.get());
ckrasic3865ee0f2016-02-29 22:04:568455
zhongyi98d6a9262017-05-19 02:47:458456 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338457 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:038458 request.Request(
Nick Harper23290b82019-05-02 00:02:568459 host_port_pair_, version_.transport_version, privacy_mode_,
8460 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:038461 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8462 failed_on_default_network_callback_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:568463
robpercival214763f2016-07-01 23:27:018464 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:248465 std::unique_ptr<HttpStream> stream = CreateStream(&request);
ckrasic3865ee0f2016-02-29 22:04:568466 EXPECT_TRUE(stream.get());
8467
8468 EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumPushStreamsCreated(factory_.get()));
8469
bnc5fdc07162016-05-23 17:36:038470 string url = "https://www.example.org/";
bnc912a04b2016-04-20 14:19:508471 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
ckrasic3865ee0f2016-02-29 22:04:568472
Ryan Hamilton8d9ee76e2018-05-29 23:52:528473 quic::QuicClientPromisedInfo promised(
Fan Yang32c5a112018-12-10 20:06:338474 session, GetNthServerInitiatedUnidirectionalStreamId(0), kDefaultUrl);
ckrasic3865ee0f2016-02-29 22:04:568475
Ryan Hamilton8d9ee76e2018-05-29 23:52:528476 quic::QuicClientPushPromiseIndex* index =
ckrasic3865ee0f2016-02-29 22:04:568477 QuicStreamFactoryPeer::GetPushPromiseIndex(factory_.get());
8478
bnc3d9035b32016-06-30 18:18:488479 (*index->promised_by_url())[kDefaultUrl] = &promised;
8480 EXPECT_EQ(index->GetPromised(kDefaultUrl), &promised);
ckrasic3865ee0f2016-02-29 22:04:568481
8482 // Doing the request should not use the push stream, but rather
8483 // cancel it because the privacy modes do not match.
zhongyi98d6a9262017-05-19 02:47:458484 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338485 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:038486 request2.Request(
Nick Harper23290b82019-05-02 00:02:568487 host_port_pair_, version_.transport_version,
8488 PRIVACY_MODE_ENABLED, DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:038489 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8490 failed_on_default_network_callback_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:568491
8492 EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumPushStreamsCreated(factory_.get()));
bnc3d9035b32016-06-30 18:18:488493 EXPECT_EQ(index->GetPromised(kDefaultUrl), nullptr);
ckrasic3865ee0f2016-02-29 22:04:568494
robpercival214763f2016-07-01 23:27:018495 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:248496 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
ckrasic3865ee0f2016-02-29 22:04:568497 EXPECT_TRUE(stream2.get());
8498
8499 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
8500 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
8501 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
8502 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
8503}
8504
Ryan Hamilton8d9ee76e2018-05-29 23:52:528505// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:458506// even if destination is different.
8507TEST_P(QuicStreamFactoryTest, PoolByOrigin) {
8508 Initialize();
8509
8510 HostPortPair destination1("first.example.com", 443);
8511 HostPortPair destination2("second.example.com", 443);
8512
8513 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8514 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8515
rcha00569732016-08-27 11:09:368516 MockQuicData socket_data;
8517 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:438518 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:178519 socket_data.AddSocketDataToFactory(socket_factory_.get());
bnc359ed2a2016-04-29 20:43:458520
zhongyi98d6a9262017-05-19 02:47:458521 QuicStreamRequest request1(factory_.get());
Nick Harper23290b82019-05-02 00:02:568522 EXPECT_EQ(ERR_IO_PENDING,
8523 request1.Request(
8524 destination1, version_.transport_version, privacy_mode_,
8525 DEFAULT_PRIORITY, SocketTag(),
8526 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8527 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:018528 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:248529 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
bnc359ed2a2016-04-29 20:43:458530 EXPECT_TRUE(stream1.get());
8531 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8532
8533 // Second request returns synchronously because it pools to existing session.
8534 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:458535 QuicStreamRequest request2(factory_.get());
Nick Harper23290b82019-05-02 00:02:568536 EXPECT_EQ(OK, request2.Request(destination2, version_.transport_version,
8537 privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
Paul Jensen8e3c5d32018-02-19 17:06:338538 /*cert_verify_flags=*/0, url_, net_log_,
Zhongyi Shia6b68d112018-09-24 07:49:038539 &net_error_details_,
8540 failed_on_default_network_callback_,
8541 callback2.callback()));
Yixin Wang7891a39d2017-11-08 20:59:248542 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
bnc359ed2a2016-04-29 20:43:458543 EXPECT_TRUE(stream2.get());
8544
rchf0b18c8a2017-05-05 19:31:578545 QuicChromiumClientSession::Handle* session1 =
8546 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
8547 QuicChromiumClientSession::Handle* session2 =
8548 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
8549 EXPECT_TRUE(session1->SharesSameSession(*session2));
Ryan Hamilton4f0b26e2018-06-27 23:52:328550 EXPECT_EQ(quic::QuicServerId(host_port_pair_.host(), host_port_pair_.port(),
8551 privacy_mode_ == PRIVACY_MODE_ENABLED),
bnc359ed2a2016-04-29 20:43:458552 session1->server_id());
8553
8554 EXPECT_TRUE(socket_data.AllReadDataConsumed());
8555 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
8556}
8557
8558class QuicStreamFactoryWithDestinationTest
8559 : public QuicStreamFactoryTestBase,
8560 public ::testing::TestWithParam<PoolingTestParams> {
8561 protected:
8562 QuicStreamFactoryWithDestinationTest()
Yixin Wang079ad542018-01-11 04:06:058563 : QuicStreamFactoryTestBase(
8564 GetParam().version,
8565 GetParam().client_headers_include_h2_stream_dependency),
bnc359ed2a2016-04-29 20:43:458566 destination_type_(GetParam().destination_type),
8567 hanging_read_(SYNCHRONOUS, ERR_IO_PENDING, 0) {}
8568
8569 HostPortPair GetDestination() {
8570 switch (destination_type_) {
8571 case SAME_AS_FIRST:
8572 return origin1_;
8573 case SAME_AS_SECOND:
8574 return origin2_;
8575 case DIFFERENT:
8576 return HostPortPair(kDifferentHostname, 443);
8577 default:
8578 NOTREACHED();
8579 return HostPortPair();
8580 }
8581 }
8582
8583 void AddHangingSocketData() {
8584 std::unique_ptr<SequencedSocketData> sequenced_socket_data(
Ryan Sleevib8d7ea02018-05-07 20:01:018585 new SequencedSocketData(base::make_span(&hanging_read_, 1),
8586 base::span<MockWrite>()));
Zhongyi Shi5f587cc2017-11-21 23:24:178587 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
bnc359ed2a2016-04-29 20:43:458588 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
8589 }
8590
8591 bool AllDataConsumed() {
8592 for (const auto& socket_data_ptr : sequenced_socket_data_vector_) {
8593 if (!socket_data_ptr->AllReadDataConsumed() ||
8594 !socket_data_ptr->AllWriteDataConsumed()) {
8595 return false;
8596 }
8597 }
8598 return true;
8599 }
8600
8601 DestinationType destination_type_;
8602 HostPortPair origin1_;
8603 HostPortPair origin2_;
8604 MockRead hanging_read_;
rch872e00e2016-12-02 02:48:188605 std::vector<std::unique_ptr<SequencedSocketData>>
8606 sequenced_socket_data_vector_;
bnc359ed2a2016-04-29 20:43:458607};
8608
Victor Costane635086f2019-01-27 05:20:308609INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
8610 QuicStreamFactoryWithDestinationTest,
8611 ::testing::ValuesIn(GetPoolingTestParams()));
bnc359ed2a2016-04-29 20:43:458612
8613// A single QUIC request fails because the certificate does not match the origin
8614// hostname, regardless of whether it matches the alternative service hostname.
8615TEST_P(QuicStreamFactoryWithDestinationTest, InvalidCertificate) {
8616 if (destination_type_ == DIFFERENT)
8617 return;
8618
8619 Initialize();
8620
8621 GURL url("https://mail.example.com/");
8622 origin1_ = HostPortPair::FromURL(url);
8623
8624 // Not used for requests, but this provides a test case where the certificate
8625 // is valid for the hostname of the alternative service.
8626 origin2_ = HostPortPair("mail.example.org", 433);
8627
8628 HostPortPair destination = GetDestination();
8629
8630 scoped_refptr<X509Certificate> cert(
8631 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:248632 ASSERT_FALSE(cert->VerifyNameMatch(origin1_.host()));
8633 ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host()));
bnc359ed2a2016-04-29 20:43:458634
8635 ProofVerifyDetailsChromium verify_details;
8636 verify_details.cert_verify_result.verified_cert = cert;
8637 verify_details.cert_verify_result.is_issued_by_known_root = true;
8638 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8639
8640 AddHangingSocketData();
8641
zhongyi98d6a9262017-05-19 02:47:458642 QuicStreamRequest request(factory_.get());
Nick Harper23290b82019-05-02 00:02:568643 EXPECT_EQ(ERR_IO_PENDING,
8644 request.Request(
8645 destination, version_.transport_version, privacy_mode_,
8646 DEFAULT_PRIORITY, SocketTag(),
8647 /*cert_verify_flags=*/0, url, net_log_, &net_error_details_,
8648 failed_on_default_network_callback_, callback_.callback()));
bnc359ed2a2016-04-29 20:43:458649
robpercival214763f2016-07-01 23:27:018650 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_QUIC_HANDSHAKE_FAILED));
bnc359ed2a2016-04-29 20:43:458651
8652 EXPECT_TRUE(AllDataConsumed());
8653}
8654
8655// QuicStreamRequest is pooled based on |destination| if certificate matches.
8656TEST_P(QuicStreamFactoryWithDestinationTest, SharedCertificate) {
8657 Initialize();
8658
8659 GURL url1("https://www.example.org/");
8660 GURL url2("https://mail.example.org/");
8661 origin1_ = HostPortPair::FromURL(url1);
8662 origin2_ = HostPortPair::FromURL(url2);
8663
8664 HostPortPair destination = GetDestination();
8665
8666 scoped_refptr<X509Certificate> cert(
8667 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:248668 ASSERT_TRUE(cert->VerifyNameMatch(origin1_.host()));
8669 ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host()));
8670 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:458671
8672 ProofVerifyDetailsChromium verify_details;
8673 verify_details.cert_verify_result.verified_cert = cert;
8674 verify_details.cert_verify_result.is_issued_by_known_root = true;
8675 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8676
fayang3bcb8b502016-12-07 21:44:378677 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:528678 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:368679 client_maker_.MakeInitialSettingsPacket(1, nullptr));
bnceb9aa7112017-01-05 01:03:468680 MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(),
8681 settings_packet->length(), 1)};
fayang3bcb8b502016-12-07 21:44:378682 std::unique_ptr<SequencedSocketData> sequenced_socket_data(
Ryan Sleevib8d7ea02018-05-07 20:01:018683 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:178684 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
fayang3bcb8b502016-12-07 21:44:378685 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
bnc359ed2a2016-04-29 20:43:458686
zhongyi98d6a9262017-05-19 02:47:458687 QuicStreamRequest request1(factory_.get());
Nick Harper23290b82019-05-02 00:02:568688 EXPECT_EQ(ERR_IO_PENDING,
8689 request1.Request(
8690 destination, version_.transport_version, privacy_mode_,
8691 DEFAULT_PRIORITY, SocketTag(),
8692 /*cert_verify_flags=*/0, url1, net_log_, &net_error_details_,
8693 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:018694 EXPECT_THAT(callback_.WaitForResult(), IsOk());
fayang3bcb8b502016-12-07 21:44:378695
Yixin Wang7891a39d2017-11-08 20:59:248696 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
bnc359ed2a2016-04-29 20:43:458697 EXPECT_TRUE(stream1.get());
8698 EXPECT_TRUE(HasActiveSession(origin1_));
8699
8700 // Second request returns synchronously because it pools to existing session.
8701 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:458702 QuicStreamRequest request2(factory_.get());
Nick Harper23290b82019-05-02 00:02:568703 EXPECT_EQ(OK, request2.Request(destination, version_.transport_version,
8704 privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
Paul Jensen8e3c5d32018-02-19 17:06:338705 /*cert_verify_flags=*/0, url2, net_log_,
Zhongyi Shia6b68d112018-09-24 07:49:038706 &net_error_details_,
8707 failed_on_default_network_callback_,
8708 callback2.callback()));
Yixin Wang7891a39d2017-11-08 20:59:248709 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
bnc359ed2a2016-04-29 20:43:458710 EXPECT_TRUE(stream2.get());
8711
rchf0b18c8a2017-05-05 19:31:578712 QuicChromiumClientSession::Handle* session1 =
8713 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
8714 QuicChromiumClientSession::Handle* session2 =
8715 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
8716 EXPECT_TRUE(session1->SharesSameSession(*session2));
bnc359ed2a2016-04-29 20:43:458717
Ryan Hamilton4f0b26e2018-06-27 23:52:328718 EXPECT_EQ(quic::QuicServerId(origin1_.host(), origin1_.port(),
8719 privacy_mode_ == PRIVACY_MODE_ENABLED),
8720 session1->server_id());
bnc359ed2a2016-04-29 20:43:458721
8722 EXPECT_TRUE(AllDataConsumed());
8723}
8724
bnc47eba7d2016-07-01 00:43:388725// QuicStreamRequest is not pooled if PrivacyMode differs.
8726TEST_P(QuicStreamFactoryWithDestinationTest, DifferentPrivacyMode) {
8727 Initialize();
8728
8729 GURL url1("https://www.example.org/");
8730 GURL url2("https://mail.example.org/");
8731 origin1_ = HostPortPair::FromURL(url1);
8732 origin2_ = HostPortPair::FromURL(url2);
8733
8734 HostPortPair destination = GetDestination();
8735
8736 scoped_refptr<X509Certificate> cert(
8737 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:248738 ASSERT_TRUE(cert->VerifyNameMatch(origin1_.host()));
8739 ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host()));
8740 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc47eba7d2016-07-01 00:43:388741
8742 ProofVerifyDetailsChromium verify_details1;
8743 verify_details1.cert_verify_result.verified_cert = cert;
8744 verify_details1.cert_verify_result.is_issued_by_known_root = true;
8745 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
8746
8747 ProofVerifyDetailsChromium verify_details2;
8748 verify_details2.cert_verify_result.verified_cert = cert;
8749 verify_details2.cert_verify_result.is_issued_by_known_root = true;
8750 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
8751
fayang3bcb8b502016-12-07 21:44:378752 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:528753 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:368754 client_maker_.MakeInitialSettingsPacket(1, nullptr));
bnceb9aa7112017-01-05 01:03:468755 MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(),
8756 settings_packet->length(), 1)};
fayang3bcb8b502016-12-07 21:44:378757 std::unique_ptr<SequencedSocketData> sequenced_socket_data(
Ryan Sleevib8d7ea02018-05-07 20:01:018758 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:178759 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
fayang3bcb8b502016-12-07 21:44:378760 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
8761 std::unique_ptr<SequencedSocketData> sequenced_socket_data1(
Ryan Sleevib8d7ea02018-05-07 20:01:018762 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:178763 socket_factory_->AddSocketDataProvider(sequenced_socket_data1.get());
fayang3bcb8b502016-12-07 21:44:378764 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data1));
bnc47eba7d2016-07-01 00:43:388765
zhongyi98d6a9262017-05-19 02:47:458766 QuicStreamRequest request1(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338767 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:038768 request1.Request(
Nick Harper23290b82019-05-02 00:02:568769 destination, version_.transport_version, PRIVACY_MODE_DISABLED,
8770 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:038771 /*cert_verify_flags=*/0, url1, net_log_, &net_error_details_,
8772 failed_on_default_network_callback_, callback_.callback()));
bnc47eba7d2016-07-01 00:43:388773 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:248774 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
bnc47eba7d2016-07-01 00:43:388775 EXPECT_TRUE(stream1.get());
8776 EXPECT_TRUE(HasActiveSession(origin1_));
8777
8778 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:458779 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338780 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:038781 request2.Request(
Nick Harper23290b82019-05-02 00:02:568782 destination, version_.transport_version, PRIVACY_MODE_ENABLED,
8783 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:038784 /*cert_verify_flags=*/0, url2, net_log_, &net_error_details_,
8785 failed_on_default_network_callback_, callback2.callback()));
bnc47eba7d2016-07-01 00:43:388786 EXPECT_EQ(OK, callback2.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:248787 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
bnc47eba7d2016-07-01 00:43:388788 EXPECT_TRUE(stream2.get());
8789
8790 // |request2| does not pool to the first session, because PrivacyMode does not
8791 // match. Instead, another session is opened to the same destination, but
Ryan Hamilton8d9ee76e2018-05-29 23:52:528792 // with a different quic::QuicServerId.
rchf0b18c8a2017-05-05 19:31:578793 QuicChromiumClientSession::Handle* session1 =
8794 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
8795 QuicChromiumClientSession::Handle* session2 =
8796 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
8797 EXPECT_FALSE(session1->SharesSameSession(*session2));
bnc47eba7d2016-07-01 00:43:388798
Ryan Hamilton4f0b26e2018-06-27 23:52:328799 EXPECT_EQ(quic::QuicServerId(origin1_.host(), origin1_.port(), false),
bnc47eba7d2016-07-01 00:43:388800 session1->server_id());
Ryan Hamilton4f0b26e2018-06-27 23:52:328801 EXPECT_EQ(quic::QuicServerId(origin2_.host(), origin2_.port(), true),
bnc47eba7d2016-07-01 00:43:388802 session2->server_id());
8803
8804 EXPECT_TRUE(AllDataConsumed());
8805}
8806
bnc359ed2a2016-04-29 20:43:458807// QuicStreamRequest is not pooled if certificate does not match its origin.
8808TEST_P(QuicStreamFactoryWithDestinationTest, DisjointCertificate) {
8809 Initialize();
8810
8811 GURL url1("https://news.example.org/");
8812 GURL url2("https://mail.example.com/");
8813 origin1_ = HostPortPair::FromURL(url1);
8814 origin2_ = HostPortPair::FromURL(url2);
8815
8816 HostPortPair destination = GetDestination();
8817
8818 scoped_refptr<X509Certificate> cert1(
8819 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:248820 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_.host()));
8821 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_.host()));
8822 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:458823
8824 ProofVerifyDetailsChromium verify_details1;
8825 verify_details1.cert_verify_result.verified_cert = cert1;
8826 verify_details1.cert_verify_result.is_issued_by_known_root = true;
8827 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
8828
8829 scoped_refptr<X509Certificate> cert2(
8830 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:248831 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_.host()));
8832 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:458833
8834 ProofVerifyDetailsChromium verify_details2;
8835 verify_details2.cert_verify_result.verified_cert = cert2;
8836 verify_details2.cert_verify_result.is_issued_by_known_root = true;
8837 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
8838
fayang3bcb8b502016-12-07 21:44:378839 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:528840 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:368841 client_maker_.MakeInitialSettingsPacket(1, nullptr));
bnceb9aa7112017-01-05 01:03:468842 MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(),
8843 settings_packet->length(), 1)};
fayang3bcb8b502016-12-07 21:44:378844 std::unique_ptr<SequencedSocketData> sequenced_socket_data(
Ryan Sleevib8d7ea02018-05-07 20:01:018845 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:178846 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
fayang3bcb8b502016-12-07 21:44:378847 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
8848 std::unique_ptr<SequencedSocketData> sequenced_socket_data1(
Ryan Sleevib8d7ea02018-05-07 20:01:018849 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:178850 socket_factory_->AddSocketDataProvider(sequenced_socket_data1.get());
fayang3bcb8b502016-12-07 21:44:378851 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data1));
bnc359ed2a2016-04-29 20:43:458852
zhongyi98d6a9262017-05-19 02:47:458853 QuicStreamRequest request1(factory_.get());
Nick Harper23290b82019-05-02 00:02:568854 EXPECT_EQ(ERR_IO_PENDING,
8855 request1.Request(
8856 destination, version_.transport_version, privacy_mode_,
8857 DEFAULT_PRIORITY, SocketTag(),
8858 /*cert_verify_flags=*/0, url1, net_log_, &net_error_details_,
8859 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:018860 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:248861 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
bnc359ed2a2016-04-29 20:43:458862 EXPECT_TRUE(stream1.get());
8863 EXPECT_TRUE(HasActiveSession(origin1_));
8864
8865 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:458866 QuicStreamRequest request2(factory_.get());
Nick Harper23290b82019-05-02 00:02:568867 EXPECT_EQ(ERR_IO_PENDING,
8868 request2.Request(
8869 destination, version_.transport_version, privacy_mode_,
8870 DEFAULT_PRIORITY, SocketTag(),
8871 /*cert_verify_flags=*/0, url2, net_log_, &net_error_details_,
8872 failed_on_default_network_callback_, callback2.callback()));
robpercival214763f2016-07-01 23:27:018873 EXPECT_THAT(callback2.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:248874 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
bnc359ed2a2016-04-29 20:43:458875 EXPECT_TRUE(stream2.get());
8876
8877 // |request2| does not pool to the first session, because the certificate does
8878 // not match. Instead, another session is opened to the same destination, but
Ryan Hamilton8d9ee76e2018-05-29 23:52:528879 // with a different quic::QuicServerId.
rchf0b18c8a2017-05-05 19:31:578880 QuicChromiumClientSession::Handle* session1 =
8881 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
8882 QuicChromiumClientSession::Handle* session2 =
8883 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
8884 EXPECT_FALSE(session1->SharesSameSession(*session2));
bnc359ed2a2016-04-29 20:43:458885
Ryan Hamilton4f0b26e2018-06-27 23:52:328886 EXPECT_EQ(quic::QuicServerId(origin1_.host(), origin1_.port(),
8887 privacy_mode_ == PRIVACY_MODE_ENABLED),
8888 session1->server_id());
8889 EXPECT_EQ(quic::QuicServerId(origin2_.host(), origin2_.port(),
8890 privacy_mode_ == PRIVACY_MODE_ENABLED),
8891 session2->server_id());
bnc359ed2a2016-04-29 20:43:458892
8893 EXPECT_TRUE(AllDataConsumed());
8894}
8895
msramek992625ec2016-08-04 18:33:588896// This test verifies that QuicStreamFactory::ClearCachedStatesInCryptoConfig
8897// correctly transform an origin filter to a ServerIdFilter. Whether the
8898// deletion itself works correctly is tested in QuicCryptoClientConfigTest.
8899TEST_P(QuicStreamFactoryTest, ClearCachedStatesInCryptoConfig) {
8900 Initialize();
Ryan Hamilton8d9ee76e2018-05-29 23:52:528901 quic::QuicCryptoClientConfig* crypto_config =
msramek992625ec2016-08-04 18:33:588902 QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
8903
8904 struct TestCase {
8905 TestCase(const std::string& host,
8906 int port,
8907 PrivacyMode privacy_mode,
Ryan Hamilton8d9ee76e2018-05-29 23:52:528908 quic::QuicCryptoClientConfig* crypto_config)
msramek992625ec2016-08-04 18:33:588909 : server_id(host, port, privacy_mode),
8910 state(crypto_config->LookupOrCreate(server_id)) {
rch872e00e2016-12-02 02:48:188911 std::vector<string> certs(1);
msramek992625ec2016-08-04 18:33:588912 certs[0] = "cert";
8913 state->SetProof(certs, "cert_sct", "chlo_hash", "signature");
8914 state->set_source_address_token("TOKEN");
8915 state->SetProofValid();
8916
8917 EXPECT_FALSE(state->certs().empty());
8918 }
8919
Ryan Hamilton8d9ee76e2018-05-29 23:52:528920 quic::QuicServerId server_id;
8921 quic::QuicCryptoClientConfig::CachedState* state;
msramek992625ec2016-08-04 18:33:588922 } test_cases[] = {
8923 TestCase("www.google.com", 443, privacy_mode_, crypto_config),
8924 TestCase("www.example.com", 443, privacy_mode_, crypto_config),
8925 TestCase("www.example.com", 4433, privacy_mode_, crypto_config)};
8926
8927 // Clear cached states for the origin https://www.example.com:4433.
8928 GURL origin("https://www.example.com:4433");
csharrisonebeca8e2016-10-18 02:35:368929 factory_->ClearCachedStatesInCryptoConfig(base::Bind(
8930 static_cast<bool (*)(const GURL&, const GURL&)>(::operator==), origin));
msramek992625ec2016-08-04 18:33:588931 EXPECT_FALSE(test_cases[0].state->certs().empty());
8932 EXPECT_FALSE(test_cases[1].state->certs().empty());
8933 EXPECT_TRUE(test_cases[2].state->certs().empty());
8934
8935 // Clear all cached states.
8936 factory_->ClearCachedStatesInCryptoConfig(
8937 base::Callback<bool(const GURL&)>());
8938 EXPECT_TRUE(test_cases[0].state->certs().empty());
8939 EXPECT_TRUE(test_cases[1].state->certs().empty());
8940 EXPECT_TRUE(test_cases[2].state->certs().empty());
8941}
8942
Yixin Wang46a425f2017-08-10 23:02:208943// Passes connection options and client connection options to QuicStreamFactory,
Ryan Hamilton8d9ee76e2018-05-29 23:52:528944// then checks that its internal quic::QuicConfig is correct.
Yixin Wang46a425f2017-08-10 23:02:208945TEST_P(QuicStreamFactoryTest, ConfigConnectionOptions) {
Zhongyi Shi967d2f12019-02-08 20:58:538946 test_params_.quic_connection_options.push_back(quic::kTIME);
8947 test_params_.quic_connection_options.push_back(quic::kTBBR);
8948 test_params_.quic_connection_options.push_back(quic::kREJ);
Yixin Wang46a425f2017-08-10 23:02:208949
Zhongyi Shi967d2f12019-02-08 20:58:538950 test_params_.quic_client_connection_options.push_back(quic::kTBBR);
8951 test_params_.quic_client_connection_options.push_back(quic::k1RTT);
Yixin Wang46a425f2017-08-10 23:02:208952
8953 Initialize();
8954
Ryan Hamilton8d9ee76e2018-05-29 23:52:528955 const quic::QuicConfig* config =
8956 QuicStreamFactoryPeer::GetConfig(factory_.get());
Zhongyi Shi967d2f12019-02-08 20:58:538957 EXPECT_EQ(test_params_.quic_connection_options,
8958 config->SendConnectionOptions());
Yixin Wang46a425f2017-08-10 23:02:208959 EXPECT_TRUE(config->HasClientRequestedIndependentOption(
Ryan Hamilton8d9ee76e2018-05-29 23:52:528960 quic::kTBBR, quic::Perspective::IS_CLIENT));
Yixin Wang46a425f2017-08-10 23:02:208961 EXPECT_TRUE(config->HasClientRequestedIndependentOption(
Ryan Hamilton8d9ee76e2018-05-29 23:52:528962 quic::k1RTT, quic::Perspective::IS_CLIENT));
Yixin Wang46a425f2017-08-10 23:02:208963}
8964
Yixin Wang247ea642017-11-15 01:15:508965// Verifies that the host resolver uses the request priority passed to
8966// QuicStreamRequest::Request().
8967TEST_P(QuicStreamFactoryTest, HostResolverUsesRequestPriority) {
8968 Initialize();
8969 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8970 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8971
8972 MockQuicData socket_data;
8973 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:438974 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:178975 socket_data.AddSocketDataToFactory(socket_factory_.get());
Yixin Wang247ea642017-11-15 01:15:508976
8977 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338978 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:038979 request.Request(
Nick Harper23290b82019-05-02 00:02:568980 host_port_pair_, version_.transport_version, privacy_mode_,
8981 MAXIMUM_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:038982 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8983 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang247ea642017-11-15 01:15:508984
8985 EXPECT_THAT(callback_.WaitForResult(), IsOk());
8986 std::unique_ptr<HttpStream> stream = CreateStream(&request);
8987 EXPECT_TRUE(stream.get());
8988
Renjiea0cb4a2c2018-09-26 23:37:308989 EXPECT_EQ(MAXIMUM_PRIORITY, host_resolver_->last_request_priority());
Yixin Wang247ea642017-11-15 01:15:508990
8991 EXPECT_TRUE(socket_data.AllReadDataConsumed());
8992 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
8993}
8994
Lily Chenf11e1292018-11-29 16:42:098995TEST_P(QuicStreamFactoryTest, HostResolverRequestReprioritizedOnSetPriority) {
8996 Initialize();
8997 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8998 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8999
9000 MockQuicData socket_data;
9001 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9002 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
9003 socket_data.AddSocketDataToFactory(socket_factory_.get());
9004
9005 QuicStreamRequest request(factory_.get());
9006 EXPECT_EQ(ERR_IO_PENDING,
9007 request.Request(
Nick Harper23290b82019-05-02 00:02:569008 host_port_pair_, version_.transport_version, privacy_mode_,
9009 MAXIMUM_PRIORITY, SocketTag(),
Lily Chenf11e1292018-11-29 16:42:099010 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9011 failed_on_default_network_callback_, callback_.callback()));
9012
9013 EXPECT_EQ(MAXIMUM_PRIORITY, host_resolver_->last_request_priority());
9014 EXPECT_EQ(MAXIMUM_PRIORITY, host_resolver_->request_priority(1));
9015
9016 QuicStreamRequest request2(factory_.get());
9017 EXPECT_EQ(ERR_IO_PENDING,
9018 request2.Request(
Nick Harper23290b82019-05-02 00:02:569019 host_port_pair_, version_.transport_version, privacy_mode_,
9020 DEFAULT_PRIORITY, SocketTag(),
Lily Chenf11e1292018-11-29 16:42:099021 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
9022 failed_on_default_network_callback_, callback_.callback()));
9023 EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_->last_request_priority());
9024 EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_->request_priority(2));
9025
9026 request.SetPriority(LOWEST);
9027 EXPECT_EQ(LOWEST, host_resolver_->request_priority(1));
9028 EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_->request_priority(2));
9029}
9030
Zhongyi Shi967d2f12019-02-08 20:58:539031// Passes |quic_max_time_before_crypto_handshake_seconds| and
9032// |quic_max_idle_time_before_crypto_handshake_seconds| to QuicStreamFactory,
Ryan Hamilton8d9ee76e2018-05-29 23:52:529033// checks that its internal quic::QuicConfig is correct.
Yixin Wang469da562017-11-15 21:34:589034TEST_P(QuicStreamFactoryTest, ConfigMaxTimeBeforeCryptoHandshake) {
Zhongyi Shi967d2f12019-02-08 20:58:539035 test_params_.quic_max_time_before_crypto_handshake_seconds = 11;
9036 test_params_.quic_max_idle_time_before_crypto_handshake_seconds = 13;
Yixin Wang469da562017-11-15 21:34:589037 Initialize();
9038
Ryan Hamilton8d9ee76e2018-05-29 23:52:529039 const quic::QuicConfig* config =
9040 QuicStreamFactoryPeer::GetConfig(factory_.get());
9041 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(11),
Yixin Wang469da562017-11-15 21:34:589042 config->max_time_before_crypto_handshake());
Ryan Hamilton8d9ee76e2018-05-29 23:52:529043 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(13),
Yixin Wang469da562017-11-15 21:34:589044 config->max_idle_time_before_crypto_handshake());
9045}
9046
Yixin Wang7c5d11a82017-12-21 02:40:009047// Verify ResultAfterHostResolutionCallback behavior when host resolution
9048// succeeds asynchronously, then crypto handshake fails synchronously.
9049TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackAsyncSync) {
9050 Initialize();
9051 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9052 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9053
Renjiea0cb4a2c2018-09-26 23:37:309054 host_resolver_->set_ondemand_mode(true);
Yixin Wang7c5d11a82017-12-21 02:40:009055
9056 MockQuicData socket_data;
9057 socket_data.AddRead(SYNCHRONOUS, ERR_FAILED);
9058 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
9059 socket_data.AddSocketDataToFactory(socket_factory_.get());
9060
9061 QuicStreamRequest request(factory_.get());
9062 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039063 request.Request(
Nick Harper23290b82019-05-02 00:02:569064 host_port_pair_, version_.transport_version, privacy_mode_,
9065 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:039066 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9067 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:009068
9069 TestCompletionCallback host_resolution_callback;
9070 EXPECT_TRUE(
9071 request.WaitForHostResolution(host_resolution_callback.callback()));
9072
9073 // |host_resolver_| has not finished host resolution at this point, so
9074 // |host_resolution_callback| should not have a result.
9075 base::RunLoop().RunUntilIdle();
9076 EXPECT_FALSE(host_resolution_callback.have_result());
9077
9078 // Allow |host_resolver_| to finish host resolution.
9079 // Since the request fails immediately after host resolution (getting
9080 // ERR_FAILED from socket reads/writes), |host_resolution_callback| should be
9081 // called with ERR_QUIC_PROTOCOL_ERROR since that's the next result in
9082 // forming the connection.
Renjiea0cb4a2c2018-09-26 23:37:309083 host_resolver_->ResolveAllPending();
Yixin Wang7c5d11a82017-12-21 02:40:009084 base::RunLoop().RunUntilIdle();
9085 EXPECT_TRUE(host_resolution_callback.have_result());
9086 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, host_resolution_callback.WaitForResult());
9087
9088 // Calling WaitForHostResolution() a second time should return
9089 // false since host resolution has finished already.
9090 EXPECT_FALSE(
9091 request.WaitForHostResolution(host_resolution_callback.callback()));
9092
9093 EXPECT_TRUE(callback_.have_result());
9094 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
9095}
9096
9097// Verify ResultAfterHostResolutionCallback behavior when host resolution
9098// succeeds asynchronously, then crypto handshake fails asynchronously.
9099TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackAsyncAsync) {
9100 Initialize();
9101 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9102 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9103
Renjiea0cb4a2c2018-09-26 23:37:309104 host_resolver_->set_ondemand_mode(true);
Yixin Wang7c5d11a82017-12-21 02:40:009105 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:279106 MockCryptoClientStream::ZERO_RTT);
Yixin Wang7c5d11a82017-12-21 02:40:009107 factory_->set_require_confirmation(true);
9108
9109 MockQuicData socket_data;
9110 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
9111 socket_data.AddRead(ASYNC, ERR_FAILED);
9112 socket_data.AddWrite(ASYNC, ERR_FAILED);
9113 socket_data.AddSocketDataToFactory(socket_factory_.get());
9114
9115 QuicStreamRequest request(factory_.get());
9116 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039117 request.Request(
Nick Harper23290b82019-05-02 00:02:569118 host_port_pair_, version_.transport_version, privacy_mode_,
9119 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:039120 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9121 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:009122
9123 TestCompletionCallback host_resolution_callback;
9124 EXPECT_TRUE(
9125 request.WaitForHostResolution(host_resolution_callback.callback()));
9126
9127 // |host_resolver_| has not finished host resolution at this point, so
9128 // |host_resolution_callback| should not have a result.
9129 base::RunLoop().RunUntilIdle();
9130 EXPECT_FALSE(host_resolution_callback.have_result());
9131
9132 // Allow |host_resolver_| to finish host resolution. Since crypto handshake
9133 // will hang after host resolution, |host_resolution_callback| should run with
9134 // ERR_IO_PENDING since that's the next result in forming the connection.
Renjiea0cb4a2c2018-09-26 23:37:309135 host_resolver_->ResolveAllPending();
Yixin Wang7c5d11a82017-12-21 02:40:009136 base::RunLoop().RunUntilIdle();
9137 EXPECT_TRUE(host_resolution_callback.have_result());
9138 EXPECT_EQ(ERR_IO_PENDING, host_resolution_callback.WaitForResult());
9139
9140 // Calling WaitForHostResolution() a second time should return
9141 // false since host resolution has finished already.
9142 EXPECT_FALSE(
9143 request.WaitForHostResolution(host_resolution_callback.callback()));
9144
9145 EXPECT_FALSE(callback_.have_result());
9146 socket_data.GetSequencedSocketData()->Resume();
9147 base::RunLoop().RunUntilIdle();
9148 EXPECT_TRUE(callback_.have_result());
9149 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
9150}
9151
9152// Verify ResultAfterHostResolutionCallback behavior when host resolution
9153// succeeds synchronously, then crypto handshake fails synchronously.
9154TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackSyncSync) {
9155 Initialize();
9156 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9157 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9158
Renjiea0cb4a2c2018-09-26 23:37:309159 host_resolver_->set_synchronous_mode(true);
Yixin Wang7c5d11a82017-12-21 02:40:009160
9161 MockQuicData socket_data;
9162 socket_data.AddRead(SYNCHRONOUS, ERR_FAILED);
9163 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
9164 socket_data.AddSocketDataToFactory(socket_factory_.get());
9165
9166 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339167 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR,
Zhongyi Shia6b68d112018-09-24 07:49:039168 request.Request(
Nick Harper23290b82019-05-02 00:02:569169 host_port_pair_, version_.transport_version, privacy_mode_,
9170 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:039171 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9172 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:009173
9174 // WaitForHostResolution() should return false since host
9175 // resolution has finished already.
9176 TestCompletionCallback host_resolution_callback;
9177 EXPECT_FALSE(
9178 request.WaitForHostResolution(host_resolution_callback.callback()));
9179 base::RunLoop().RunUntilIdle();
9180 EXPECT_FALSE(host_resolution_callback.have_result());
9181 EXPECT_FALSE(callback_.have_result());
9182}
9183
9184// Verify ResultAfterHostResolutionCallback behavior when host resolution
9185// succeeds synchronously, then crypto handshake fails asynchronously.
9186TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackSyncAsync) {
9187 Initialize();
9188 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9189 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9190
9191 // Host resolution will succeed synchronously, but Request() as a whole
9192 // will fail asynchronously.
Renjiea0cb4a2c2018-09-26 23:37:309193 host_resolver_->set_synchronous_mode(true);
Yixin Wang7c5d11a82017-12-21 02:40:009194 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:279195 MockCryptoClientStream::ZERO_RTT);
Yixin Wang7c5d11a82017-12-21 02:40:009196 factory_->set_require_confirmation(true);
9197
9198 MockQuicData socket_data;
9199 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
9200 socket_data.AddRead(ASYNC, ERR_FAILED);
9201 socket_data.AddWrite(ASYNC, ERR_FAILED);
9202 socket_data.AddSocketDataToFactory(socket_factory_.get());
9203
9204 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339205 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039206 request.Request(
Nick Harper23290b82019-05-02 00:02:569207 host_port_pair_, version_.transport_version, privacy_mode_,
9208 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:039209 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9210 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:009211
9212 // WaitForHostResolution() should return false since host
9213 // resolution has finished already.
9214 TestCompletionCallback host_resolution_callback;
9215 EXPECT_FALSE(
9216 request.WaitForHostResolution(host_resolution_callback.callback()));
9217 base::RunLoop().RunUntilIdle();
9218 EXPECT_FALSE(host_resolution_callback.have_result());
9219
9220 EXPECT_FALSE(callback_.have_result());
9221 socket_data.GetSequencedSocketData()->Resume();
9222 base::RunLoop().RunUntilIdle();
9223 EXPECT_TRUE(callback_.have_result());
9224 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
9225}
9226
9227// Verify ResultAfterHostResolutionCallback behavior when host resolution fails
9228// synchronously.
9229TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackFailSync) {
9230 Initialize();
9231 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9232 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9233
9234 // Host resolution will fail synchronously.
Renjiea0cb4a2c2018-09-26 23:37:309235 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
9236 host_resolver_->set_synchronous_mode(true);
Yixin Wang7c5d11a82017-12-21 02:40:009237
9238 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339239 EXPECT_EQ(ERR_NAME_NOT_RESOLVED,
Zhongyi Shia6b68d112018-09-24 07:49:039240 request.Request(
Nick Harper23290b82019-05-02 00:02:569241 host_port_pair_, version_.transport_version, privacy_mode_,
9242 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:039243 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9244 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:009245
9246 // WaitForHostResolution() should return false since host
9247 // resolution has failed already.
9248 TestCompletionCallback host_resolution_callback;
9249 EXPECT_FALSE(
9250 request.WaitForHostResolution(host_resolution_callback.callback()));
9251 base::RunLoop().RunUntilIdle();
9252 EXPECT_FALSE(host_resolution_callback.have_result());
9253}
9254
9255// Verify ResultAfterHostResolutionCallback behavior when host resolution fails
9256// asynchronously.
9257TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackFailAsync) {
9258 Initialize();
9259 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9260 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9261
Renjiea0cb4a2c2018-09-26 23:37:309262 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
Yixin Wang7c5d11a82017-12-21 02:40:009263
9264 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339265 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039266 request.Request(
Nick Harper23290b82019-05-02 00:02:569267 host_port_pair_, version_.transport_version, privacy_mode_,
9268 DEFAULT_PRIORITY, SocketTag(),
Zhongyi Shia6b68d112018-09-24 07:49:039269 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9270 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:009271
9272 TestCompletionCallback host_resolution_callback;
9273 EXPECT_TRUE(
9274 request.WaitForHostResolution(host_resolution_callback.callback()));
9275
9276 // Allow |host_resolver_| to fail host resolution. |host_resolution_callback|
9277 // Should run with ERR_NAME_NOT_RESOLVED since that's the error host
9278 // resolution failed with.
9279 base::RunLoop().RunUntilIdle();
9280 EXPECT_TRUE(host_resolution_callback.have_result());
9281 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, host_resolution_callback.WaitForResult());
9282
9283 EXPECT_TRUE(callback_.have_result());
9284 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, callback_.WaitForResult());
9285}
9286
Renjiea0cb4a2c2018-09-26 23:37:309287// With dns race experiment turned on, and DNS resolve succeeds synchronously,
9288// the final connection is established through the resolved DNS. No racing
9289// connection.
9290TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceAndHostResolutionSync) {
Zhongyi Shi967d2f12019-02-08 20:58:539291 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:309292 host_resolver_ = std::make_unique<MockCachingHostResolver>();
9293 Initialize();
9294 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9295 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9296
9297 // Set an address in resolver for synchronous return.
9298 host_resolver_->set_synchronous_mode(true);
9299 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
9300 kNonCachedIPAddress, "");
9301
9302 // Set up a different address in stale resolver cache.
9303 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
9304 HostCache::Entry entry(OK,
9305 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
9306 HostCache::Entry::SOURCE_DNS);
9307 base::TimeDelta zero;
9308 HostCache* cache = host_resolver_->GetHostCache();
9309 cache->Set(key, entry, base::TimeTicks::Now(), zero);
9310 // Expire the cache
Eric Orth37b18192019-04-22 19:09:289311 cache->Invalidate();
Renjie8d2d8d91b2018-09-29 00:29:039312
Renjiea0cb4a2c2018-09-26 23:37:309313 MockQuicData quic_data;
9314 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9315 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
9316 quic_data.AddSocketDataToFactory(socket_factory_.get());
9317
9318 QuicStreamRequest request(factory_.get());
9319 EXPECT_THAT(request.Request(
Nick Harper23290b82019-05-02 00:02:569320 host_port_pair_, version_.transport_version, privacy_mode_,
9321 DEFAULT_PRIORITY, SocketTag(),
Renjiea0cb4a2c2018-09-26 23:37:309322 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9323 failed_on_default_network_callback_, callback_.callback()),
9324 IsOk());
9325 std::unique_ptr<HttpStream> stream = CreateStream(&request);
9326 EXPECT_TRUE(stream.get());
9327 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Victor Vasilievbee79ea2019-05-15 01:25:489328 EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress);
Renjiea0cb4a2c2018-09-26 23:37:309329
9330 EXPECT_TRUE(quic_data.AllReadDataConsumed());
9331 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
9332}
9333
9334// With dns race experiment on, DNS resolve returns async, no matching cache in
9335// host resolver, connection should be successful and through resolved DNS. No
9336// racing connection.
9337TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceAndHostResolutionAsync) {
Renjiea0cb4a2c2018-09-26 23:37:309338 host_resolver_ = std::make_unique<MockCachingHostResolver>();
9339 Initialize();
9340 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9341 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9342
9343 // Set an address in resolver for asynchronous return.
9344 host_resolver_->set_ondemand_mode(true);
9345 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
9346 kNonCachedIPAddress, "");
9347
9348 MockQuicData quic_data;
9349 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9350 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
9351 quic_data.AddSocketDataToFactory(socket_factory_.get());
9352
9353 QuicStreamRequest request(factory_.get());
9354 EXPECT_EQ(ERR_IO_PENDING,
9355 request.Request(
Nick Harper23290b82019-05-02 00:02:569356 host_port_pair_, version_.transport_version, privacy_mode_,
9357 DEFAULT_PRIORITY, SocketTag(),
Renjiea0cb4a2c2018-09-26 23:37:309358 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9359 failed_on_default_network_callback_, callback_.callback()));
9360 TestCompletionCallback host_resolution_callback;
9361 EXPECT_TRUE(
9362 request.WaitForHostResolution(host_resolution_callback.callback()));
9363 base::RunLoop().RunUntilIdle();
9364 EXPECT_FALSE(host_resolution_callback.have_result());
9365
9366 // Cause the host resolution to return.
9367 host_resolver_->ResolveAllPending();
9368 EXPECT_THAT(host_resolution_callback.WaitForResult(), IsOk());
9369 EXPECT_THAT(callback_.WaitForResult(), IsOk());
9370
9371 std::unique_ptr<HttpStream> stream = CreateStream(&request);
9372 EXPECT_TRUE(stream.get());
9373 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
9374
Victor Vasilievbee79ea2019-05-15 01:25:489375 EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress);
Renjiea0cb4a2c2018-09-26 23:37:309376
9377 EXPECT_TRUE(quic_data.AllReadDataConsumed());
9378 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
9379}
9380
9381// With dns race experiment on, DNS resolve returns async, stale dns used,
9382// connects synchrounously, and then the resolved DNS matches.
9383TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveAsyncStaleMatch) {
Zhongyi Shi967d2f12019-02-08 20:58:539384 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:309385 host_resolver_ = std::make_unique<MockCachingHostResolver>();
9386 Initialize();
9387 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9388 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9389
9390 // Set an address in resolver for asynchronous return.
9391 host_resolver_->set_ondemand_mode(true);
9392 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
9393 kCachedIPAddress.ToString(), "");
9394
9395 // Set up the same address in the stale resolver cache.
9396 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
9397 HostCache::Entry entry(OK,
9398 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
9399 HostCache::Entry::SOURCE_DNS);
9400 base::TimeDelta zero;
9401 HostCache* cache = host_resolver_->GetHostCache();
9402 cache->Set(key, entry, base::TimeTicks::Now(), zero);
9403 // Expire the cache
Eric Orth37b18192019-04-22 19:09:289404 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:309405
9406 MockQuicData quic_data;
9407 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9408 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
9409 quic_data.AddSocketDataToFactory(socket_factory_.get());
9410
9411 QuicStreamRequest request(factory_.get());
9412 EXPECT_EQ(ERR_IO_PENDING,
9413 request.Request(
Nick Harper23290b82019-05-02 00:02:569414 host_port_pair_, version_.transport_version, privacy_mode_,
9415 DEFAULT_PRIORITY, SocketTag(),
Renjiea0cb4a2c2018-09-26 23:37:309416 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9417 failed_on_default_network_callback_, callback_.callback()));
9418
9419 // Check that the racing job is running.
9420 EXPECT_TRUE(HasLiveSession(host_port_pair_));
9421 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
9422
9423 // Resolve dns and return.
9424 host_resolver_->ResolveAllPending();
9425 EXPECT_THAT(callback_.WaitForResult(), IsOk());
9426 std::unique_ptr<HttpStream> stream = CreateStream(&request);
9427 EXPECT_TRUE(stream.get());
9428
9429 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
9430
Victor Vasilievbee79ea2019-05-15 01:25:489431 EXPECT_EQ(session->peer_address().host().ToString(),
9432 kCachedIPAddress.ToString());
Renjiea0cb4a2c2018-09-26 23:37:309433
9434 EXPECT_TRUE(quic_data.AllReadDataConsumed());
9435 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
9436}
9437
9438// With dns race experiment on, dns resolve async, stale dns used, connect
9439// async, and then the result matches.
9440TEST_P(QuicStreamFactoryTest,
9441 ResultAfterDNSRaceHostResolveAsyncConnectAsyncStaleMatch) {
Zhongyi Shi967d2f12019-02-08 20:58:539442 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:309443 host_resolver_ = std::make_unique<MockCachingHostResolver>();
9444 Initialize();
9445 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9446 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9447
9448 // Set an address in resolver for asynchronous return.
9449 host_resolver_->set_ondemand_mode(true);
9450 factory_->set_require_confirmation(true);
9451 crypto_client_stream_factory_.set_handshake_mode(
9452 MockCryptoClientStream::ZERO_RTT);
9453 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
9454 kCachedIPAddress.ToString(), "");
9455
9456 // Set up the same address in the stale resolver cache.
9457 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
9458 HostCache::Entry entry(OK,
9459 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
9460 HostCache::Entry::SOURCE_DNS);
9461 base::TimeDelta zero;
9462 HostCache* cache = host_resolver_->GetHostCache();
9463 cache->Set(key, entry, base::TimeTicks::Now(), zero);
9464 // Expire the cache
Eric Orth37b18192019-04-22 19:09:289465 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:309466
9467 MockQuicData quic_data;
9468 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9469 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
9470 quic_data.AddSocketDataToFactory(socket_factory_.get());
9471
9472 QuicStreamRequest request(factory_.get());
9473 EXPECT_EQ(ERR_IO_PENDING,
9474 request.Request(
Nick Harper23290b82019-05-02 00:02:569475 host_port_pair_, version_.transport_version, privacy_mode_,
9476 DEFAULT_PRIORITY, SocketTag(),
Renjiea0cb4a2c2018-09-26 23:37:309477 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9478 failed_on_default_network_callback_, callback_.callback()));
9479
9480 // Send Crypto handshake so connect will call back.
9481 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
9482 quic::QuicSession::HANDSHAKE_CONFIRMED);
9483 base::RunLoop().RunUntilIdle();
9484
9485 // Check that the racing job is running.
9486 EXPECT_TRUE(HasLiveSession(host_port_pair_));
9487 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
9488
9489 // Resolve dns and call back, make sure job finishes.
9490 host_resolver_->ResolveAllPending();
9491 EXPECT_THAT(callback_.WaitForResult(), IsOk());
9492
9493 std::unique_ptr<HttpStream> stream = CreateStream(&request);
9494 EXPECT_TRUE(stream.get());
9495
9496 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
9497
Victor Vasilievbee79ea2019-05-15 01:25:489498 EXPECT_EQ(session->peer_address().host().ToString(),
9499 kCachedIPAddress.ToString());
Renjiea0cb4a2c2018-09-26 23:37:309500
9501 EXPECT_TRUE(quic_data.AllReadDataConsumed());
9502 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
9503}
9504
9505// With dns race experiment on, dns resolve async, stale dns used, dns resolve
9506// return, then connection finishes and matches with the result.
9507TEST_P(QuicStreamFactoryTest,
9508 ResultAfterDNSRaceHostResolveAsyncStaleMatchConnectAsync) {
Zhongyi Shi967d2f12019-02-08 20:58:539509 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:309510 host_resolver_ = std::make_unique<MockCachingHostResolver>();
9511 Initialize();
9512 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9513 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9514
9515 // Set an address in resolver for asynchronous return.
9516 host_resolver_->set_ondemand_mode(true);
9517 factory_->set_require_confirmation(true);
9518 crypto_client_stream_factory_.set_handshake_mode(
9519 MockCryptoClientStream::ZERO_RTT);
9520 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
9521 kCachedIPAddress.ToString(), "");
9522
9523 // Set up the same address in the stale resolver cache.
9524 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
9525 HostCache::Entry entry(OK,
9526 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
9527 HostCache::Entry::SOURCE_DNS);
9528 base::TimeDelta zero;
9529 HostCache* cache = host_resolver_->GetHostCache();
9530 cache->Set(key, entry, base::TimeTicks::Now(), zero);
9531 // Expire the cache
Eric Orth37b18192019-04-22 19:09:289532 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:309533
9534 MockQuicData quic_data;
9535 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9536 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
9537 quic_data.AddSocketDataToFactory(socket_factory_.get());
9538
9539 QuicStreamRequest request(factory_.get());
9540 EXPECT_EQ(ERR_IO_PENDING,
9541 request.Request(
Nick Harper23290b82019-05-02 00:02:569542 host_port_pair_, version_.transport_version, privacy_mode_,
9543 DEFAULT_PRIORITY, SocketTag(),
Renjiea0cb4a2c2018-09-26 23:37:309544 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9545 failed_on_default_network_callback_, callback_.callback()));
9546
9547 // Finish dns async, check we still need to wait for stale connection async.
9548 host_resolver_->ResolveAllPending();
9549 base::RunLoop().RunUntilIdle();
9550 EXPECT_FALSE(callback_.have_result());
9551
9552 // Finish stale connection async, and the stale connection should pass dns
9553 // validation.
9554 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
9555 quic::QuicSession::HANDSHAKE_CONFIRMED);
9556 EXPECT_THAT(callback_.WaitForResult(), IsOk());
9557 std::unique_ptr<HttpStream> stream = CreateStream(&request);
9558 EXPECT_TRUE(stream.get());
9559
9560 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Victor Vasilievbee79ea2019-05-15 01:25:489561 EXPECT_EQ(session->peer_address().host().ToString(),
9562 kCachedIPAddress.ToString());
Renjiea0cb4a2c2018-09-26 23:37:309563
9564 EXPECT_TRUE(quic_data.AllReadDataConsumed());
9565 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
9566}
9567
9568// With dns race experiment on, dns resolve async, stale used and connects
9569// sync, but dns no match
9570TEST_P(QuicStreamFactoryTest,
9571 ResultAfterDNSRaceHostResolveAsyncStaleSyncNoMatch) {
Zhongyi Shi967d2f12019-02-08 20:58:539572 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:309573 host_resolver_ = std::make_unique<MockCachingHostResolver>();
9574 Initialize();
9575 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9576 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9577
9578 // Set an address in resolver for asynchronous return.
9579 host_resolver_->set_ondemand_mode(true);
9580 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
9581 kNonCachedIPAddress, "");
9582
9583 // Set up a different address in the stale resolver cache.
9584 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
9585 HostCache::Entry entry(OK,
9586 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
9587 HostCache::Entry::SOURCE_DNS);
9588 base::TimeDelta zero;
9589 HostCache* cache = host_resolver_->GetHostCache();
9590 cache->Set(key, entry, base::TimeTicks::Now(), zero);
9591 // Expire the cache
Eric Orth37b18192019-04-22 19:09:289592 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:309593
9594 // Socket for the stale connection which will invoke connection closure.
9595 MockQuicData quic_data;
9596 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9597 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
9598 quic_data.AddWrite(
Renjief5fcb172019-02-05 01:59:339599 SYNCHRONOUS,
9600 client_maker_.MakeConnectionClosePacket(
9601 2, true, quic::QUIC_STALE_CONNECTION_CANCELLED, "net error"));
Renjiea0cb4a2c2018-09-26 23:37:309602 quic_data.AddSocketDataToFactory(socket_factory_.get());
9603
9604 // Socket for the new connection.
9605 MockQuicData quic_data2;
9606 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9607 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
9608 quic_data2.AddSocketDataToFactory(socket_factory_.get());
9609
9610 QuicStreamRequest request(factory_.get());
9611 EXPECT_EQ(ERR_IO_PENDING,
9612 request.Request(
Nick Harper23290b82019-05-02 00:02:569613 host_port_pair_, version_.transport_version, privacy_mode_,
9614 DEFAULT_PRIORITY, SocketTag(),
Renjiea0cb4a2c2018-09-26 23:37:309615 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9616 failed_on_default_network_callback_, callback_.callback()));
9617
9618 // Check the stale connection is running.
9619 EXPECT_TRUE(HasLiveSession(host_port_pair_));
9620 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
9621
9622 // Finish dns resolution and check the job has finished.
9623 host_resolver_->ResolveAllPending();
9624 EXPECT_THAT(callback_.WaitForResult(), IsOk());
9625
9626 std::unique_ptr<HttpStream> stream = CreateStream(&request);
9627 EXPECT_TRUE(stream.get());
9628
9629 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
9630
Victor Vasilievbee79ea2019-05-15 01:25:489631 EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress);
Renjiea0cb4a2c2018-09-26 23:37:309632
9633 EXPECT_TRUE(quic_data.AllReadDataConsumed());
9634 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
9635 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
9636 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
9637}
9638
9639// With dns race experiment on, dns resolve async, stale used and connects
9640// async, finishes before dns, but no match
9641TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleAsyncResolveAsyncNoMatch) {
Zhongyi Shi967d2f12019-02-08 20:58:539642 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:309643 host_resolver_ = std::make_unique<MockCachingHostResolver>();
9644 Initialize();
9645 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9646 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9647
9648 // Set an address in resolver for asynchronous return.
9649 host_resolver_->set_ondemand_mode(true);
9650 factory_->set_require_confirmation(true);
9651 crypto_client_stream_factory_.set_handshake_mode(
9652 MockCryptoClientStream::ZERO_RTT);
9653 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
9654 kNonCachedIPAddress, "");
9655
9656 // Set up a different address in the stale resolvercache.
9657 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
9658 HostCache::Entry entry(OK,
9659 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
9660 HostCache::Entry::SOURCE_DNS);
9661 base::TimeDelta zero;
9662 HostCache* cache = host_resolver_->GetHostCache();
9663 cache->Set(key, entry, base::TimeTicks::Now(), zero);
9664 // Expire the cache
Eric Orth37b18192019-04-22 19:09:289665 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:309666
9667 MockQuicData quic_data;
9668 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9669 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
9670 quic_data.AddWrite(
Renjief5fcb172019-02-05 01:59:339671 SYNCHRONOUS,
9672 client_maker_.MakeConnectionClosePacket(
9673 2, true, quic::QUIC_STALE_CONNECTION_CANCELLED, "net error"));
Renjiea0cb4a2c2018-09-26 23:37:309674 quic_data.AddSocketDataToFactory(socket_factory_.get());
9675
9676 MockQuicData quic_data2;
9677 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9678 quic_data2.AddSocketDataToFactory(socket_factory_.get());
9679
9680 QuicStreamRequest request(factory_.get());
9681 EXPECT_EQ(ERR_IO_PENDING,
9682 request.Request(
Nick Harper23290b82019-05-02 00:02:569683 host_port_pair_, version_.transport_version, privacy_mode_,
9684 DEFAULT_PRIORITY, SocketTag(),
Renjiea0cb4a2c2018-09-26 23:37:309685 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9686 failed_on_default_network_callback_, callback_.callback()));
9687
9688 // Finish the stale connection.
9689 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
9690 quic::QuicSession::HANDSHAKE_CONFIRMED);
9691 base::RunLoop().RunUntilIdle();
9692 EXPECT_TRUE(HasLiveSession(host_port_pair_));
9693 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
9694
9695 // Finish host resolution and check the job is done.
9696 host_resolver_->ResolveAllPending();
9697 EXPECT_THAT(callback_.WaitForResult(), IsOk());
9698
9699 std::unique_ptr<HttpStream> stream = CreateStream(&request);
9700 EXPECT_TRUE(stream.get());
9701
9702 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Victor Vasilievbee79ea2019-05-15 01:25:489703 EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress);
Renjiea0cb4a2c2018-09-26 23:37:309704
9705 EXPECT_TRUE(quic_data.AllReadDataConsumed());
9706 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
9707 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
9708 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
9709}
9710
9711// With dns race experiment on, dns resolve async, stale used and connects
9712// async, dns finishes first, but no match
9713TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceResolveAsyncStaleAsyncNoMatch) {
Zhongyi Shi967d2f12019-02-08 20:58:539714 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:309715 host_resolver_ = std::make_unique<MockCachingHostResolver>();
9716 Initialize();
9717 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9718 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9719
9720 // Set an address in resolver for asynchronous return.
9721 host_resolver_->set_ondemand_mode(true);
9722 factory_->set_require_confirmation(true);
9723 crypto_client_stream_factory_.set_handshake_mode(
9724 MockCryptoClientStream::ZERO_RTT);
9725 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
9726 kNonCachedIPAddress, "");
9727
9728 // Set up a different address in the stale resolver cache.
9729 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
9730 HostCache::Entry entry(OK,
9731 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
9732 HostCache::Entry::SOURCE_DNS);
9733 base::TimeDelta zero;
9734 HostCache* cache = host_resolver_->GetHostCache();
9735 cache->Set(key, entry, base::TimeTicks::Now(), zero);
9736 // Expire the cache
Eric Orth37b18192019-04-22 19:09:289737 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:309738
9739 MockQuicData quic_data;
9740 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Michael Warres167db3e2019-03-01 21:38:039741 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:309742 quic_data.AddWrite(
Renjief5fcb172019-02-05 01:59:339743 SYNCHRONOUS,
9744 client_maker_.MakeConnectionClosePacket(
9745 1, true, quic::QUIC_STALE_CONNECTION_CANCELLED, "net error"));
Renjiea0cb4a2c2018-09-26 23:37:309746 quic_data.AddSocketDataToFactory(socket_factory_.get());
9747
9748 MockQuicData quic_data2;
9749 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie8d2d8d91b2018-09-29 00:29:039750 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
9751 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Renjiea0cb4a2c2018-09-26 23:37:309752 quic_data2.AddSocketDataToFactory(socket_factory_.get());
9753
9754 QuicStreamRequest request(factory_.get());
9755 EXPECT_EQ(ERR_IO_PENDING,
9756 request.Request(
Nick Harper23290b82019-05-02 00:02:569757 host_port_pair_, version_.transport_version, privacy_mode_,
9758 DEFAULT_PRIORITY, SocketTag(),
Renjiea0cb4a2c2018-09-26 23:37:309759 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9760 failed_on_default_network_callback_, callback_.callback()));
9761 // Finish dns resolution, but need to wait for stale connection.
9762 host_resolver_->ResolveAllPending();
Renjie8d2d8d91b2018-09-29 00:29:039763 base::RunLoop().RunUntilIdle();
Renjiea0cb4a2c2018-09-26 23:37:309764 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
9765 quic::QuicSession::HANDSHAKE_CONFIRMED);
9766 EXPECT_THAT(callback_.WaitForResult(), IsOk());
9767
9768 std::unique_ptr<HttpStream> stream = CreateStream(&request);
9769 EXPECT_TRUE(stream.get());
9770
9771 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Victor Vasilievbee79ea2019-05-15 01:25:489772 EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress);
Renjiea0cb4a2c2018-09-26 23:37:309773
9774 EXPECT_TRUE(quic_data.AllReadDataConsumed());
9775 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
9776 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
9777 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
9778}
9779
9780// With dns race experiment on, dns resolve returns error sync, same behavior
9781// as experiment is not on
9782TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveError) {
Zhongyi Shi967d2f12019-02-08 20:58:539783 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:309784 host_resolver_ = std::make_unique<MockCachingHostResolver>();
9785 Initialize();
9786 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9787 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9788
9789 // Set synchronous failure in resolver.
9790 host_resolver_->set_synchronous_mode(true);
9791 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
9792
9793 MockQuicData quic_data;
9794 quic_data.AddSocketDataToFactory(socket_factory_.get());
9795 QuicStreamRequest request(factory_.get());
9796
9797 EXPECT_EQ(ERR_NAME_NOT_RESOLVED,
9798 request.Request(
Nick Harper23290b82019-05-02 00:02:569799 host_port_pair_, version_.transport_version, privacy_mode_,
9800 DEFAULT_PRIORITY, SocketTag(),
Renjiea0cb4a2c2018-09-26 23:37:309801 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9802 failed_on_default_network_callback_, callback_.callback()));
9803}
9804
9805// With dns race experiment on, no cache available, dns resolve returns error
9806// async
9807TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveAsyncError) {
Zhongyi Shi967d2f12019-02-08 20:58:539808 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:309809 host_resolver_ = std::make_unique<MockCachingHostResolver>();
9810 Initialize();
9811 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9812 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9813
9814 // Set asynchronous failure in resolver.
9815 host_resolver_->set_ondemand_mode(true);
9816 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
9817
9818 MockQuicData quic_data;
9819 quic_data.AddSocketDataToFactory(socket_factory_.get());
9820 QuicStreamRequest request(factory_.get());
9821
9822 EXPECT_EQ(ERR_IO_PENDING,
9823 request.Request(
Nick Harper23290b82019-05-02 00:02:569824 host_port_pair_, version_.transport_version, privacy_mode_,
9825 DEFAULT_PRIORITY, SocketTag(),
Renjiea0cb4a2c2018-09-26 23:37:309826 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9827 failed_on_default_network_callback_, callback_.callback()));
9828
9829 // Resolve and expect result that shows the resolution error.
9830 host_resolver_->ResolveAllPending();
9831 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
9832}
9833
9834// With dns race experiment on, dns resolve async, staled used and connects
9835// sync, dns returns error and no connection is established.
9836TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleSyncHostResolveError) {
Zhongyi Shi967d2f12019-02-08 20:58:539837 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:309838 host_resolver_ = std::make_unique<MockCachingHostResolver>();
9839 Initialize();
9840 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9841 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9842
9843 // Set asynchronous failure in resolver.
9844 host_resolver_->set_ondemand_mode(true);
9845 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
9846
9847 // Set up an address in the stale cache.
9848 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
9849 HostCache::Entry entry(OK,
9850 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
9851 HostCache::Entry::SOURCE_DNS);
9852 base::TimeDelta zero;
9853 HostCache* cache = host_resolver_->GetHostCache();
9854 cache->Set(key, entry, base::TimeTicks::Now(), zero);
9855 // Expire the cache
Eric Orth37b18192019-04-22 19:09:289856 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:309857
9858 // Socket for the stale connection which is supposed to disconnect.
9859 MockQuicData quic_data;
9860 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9861 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
9862 quic_data.AddWrite(
Renjief5fcb172019-02-05 01:59:339863 SYNCHRONOUS,
9864 client_maker_.MakeConnectionClosePacket(
9865 2, true, quic::QUIC_STALE_CONNECTION_CANCELLED, "net error"));
Renjiea0cb4a2c2018-09-26 23:37:309866 quic_data.AddSocketDataToFactory(socket_factory_.get());
9867
9868 QuicStreamRequest request(factory_.get());
9869 EXPECT_EQ(ERR_IO_PENDING,
9870 request.Request(
Nick Harper23290b82019-05-02 00:02:569871 host_port_pair_, version_.transport_version, privacy_mode_,
9872 DEFAULT_PRIORITY, SocketTag(),
Renjiea0cb4a2c2018-09-26 23:37:309873 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9874 failed_on_default_network_callback_, callback_.callback()));
9875
9876 // Check that the stale connection is running.
9877 EXPECT_TRUE(HasLiveSession(host_port_pair_));
9878 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
9879
9880 // Finish host resolution.
9881 host_resolver_->ResolveAllPending();
9882 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
9883
Renjiea0cb4a2c2018-09-26 23:37:309884 EXPECT_TRUE(quic_data.AllReadDataConsumed());
9885 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
9886}
9887
9888// With dns race experiment on, dns resolve async, stale used and connection
Renjie99ec24b2019-04-26 17:44:349889// return error, then dns matches.
9890// This serves as a regression test for crbug.com/956374.
Renjiea0cb4a2c2018-09-26 23:37:309891TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleErrorDNSMatches) {
Zhongyi Shi967d2f12019-02-08 20:58:539892 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:309893 host_resolver_ = std::make_unique<MockCachingHostResolver>();
9894 Initialize();
9895 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9896 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9897
9898 // Set an address in host resolver for asynchronous return.
9899 host_resolver_->set_ondemand_mode(true);
9900 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
9901 kCachedIPAddress.ToString(), "");
9902
9903 // Set up the same address in the stale resolver cache.
9904 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
9905 HostCache::Entry entry(OK,
9906 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
9907 HostCache::Entry::SOURCE_DNS);
9908 base::TimeDelta zero;
9909 HostCache* cache = host_resolver_->GetHostCache();
9910 cache->Set(key, entry, base::TimeTicks::Now(), zero);
9911 // Expire the cache
Eric Orth37b18192019-04-22 19:09:289912 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:309913
9914 // Simulate synchronous connect failure.
9915 MockQuicData quic_data;
9916 quic_data.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
9917 quic_data.AddSocketDataToFactory(socket_factory_.get());
9918
9919 MockQuicData quic_data2;
9920 quic_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
9921 quic_data2.AddSocketDataToFactory(socket_factory_.get());
9922
9923 QuicStreamRequest request(factory_.get());
9924 EXPECT_EQ(ERR_IO_PENDING,
9925 request.Request(
Nick Harper23290b82019-05-02 00:02:569926 host_port_pair_, version_.transport_version, privacy_mode_,
9927 DEFAULT_PRIORITY, SocketTag(),
Renjiea0cb4a2c2018-09-26 23:37:309928 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9929 failed_on_default_network_callback_, callback_.callback()));
9930 EXPECT_FALSE(HasLiveSession(host_port_pair_));
9931 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
9932
9933 host_resolver_->ResolveAllPending();
9934 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_ADDRESS_IN_USE));
9935}
9936
9937// With dns race experiment on, dns resolve async, stale used and connection
9938// returns error, dns no match, new connection is established
9939TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleErrorDNSNoMatch) {
Zhongyi Shi967d2f12019-02-08 20:58:539940 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:309941 host_resolver_ = std::make_unique<MockCachingHostResolver>();
9942 Initialize();
9943 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9944 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9945
9946 // Set an address in host resolver.
9947 host_resolver_->set_ondemand_mode(true);
9948 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
9949 kNonCachedIPAddress, "");
9950
9951 // Set up a different address in stale resolver cache.
9952 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
9953 HostCache::Entry entry(OK,
9954 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
9955 HostCache::Entry::SOURCE_DNS);
9956 base::TimeDelta zero;
9957 HostCache* cache = host_resolver_->GetHostCache();
9958 cache->Set(key, entry, base::TimeTicks::Now(), zero);
9959 // Expire the cache
Eric Orth37b18192019-04-22 19:09:289960 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:309961
9962 // Add failure for the stale connection.
9963 MockQuicData quic_data;
9964 quic_data.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
9965 quic_data.AddSocketDataToFactory(socket_factory_.get());
9966
9967 MockQuicData quic_data2;
9968 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9969 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
9970 quic_data2.AddSocketDataToFactory(socket_factory_.get());
9971
9972 QuicStreamRequest request(factory_.get());
9973 EXPECT_EQ(ERR_IO_PENDING,
9974 request.Request(
Nick Harper23290b82019-05-02 00:02:569975 host_port_pair_, version_.transport_version, privacy_mode_,
9976 DEFAULT_PRIORITY, SocketTag(),
Renjiea0cb4a2c2018-09-26 23:37:309977 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9978 failed_on_default_network_callback_, callback_.callback()));
9979
9980 // Check that the stale connection fails.
9981 EXPECT_FALSE(HasLiveSession(host_port_pair_));
9982 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
9983
9984 // Finish host resolution and check the job finishes ok.
9985 host_resolver_->ResolveAllPending();
9986 EXPECT_THAT(callback_.WaitForResult(), IsOk());
9987
9988 std::unique_ptr<HttpStream> stream = CreateStream(&request);
9989 EXPECT_TRUE(stream.get());
9990
9991 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
9992
Victor Vasilievbee79ea2019-05-15 01:25:489993 EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress);
Renjiea0cb4a2c2018-09-26 23:37:309994
9995 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
9996 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
9997}
9998
9999// With dns race experiment on, dns resolve async, stale used and connection
10000// returns error, dns no match, new connection error
10001TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleErrorDNSNoMatchError) {
Zhongyi Shi967d2f12019-02-08 20:58:5310002 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010003 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10004 Initialize();
10005 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10006 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10007
10008 // Set an address in host resolver asynchronously.
10009 host_resolver_->set_ondemand_mode(true);
10010 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10011 kNonCachedIPAddress, "");
10012
10013 // Set up a different address in the stale cache.
10014 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10015 HostCache::Entry entry(OK,
10016 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10017 HostCache::Entry::SOURCE_DNS);
10018 base::TimeDelta zero;
10019 HostCache* cache = host_resolver_->GetHostCache();
10020 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10021 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810022 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010023
10024 // Add failure for stale connection.
10025 MockQuicData quic_data;
10026 quic_data.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
10027 quic_data.AddSocketDataToFactory(socket_factory_.get());
10028
10029 // Add failure for resolved dns connection.
10030 MockQuicData quic_data2;
10031 quic_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
10032 quic_data2.AddSocketDataToFactory(socket_factory_.get());
10033
10034 QuicStreamRequest request(factory_.get());
10035 EXPECT_EQ(ERR_IO_PENDING,
10036 request.Request(
Nick Harper23290b82019-05-02 00:02:5610037 host_port_pair_, version_.transport_version, privacy_mode_,
10038 DEFAULT_PRIORITY, SocketTag(),
Renjiea0cb4a2c2018-09-26 23:37:3010039 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10040 failed_on_default_network_callback_, callback_.callback()));
10041
10042 // Check the stale connection fails.
10043 EXPECT_FALSE(HasLiveSession(host_port_pair_));
10044 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10045
10046 // Check the resolved dns connection fails.
10047 host_resolver_->ResolveAllPending();
10048 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_ADDRESS_IN_USE));
10049}
10050
10051// With dns race experiment on, dns resolve async and stale connect async, dns
10052// resolve returns error and then preconnect finishes
10053TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceResolveAsyncErrorStaleAsync) {
Zhongyi Shi967d2f12019-02-08 20:58:5310054 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010055 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10056 Initialize();
10057 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10058 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10059
10060 // Add asynchronous failure in host resolver.
10061 host_resolver_->set_ondemand_mode(true);
10062 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
10063 factory_->set_require_confirmation(true);
10064 crypto_client_stream_factory_.set_handshake_mode(
10065 MockCryptoClientStream::ZERO_RTT);
10066
10067 // Set up an address in stale resolver cache.
10068 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10069 HostCache::Entry entry(OK,
10070 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10071 HostCache::Entry::SOURCE_DNS);
10072 base::TimeDelta zero;
10073 HostCache* cache = host_resolver_->GetHostCache();
10074 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10075 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810076 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010077
10078 // Socket data for stale connection which is supposed to disconnect.
10079 MockQuicData quic_data;
10080 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Michael Warres167db3e2019-03-01 21:38:0310081 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:3010082 quic_data.AddWrite(
Renjief5fcb172019-02-05 01:59:3310083 SYNCHRONOUS,
10084 client_maker_.MakeConnectionClosePacket(
10085 1, true, quic::QUIC_STALE_CONNECTION_CANCELLED, "net error"));
Renjiea0cb4a2c2018-09-26 23:37:3010086 quic_data.AddSocketDataToFactory(socket_factory_.get());
10087
10088 QuicStreamRequest request(factory_.get());
10089 EXPECT_EQ(ERR_IO_PENDING,
10090 request.Request(
Nick Harper23290b82019-05-02 00:02:5610091 host_port_pair_, version_.transport_version, privacy_mode_,
10092 DEFAULT_PRIORITY, SocketTag(),
Renjiea0cb4a2c2018-09-26 23:37:3010093 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10094 failed_on_default_network_callback_, callback_.callback()));
10095
10096 // host resolution returned but stale connection hasn't finished yet.
10097 host_resolver_->ResolveAllPending();
10098 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
10099
10100 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10101 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10102}
10103
10104// With dns race experiment on, dns resolve async and stale connect async, dns
Renjiea0cb4a2c2018-09-26 23:37:3010105// resolve returns error and then preconnect fails.
10106TEST_P(QuicStreamFactoryTest,
10107 ResultAfterDNSRaceResolveAsyncErrorStaleAsyncError) {
Zhongyi Shi967d2f12019-02-08 20:58:5310108 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010109 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10110 Initialize();
10111 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10112 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10113
10114 // Add asynchronous failure to host resolver.
10115 host_resolver_->set_ondemand_mode(true);
10116 factory_->set_require_confirmation(true);
10117 crypto_client_stream_factory_.set_handshake_mode(
10118 MockCryptoClientStream::ZERO_RTT);
10119 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
10120
10121 // Set up an address in stale resolver cache.
10122 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10123 HostCache::Entry entry(OK,
10124 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10125 HostCache::Entry::SOURCE_DNS);
10126 base::TimeDelta zero;
10127 HostCache* cache = host_resolver_->GetHostCache();
10128 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10129 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810130 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010131
10132 MockQuicData quic_data;
10133 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Michael Warres167db3e2019-03-01 21:38:0310134 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:3010135 quic_data.AddWrite(
Renjief5fcb172019-02-05 01:59:3310136 SYNCHRONOUS,
10137 client_maker_.MakeConnectionClosePacket(
10138 1, true, quic::QUIC_STALE_CONNECTION_CANCELLED, "net error"));
Renjiea0cb4a2c2018-09-26 23:37:3010139 quic_data.AddSocketDataToFactory(socket_factory_.get());
10140
10141 QuicStreamRequest request(factory_.get());
10142 EXPECT_EQ(ERR_IO_PENDING,
10143 request.Request(
Nick Harper23290b82019-05-02 00:02:5610144 host_port_pair_, version_.transport_version, privacy_mode_,
10145 DEFAULT_PRIORITY, SocketTag(),
Renjiea0cb4a2c2018-09-26 23:37:3010146 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10147 failed_on_default_network_callback_, callback_.callback()));
10148
10149 // Host Resolution returns failure but stale connection hasn't finished.
10150 host_resolver_->ResolveAllPending();
10151
10152 // Check that the final error is on resolution failure.
10153 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
10154
10155 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10156}
10157
10158// With dns race experiment on, test that host resolution callback behaves
10159// normal as experiment is not on
10160TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveAsync) {
Zhongyi Shi967d2f12019-02-08 20:58:5310161 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010162 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10163 Initialize();
10164 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10165 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10166
10167 host_resolver_->set_ondemand_mode(true);
10168 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10169 kNonCachedIPAddress, "");
10170
10171 MockQuicData quic_data;
10172 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10173 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10174 quic_data.AddSocketDataToFactory(socket_factory_.get());
10175
10176 QuicStreamRequest request(factory_.get());
10177 EXPECT_EQ(ERR_IO_PENDING,
10178 request.Request(
Nick Harper23290b82019-05-02 00:02:5610179 host_port_pair_, version_.transport_version, privacy_mode_,
10180 DEFAULT_PRIORITY, SocketTag(),
Renjiea0cb4a2c2018-09-26 23:37:3010181 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10182 failed_on_default_network_callback_, callback_.callback()));
10183
10184 // Check that expect_on_host_resolution_ is properlly set.
10185 TestCompletionCallback host_resolution_callback;
10186 EXPECT_TRUE(
10187 request.WaitForHostResolution(host_resolution_callback.callback()));
10188 base::RunLoop().RunUntilIdle();
10189 EXPECT_FALSE(host_resolution_callback.have_result());
10190
10191 host_resolver_->ResolveAllPending();
10192 EXPECT_THAT(host_resolution_callback.WaitForResult(), IsOk());
10193
10194 // Check that expect_on_host_resolution_ is flipped back.
10195 EXPECT_FALSE(
10196 request.WaitForHostResolution(host_resolution_callback.callback()));
10197
10198 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10199 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10200}
10201
Renjiea0522f062019-04-29 18:52:2110202TEST_P(QuicStreamFactoryTest, ConfigInitialRttForHandshake) {
10203 int kInitialRtt = 400;
10204 test_params_.quic_initial_rtt_for_handshake_milliseconds = kInitialRtt;
10205 crypto_client_stream_factory_.set_handshake_mode(
10206 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
10207 Initialize();
10208 factory_->set_require_confirmation(true);
10209 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10210 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10211
10212 // Using a testing task runner so that we can control time.
10213 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
10214
10215 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
10216 QuicStreamFactoryPeer::SetAlarmFactory(
10217 factory_.get(),
10218 std::make_unique<QuicChromiumAlarmFactory>(task_runner.get(), &clock_));
10219
10220 MockQuicData socket_data;
10221 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10222 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
10223 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(2));
10224 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
10225 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(3, 0));
10226 socket_data.AddSocketDataToFactory(socket_factory_.get());
10227
10228 QuicStreamRequest request(factory_.get());
10229 EXPECT_EQ(ERR_IO_PENDING,
10230 request.Request(
Nick Harper23290b82019-05-02 00:02:5610231 host_port_pair_, version_.transport_version, privacy_mode_,
10232 DEFAULT_PRIORITY, SocketTag(),
Renjiea0522f062019-04-29 18:52:2110233 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10234 failed_on_default_network_callback_, callback_.callback()));
10235 base::RunLoop().RunUntilIdle();
10236
10237 EXPECT_FALSE(HasActiveSession(host_port_pair_));
10238 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10239
10240 // The pending task is scheduled for handshake timeout retransmission,
10241 // which is 2 * 400ms for v99 and 1.5 * 400ms for others.
Nick Harper23290b82019-05-02 00:02:5610242 int handshake_timeout = version_.transport_version == quic::QUIC_VERSION_99
10243 ? 2 * kInitialRtt
10244 : 1.5 * kInitialRtt;
Renjiea0522f062019-04-29 18:52:2110245 EXPECT_EQ(base::TimeDelta::FromMilliseconds(handshake_timeout),
10246 task_runner->NextPendingTaskDelay());
10247
10248 // The alarm factory dependes on |clock_|, so clock is advanced to trigger
10249 // retransmission alarm.
10250 clock_.AdvanceTime(
10251 quic::QuicTime::Delta::FromMilliseconds(handshake_timeout));
10252 task_runner->FastForwardBy(
10253 base::TimeDelta::FromMilliseconds(handshake_timeout));
10254
10255 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
10256 quic::QuicSession::HANDSHAKE_CONFIRMED);
10257
10258 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10259
10260 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
10261 EXPECT_EQ(400000u, session->config()->GetInitialRoundTripTimeUsToSend());
10262 EXPECT_TRUE(socket_data.AllReadDataConsumed());
10263 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
10264}
10265
Paul Jensen8e3c5d32018-02-19 17:06:3310266// Test that QuicStreamRequests with similar and different tags results in
10267// reused and unique QUIC streams using appropriately tagged sockets.
10268TEST_P(QuicStreamFactoryTest, Tag) {
10269 MockTaggingClientSocketFactory* socket_factory =
10270 new MockTaggingClientSocketFactory();
10271 socket_factory_.reset(socket_factory);
10272 Initialize();
10273 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10274 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10275
10276 // Prepare to establish two QUIC sessions.
10277 MockQuicData socket_data;
10278 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:4310279 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Paul Jensen8e3c5d32018-02-19 17:06:3310280 socket_data.AddSocketDataToFactory(socket_factory_.get());
10281 MockQuicData socket_data2;
10282 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:4310283 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Paul Jensen8e3c5d32018-02-19 17:06:3310284 socket_data2.AddSocketDataToFactory(socket_factory_.get());
10285
10286#if defined(OS_ANDROID)
10287 SocketTag tag1(SocketTag::UNSET_UID, 0x12345678);
10288 SocketTag tag2(getuid(), 0x87654321);
10289#else
10290 // On non-Android platforms we can only use the default constructor.
10291 SocketTag tag1, tag2;
10292#endif
10293
10294 // Request a stream with |tag1|.
10295 QuicStreamRequest request1(factory_.get());
Zhongyi Shia6b68d112018-09-24 07:49:0310296 int rv = request1.Request(
Nick Harper23290b82019-05-02 00:02:5610297 host_port_pair_, version_.transport_version, privacy_mode_,
10298 DEFAULT_PRIORITY, tag1,
Zhongyi Shia6b68d112018-09-24 07:49:0310299 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10300 failed_on_default_network_callback_, callback_.callback());
Paul Jensen8e3c5d32018-02-19 17:06:3310301 EXPECT_THAT(callback_.GetResult(rv), IsOk());
10302 EXPECT_EQ(socket_factory->GetLastProducedUDPSocket()->tag(), tag1);
10303 EXPECT_TRUE(socket_factory->GetLastProducedUDPSocket()
10304 ->tagged_before_data_transferred());
10305 std::unique_ptr<QuicChromiumClientSession::Handle> stream1 =
10306 request1.ReleaseSessionHandle();
10307 EXPECT_TRUE(stream1);
10308 EXPECT_TRUE(stream1->IsConnected());
10309
10310 // Request a stream with |tag1| and verify underlying session is reused.
10311 QuicStreamRequest request2(factory_.get());
Zhongyi Shia6b68d112018-09-24 07:49:0310312 rv = request2.Request(
Nick Harper23290b82019-05-02 00:02:5610313 host_port_pair_, version_.transport_version, privacy_mode_,
10314 DEFAULT_PRIORITY, tag1,
Zhongyi Shia6b68d112018-09-24 07:49:0310315 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10316 failed_on_default_network_callback_, callback_.callback());
Paul Jensen8e3c5d32018-02-19 17:06:3310317 EXPECT_THAT(callback_.GetResult(rv), IsOk());
10318 std::unique_ptr<QuicChromiumClientSession::Handle> stream2 =
10319 request2.ReleaseSessionHandle();
10320 EXPECT_TRUE(stream2);
10321 EXPECT_TRUE(stream2->IsConnected());
10322 EXPECT_TRUE(stream2->SharesSameSession(*stream1));
10323
10324 // Request a stream with |tag2| and verify a new session is created.
10325 QuicStreamRequest request3(factory_.get());
Zhongyi Shia6b68d112018-09-24 07:49:0310326 rv = request3.Request(
Nick Harper23290b82019-05-02 00:02:5610327 host_port_pair_, version_.transport_version, privacy_mode_,
10328 DEFAULT_PRIORITY, tag2,
Zhongyi Shia6b68d112018-09-24 07:49:0310329 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10330 failed_on_default_network_callback_, callback_.callback());
Paul Jensen8e3c5d32018-02-19 17:06:3310331 EXPECT_THAT(callback_.GetResult(rv), IsOk());
10332 EXPECT_EQ(socket_factory->GetLastProducedUDPSocket()->tag(), tag2);
10333 EXPECT_TRUE(socket_factory->GetLastProducedUDPSocket()
10334 ->tagged_before_data_transferred());
10335 std::unique_ptr<QuicChromiumClientSession::Handle> stream3 =
10336 request3.ReleaseSessionHandle();
10337 EXPECT_TRUE(stream3);
10338 EXPECT_TRUE(stream3->IsConnected());
10339#if defined(OS_ANDROID)
10340 EXPECT_FALSE(stream3->SharesSameSession(*stream1));
10341#else
10342 // Same tag should reuse session.
10343 EXPECT_TRUE(stream3->SharesSameSession(*stream1));
10344#endif
10345}
10346
[email protected]e13201d82012-12-12 05:00:3210347} // namespace test
[email protected]e13201d82012-12-12 05:00:3210348} // namespace net