blob: 6266cbe7d1a3db9c5c96c7b7dbb674882f65a5cb [file] [log] [blame]
[email protected]e13201d82012-12-12 05:00:321// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Ryan Hamiltona3ee93a72018-08-01 22:03:085#include "net/quic/quic_stream_factory.h"
[email protected]e13201d82012-12-12 05:00:326
avib3635452016-10-21 18:33:537#include <memory>
bnc359ed2a2016-04-29 20:43:458#include <ostream>
bnc086b39e12016-06-24 13:05:269#include <utility>
bnc359ed2a2016-04-29 20:43:4510
msramek992625ec2016-08-04 18:33:5811#include "base/bind.h"
12#include "base/callback.h"
xunjieli48e4f102017-04-11 23:06:5313#include "base/macros.h"
[email protected]e13201d82012-12-12 05:00:3214#include "base/run_loop.h"
[email protected]fc9be5802013-06-11 10:56:5115#include "base/strings/string_util.h"
Zhongyi Shic16b4102019-02-12 00:37:4016#include "base/test/simple_test_tick_clock.h"
Zhongyi Shic4823bd2018-04-27 00:49:1917#include "base/test/test_mock_time_task_runner.h"
Paul Jensen8e3c5d32018-02-19 17:06:3318#include "build/build_config.h"
mgershaf9a9232017-04-13 20:19:0319#include "net/base/mock_network_change_notifier.h"
Matt Menke26e41542019-06-05 01:09:5120#include "net/base/network_isolation_key.h"
rsleevid6de8302016-06-21 01:33:2021#include "net/cert/ct_policy_enforcer.h"
Ryan Sleevi987d2d92017-12-19 19:22:1422#include "net/cert/do_nothing_ct_verifier.h"
23#include "net/cert/mock_cert_verifier.h"
[email protected]f2cb3cf2013-03-21 01:40:5324#include "net/dns/mock_host_resolver.h"
[email protected]e13201d82012-12-12 05:00:3225#include "net/http/http_response_headers.h"
26#include "net/http/http_response_info.h"
rtenneti8332ba52015-09-17 19:33:4127#include "net/http/http_server_properties_impl.h"
[email protected]e13201d82012-12-12 05:00:3228#include "net/http/http_util.h"
[email protected]080b77932014-08-04 01:22:4629#include "net/http/transport_security_state.h"
Matt Mueller230996f12018-10-22 19:39:4430#include "net/http/transport_security_state_test_util.h"
Victor Vasilievbee79ea2019-05-15 01:25:4831#include "net/quic/address_utils.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0832#include "net/quic/crypto/proof_verifier_chromium.h"
33#include "net/quic/mock_crypto_client_stream_factory.h"
34#include "net/quic/mock_quic_data.h"
35#include "net/quic/properties_based_quic_server_info.h"
Renjiea0522f062019-04-29 18:52:2136#include "net/quic/quic_chromium_alarm_factory.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0837#include "net/quic/quic_http_stream.h"
38#include "net/quic/quic_http_utils.h"
39#include "net/quic/quic_server_info.h"
40#include "net/quic/quic_stream_factory_peer.h"
41#include "net/quic/quic_test_packet_maker.h"
Ryan Hamilton0d65a8c2019-06-07 00:46:0242#include "net/quic/quic_test_packet_printer.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0843#include "net/quic/test_task_runner.h"
bnc3472afd2016-11-17 15:27:2144#include "net/socket/next_proto.h"
[email protected]e13201d82012-12-12 05:00:3245#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5846#include "net/spdy/spdy_session_test_util.h"
47#include "net/spdy/spdy_test_util_common.h"
[email protected]eed749f92013-12-23 18:57:3848#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0149#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4350#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:0151#include "net/test/test_with_scoped_task_environment.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5152#include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h"
53#include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h"
54#include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
55#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
56#include "net/third_party/quiche/src/quic/core/http/quic_client_promised_info.h"
57#include "net/third_party/quiche/src/quic/core/quic_utils.h"
58#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
59#include "net/third_party/quiche/src/quic/test_tools/mock_clock.h"
60#include "net/third_party/quiche/src/quic/test_tools/mock_random.h"
61#include "net/third_party/quiche/src/quic/test_tools/quic_config_peer.h"
62#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h"
63#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
Victor Vasiliev27cc7712019-01-24 11:50:1464#include "net/third_party/quiche/src/spdy/core/spdy_test_utils.h"
Ramin Halavati683bcaa92018-02-14 08:42:3965#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
robpercival214763f2016-07-01 23:27:0166#include "testing/gmock/include/gmock/gmock.h"
[email protected]e13201d82012-12-12 05:00:3267#include "testing/gtest/include/gtest/gtest.h"
msramek992625ec2016-08-04 18:33:5868#include "url/gurl.h"
[email protected]e13201d82012-12-12 05:00:3269
[email protected]6e12d702013-11-13 00:17:1770using std::string;
[email protected]6e12d702013-11-13 00:17:1771
[email protected]e13201d82012-12-12 05:00:3272namespace net {
jri7e636642016-01-14 06:57:0873
nharper642ae4b2016-06-30 00:40:3674namespace {
75
76class MockSSLConfigService : public SSLConfigService {
77 public:
78 MockSSLConfigService() {}
Ryan Sleevib8449e02018-07-15 04:31:0779 ~MockSSLConfigService() override {}
nharper642ae4b2016-06-30 00:40:3680
81 void GetSSLConfig(SSLConfig* config) override { *config = config_; }
82
Nick Harper89bc7212018-07-31 19:07:5783 bool CanShareConnectionWithClientCerts(
84 const std::string& hostname) const override {
85 return false;
86 }
87
nharper642ae4b2016-06-30 00:40:3688 private:
nharper642ae4b2016-06-30 00:40:3689 SSLConfig config_;
90};
91
92} // namespace
93
[email protected]e13201d82012-12-12 05:00:3294namespace test {
95
[email protected]3c772402013-12-18 21:38:1196namespace {
bnc359ed2a2016-04-29 20:43:4597
98enum DestinationType {
99 // In pooling tests with two requests for different origins to the same
100 // destination, the destination should be
101 SAME_AS_FIRST, // the same as the first origin,
102 SAME_AS_SECOND, // the same as the second origin, or
103 DIFFERENT, // different from both.
104};
105
rch6faa4d42016-01-05 20:48:43106const char kDefaultServerHostName[] = "www.example.org";
107const char kServer2HostName[] = "mail.example.org";
bnc359ed2a2016-04-29 20:43:45108const char kDifferentHostname[] = "different.example.com";
[email protected]3c772402013-12-18 21:38:11109const int kDefaultServerPort = 443;
ckrasic3865ee0f2016-02-29 22:04:56110const char kDefaultUrl[] = "https://www.example.org/";
111const char kServer2Url[] = "https://mail.example.org/";
112const char kServer3Url[] = "https://docs.example.org/";
113const char kServer4Url[] = "https://images.example.org/";
Zhongyi Shic4823bd2018-04-27 00:49:19114const int kDefaultRTTMilliSecs = 300;
115const size_t kMinRetryTimeForDefaultNetworkSecs = 1;
Zhongyi Shib1b1fa42018-06-19 23:13:47116const size_t kWaitTimeForNewNetworkSecs = 10;
Renjiea0cb4a2c2018-09-26 23:37:30117const IPAddress kCachedIPAddress = IPAddress(192, 168, 0, 2);
118const char kNonCachedIPAddress[] = "192.168.0.1";
rtenneti14abd312015-02-06 21:56:01119
bnc359ed2a2016-04-29 20:43:45120// Run QuicStreamFactoryTest instances with all value combinations of version
121// and enable_connection_racting.
rtenneti14abd312015-02-06 21:56:01122struct TestParams {
bnc359ed2a2016-04-29 20:43:45123 friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
Nick Harper23290b82019-05-02 00:02:56124 os << "{ version: " << ParsedQuicVersionToString(p.version)
Yixin Wang079ad542018-01-11 04:06:05125 << ", client_headers_include_h2_stream_dependency: "
126 << p.client_headers_include_h2_stream_dependency << " }";
rtenneti14abd312015-02-06 21:56:01127 return os;
128 }
129
Nick Harper23290b82019-05-02 00:02:56130 quic::ParsedQuicVersion version;
Yixin Wang079ad542018-01-11 04:06:05131 bool client_headers_include_h2_stream_dependency;
rtenneti14abd312015-02-06 21:56:01132};
133
rch872e00e2016-12-02 02:48:18134std::vector<TestParams> GetTestParams() {
135 std::vector<TestParams> params;
Nick Harper23290b82019-05-02 00:02:56136 quic::ParsedQuicVersionVector all_supported_versions =
Ryan Hamilton9f2eac32019-06-27 03:15:54137 quic::AllSupportedVersions();
Yixin Wang079ad542018-01-11 04:06:05138 for (const auto& version : all_supported_versions) {
Ryan Hamilton9f2eac32019-06-27 03:15:54139 // TODO(rch): crbug.com/978745 - Make this work with TLS
140 if (version.handshake_protocol != quic::PROTOCOL_TLS1_3) {
141 params.push_back(TestParams{version, false});
142 params.push_back(TestParams{version, true});
143 }
Yixin Wang079ad542018-01-11 04:06:05144 }
bnc359ed2a2016-04-29 20:43:45145 return params;
146}
147
148// Run QuicStreamFactoryWithDestinationTest instances with all value
149// combinations of version, enable_connection_racting, and destination_type.
150struct PoolingTestParams {
151 friend std::ostream& operator<<(std::ostream& os,
152 const PoolingTestParams& p) {
Nick Harper23290b82019-05-02 00:02:56153 os << "{ version: " << ParsedQuicVersionToString(p.version)
bnc359ed2a2016-04-29 20:43:45154 << ", destination_type: ";
155 switch (p.destination_type) {
156 case SAME_AS_FIRST:
157 os << "SAME_AS_FIRST";
158 break;
159 case SAME_AS_SECOND:
160 os << "SAME_AS_SECOND";
161 break;
162 case DIFFERENT:
163 os << "DIFFERENT";
164 break;
165 }
Yixin Wang079ad542018-01-11 04:06:05166 os << ", client_headers_include_h2_stream_dependency: "
167 << p.client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45168 os << " }";
169 return os;
170 }
171
Nick Harper23290b82019-05-02 00:02:56172 quic::ParsedQuicVersion version;
bnc359ed2a2016-04-29 20:43:45173 DestinationType destination_type;
Yixin Wang079ad542018-01-11 04:06:05174 bool client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45175};
176
rch872e00e2016-12-02 02:48:18177std::vector<PoolingTestParams> GetPoolingTestParams() {
178 std::vector<PoolingTestParams> params;
Nick Harper23290b82019-05-02 00:02:56179 quic::ParsedQuicVersionVector all_supported_versions =
Ryan Hamilton9f2eac32019-06-27 03:15:54180 quic::AllSupportedVersions();
Nick Harper23290b82019-05-02 00:02:56181 for (const quic::ParsedQuicVersion version : all_supported_versions) {
Yixin Wang079ad542018-01-11 04:06:05182 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, false});
183 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, true});
184 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, false});
185 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, true});
186 params.push_back(PoolingTestParams{version, DIFFERENT, false});
187 params.push_back(PoolingTestParams{version, DIFFERENT, true});
rtenneti14abd312015-02-06 21:56:01188 }
189 return params;
190}
191
bnc912a04b2016-04-20 14:19:50192} // namespace
[email protected]3c772402013-12-18 21:38:11193
bnc359ed2a2016-04-29 20:43:45194class QuicHttpStreamPeer {
195 public:
rchf0b18c8a2017-05-05 19:31:57196 static QuicChromiumClientSession::Handle* GetSessionHandle(
197 HttpStream* stream) {
198 return static_cast<QuicHttpStream*>(stream)->quic_session();
bnc359ed2a2016-04-29 20:43:45199 }
200};
201
Zhongyi Shi5f587cc2017-11-21 23:24:17202// TestConnectionMigrationSocketFactory will vend sockets with incremental port
203// number.
204class TestConnectionMigrationSocketFactory : public MockClientSocketFactory {
205 public:
206 TestConnectionMigrationSocketFactory() : next_source_port_num_(1u) {}
207 ~TestConnectionMigrationSocketFactory() override {}
208
209 std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
210 DatagramSocket::BindType bind_type,
Zhongyi Shi5f587cc2017-11-21 23:24:17211 NetLog* net_log,
212 const NetLogSource& source) override {
213 SocketDataProvider* data_provider = mock_data().GetNext();
214 std::unique_ptr<MockUDPClientSocket> socket(
215 new MockUDPClientSocket(data_provider, net_log));
216 socket->set_source_port(next_source_port_num_++);
217 return std::move(socket);
218 }
219
220 private:
221 uint16_t next_source_port_num_;
222
223 DISALLOW_COPY_AND_ASSIGN(TestConnectionMigrationSocketFactory);
224};
225
Bence Béky98447b12018-05-08 03:14:01226class QuicStreamFactoryTestBase : public WithScopedTaskEnvironment {
[email protected]e13201d82012-12-12 05:00:32227 protected:
Nick Harper23290b82019-05-02 00:02:56228 QuicStreamFactoryTestBase(quic::ParsedQuicVersion version,
Yixin Wang079ad542018-01-11 04:06:05229 bool client_headers_include_h2_stream_dependency)
Renjiea0cb4a2c2018-09-26 23:37:30230 : host_resolver_(new MockHostResolver),
231 ssl_config_service_(new MockSSLConfigService),
Zhongyi Shi5f587cc2017-11-21 23:24:17232 socket_factory_(new MockClientSocketFactory),
nharper642ae4b2016-06-30 00:40:36233 random_generator_(0),
rchbf4c26d2017-04-16 23:17:55234 runner_(new TestTaskRunner(&clock_)),
bnc359ed2a2016-04-29 20:43:45235 version_(version),
David Schinazic8281052019-01-24 06:14:17236 client_maker_(
237 version_,
238 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
239 &clock_,
240 kDefaultServerHostName,
241 quic::Perspective::IS_CLIENT,
Zhongyi Shi967d2f12019-02-08 20:58:53242 client_headers_include_h2_stream_dependency),
David Schinazic8281052019-01-24 06:14:17243 server_maker_(
244 version_,
245 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
246 &clock_,
247 kDefaultServerHostName,
248 quic::Perspective::IS_SERVER,
249 false),
Ryan Sleevi987d2d92017-12-19 19:22:14250 cert_verifier_(std::make_unique<MockCertVerifier>()),
Ryan Sleevi987d2d92017-12-19 19:22:14251 cert_transparency_verifier_(std::make_unique<DoNothingCTVerifier>()),
jri7e636642016-01-14 06:57:08252 scoped_mock_network_change_notifier_(nullptr),
jri7046038f2015-10-22 00:29:26253 factory_(nullptr),
[email protected]bf4ea2f2014-03-10 22:57:53254 host_port_pair_(kDefaultServerHostName, kDefaultServerPort),
ckrasic3865ee0f2016-02-29 22:04:56255 url_(kDefaultUrl),
256 url2_(kServer2Url),
257 url3_(kServer3Url),
258 url4_(kServer4Url),
jri7046038f2015-10-22 00:29:26259 privacy_mode_(PRIVACY_MODE_DISABLED),
Zhongyi Shia6b68d112018-09-24 07:49:03260 failed_on_default_network_callback_(base::BindRepeating(
261 &QuicStreamFactoryTestBase::OnFailedOnDefaultNetwork,
262 base::Unretained(this))),
263 failed_on_default_network_(false),
Zhongyi Shi967d2f12019-02-08 20:58:53264 store_server_configs_in_properties_(false) {
265 test_params_.quic_headers_include_h2_stream_dependency =
266 client_headers_include_h2_stream_dependency;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52267 clock_.AdvanceTime(quic::QuicTime::Delta::FromSeconds(1));
bnc359ed2a2016-04-29 20:43:45268 }
269
jri7046038f2015-10-22 00:29:26270 void Initialize() {
bnc359ed2a2016-04-29 20:43:45271 DCHECK(!factory_);
jri7046038f2015-10-22 00:29:26272 factory_.reset(new QuicStreamFactory(
Renjiea0cb4a2c2018-09-26 23:37:30273 net_log_.net_log(), host_resolver_.get(), ssl_config_service_.get(),
Zhongyi Shi5f587cc2017-11-21 23:24:17274 socket_factory_.get(), &http_server_properties_, cert_verifier_.get(),
Nick Harperecf319d2018-10-16 07:58:54275 &ct_policy_enforcer_, &transport_security_state_,
276 cert_transparency_verifier_.get(),
jri7046038f2015-10-22 00:29:26277 /*SocketPerformanceWatcherFactory*/ nullptr,
rchbf4c26d2017-04-16 23:17:55278 &crypto_client_stream_factory_, &random_generator_, &clock_,
Zhongyi Shi967d2f12019-02-08 20:58:53279 test_params_.quic_max_packet_length, test_params_.quic_user_agent_id,
280 store_server_configs_in_properties_,
281 test_params_.quic_close_sessions_on_ip_change,
282 test_params_.quic_goaway_sessions_on_ip_change,
283 test_params_.mark_quic_broken_when_network_blackholes,
284 test_params_.quic_idle_connection_timeout_seconds,
285 test_params_.quic_reduced_ping_timeout_seconds,
Zhongyi Shie01f2db2019-02-22 19:53:23286 test_params_.quic_retransmittable_on_wire_timeout_milliseconds,
Zhongyi Shi967d2f12019-02-08 20:58:53287 test_params_.quic_max_time_before_crypto_handshake_seconds,
288 test_params_.quic_max_idle_time_before_crypto_handshake_seconds,
289 test_params_.quic_migrate_sessions_on_network_change_v2,
290 test_params_.quic_migrate_sessions_early_v2,
291 test_params_.quic_retry_on_alternate_network_before_handshake,
Zhongyi Shi32fe14d42019-02-28 00:25:36292 test_params_.quic_migrate_idle_sessions,
Zhongyi Shic16b4102019-02-12 00:37:40293 test_params_.quic_idle_session_migration_period,
Zhongyi Shi967d2f12019-02-08 20:58:53294 test_params_.quic_max_time_on_non_default_network,
295 test_params_.quic_max_migrations_to_non_default_network_on_write_error,
296 test_params_
297 .quic_max_migrations_to_non_default_network_on_path_degrading,
298 test_params_.quic_allow_server_migration,
299 test_params_.quic_race_stale_dns_on_connection,
300 test_params_.quic_go_away_on_path_degrading,
301 test_params_.quic_race_cert_verification,
302 test_params_.quic_estimate_initial_rtt,
303 test_params_.quic_headers_include_h2_stream_dependency,
304 test_params_.quic_connection_options,
305 test_params_.quic_client_connection_options,
Renjiea0522f062019-04-29 18:52:21306 test_params_.quic_enable_socket_recv_optimization,
307 test_params_.quic_initial_rtt_for_handshake_milliseconds));
[email protected]e13201d82012-12-12 05:00:32308 }
309
Zhongyi Shi5f587cc2017-11-21 23:24:17310 void InitializeConnectionMigrationV2Test(
311 NetworkChangeNotifier::NetworkList connected_networks) {
312 scoped_mock_network_change_notifier_.reset(
313 new ScopedMockNetworkChangeNotifier());
314 MockNetworkChangeNotifier* mock_ncn =
315 scoped_mock_network_change_notifier_->mock_network_change_notifier();
316 mock_ncn->ForceNetworkHandlesSupported();
317 mock_ncn->SetConnectedNetworksList(connected_networks);
Zhongyi Shi967d2f12019-02-08 20:58:53318 test_params_.quic_migrate_sessions_on_network_change_v2 = true;
319 test_params_.quic_migrate_sessions_early_v2 = true;
Zhongyi Shi5f587cc2017-11-21 23:24:17320 socket_factory_.reset(new TestConnectionMigrationSocketFactory);
321 Initialize();
322 }
323
Yixin Wang7891a39d2017-11-08 20:59:24324 std::unique_ptr<HttpStream> CreateStream(QuicStreamRequest* request) {
325 std::unique_ptr<QuicChromiumClientSession::Handle> session =
326 request->ReleaseSessionHandle();
327 if (!session || !session->IsConnected())
328 return nullptr;
329
330 return std::make_unique<QuicHttpStream>(std::move(session));
331 }
332
bnccb7ff3c2015-05-21 20:51:55333 bool HasActiveSession(const HostPortPair& host_port_pair) {
Ryan Hamilton4f0b26e2018-06-27 23:52:32334 quic::QuicServerId server_id(host_port_pair.host(), host_port_pair.port(),
335 false);
bnc5fdc07162016-05-23 17:36:03336 return QuicStreamFactoryPeer::HasActiveSession(factory_.get(), server_id);
bnccb7ff3c2015-05-21 20:51:55337 }
338
Renjiea0cb4a2c2018-09-26 23:37:30339 bool HasLiveSession(const HostPortPair& host_port_pair) {
340 quic::QuicServerId server_id(host_port_pair.host(), host_port_pair.port(),
341 false);
342 return QuicStreamFactoryPeer::HasLiveSession(factory_.get(), host_port_pair,
343 server_id);
344 }
345
zhongyi363c91c2017-03-23 23:16:08346 bool HasActiveJob(const HostPortPair& host_port_pair,
347 const PrivacyMode privacy_mode) {
Ryan Hamilton4f0b26e2018-06-27 23:52:32348 quic::QuicServerId server_id(host_port_pair.host(), host_port_pair.port(),
349 privacy_mode == PRIVACY_MODE_ENABLED);
zhongyi363c91c2017-03-23 23:16:08350 return QuicStreamFactoryPeer::HasActiveJob(factory_.get(), server_id);
351 }
352
Ryan Hamilton8d9ee76e2018-05-29 23:52:52353 bool HasActiveCertVerifierJob(const quic::QuicServerId& server_id) {
rtennetid073dd22016-08-04 01:58:33354 return QuicStreamFactoryPeer::HasActiveCertVerifierJob(factory_.get(),
355 server_id);
356 }
357
Zhongyi Shic1449372018-08-09 09:58:58358 // Get the pending, not activated session, if there is only one session alive.
359 QuicChromiumClientSession* GetPendingSession(
360 const HostPortPair& host_port_pair) {
361 quic::QuicServerId server_id(host_port_pair.host(), host_port_pair.port(),
362 false);
363 return QuicStreamFactoryPeer::GetPendingSession(factory_.get(), server_id,
364 host_port_pair);
365 }
366
bnc912a04b2016-04-20 14:19:50367 QuicChromiumClientSession* GetActiveSession(
368 const HostPortPair& host_port_pair) {
Ryan Hamilton4f0b26e2018-06-27 23:52:32369 quic::QuicServerId server_id(host_port_pair.host(), host_port_pair.port(),
370 false);
bnc5fdc07162016-05-23 17:36:03371 return QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server_id);
bnc912a04b2016-04-20 14:19:50372 }
373
[email protected]bf4ea2f2014-03-10 22:57:53374 int GetSourcePortForNewSession(const HostPortPair& destination) {
[email protected]d8e2abf82014-03-06 10:30:10375 return GetSourcePortForNewSessionInner(destination, false);
376 }
377
rjshaded5ced072015-12-18 19:26:02378 int GetSourcePortForNewSessionAndGoAway(const HostPortPair& destination) {
[email protected]d8e2abf82014-03-06 10:30:10379 return GetSourcePortForNewSessionInner(destination, true);
380 }
381
[email protected]bf4ea2f2014-03-10 22:57:53382 int GetSourcePortForNewSessionInner(const HostPortPair& destination,
[email protected]d8e2abf82014-03-06 10:30:10383 bool goaway_received) {
[email protected]3c772402013-12-18 21:38:11384 // Should only be called if there is no active session for this destination.
bnccb7ff3c2015-05-21 20:51:55385 EXPECT_FALSE(HasActiveSession(destination));
Zhongyi Shi5f587cc2017-11-21 23:24:17386 size_t socket_count = socket_factory_->udp_client_socket_ports().size();
[email protected]3c772402013-12-18 21:38:11387
Ryan Hamiltonabad59e2019-06-06 04:02:59388 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:36389 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:43390 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:17391 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]3c772402013-12-18 21:38:11392
zhongyi98d6a9262017-05-19 02:47:45393 QuicStreamRequest request(factory_.get());
ckrasic3865ee0f2016-02-29 22:04:56394 GURL url("https://" + destination.host() + "/");
Nick Harper23290b82019-05-02 00:02:56395 EXPECT_EQ(ERR_IO_PENDING,
396 request.Request(
397 destination, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:51398 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Nick Harper23290b82019-05-02 00:02:56399 /*cert_verify_flags=*/0, url, net_log_, &net_error_details_,
400 failed_on_default_network_callback_, callback_.callback()));
[email protected]3c772402013-12-18 21:38:11401
robpercival214763f2016-07-01 23:27:01402 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:24403 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]3c772402013-12-18 21:38:11404 EXPECT_TRUE(stream.get());
405 stream.reset();
406
bnc912a04b2016-04-20 14:19:50407 QuicChromiumClientSession* session = GetActiveSession(destination);
[email protected]3c772402013-12-18 21:38:11408
Zhongyi Shi5f587cc2017-11-21 23:24:17409 if (socket_count + 1 != socket_factory_->udp_client_socket_ports().size()) {
mmenke651bae7f2015-12-18 21:26:45410 ADD_FAILURE();
[email protected]3c772402013-12-18 21:38:11411 return 0;
412 }
413
[email protected]d8e2abf82014-03-06 10:30:10414 if (goaway_received) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:52415 quic::QuicGoAwayFrame goaway(quic::kInvalidControlFrameId,
416 quic::QUIC_NO_ERROR, 1, "");
rtenneti9bd5d4b2015-08-21 05:44:52417 session->connection()->OnGoAwayFrame(goaway);
[email protected]d8e2abf82014-03-06 10:30:10418 }
[email protected]3c772402013-12-18 21:38:11419
jri7046038f2015-10-22 00:29:26420 factory_->OnSessionClosed(session);
bnccb7ff3c2015-05-21 20:51:55421 EXPECT_FALSE(HasActiveSession(destination));
rch37de576c2015-05-17 20:28:17422 EXPECT_TRUE(socket_data.AllReadDataConsumed());
423 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
Zhongyi Shi5f587cc2017-11-21 23:24:17424 return socket_factory_->udp_client_socket_ports()[socket_count];
[email protected]3c772402013-12-18 21:38:11425 }
426
Ryan Hamilton8d9ee76e2018-05-29 23:52:52427 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23428 ConstructClientConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03429 return client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52430 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
rtenneti1cd3b162015-09-29 02:58:28431 }
432
Ryan Hamilton8d9ee76e2018-05-29 23:52:52433 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
Fan Yangac867502019-01-28 21:10:23434 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52435 quic::QuicRstStreamErrorCode error_code) {
Fan Yang32c5a112018-12-10 20:06:33436 quic::QuicStreamId stream_id =
437 GetNthClientInitiatedBidirectionalStreamId(0);
fayang3bcb8b502016-12-07 21:44:37438 return client_maker_.MakeRstPacket(packet_number, true, stream_id,
Jana Iyengarba355772017-09-21 22:03:21439 error_code);
fayang3bcb8b502016-12-07 21:44:37440 }
441
bncf8bf0722015-05-19 20:04:13442 static ProofVerifyDetailsChromium DefaultProofVerifyDetails() {
rch6faa4d42016-01-05 20:48:43443 // Load a certificate that is valid for *.example.org
bncf8bf0722015-05-19 20:04:13444 scoped_refptr<X509Certificate> test_cert(
rch6faa4d42016-01-05 20:48:43445 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bncf8bf0722015-05-19 20:04:13446 EXPECT_TRUE(test_cert.get());
447 ProofVerifyDetailsChromium verify_details;
448 verify_details.cert_verify_result.verified_cert = test_cert;
449 verify_details.cert_verify_result.is_issued_by_known_root = true;
450 return verify_details;
451 }
452
jri8c44d692015-10-23 23:53:41453 void NotifyIPAddressChanged() {
454 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
jri7e636642016-01-14 06:57:08455 // Spin the message loop so the notification is delivered.
fdoray92e35a72016-06-10 15:54:55456 base::RunLoop().RunUntilIdle();
jri8c44d692015-10-23 23:53:41457 }
458
Ryan Hamilton8d9ee76e2018-05-29 23:52:52459 std::unique_ptr<quic::QuicEncryptedPacket> ConstructGetRequestPacket(
Fan Yangac867502019-01-28 21:10:23460 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52461 quic::QuicStreamId stream_id,
jri7e636642016-01-14 06:57:08462 bool should_include_version,
463 bool fin) {
Ryan Hamilton0239aac2018-05-19 00:03:13464 spdy::SpdyHeaderBlock headers =
alyssar2adf3ac2016-05-03 17:12:58465 client_maker_.GetRequestHeaders("GET", "https", "/");
Ryan Hamilton0239aac2018-05-19 00:03:13466 spdy::SpdyPriority priority =
jri7e636642016-01-14 06:57:08467 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
468 size_t spdy_headers_frame_len;
alyssar2adf3ac2016-05-03 17:12:58469 return client_maker_.MakeRequestHeadersPacket(
jri7e636642016-01-14 06:57:08470 packet_number, stream_id, should_include_version, fin, priority,
Yixin Wang7a3f1b8d2018-01-17 21:40:48471 std::move(headers), 0, &spdy_headers_frame_len);
jri7e636642016-01-14 06:57:08472 }
473
Ryan Hamilton8d9ee76e2018-05-29 23:52:52474 std::unique_ptr<quic::QuicEncryptedPacket> ConstructGetRequestPacket(
Fan Yangac867502019-01-28 21:10:23475 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52476 quic::QuicStreamId stream_id,
Zhongyi Shi3c4c9e92018-07-02 23:16:23477 quic::QuicStreamId parent_stream_id,
fayang3bcb8b502016-12-07 21:44:37478 bool should_include_version,
Ryan Hamilton0d65a8c2019-06-07 00:46:02479 bool fin) {
Ryan Hamilton0239aac2018-05-19 00:03:13480 spdy::SpdyHeaderBlock headers =
fayang3bcb8b502016-12-07 21:44:37481 client_maker_.GetRequestHeaders("GET", "https", "/");
Ryan Hamilton0239aac2018-05-19 00:03:13482 spdy::SpdyPriority priority =
fayang3bcb8b502016-12-07 21:44:37483 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
484 size_t spdy_headers_frame_len;
485 return client_maker_.MakeRequestHeadersPacket(
486 packet_number, stream_id, should_include_version, fin, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02487 std::move(headers), parent_stream_id, &spdy_headers_frame_len);
fayang3bcb8b502016-12-07 21:44:37488 }
489
Ryan Hamilton8d9ee76e2018-05-29 23:52:52490 std::unique_ptr<quic::QuicEncryptedPacket> ConstructOkResponsePacket(
Fan Yangac867502019-01-28 21:10:23491 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52492 quic::QuicStreamId stream_id,
jri7e636642016-01-14 06:57:08493 bool should_include_version,
494 bool fin) {
Ryan Hamilton0239aac2018-05-19 00:03:13495 spdy::SpdyHeaderBlock headers = server_maker_.GetResponseHeaders("200 OK");
jri7e636642016-01-14 06:57:08496 size_t spdy_headers_frame_len;
alyssar2adf3ac2016-05-03 17:12:58497 return server_maker_.MakeResponseHeadersPacket(
bnc086b39e12016-06-24 13:05:26498 packet_number, stream_id, should_include_version, fin,
499 std::move(headers), &spdy_headers_frame_len);
jri7e636642016-01-14 06:57:08500 }
501
Ryan Hamilton8d9ee76e2018-05-29 23:52:52502 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket() {
Ryan Hamilton0d65a8c2019-06-07 00:46:02503 return client_maker_.MakeInitialSettingsPacket(1);
rch5cb522462017-04-25 20:18:36504 }
505
Ryan Hamilton8d9ee76e2018-05-29 23:52:52506 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:02507 uint64_t packet_number) {
508 return client_maker_.MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:37509 }
510
jri053fdbd2016-08-19 02:33:05511 // Helper method for server migration tests.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52512 void VerifyServerMigration(const quic::QuicConfig& config,
bnc6a0348c2017-05-22 18:56:19513 IPEndPoint expected_address) {
Zhongyi Shi967d2f12019-02-08 20:58:53514 test_params_.quic_allow_server_migration = true;
jri053fdbd2016-08-19 02:33:05515 Initialize();
516
517 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
518 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri053fdbd2016-08-19 02:33:05519 crypto_client_stream_factory_.SetConfig(config);
520
521 // Set up first socket data provider.
Ryan Hamiltonabad59e2019-06-06 04:02:59522 MockQuicData socket_data1(version_);
rcha00569732016-08-27 11:09:36523 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:17524 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri053fdbd2016-08-19 02:33:05525
Ryan Hamilton9f2eac32019-06-27 03:15:54526 client_maker_.set_coalesce_http_frames(true);
rcha00569732016-08-27 11:09:36527 // Set up second socket data provider that is used after
528 // migration.
Ryan Hamiltonabad59e2019-06-06 04:02:59529 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:36530 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:43531 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
fayang3bcb8b502016-12-07 21:44:37532 socket_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:43533 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
534 socket_data2.AddWrite(
Fan Yang32c5a112018-12-10 20:06:33535 SYNCHRONOUS, client_maker_.MakeRstPacket(
536 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
537 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:17538 socket_data2.AddSocketDataToFactory(socket_factory_.get());
jri053fdbd2016-08-19 02:33:05539
540 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:45541 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:33542 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:03543 request.Request(
Nick Harper23290b82019-05-02 00:02:56544 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:51545 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:03546 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
547 failed_on_default_network_callback_, callback_.callback()));
jri053fdbd2016-08-19 02:33:05548 EXPECT_EQ(OK, callback_.WaitForResult());
bnceb9aa7112017-01-05 01:03:46549
550 // Run QuicChromiumClientSession::WriteToNewSocket()
551 // posted by QuicChromiumClientSession::MigrateToSocket().
552 base::RunLoop().RunUntilIdle();
553
Yixin Wang7891a39d2017-11-08 20:59:24554 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri053fdbd2016-08-19 02:33:05555 EXPECT_TRUE(stream.get());
556
557 // Cause QUIC stream to be created.
558 HttpRequestInfo request_info;
559 request_info.method = "GET";
560 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:39561 request_info.traffic_annotation =
562 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:27563 EXPECT_EQ(OK,
564 stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:39565 net_log_, CompletionOnceCallback()));
jri053fdbd2016-08-19 02:33:05566 // Ensure that session is alive and active.
567 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
568 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
569 EXPECT_TRUE(HasActiveSession(host_port_pair_));
570
571 IPEndPoint actual_address;
572 session->GetDefaultSocket()->GetPeerAddress(&actual_address);
573 EXPECT_EQ(actual_address, expected_address);
574 DVLOG(1) << "Socket connected to: " << actual_address.address().ToString()
575 << " " << actual_address.port();
576 DVLOG(1) << "Expected address: " << expected_address.address().ToString()
577 << " " << expected_address.port();
578
579 stream.reset();
580 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
581 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
582 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
583 }
584
tbansal3b966952016-10-25 23:25:14585 // Verifies that the QUIC stream factory is initialized correctly.
tbansal9b1cdf32017-05-10 17:28:39586 void VerifyInitialization() {
rch431dd4452017-04-19 15:22:35587 store_server_configs_in_properties_ = true;
Zhongyi Shi967d2f12019-02-08 20:58:53588 test_params_.quic_idle_connection_timeout_seconds = 500;
tbansal3b966952016-10-25 23:25:14589 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:20590 factory_->set_require_confirmation(false);
tbansal3b966952016-10-25 23:25:14591 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
592 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rch431dd4452017-04-19 15:22:35593 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
594 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:27595 MockCryptoClientStream::ZERO_RTT);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52596 const quic::QuicConfig* config =
597 QuicStreamFactoryPeer::GetConfig(factory_.get());
ckrasic32b17dcd2016-10-31 06:15:35598 EXPECT_EQ(500, config->IdleNetworkTimeout().ToSeconds());
tbansal3b966952016-10-25 23:25:14599
600 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
601
bnc3472afd2016-11-17 15:27:21602 const AlternativeService alternative_service1(
603 kProtoQUIC, host_port_pair_.host(), host_port_pair_.port());
tbansal3b966952016-10-25 23:25:14604 AlternativeServiceInfoVector alternative_service_info_vector;
605 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
606 alternative_service_info_vector.push_back(
zhongyie537a002017-06-27 16:48:21607 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
608 alternative_service1, expiration, {version_}));
tbansal3b966952016-10-25 23:25:14609 http_server_properties_.SetAlternativeServices(
610 url::SchemeHostPort(url_), alternative_service_info_vector);
611
612 HostPortPair host_port_pair2(kServer2HostName, kDefaultServerPort);
613 url::SchemeHostPort server2("https", kServer2HostName, kDefaultServerPort);
bnc3472afd2016-11-17 15:27:21614 const AlternativeService alternative_service2(
615 kProtoQUIC, host_port_pair2.host(), host_port_pair2.port());
tbansal3b966952016-10-25 23:25:14616 AlternativeServiceInfoVector alternative_service_info_vector2;
617 alternative_service_info_vector2.push_back(
zhongyie537a002017-06-27 16:48:21618 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
619 alternative_service2, expiration, {version_}));
tbansal9b1cdf32017-05-10 17:28:39620
621 http_server_properties_.SetAlternativeServices(
622 server2, alternative_service_info_vector2);
623 // Verify that the properties of both QUIC servers are stored in the
624 // HTTP properties map.
625 EXPECT_EQ(2U, http_server_properties_.alternative_service_map().size());
tbansal3b966952016-10-25 23:25:14626
627 http_server_properties_.SetMaxServerConfigsStoredInProperties(
Yixin Wang4a227aa22017-11-30 21:33:01628 kDefaultMaxQuicServerEntries);
tbansal3b966952016-10-25 23:25:14629
Ryan Hamilton8d9ee76e2018-05-29 23:52:52630 quic::QuicServerId quic_server_id(kDefaultServerHostName, 443,
631 PRIVACY_MODE_DISABLED);
rch431dd4452017-04-19 15:22:35632 std::unique_ptr<QuicServerInfo> quic_server_info =
Jeremy Roman0579ed62017-08-29 15:56:19633 std::make_unique<PropertiesBasedQuicServerInfo>(
rch431dd4452017-04-19 15:22:35634 quic_server_id, &http_server_properties_);
tbansal3b966952016-10-25 23:25:14635
636 // Update quic_server_info's server_config and persist it.
637 QuicServerInfo::State* state = quic_server_info->mutable_state();
638 // Minimum SCFG that passes config validation checks.
639 const char scfg[] = {// SCFG
640 0x53, 0x43, 0x46, 0x47,
641 // num entries
642 0x01, 0x00,
643 // padding
644 0x00, 0x00,
645 // EXPY
646 0x45, 0x58, 0x50, 0x59,
647 // EXPY end offset
648 0x08, 0x00, 0x00, 0x00,
649 // Value
650 '1', '2', '3', '4', '5', '6', '7', '8'};
651
652 // Create temporary strings becasue Persist() clears string data in |state|.
653 string server_config(reinterpret_cast<const char*>(&scfg), sizeof(scfg));
654 string source_address_token("test_source_address_token");
655 string cert_sct("test_cert_sct");
656 string chlo_hash("test_chlo_hash");
657 string signature("test_signature");
658 string test_cert("test_cert");
rch872e00e2016-12-02 02:48:18659 std::vector<string> certs;
tbansal3b966952016-10-25 23:25:14660 certs.push_back(test_cert);
661 state->server_config = server_config;
662 state->source_address_token = source_address_token;
663 state->cert_sct = cert_sct;
664 state->chlo_hash = chlo_hash;
665 state->server_config_sig = signature;
666 state->certs = certs;
667
668 quic_server_info->Persist();
669
Ryan Hamilton8d9ee76e2018-05-29 23:52:52670 quic::QuicServerId quic_server_id2(kServer2HostName, 443,
671 PRIVACY_MODE_DISABLED);
rch431dd4452017-04-19 15:22:35672 std::unique_ptr<QuicServerInfo> quic_server_info2 =
Jeremy Roman0579ed62017-08-29 15:56:19673 std::make_unique<PropertiesBasedQuicServerInfo>(
rch431dd4452017-04-19 15:22:35674 quic_server_id2, &http_server_properties_);
tbansal3b966952016-10-25 23:25:14675 // Update quic_server_info2's server_config and persist it.
676 QuicServerInfo::State* state2 = quic_server_info2->mutable_state();
677
678 // Minimum SCFG that passes config validation checks.
679 const char scfg2[] = {// SCFG
680 0x53, 0x43, 0x46, 0x47,
681 // num entries
682 0x01, 0x00,
683 // padding
684 0x00, 0x00,
685 // EXPY
686 0x45, 0x58, 0x50, 0x59,
687 // EXPY end offset
688 0x08, 0x00, 0x00, 0x00,
689 // Value
690 '8', '7', '3', '4', '5', '6', '2', '1'};
691
692 // Create temporary strings becasue Persist() clears string data in
693 // |state2|.
694 string server_config2(reinterpret_cast<const char*>(&scfg2), sizeof(scfg2));
695 string source_address_token2("test_source_address_token2");
696 string cert_sct2("test_cert_sct2");
697 string chlo_hash2("test_chlo_hash2");
698 string signature2("test_signature2");
699 string test_cert2("test_cert2");
rch872e00e2016-12-02 02:48:18700 std::vector<string> certs2;
tbansal3b966952016-10-25 23:25:14701 certs2.push_back(test_cert2);
702 state2->server_config = server_config2;
703 state2->source_address_token = source_address_token2;
704 state2->cert_sct = cert_sct2;
705 state2->chlo_hash = chlo_hash2;
706 state2->server_config_sig = signature2;
707 state2->certs = certs2;
708
709 quic_server_info2->Persist();
710
tbansal3b966952016-10-25 23:25:14711 // Verify the MRU order is maintained.
712 const QuicServerInfoMap& quic_server_info_map =
713 http_server_properties_.quic_server_info_map();
714 EXPECT_EQ(2u, quic_server_info_map.size());
jdoerrie22a91d8b92018-10-05 08:43:26715 auto quic_server_info_map_it = quic_server_info_map.begin();
tbansal3b966952016-10-25 23:25:14716 EXPECT_EQ(quic_server_info_map_it->first, quic_server_id2);
717 ++quic_server_info_map_it;
718 EXPECT_EQ(quic_server_info_map_it->first, quic_server_id);
719
Renjiea0cb4a2c2018-09-26 23:37:30720 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
721 "192.168.0.1", "");
rch431dd4452017-04-19 15:22:35722
723 // Create a session and verify that the cached state is loaded.
Ryan Hamiltonabad59e2019-06-06 04:02:59724 MockQuicData socket_data(version_);
rch431dd4452017-04-19 15:22:35725 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:17726 socket_data.AddSocketDataToFactory(socket_factory_.get());
rch431dd4452017-04-19 15:22:35727
zhongyi98d6a9262017-05-19 02:47:45728 QuicStreamRequest request(factory_.get());
Yixin Wang247ea642017-11-15 01:15:50729 EXPECT_EQ(ERR_IO_PENDING,
Ryan Hamilton4f0b26e2018-06-27 23:52:32730 request.Request(
731 HostPortPair(quic_server_id.host(), quic_server_id.port()),
Nick Harper23290b82019-05-02 00:02:56732 version_.transport_version, privacy_mode_, DEFAULT_PRIORITY,
Matt Menke26e41542019-06-05 01:09:51733 SocketTag(), NetworkIsolationKey(),
Ryan Hamilton4f0b26e2018-06-27 23:52:32734 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
Zhongyi Shia6b68d112018-09-24 07:49:03735 failed_on_default_network_callback_, callback_.callback()));
rch431dd4452017-04-19 15:22:35736 EXPECT_THAT(callback_.WaitForResult(), IsOk());
737
tbansal3b966952016-10-25 23:25:14738 EXPECT_FALSE(QuicStreamFactoryPeer::CryptoConfigCacheIsEmpty(
739 factory_.get(), quic_server_id));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52740 quic::QuicCryptoClientConfig* crypto_config =
tbansal3b966952016-10-25 23:25:14741 QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
Ryan Hamilton8d9ee76e2018-05-29 23:52:52742 quic::QuicCryptoClientConfig::CachedState* cached =
tbansal3b966952016-10-25 23:25:14743 crypto_config->LookupOrCreate(quic_server_id);
744 EXPECT_FALSE(cached->server_config().empty());
745 EXPECT_TRUE(cached->GetServerConfig());
746 EXPECT_EQ(server_config, cached->server_config());
747 EXPECT_EQ(source_address_token, cached->source_address_token());
748 EXPECT_EQ(cert_sct, cached->cert_sct());
749 EXPECT_EQ(chlo_hash, cached->chlo_hash());
750 EXPECT_EQ(signature, cached->signature());
751 ASSERT_EQ(1U, cached->certs().size());
752 EXPECT_EQ(test_cert, cached->certs()[0]);
753
rch431dd4452017-04-19 15:22:35754 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
755
756 // Create a session and verify that the cached state is loaded.
Ryan Hamiltonabad59e2019-06-06 04:02:59757 MockQuicData socket_data2(version_);
rch431dd4452017-04-19 15:22:35758 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:17759 socket_data2.AddSocketDataToFactory(socket_factory_.get());
rch431dd4452017-04-19 15:22:35760
Renjiea0cb4a2c2018-09-26 23:37:30761 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
762 "192.168.0.2", "");
rch431dd4452017-04-19 15:22:35763
zhongyi98d6a9262017-05-19 02:47:45764 QuicStreamRequest request2(factory_.get());
rch431dd4452017-04-19 15:22:35765 EXPECT_EQ(ERR_IO_PENDING,
Ryan Hamilton4f0b26e2018-06-27 23:52:32766 request2.Request(
767 HostPortPair(quic_server_id2.host(), quic_server_id2.port()),
Nick Harper23290b82019-05-02 00:02:56768 version_.transport_version, privacy_mode_, DEFAULT_PRIORITY,
Matt Menke26e41542019-06-05 01:09:51769 SocketTag(), NetworkIsolationKey(),
Ryan Hamilton4f0b26e2018-06-27 23:52:32770 /*cert_verify_flags=*/0, GURL("https://mail.example.org/"),
Zhongyi Shia6b68d112018-09-24 07:49:03771 net_log_, &net_error_details_,
772 failed_on_default_network_callback_, callback_.callback()));
rch431dd4452017-04-19 15:22:35773 EXPECT_THAT(callback_.WaitForResult(), IsOk());
774
tbansal3b966952016-10-25 23:25:14775 EXPECT_FALSE(QuicStreamFactoryPeer::CryptoConfigCacheIsEmpty(
776 factory_.get(), quic_server_id2));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52777 quic::QuicCryptoClientConfig::CachedState* cached2 =
tbansal3b966952016-10-25 23:25:14778 crypto_config->LookupOrCreate(quic_server_id2);
779 EXPECT_FALSE(cached2->server_config().empty());
780 EXPECT_TRUE(cached2->GetServerConfig());
781 EXPECT_EQ(server_config2, cached2->server_config());
782 EXPECT_EQ(source_address_token2, cached2->source_address_token());
783 EXPECT_EQ(cert_sct2, cached2->cert_sct());
784 EXPECT_EQ(chlo_hash2, cached2->chlo_hash());
785 EXPECT_EQ(signature2, cached2->signature());
786 ASSERT_EQ(1U, cached->certs().size());
787 EXPECT_EQ(test_cert2, cached2->certs()[0]);
788 }
789
jri5b785512016-09-13 04:29:11790 void RunTestLoopUntilIdle() {
791 while (!runner_->GetPostedTasks().empty())
792 runner_->RunNextTask();
793 }
794
Fan Yang32c5a112018-12-10 20:06:33795 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56796 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
797 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36798 }
799
Zhongyi Shi99d0cdd2019-05-21 01:18:42800 std::string ConstructDataHeader(size_t body_len) {
801 if (version_.transport_version != quic::QUIC_VERSION_99) {
802 return "";
803 }
804 quic::HttpEncoder encoder;
805 std::unique_ptr<char[]> buffer;
806 auto header_length = encoder.SerializeDataFrameHeader(body_len, &buffer);
807 return std::string(buffer.get(), header_length);
808 }
809
810 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
811 uint64_t packet_number,
812 quic::QuicStreamId stream_id,
813 bool should_include_version,
814 bool fin,
Zhongyi Shi99d0cdd2019-05-21 01:18:42815 quic::QuicStringPiece data) {
Ryan Hamilton7505eb92019-06-08 00:22:17816 return server_maker_.MakeDataPacket(packet_number, stream_id,
817 should_include_version, fin, data);
Zhongyi Shi99d0cdd2019-05-21 01:18:42818 }
819
Fan Yang32c5a112018-12-10 20:06:33820 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56821 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
822 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36823 }
824
Zhongyi Shia6b68d112018-09-24 07:49:03825 void OnFailedOnDefaultNetwork(int rv) { failed_on_default_network_ = true; }
826
jri9f303712016-09-13 01:10:22827 // Helper methods for tests of connection migration on write error.
Zhongyi Shi32fe14d42019-02-28 00:25:36828 void TestMigrationOnWriteErrorNonMigratableStream(IoMode write_error_mode,
829 bool migrate_idle_sessions);
Zhongyi Shi0439ecc72018-07-11 04:41:26830 // Migratable stream triggers write error.
831 void TestMigrationOnWriteErrorMixedStreams(IoMode write_error_mode);
832 // Non-migratable stream triggers write error.
833 void TestMigrationOnWriteErrorMixedStreams2(IoMode write_error_mode);
jri9f303712016-09-13 01:10:22834 void TestMigrationOnWriteErrorMigrationDisabled(IoMode write_error_mode);
835 void TestMigrationOnWriteError(IoMode write_error_mode);
Zhongyi Shi0439ecc72018-07-11 04:41:26836 void TestMigrationOnWriteErrorWithMultipleRequests(IoMode write_error_mode);
jri9f303712016-09-13 01:10:22837 void TestMigrationOnWriteErrorNoNewNetwork(IoMode write_error_mode);
Zhongyi Shi7f1d9212018-06-22 23:24:36838 void TestMigrationOnMultipleWriteErrors(
839 IoMode write_error_mode_on_old_network,
840 IoMode write_error_mode_on_new_network);
Zhongyi Shib24001c02018-06-18 20:01:52841 void TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
842 bool disconnected);
Zhongyi Shi1e2bc742018-06-16 02:06:07843 void TestMigrationOnWriteErrorWithNotificationQueuedLater(bool disconnected);
Zhongyi Shi9f316b262018-06-18 22:01:16844 void TestMigrationOnNetworkDisconnected(bool async_write_before);
Zhongyi Shia0644e32018-06-21 05:19:52845 void TestMigrationOnNetworkMadeDefault(IoMode write_mode);
Zhongyi Shi22fd5f52018-06-20 17:39:09846 void TestMigrationOnPathDegrading(bool async_write_before);
Zhongyi Shib3bc982c2018-07-10 19:59:24847 void TestMigrateSessionWithDrainingStream(
848 IoMode write_mode_for_queued_packet);
jri5b785512016-09-13 04:29:11849 void TestMigrationOnWriteErrorPauseBeforeConnected(IoMode write_error_mode);
Zhongyi Shi4ac9e1f2018-06-21 05:21:47850 void TestMigrationOnWriteErrorWithMultipleNotifications(
jri5b785512016-09-13 04:29:11851 IoMode write_error_mode,
Zhongyi Shi4ac9e1f2018-06-21 05:21:47852 bool disconnect_before_connect);
Zhongyi Shi634c1882018-08-16 04:05:59853 void TestNoAlternateNetworkBeforeHandshake(quic::QuicErrorCode error);
Zhongyi Shi8de43832018-08-15 23:40:00854 void TestNewConnectionOnAlternateNetworkBeforeHandshake(
855 quic::QuicErrorCode error);
Zhongyi Shi32fe14d42019-02-28 00:25:36856 void TestOnNetworkMadeDefaultNonMigratableStream(bool migrate_idle_sessions);
857 void TestMigrateSessionEarlyNonMigratableStream(bool migrate_idle_sessions);
858 void TestOnNetworkDisconnectedNoOpenStreams(bool migrate_idle_sessions);
859 void TestOnNetworkMadeDefaultNoOpenStreams(bool migrate_idle_sessions);
860 void TestOnNetworkDisconnectedNonMigratableStream(bool migrate_idle_sessions);
jri9f303712016-09-13 01:10:22861
Jana Iyengarf6b13d82017-09-04 02:09:10862 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Renjiea0cb4a2c2018-09-26 23:37:30863 std::unique_ptr<MockHostResolverBase> host_resolver_;
Ryan Sleevib8449e02018-07-15 04:31:07864 std::unique_ptr<SSLConfigService> ssl_config_service_;
Zhongyi Shi5f587cc2017-11-21 23:24:17865 std::unique_ptr<MockClientSocketFactory> socket_factory_;
[email protected]e8ff26842013-03-22 21:02:05866 MockCryptoClientStreamFactory crypto_client_stream_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52867 quic::test::MockRandom random_generator_;
868 quic::MockClock clock_;
rtenneti38f5cd52014-10-28 20:28:28869 scoped_refptr<TestTaskRunner> runner_;
Nick Harper23290b82019-05-02 00:02:56870 const quic::ParsedQuicVersion version_;
alyssar2adf3ac2016-05-03 17:12:58871 QuicTestPacketMaker client_maker_;
872 QuicTestPacketMaker server_maker_;
rtenneticcab42b2015-10-09 06:38:16873 HttpServerPropertiesImpl http_server_properties_;
danakjad1777e2016-04-16 00:56:42874 std::unique_ptr<CertVerifier> cert_verifier_;
[email protected]080b77932014-08-04 01:22:46875 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42876 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:23877 DefaultCTPolicyEnforcer ct_policy_enforcer_;
danakjad1777e2016-04-16 00:56:42878 std::unique_ptr<ScopedMockNetworkChangeNotifier>
jri7e636642016-01-14 06:57:08879 scoped_mock_network_change_notifier_;
danakjad1777e2016-04-16 00:56:42880 std::unique_ptr<QuicStreamFactory> factory_;
[email protected]bf4ea2f2014-03-10 22:57:53881 HostPortPair host_port_pair_;
ckrasic3865ee0f2016-02-29 22:04:56882 GURL url_;
883 GURL url2_;
884 GURL url3_;
885 GURL url4_;
886
[email protected]9dd3ff0f2014-03-26 09:51:28887 PrivacyMode privacy_mode_;
tfarina42834112016-09-22 13:38:20888 NetLogWithSource net_log_;
[email protected]e13201d82012-12-12 05:00:32889 TestCompletionCallback callback_;
Zhongyi Shia6b68d112018-09-24 07:49:03890 const CompletionRepeatingCallback failed_on_default_network_callback_;
891 bool failed_on_default_network_;
Ryan Hamilton75f197262017-08-17 14:00:07892 NetErrorDetails net_error_details_;
jri7046038f2015-10-22 00:29:26893
894 // Variables to configure QuicStreamFactory.
Zhongyi Shi967d2f12019-02-08 20:58:53895 HttpNetworkSession::Params test_params_;
rch431dd4452017-04-19 15:22:35896 bool store_server_configs_in_properties_;
[email protected]e13201d82012-12-12 05:00:32897};
898
bnc359ed2a2016-04-29 20:43:45899class QuicStreamFactoryTest : public QuicStreamFactoryTestBase,
900 public ::testing::TestWithParam<TestParams> {
901 protected:
Yixin Wang079ad542018-01-11 04:06:05902 QuicStreamFactoryTest()
903 : QuicStreamFactoryTestBase(
904 GetParam().version,
905 GetParam().client_headers_include_h2_stream_dependency) {}
bnc359ed2a2016-04-29 20:43:45906};
907
Victor Costane635086f2019-01-27 05:20:30908INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
909 QuicStreamFactoryTest,
910 ::testing::ValuesIn(GetTestParams()));
[email protected]1e960032013-12-20 19:00:20911
[email protected]1e960032013-12-20 19:00:20912TEST_P(QuicStreamFactoryTest, Create) {
jri7046038f2015-10-22 00:29:26913 Initialize();
rch6faa4d42016-01-05 20:48:43914 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
915 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:26916
Ryan Hamiltonabad59e2019-06-06 04:02:59917 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:36918 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:43919 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:17920 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]e13201d82012-12-12 05:00:32921
zhongyi98d6a9262017-05-19 02:47:45922 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:33923 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:03924 request.Request(
Nick Harper23290b82019-05-02 00:02:56925 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:51926 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:03927 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
928 failed_on_default_network_callback_, callback_.callback()));
[email protected]e13201d82012-12-12 05:00:32929
robpercival214763f2016-07-01 23:27:01930 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:24931 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0edce6a2013-05-08 18:02:40932 EXPECT_TRUE(stream.get());
[email protected]e13201d82012-12-12 05:00:32933
Renjiea0cb4a2c2018-09-26 23:37:30934 EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_->last_request_priority());
Yixin Wang247ea642017-11-15 01:15:50935
zhongyi98d6a9262017-05-19 02:47:45936 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:51937 EXPECT_EQ(OK,
938 request2.Request(
939 host_port_pair_, version_.transport_version, privacy_mode_,
940 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
941 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
942 failed_on_default_network_callback_, callback_.callback()));
rch68a80eb2017-04-25 05:24:24943 // Will reset stream 3.
Yixin Wang7891a39d2017-11-08 20:59:24944 stream = CreateStream(&request2);
rch68a80eb2017-04-25 05:24:24945
946 EXPECT_TRUE(stream.get());
947
948 // TODO(rtenneti): We should probably have a tests that HTTP and HTTPS result
949 // in streams on different sessions.
zhongyi98d6a9262017-05-19 02:47:45950 QuicStreamRequest request3(factory_.get());
Matt Menke26e41542019-06-05 01:09:51951 EXPECT_EQ(OK,
952 request3.Request(
953 host_port_pair_, version_.transport_version, privacy_mode_,
954 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
955 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
956 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:24957 stream = CreateStream(&request3); // Will reset stream 5.
Ryan Hamiltona12722b2017-08-12 02:23:20958 stream.reset(); // Will reset stream 7.
[email protected]e13201d82012-12-12 05:00:32959
rch37de576c2015-05-17 20:28:17960 EXPECT_TRUE(socket_data.AllReadDataConsumed());
961 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]e13201d82012-12-12 05:00:32962}
963
[email protected]8bd2b812014-03-26 04:01:17964TEST_P(QuicStreamFactoryTest, CreateZeroRtt) {
jri7046038f2015-10-22 00:29:26965 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:20966 factory_->set_require_confirmation(false);
rch6faa4d42016-01-05 20:48:43967 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
968 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:26969
Ryan Hamiltonabad59e2019-06-06 04:02:59970 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:36971 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:17972 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]8bd2b812014-03-26 04:01:17973
974 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:27975 MockCryptoClientStream::ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:30976 host_resolver_->set_synchronous_mode(true);
977 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
978 "192.168.0.1", "");
[email protected]8bd2b812014-03-26 04:01:17979
zhongyi98d6a9262017-05-19 02:47:45980 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:51981 EXPECT_EQ(OK,
982 request.Request(
983 host_port_pair_, version_.transport_version, privacy_mode_,
984 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
985 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
986 failed_on_default_network_callback_, callback_.callback()));
[email protected]8bd2b812014-03-26 04:01:17987
Yixin Wang7891a39d2017-11-08 20:59:24988 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]8bd2b812014-03-26 04:01:17989 EXPECT_TRUE(stream.get());
rch37de576c2015-05-17 20:28:17990 EXPECT_TRUE(socket_data.AllReadDataConsumed());
991 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]8bd2b812014-03-26 04:01:17992}
993
rchd6163f32017-01-30 23:50:38994TEST_P(QuicStreamFactoryTest, DefaultInitialRtt) {
995 Initialize();
996 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
997 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
998
Ryan Hamiltonabad59e2019-06-06 04:02:59999 MockQuicData socket_data(version_);
rchd6163f32017-01-30 23:50:381000 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431001 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171002 socket_data.AddSocketDataToFactory(socket_factory_.get());
rchd6163f32017-01-30 23:50:381003
zhongyi98d6a9262017-05-19 02:47:451004 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331005 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031006 request.Request(
Nick Harper23290b82019-05-02 00:02:561007 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511008 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031009 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1010 failed_on_default_network_callback_, callback_.callback()));
rchd6163f32017-01-30 23:50:381011
1012 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241013 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rchd6163f32017-01-30 23:50:381014 EXPECT_TRUE(stream.get());
1015
1016 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Ryan Hamiltona12722b2017-08-12 02:23:201017 EXPECT_TRUE(session->require_confirmation());
rchd6163f32017-01-30 23:50:381018 EXPECT_EQ(100000u, session->connection()->GetStats().srtt_us);
1019 ASSERT_FALSE(session->config()->HasInitialRoundTripTimeUsToSend());
1020}
1021
Helen Li0e823912017-09-25 19:48:301022TEST_P(QuicStreamFactoryTest, FactoryDestroyedWhenJobPending) {
1023 Initialize();
1024 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1025 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1026
Ryan Hamiltonabad59e2019-06-06 04:02:591027 MockQuicData socket_data(version_);
Helen Li0e823912017-09-25 19:48:301028 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431029 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171030 socket_data.AddSocketDataToFactory(socket_factory_.get());
Helen Li0e823912017-09-25 19:48:301031
1032 auto request = std::make_unique<QuicStreamRequest>(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331033 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031034 request->Request(
Nick Harper23290b82019-05-02 00:02:561035 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511036 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031037 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1038 failed_on_default_network_callback_, callback_.callback()));
Helen Li0e823912017-09-25 19:48:301039 request.reset();
1040 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
1041 // Tearing down a QuicStreamFactory with a pending Job should not cause any
1042 // crash. crbug.com/768343.
1043 factory_.reset();
1044}
1045
Ryan Hamiltona12722b2017-08-12 02:23:201046TEST_P(QuicStreamFactoryTest, RequireConfirmation) {
1047 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271048 MockCryptoClientStream::ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:301049 host_resolver_->set_synchronous_mode(true);
1050 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
1051 "192.168.0.1", "");
Ryan Hamiltona12722b2017-08-12 02:23:201052 Initialize();
1053 factory_->set_require_confirmation(true);
1054 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1055 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1056
Ryan Hamiltonabad59e2019-06-06 04:02:591057 MockQuicData socket_data(version_);
Ryan Hamiltona12722b2017-08-12 02:23:201058 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431059 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171060 socket_data.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamiltona12722b2017-08-12 02:23:201061
1062 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331063 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031064 request.Request(
Nick Harper23290b82019-05-02 00:02:561065 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511066 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031067 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1068 failed_on_default_network_callback_, callback_.callback()));
Ryan Hamiltona12722b2017-08-12 02:23:201069
Ryan Hamilton8e32a2b2017-08-28 20:06:521070 IPAddress last_address;
1071 EXPECT_FALSE(http_server_properties_.GetSupportsQuic(&last_address));
1072
Ryan Hamiltona12722b2017-08-12 02:23:201073 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521074 quic::QuicSession::HANDSHAKE_CONFIRMED);
Ryan Hamiltona12722b2017-08-12 02:23:201075
Ryan Hamilton8e32a2b2017-08-28 20:06:521076 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
1077
Ryan Hamiltona12722b2017-08-12 02:23:201078 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241079 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Ryan Hamiltona12722b2017-08-12 02:23:201080 EXPECT_TRUE(stream.get());
1081
1082 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1083 EXPECT_TRUE(session->require_confirmation());
1084}
1085
1086TEST_P(QuicStreamFactoryTest, DontRequireConfirmationFromSameIP) {
1087 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271088 MockCryptoClientStream::ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:301089 host_resolver_->set_synchronous_mode(true);
1090 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
1091 "192.168.0.1", "");
Ryan Hamiltona12722b2017-08-12 02:23:201092 Initialize();
1093 factory_->set_require_confirmation(true);
1094 http_server_properties_.SetSupportsQuic(IPAddress(192, 0, 2, 33));
1095
1096 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1097 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1098
Ryan Hamiltonabad59e2019-06-06 04:02:591099 MockQuicData socket_data(version_);
Ryan Hamiltona12722b2017-08-12 02:23:201100 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431101 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171102 socket_data.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamiltona12722b2017-08-12 02:23:201103
1104 QuicStreamRequest request(factory_.get());
Zhongyi Shia6b68d112018-09-24 07:49:031105 EXPECT_THAT(request.Request(
Nick Harper23290b82019-05-02 00:02:561106 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511107 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031108 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1109 failed_on_default_network_callback_, callback_.callback()),
Paul Jensen8e3c5d32018-02-19 17:06:331110 IsOk());
Ryan Hamiltona12722b2017-08-12 02:23:201111
Ryan Hamilton8e32a2b2017-08-28 20:06:521112 IPAddress last_address;
1113 EXPECT_FALSE(http_server_properties_.GetSupportsQuic(&last_address));
1114
Yixin Wang7891a39d2017-11-08 20:59:241115 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Ryan Hamiltona12722b2017-08-12 02:23:201116 EXPECT_TRUE(stream.get());
1117
1118 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1119 EXPECT_FALSE(session->require_confirmation());
Ryan Hamilton8e32a2b2017-08-28 20:06:521120
1121 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521122 quic::QuicSession::HANDSHAKE_CONFIRMED);
Ryan Hamilton8e32a2b2017-08-28 20:06:521123
1124 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
Ryan Hamiltona12722b2017-08-12 02:23:201125}
1126
rchd6163f32017-01-30 23:50:381127TEST_P(QuicStreamFactoryTest, CachedInitialRtt) {
1128 ServerNetworkStats stats;
1129 stats.srtt = base::TimeDelta::FromMilliseconds(10);
1130 http_server_properties_.SetServerNetworkStats(url::SchemeHostPort(url_),
1131 stats);
Zhongyi Shi967d2f12019-02-08 20:58:531132 test_params_.quic_estimate_initial_rtt = true;
rchd6163f32017-01-30 23:50:381133
1134 Initialize();
1135 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1136 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1137
Ryan Hamiltonabad59e2019-06-06 04:02:591138 MockQuicData socket_data(version_);
rchd6163f32017-01-30 23:50:381139 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431140 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171141 socket_data.AddSocketDataToFactory(socket_factory_.get());
rchd6163f32017-01-30 23:50:381142
zhongyi98d6a9262017-05-19 02:47:451143 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331144 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031145 request.Request(
Nick Harper23290b82019-05-02 00:02:561146 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511147 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031148 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1149 failed_on_default_network_callback_, callback_.callback()));
rchd6163f32017-01-30 23:50:381150
1151 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241152 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rchd6163f32017-01-30 23:50:381153 EXPECT_TRUE(stream.get());
1154
1155 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1156 EXPECT_EQ(10000u, session->connection()->GetStats().srtt_us);
1157 ASSERT_TRUE(session->config()->HasInitialRoundTripTimeUsToSend());
1158 EXPECT_EQ(10000u, session->config()->GetInitialRoundTripTimeUsToSend());
1159}
1160
1161TEST_P(QuicStreamFactoryTest, 2gInitialRtt) {
1162 ScopedMockNetworkChangeNotifier notifier;
1163 notifier.mock_network_change_notifier()->SetConnectionType(
1164 NetworkChangeNotifier::CONNECTION_2G);
Zhongyi Shi967d2f12019-02-08 20:58:531165 test_params_.quic_estimate_initial_rtt = true;
rchd6163f32017-01-30 23:50:381166
1167 Initialize();
1168 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1169 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1170
Ryan Hamiltonabad59e2019-06-06 04:02:591171 MockQuicData socket_data(version_);
rchd6163f32017-01-30 23:50:381172 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431173 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171174 socket_data.AddSocketDataToFactory(socket_factory_.get());
rchd6163f32017-01-30 23:50:381175
zhongyi98d6a9262017-05-19 02:47:451176 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331177 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031178 request.Request(
Nick Harper23290b82019-05-02 00:02:561179 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511180 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031181 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1182 failed_on_default_network_callback_, callback_.callback()));
rchd6163f32017-01-30 23:50:381183
1184 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241185 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rchd6163f32017-01-30 23:50:381186 EXPECT_TRUE(stream.get());
1187
1188 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1189 EXPECT_EQ(1200000u, session->connection()->GetStats().srtt_us);
1190 ASSERT_TRUE(session->config()->HasInitialRoundTripTimeUsToSend());
1191 EXPECT_EQ(1200000u, session->config()->GetInitialRoundTripTimeUsToSend());
1192}
1193
1194TEST_P(QuicStreamFactoryTest, 3gInitialRtt) {
1195 ScopedMockNetworkChangeNotifier notifier;
1196 notifier.mock_network_change_notifier()->SetConnectionType(
1197 NetworkChangeNotifier::CONNECTION_3G);
Zhongyi Shi967d2f12019-02-08 20:58:531198 test_params_.quic_estimate_initial_rtt = true;
rchd6163f32017-01-30 23:50:381199
1200 Initialize();
1201 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1202 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1203
Ryan Hamiltonabad59e2019-06-06 04:02:591204 MockQuicData socket_data(version_);
rchd6163f32017-01-30 23:50:381205 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431206 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171207 socket_data.AddSocketDataToFactory(socket_factory_.get());
rchd6163f32017-01-30 23:50:381208
zhongyi98d6a9262017-05-19 02:47:451209 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331210 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031211 request.Request(
Nick Harper23290b82019-05-02 00:02:561212 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511213 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031214 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1215 failed_on_default_network_callback_, callback_.callback()));
rchd6163f32017-01-30 23:50:381216
1217 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241218 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rchd6163f32017-01-30 23:50:381219 EXPECT_TRUE(stream.get());
1220
1221 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1222 EXPECT_EQ(400000u, session->connection()->GetStats().srtt_us);
1223 ASSERT_TRUE(session->config()->HasInitialRoundTripTimeUsToSend());
1224 EXPECT_EQ(400000u, session->config()->GetInitialRoundTripTimeUsToSend());
1225}
1226
rch68955482015-09-24 00:14:391227TEST_P(QuicStreamFactoryTest, GoAway) {
jri7046038f2015-10-22 00:29:261228 Initialize();
rch6faa4d42016-01-05 20:48:431229 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1230 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:261231
Ryan Hamiltonabad59e2019-06-06 04:02:591232 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361233 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431234 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171235 socket_data.AddSocketDataToFactory(socket_factory_.get());
rch68955482015-09-24 00:14:391236
zhongyi98d6a9262017-05-19 02:47:451237 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331238 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031239 request.Request(
Nick Harper23290b82019-05-02 00:02:561240 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511241 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031242 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1243 failed_on_default_network_callback_, callback_.callback()));
rch68955482015-09-24 00:14:391244
robpercival214763f2016-07-01 23:27:011245 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241246 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rch68955482015-09-24 00:14:391247 EXPECT_TRUE(stream.get());
1248
bnc912a04b2016-04-20 14:19:501249 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
rch68955482015-09-24 00:14:391250
Ryan Hamilton8d9ee76e2018-05-29 23:52:521251 session->OnGoAway(quic::QuicGoAwayFrame());
rch68955482015-09-24 00:14:391252
bnc912a04b2016-04-20 14:19:501253 EXPECT_FALSE(HasActiveSession(host_port_pair_));
rch68955482015-09-24 00:14:391254
1255 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1256 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1257}
1258
zhongyi6b5a3892016-03-12 04:46:201259TEST_P(QuicStreamFactoryTest, GoAwayForConnectionMigrationWithPortOnly) {
1260 Initialize();
1261 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1262 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1263
Ryan Hamiltonabad59e2019-06-06 04:02:591264 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361265 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431266 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171267 socket_data.AddSocketDataToFactory(socket_factory_.get());
zhongyi6b5a3892016-03-12 04:46:201268
zhongyi98d6a9262017-05-19 02:47:451269 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331270 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031271 request.Request(
Nick Harper23290b82019-05-02 00:02:561272 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511273 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031274 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1275 failed_on_default_network_callback_, callback_.callback()));
zhongyi6b5a3892016-03-12 04:46:201276
robpercival214763f2016-07-01 23:27:011277 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241278 std::unique_ptr<HttpStream> stream = CreateStream(&request);
zhongyi6b5a3892016-03-12 04:46:201279 EXPECT_TRUE(stream.get());
1280
bnc912a04b2016-04-20 14:19:501281 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
zhongyi6b5a3892016-03-12 04:46:201282
Ryan Hamilton8d9ee76e2018-05-29 23:52:521283 session->OnGoAway(quic::QuicGoAwayFrame(
1284 quic::kInvalidControlFrameId, quic::QUIC_ERROR_MIGRATING_PORT, 0,
1285 "peer connection migration due to port change only"));
zhongyi6b5a3892016-03-12 04:46:201286 NetErrorDetails details;
1287 EXPECT_FALSE(details.quic_port_migration_detected);
1288 session->PopulateNetErrorDetails(&details);
1289 EXPECT_TRUE(details.quic_port_migration_detected);
1290 details.quic_port_migration_detected = false;
1291 stream->PopulateNetErrorDetails(&details);
1292 EXPECT_TRUE(details.quic_port_migration_detected);
1293
bnc912a04b2016-04-20 14:19:501294 EXPECT_FALSE(HasActiveSession(host_port_pair_));
zhongyi6b5a3892016-03-12 04:46:201295
1296 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1297 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1298}
1299
[email protected]5db452202014-08-19 05:22:151300TEST_P(QuicStreamFactoryTest, Pooling) {
jri7046038f2015-10-22 00:29:261301 Initialize();
rch6faa4d42016-01-05 20:48:431302 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1303 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:261304
Ryan Hamiltonabad59e2019-06-06 04:02:591305 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361306 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431307 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171308 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]eed749f92013-12-23 18:57:381309
rch6faa4d42016-01-05 20:48:431310 HostPortPair server2(kServer2HostName, kDefaultServerPort);
Renjiea0cb4a2c2018-09-26 23:37:301311 host_resolver_->set_synchronous_mode(true);
1312 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
1313 "192.168.0.1", "");
1314 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]eed749f92013-12-23 18:57:381315
zhongyi98d6a9262017-05-19 02:47:451316 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:511317 EXPECT_EQ(OK,
1318 request.Request(
1319 host_port_pair_, version_.transport_version, privacy_mode_,
1320 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
1321 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1322 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241323 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]eed749f92013-12-23 18:57:381324 EXPECT_TRUE(stream.get());
1325
1326 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451327 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:511328 EXPECT_EQ(OK,
1329 request2.Request(
1330 server2, version_.transport_version, privacy_mode_,
1331 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
1332 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
1333 failed_on_default_network_callback_, callback.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241334 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]eed749f92013-12-23 18:57:381335 EXPECT_TRUE(stream2.get());
1336
bnc912a04b2016-04-20 14:19:501337 EXPECT_EQ(GetActiveSession(host_port_pair_), GetActiveSession(server2));
[email protected]eed749f92013-12-23 18:57:381338
rch37de576c2015-05-17 20:28:171339 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1340 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]eed749f92013-12-23 18:57:381341}
1342
jri94ddc3142016-08-26 01:32:431343TEST_P(QuicStreamFactoryTest, PoolingWithServerMigration) {
1344 // Set up session to migrate.
Renjiea0cb4a2c2018-09-26 23:37:301345 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
1346 "192.168.0.1", "");
jri94ddc3142016-08-26 01:32:431347 IPEndPoint alt_address = IPEndPoint(IPAddress(1, 2, 3, 4), 443);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521348 quic::QuicConfig config;
Victor Vasiliev4f6fb892019-05-31 16:58:311349 config.SetAlternateServerAddressToSend(ToQuicSocketAddress(alt_address));
jri94ddc3142016-08-26 01:32:431350
1351 VerifyServerMigration(config, alt_address);
1352
1353 // Close server-migrated session.
1354 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Renjieba55fae2018-09-20 03:05:161355 session->CloseSessionOnError(0u, quic::QUIC_NO_ERROR,
1356 quic::ConnectionCloseBehavior::SILENT_CLOSE);
jri94ddc3142016-08-26 01:32:431357
Ryan Hamilton0d65a8c2019-06-07 00:46:021358 client_maker_.Reset();
Ryan Hamilton9f2eac32019-06-27 03:15:541359 client_maker_.set_coalesce_http_frames(false);
jri94ddc3142016-08-26 01:32:431360 // Set up server IP, socket, proof, and config for new session.
1361 HostPortPair server2(kServer2HostName, kDefaultServerPort);
Renjiea0cb4a2c2018-09-26 23:37:301362 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
jri94ddc3142016-08-26 01:32:431363
1364 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521365 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Ryan Hamilton0d65a8c2019-06-07 00:46:021366 client_maker_.MakeInitialSettingsPacket(1));
bnceb9aa7112017-01-05 01:03:461367 MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(),
1368 settings_packet->length(), 1)};
fayang3bcb8b502016-12-07 21:44:371369
Ryan Sleevib8d7ea02018-05-07 20:01:011370 SequencedSocketData socket_data(reads, writes);
Ryan Hamilton0d65a8c2019-06-07 00:46:021371 QuicPacketPrinter printer(version_);
1372 socket_data.set_printer(&printer);
Zhongyi Shi5f587cc2017-11-21 23:24:171373 socket_factory_->AddSocketDataProvider(&socket_data);
jri94ddc3142016-08-26 01:32:431374
1375 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1376 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521377 quic::QuicConfig config2;
jri94ddc3142016-08-26 01:32:431378 crypto_client_stream_factory_.SetConfig(config2);
1379
1380 // Create new request to cause new session creation.
1381 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451382 QuicStreamRequest request2(factory_.get());
jri94ddc3142016-08-26 01:32:431383 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031384 request2.Request(
Nick Harper23290b82019-05-02 00:02:561385 server2, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511386 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031387 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
1388 failed_on_default_network_callback_, callback.callback()));
jri94ddc3142016-08-26 01:32:431389 EXPECT_EQ(OK, callback.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:241390 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
jri94ddc3142016-08-26 01:32:431391 EXPECT_TRUE(stream2.get());
1392
1393 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1394 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1395 // EXPECT_EQ(GetActiveSession(host_port_pair_), GetActiveSession(server2));
1396}
1397
[email protected]eed749f92013-12-23 18:57:381398TEST_P(QuicStreamFactoryTest, NoPoolingAfterGoAway) {
jri7046038f2015-10-22 00:29:261399 Initialize();
rch6faa4d42016-01-05 20:48:431400 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1401 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1402 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:261403
Ryan Hamiltonabad59e2019-06-06 04:02:591404 MockQuicData socket_data1(version_);
rcha00569732016-08-27 11:09:361405 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431406 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171407 socket_data1.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamilton0d65a8c2019-06-07 00:46:021408 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:591409 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:361410 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431411 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171412 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]eed749f92013-12-23 18:57:381413
rch6faa4d42016-01-05 20:48:431414 HostPortPair server2(kServer2HostName, kDefaultServerPort);
Renjiea0cb4a2c2018-09-26 23:37:301415 host_resolver_->set_synchronous_mode(true);
1416 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
1417 "192.168.0.1", "");
1418 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]eed749f92013-12-23 18:57:381419
zhongyi98d6a9262017-05-19 02:47:451420 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:511421 EXPECT_EQ(OK,
1422 request.Request(
1423 host_port_pair_, version_.transport_version, privacy_mode_,
1424 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
1425 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1426 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241427 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]eed749f92013-12-23 18:57:381428 EXPECT_TRUE(stream.get());
1429
1430 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451431 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:511432 EXPECT_EQ(OK,
1433 request2.Request(
1434 server2, version_.transport_version, privacy_mode_,
1435 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
1436 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
1437 failed_on_default_network_callback_, callback.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241438 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]eed749f92013-12-23 18:57:381439 EXPECT_TRUE(stream2.get());
1440
bnc912a04b2016-04-20 14:19:501441 factory_->OnSessionGoingAway(GetActiveSession(host_port_pair_));
1442 EXPECT_FALSE(HasActiveSession(host_port_pair_));
1443 EXPECT_FALSE(HasActiveSession(server2));
[email protected]eed749f92013-12-23 18:57:381444
1445 TestCompletionCallback callback3;
zhongyi98d6a9262017-05-19 02:47:451446 QuicStreamRequest request3(factory_.get());
Matt Menke26e41542019-06-05 01:09:511447 EXPECT_EQ(OK,
1448 request3.Request(
1449 server2, version_.transport_version, privacy_mode_,
1450 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
1451 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
1452 failed_on_default_network_callback_, callback3.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241453 std::unique_ptr<HttpStream> stream3 = CreateStream(&request3);
[email protected]eed749f92013-12-23 18:57:381454 EXPECT_TRUE(stream3.get());
1455
bnc912a04b2016-04-20 14:19:501456 EXPECT_TRUE(HasActiveSession(server2));
[email protected]eed749f92013-12-23 18:57:381457
rch37de576c2015-05-17 20:28:171458 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
1459 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
1460 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1461 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]eed749f92013-12-23 18:57:381462}
1463
[email protected]5db452202014-08-19 05:22:151464TEST_P(QuicStreamFactoryTest, HttpsPooling) {
jri7046038f2015-10-22 00:29:261465 Initialize();
rch6faa4d42016-01-05 20:48:431466
Ryan Hamiltonabad59e2019-06-06 04:02:591467 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361468 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431469 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171470 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]eed749f92013-12-23 18:57:381471
rch6faa4d42016-01-05 20:48:431472 HostPortPair server1(kDefaultServerHostName, 443);
1473 HostPortPair server2(kServer2HostName, 443);
[email protected]eed749f92013-12-23 18:57:381474
bncf8bf0722015-05-19 20:04:131475 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
bnc20daf9a2015-05-15 17:11:011476 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
[email protected]eed749f92013-12-23 18:57:381477
Renjiea0cb4a2c2018-09-26 23:37:301478 host_resolver_->set_synchronous_mode(true);
1479 host_resolver_->rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
1480 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]eed749f92013-12-23 18:57:381481
zhongyi98d6a9262017-05-19 02:47:451482 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:511483 EXPECT_EQ(OK,
1484 request.Request(
1485 server1, version_.transport_version, privacy_mode_,
1486 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
1487 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1488 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241489 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]eed749f92013-12-23 18:57:381490 EXPECT_TRUE(stream.get());
1491
1492 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451493 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:511494 EXPECT_EQ(OK,
1495 request2.Request(
1496 server2, version_.transport_version, privacy_mode_,
1497 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
1498 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
1499 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241500 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]eed749f92013-12-23 18:57:381501 EXPECT_TRUE(stream2.get());
1502
bnc912a04b2016-04-20 14:19:501503 EXPECT_EQ(GetActiveSession(server1), GetActiveSession(server2));
[email protected]eed749f92013-12-23 18:57:381504
rch37de576c2015-05-17 20:28:171505 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1506 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]eed749f92013-12-23 18:57:381507}
1508
[email protected]5db452202014-08-19 05:22:151509TEST_P(QuicStreamFactoryTest, HttpsPoolingWithMatchingPins) {
jri7046038f2015-10-22 00:29:261510 Initialize();
Ryan Hamiltonabad59e2019-06-06 04:02:591511 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361512 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431513 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171514 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]5db452202014-08-19 05:22:151515
rch6faa4d42016-01-05 20:48:431516 HostPortPair server1(kDefaultServerHostName, 443);
1517 HostPortPair server2(kServer2HostName, 443);
Matt Mueller230996f12018-10-22 19:39:441518 transport_security_state_.EnableStaticPinsForTesting();
1519 ScopedTransportSecurityStateSource scoped_security_state_source;
[email protected]5db452202014-08-19 05:22:151520
Matt Mueller230996f12018-10-22 19:39:441521 HashValue primary_pin(HASH_VALUE_SHA256);
1522 EXPECT_TRUE(primary_pin.FromString(
1523 "sha256/Nn8jk5By4Vkq6BeOVZ7R7AC6XUUBZsWmUbJR1f1Y5FY="));
bncf8bf0722015-05-19 20:04:131524 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
Matt Mueller230996f12018-10-22 19:39:441525 verify_details.cert_verify_result.public_key_hashes.push_back(primary_pin);
bnc20daf9a2015-05-15 17:11:011526 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
[email protected]5db452202014-08-19 05:22:151527
Renjiea0cb4a2c2018-09-26 23:37:301528 host_resolver_->set_synchronous_mode(true);
1529 host_resolver_->rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
1530 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]5db452202014-08-19 05:22:151531
zhongyi98d6a9262017-05-19 02:47:451532 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:511533 EXPECT_EQ(OK,
1534 request.Request(
1535 server1, version_.transport_version, privacy_mode_,
1536 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
1537 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1538 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241539 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]5db452202014-08-19 05:22:151540 EXPECT_TRUE(stream.get());
1541
1542 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451543 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:511544 EXPECT_EQ(OK,
1545 request2.Request(
1546 server2, version_.transport_version, privacy_mode_,
1547 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
1548 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
1549 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241550 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]5db452202014-08-19 05:22:151551 EXPECT_TRUE(stream2.get());
1552
bnc912a04b2016-04-20 14:19:501553 EXPECT_EQ(GetActiveSession(server1), GetActiveSession(server2));
[email protected]5db452202014-08-19 05:22:151554
rch37de576c2015-05-17 20:28:171555 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1556 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]5db452202014-08-19 05:22:151557}
1558
1559TEST_P(QuicStreamFactoryTest, NoHttpsPoolingWithDifferentPins) {
jri7046038f2015-10-22 00:29:261560 Initialize();
rcha00569732016-08-27 11:09:361561
Ryan Hamiltonabad59e2019-06-06 04:02:591562 MockQuicData socket_data1(version_);
rcha00569732016-08-27 11:09:361563 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431564 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171565 socket_data1.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamilton0d65a8c2019-06-07 00:46:021566 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:591567 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:361568 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431569 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171570 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]5db452202014-08-19 05:22:151571
rch6faa4d42016-01-05 20:48:431572 HostPortPair server1(kDefaultServerHostName, 443);
1573 HostPortPair server2(kServer2HostName, 443);
Matt Mueller230996f12018-10-22 19:39:441574 transport_security_state_.EnableStaticPinsForTesting();
1575 ScopedTransportSecurityStateSource scoped_security_state_source;
[email protected]5db452202014-08-19 05:22:151576
bncf8bf0722015-05-19 20:04:131577 ProofVerifyDetailsChromium verify_details1 = DefaultProofVerifyDetails();
Matt Mueller230996f12018-10-22 19:39:441578 uint8_t bad_pin = 3;
bnc20daf9a2015-05-15 17:11:011579 verify_details1.cert_verify_result.public_key_hashes.push_back(
1580 test::GetTestHashValue(bad_pin));
1581 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
1582
Matt Mueller230996f12018-10-22 19:39:441583 HashValue primary_pin(HASH_VALUE_SHA256);
1584 EXPECT_TRUE(primary_pin.FromString(
1585 "sha256/Nn8jk5By4Vkq6BeOVZ7R7AC6XUUBZsWmUbJR1f1Y5FY="));
bncf8bf0722015-05-19 20:04:131586 ProofVerifyDetailsChromium verify_details2 = DefaultProofVerifyDetails();
Matt Mueller230996f12018-10-22 19:39:441587 verify_details2.cert_verify_result.public_key_hashes.push_back(primary_pin);
bnc20daf9a2015-05-15 17:11:011588 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
[email protected]5db452202014-08-19 05:22:151589
Renjiea0cb4a2c2018-09-26 23:37:301590 host_resolver_->set_synchronous_mode(true);
1591 host_resolver_->rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
1592 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]5db452202014-08-19 05:22:151593
zhongyi98d6a9262017-05-19 02:47:451594 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:511595 EXPECT_EQ(OK,
1596 request.Request(
1597 server1, version_.transport_version, privacy_mode_,
1598 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
1599 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1600 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241601 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]5db452202014-08-19 05:22:151602 EXPECT_TRUE(stream.get());
1603
1604 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451605 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:511606 EXPECT_EQ(OK,
1607 request2.Request(
1608 server2, version_.transport_version, privacy_mode_,
1609 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
1610 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
1611 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241612 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]5db452202014-08-19 05:22:151613 EXPECT_TRUE(stream2.get());
1614
bnc912a04b2016-04-20 14:19:501615 EXPECT_NE(GetActiveSession(server1), GetActiveSession(server2));
[email protected]5db452202014-08-19 05:22:151616
rch37de576c2015-05-17 20:28:171617 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
1618 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
1619 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1620 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]5db452202014-08-19 05:22:151621}
1622
[email protected]1e960032013-12-20 19:00:201623TEST_P(QuicStreamFactoryTest, Goaway) {
jri7046038f2015-10-22 00:29:261624 Initialize();
rch6faa4d42016-01-05 20:48:431625 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1626 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1627 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1628
Ryan Hamiltonabad59e2019-06-06 04:02:591629 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361630 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431631 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171632 socket_data.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamilton0d65a8c2019-06-07 00:46:021633 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:591634 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:361635 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431636 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171637 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]4d283b32013-10-17 12:57:271638
zhongyi98d6a9262017-05-19 02:47:451639 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331640 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031641 request.Request(
Nick Harper23290b82019-05-02 00:02:561642 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511643 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031644 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1645 failed_on_default_network_callback_, callback_.callback()));
[email protected]4d283b32013-10-17 12:57:271646
robpercival214763f2016-07-01 23:27:011647 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241648 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]4d283b32013-10-17 12:57:271649 EXPECT_TRUE(stream.get());
1650
1651 // Mark the session as going away. Ensure that while it is still alive
1652 // that it is no longer active.
bnc912a04b2016-04-20 14:19:501653 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri7046038f2015-10-22 00:29:261654 factory_->OnSessionGoingAway(session);
1655 EXPECT_EQ(true,
1656 QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
bnc912a04b2016-04-20 14:19:501657 EXPECT_FALSE(HasActiveSession(host_port_pair_));
[email protected]4d283b32013-10-17 12:57:271658
1659 // Create a new request for the same destination and verify that a
1660 // new session is created.
zhongyi98d6a9262017-05-19 02:47:451661 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331662 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031663 request2.Request(
Nick Harper23290b82019-05-02 00:02:561664 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511665 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031666 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1667 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:011668 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241669 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]4d283b32013-10-17 12:57:271670 EXPECT_TRUE(stream2.get());
1671
bnc912a04b2016-04-20 14:19:501672 EXPECT_TRUE(HasActiveSession(host_port_pair_));
1673 EXPECT_NE(session, GetActiveSession(host_port_pair_));
jri7046038f2015-10-22 00:29:261674 EXPECT_EQ(true,
1675 QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
[email protected]4d283b32013-10-17 12:57:271676
1677 stream2.reset();
1678 stream.reset();
1679
rch37de576c2015-05-17 20:28:171680 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1681 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1682 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1683 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]4d283b32013-10-17 12:57:271684}
1685
[email protected]1e960032013-12-20 19:00:201686TEST_P(QuicStreamFactoryTest, MaxOpenStream) {
jri7046038f2015-10-22 00:29:261687 Initialize();
rch6faa4d42016-01-05 20:48:431688 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1689 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1690
Fan Yang32c5a112018-12-10 20:06:331691 quic::QuicStreamId stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
Ryan Hamiltonabad59e2019-06-06 04:02:591692 MockQuicData socket_data(version_);
Zhongyi Shi32f2fd02018-04-16 18:23:431693 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Nick Harper23290b82019-05-02 00:02:561694 if (version_.transport_version == quic::QUIC_VERSION_99) {
David Schinazicc1bc592019-04-24 19:40:311695 socket_data.AddWrite(SYNCHRONOUS, client_maker_.MakeStreamsBlockedPacket(
Ryan Hamilton4aeec562019-05-17 21:22:521696 2, true, 51,
David Schinazicc1bc592019-04-24 19:40:311697 /*unidirectional=*/false));
Frank Kastenholzc9b9bea2018-12-03 20:13:471698 socket_data.AddWrite(
1699 SYNCHRONOUS, client_maker_.MakeRstPacket(3, true, stream_id,
1700 quic::QUIC_STREAM_CANCELLED));
1701 socket_data.AddRead(
1702 ASYNC, server_maker_.MakeRstPacket(1, false, stream_id,
1703 quic::QUIC_STREAM_CANCELLED));
Fan Yang32c5a112018-12-10 20:06:331704 socket_data.AddRead(
Ryan Hamilton4aeec562019-05-17 21:22:521705 ASYNC, server_maker_.MakeMaxStreamsPacket(4, true, 52,
David Schinazicc1bc592019-04-24 19:40:311706 /*unidirectional=*/false));
Frank Kastenholzc9b9bea2018-12-03 20:13:471707 } else {
1708 socket_data.AddWrite(
1709 SYNCHRONOUS, client_maker_.MakeRstPacket(2, true, stream_id,
1710 quic::QUIC_STREAM_CANCELLED));
1711 socket_data.AddRead(
1712 ASYNC, server_maker_.MakeRstPacket(1, false, stream_id,
1713 quic::QUIC_STREAM_CANCELLED));
Frank Kastenholz878763bf2018-11-28 19:14:481714 }
rcha00569732016-08-27 11:09:361715 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:171716 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]0b2294d32013-08-02 00:46:361717
1718 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:391719 request_info.traffic_annotation =
1720 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1721
xunjieli1d2b4272017-04-25 22:37:171722 std::vector<std::unique_ptr<HttpStream>> streams;
Ryan Hamilton9835e662018-08-02 05:36:271723 // The MockCryptoClientStream sets max_open_streams to be
Ryan Hamilton8d9ee76e2018-05-29 23:52:521724 // quic::kDefaultMaxStreamsPerConnection / 2.
1725 for (size_t i = 0; i < quic::kDefaultMaxStreamsPerConnection / 2; i++) {
zhongyi98d6a9262017-05-19 02:47:451726 QuicStreamRequest request(factory_.get());
Zhongyi Shia6b68d112018-09-24 07:49:031727 int rv = request.Request(
Nick Harper23290b82019-05-02 00:02:561728 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511729 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031730 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1731 failed_on_default_network_callback_, callback_.callback());
[email protected]0b2294d32013-08-02 00:46:361732 if (i == 0) {
robpercival214763f2016-07-01 23:27:011733 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1734 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]0b2294d32013-08-02 00:46:361735 } else {
robpercival214763f2016-07-01 23:27:011736 EXPECT_THAT(rv, IsOk());
[email protected]0b2294d32013-08-02 00:46:361737 }
Yixin Wang7891a39d2017-11-08 20:59:241738 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0b2294d32013-08-02 00:46:361739 EXPECT_TRUE(stream);
Steven Valdezb4ff0412018-01-18 22:39:271740 EXPECT_EQ(OK,
1741 stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:391742 net_log_, CompletionOnceCallback()));
avib3635452016-10-21 18:33:531743 streams.push_back(std::move(stream));
[email protected]0b2294d32013-08-02 00:46:361744 }
1745
zhongyi98d6a9262017-05-19 02:47:451746 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:511747 EXPECT_EQ(OK,
1748 request.Request(
1749 host_port_pair_, version_.transport_version, privacy_mode_,
1750 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
1751 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1752 failed_on_default_network_callback_, CompletionOnceCallback()));
Yixin Wang7891a39d2017-11-08 20:59:241753 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0b2294d32013-08-02 00:46:361754 EXPECT_TRUE(stream);
rjshaded5ced072015-12-18 19:26:021755 EXPECT_EQ(ERR_IO_PENDING,
Steven Valdezb4ff0412018-01-18 22:39:271756 stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
1757 net_log_, callback_.callback()));
[email protected]0b2294d32013-08-02 00:46:361758
1759 // Close the first stream.
1760 streams.front()->Close(false);
ckrasicea295fe2015-10-31 05:03:271761 // Trigger exchange of RSTs that in turn allow progress for the last
1762 // stream.
Frank Kastenholz878763bf2018-11-28 19:14:481763 base::RunLoop().RunUntilIdle();
robpercival214763f2016-07-01 23:27:011764 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]0b2294d32013-08-02 00:46:361765
rch37de576c2015-05-17 20:28:171766 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1767 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
ckrasicea295fe2015-10-31 05:03:271768
1769 // Force close of the connection to suppress the generation of RST
1770 // packets when streams are torn down, which wouldn't be relevant to
1771 // this test anyway.
bnc912a04b2016-04-20 14:19:501772 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521773 session->connection()->CloseConnection(
1774 quic::QUIC_PUBLIC_RESET, "test",
1775 quic::ConnectionCloseBehavior::SILENT_CLOSE);
[email protected]0b2294d32013-08-02 00:46:361776}
1777
[email protected]1e960032013-12-20 19:00:201778TEST_P(QuicStreamFactoryTest, ResolutionErrorInCreate) {
jri7046038f2015-10-22 00:29:261779 Initialize();
Ryan Hamiltonabad59e2019-06-06 04:02:591780 MockQuicData socket_data(version_);
Zhongyi Shi5f587cc2017-11-21 23:24:171781 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]e13201d82012-12-12 05:00:321782
Renjiea0cb4a2c2018-09-26 23:37:301783 host_resolver_->rules()->AddSimulatedFailure(kDefaultServerHostName);
[email protected]e13201d82012-12-12 05:00:321784
zhongyi98d6a9262017-05-19 02:47:451785 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331786 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031787 request.Request(
Nick Harper23290b82019-05-02 00:02:561788 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511789 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031790 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1791 failed_on_default_network_callback_, callback_.callback()));
[email protected]e13201d82012-12-12 05:00:321792
robpercival214763f2016-07-01 23:27:011793 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
[email protected]e13201d82012-12-12 05:00:321794
rch37de576c2015-05-17 20:28:171795 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1796 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]e13201d82012-12-12 05:00:321797}
1798
[email protected]1e960032013-12-20 19:00:201799TEST_P(QuicStreamFactoryTest, ConnectErrorInCreate) {
jri7046038f2015-10-22 00:29:261800 Initialize();
rcha00569732016-08-27 11:09:361801
Ryan Hamiltonabad59e2019-06-06 04:02:591802 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361803 socket_data.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
Zhongyi Shi5f587cc2017-11-21 23:24:171804 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]3c772402013-12-18 21:38:111805
zhongyi98d6a9262017-05-19 02:47:451806 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331807 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031808 request.Request(
Nick Harper23290b82019-05-02 00:02:561809 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511810 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031811 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1812 failed_on_default_network_callback_, callback_.callback()));
[email protected]3c772402013-12-18 21:38:111813
robpercival214763f2016-07-01 23:27:011814 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_ADDRESS_IN_USE));
[email protected]3c772402013-12-18 21:38:111815
rch37de576c2015-05-17 20:28:171816 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1817 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]3c772402013-12-18 21:38:111818}
1819
[email protected]1e960032013-12-20 19:00:201820TEST_P(QuicStreamFactoryTest, CancelCreate) {
jri7046038f2015-10-22 00:29:261821 Initialize();
Ryan Hamiltonabad59e2019-06-06 04:02:591822 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361823 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431824 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171825 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]e13201d82012-12-12 05:00:321826 {
zhongyi98d6a9262017-05-19 02:47:451827 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331828 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031829 request.Request(
Nick Harper23290b82019-05-02 00:02:561830 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511831 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031832 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1833 failed_on_default_network_callback_, callback_.callback()));
[email protected]e13201d82012-12-12 05:00:321834 }
1835
mmenke651bae7f2015-12-18 21:26:451836 base::RunLoop().RunUntilIdle();
[email protected]e13201d82012-12-12 05:00:321837
zhongyi98d6a9262017-05-19 02:47:451838 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:511839 EXPECT_EQ(OK,
1840 request2.Request(
1841 host_port_pair_, version_.transport_version, privacy_mode_,
1842 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
1843 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1844 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241845 std::unique_ptr<HttpStream> stream = CreateStream(&request2);
rch68a80eb2017-04-25 05:24:241846
[email protected]e13201d82012-12-12 05:00:321847 EXPECT_TRUE(stream.get());
1848 stream.reset();
1849
rch37de576c2015-05-17 20:28:171850 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1851 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]e13201d82012-12-12 05:00:321852}
1853
[email protected]1e960032013-12-20 19:00:201854TEST_P(QuicStreamFactoryTest, CloseAllSessions) {
jri7046038f2015-10-22 00:29:261855 Initialize();
rch6faa4d42016-01-05 20:48:431856 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1857 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1858 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1859
Ryan Hamiltonabad59e2019-06-06 04:02:591860 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361861 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431862 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Ryan Hamilton8d9ee76e2018-05-29 23:52:521863 socket_data.AddWrite(
1864 SYNCHRONOUS, ConstructClientRstPacket(2, quic::QUIC_RST_ACKNOWLEDGEMENT));
Renjieba55fae2018-09-20 03:05:161865 socket_data.AddWrite(SYNCHRONOUS,
1866 client_maker_.MakeConnectionClosePacket(
Ryan Hamilton1556a722019-06-19 21:04:171867 3, true, quic::QUIC_PEER_GOING_AWAY, "net error"));
Zhongyi Shi5f587cc2017-11-21 23:24:171868 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]56dfb902013-01-03 23:17:551869
Ryan Hamilton0d65a8c2019-06-07 00:46:021870 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:591871 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:361872 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431873 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171874 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]56dfb902013-01-03 23:17:551875
zhongyi98d6a9262017-05-19 02:47:451876 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331877 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031878 request.Request(
Nick Harper23290b82019-05-02 00:02:561879 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511880 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031881 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1882 failed_on_default_network_callback_, callback_.callback()));
[email protected]56dfb902013-01-03 23:17:551883
robpercival214763f2016-07-01 23:27:011884 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241885 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0b2294d32013-08-02 00:46:361886 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:391887 request_info.traffic_annotation =
1888 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:271889 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:391890 net_log_, CompletionOnceCallback()));
[email protected]56dfb902013-01-03 23:17:551891
1892 // Close the session and verify that stream saw the error.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521893 factory_->CloseAllSessions(ERR_INTERNET_DISCONNECTED,
Ryan Hamilton1556a722019-06-19 21:04:171894 quic::QUIC_PEER_GOING_AWAY);
[email protected]56dfb902013-01-03 23:17:551895 EXPECT_EQ(ERR_INTERNET_DISCONNECTED,
1896 stream->ReadResponseHeaders(callback_.callback()));
1897
1898 // Now attempting to request a stream to the same origin should create
1899 // a new session.
1900
zhongyi98d6a9262017-05-19 02:47:451901 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331902 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031903 request2.Request(
Nick Harper23290b82019-05-02 00:02:561904 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511905 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031906 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1907 failed_on_default_network_callback_, callback_.callback()));
[email protected]56dfb902013-01-03 23:17:551908
robpercival214763f2016-07-01 23:27:011909 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241910 stream = CreateStream(&request2);
[email protected]56dfb902013-01-03 23:17:551911 stream.reset(); // Will reset stream 3.
1912
rch37de576c2015-05-17 20:28:171913 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1914 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1915 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1916 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]56dfb902013-01-03 23:17:551917}
1918
zhongyi363c91c2017-03-23 23:16:081919// Regression test for crbug.com/700617. Test a write error during the
1920// crypto handshake will not hang QuicStreamFactory::Job and should
1921// report QUIC_HANDSHAKE_FAILED to upper layers. Subsequent
1922// QuicStreamRequest should succeed without hanging.
1923TEST_P(QuicStreamFactoryTest,
1924 WriteErrorInCryptoConnectWithAsyncHostResolution) {
1925 Initialize();
1926 // Use unmocked crypto stream to do crypto connect.
1927 crypto_client_stream_factory_.set_handshake_mode(
Zhongyi Shi879659422018-08-02 17:58:251928 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
zhongyi363c91c2017-03-23 23:16:081929
Ryan Hamiltonabad59e2019-06-06 04:02:591930 MockQuicData socket_data(version_);
zhongyi363c91c2017-03-23 23:16:081931 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1932 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
1933 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:171934 socket_data.AddSocketDataToFactory(socket_factory_.get());
zhongyi363c91c2017-03-23 23:16:081935
1936 // Create request, should fail after the write of the CHLO fails.
zhongyi98d6a9262017-05-19 02:47:451937 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331938 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031939 request.Request(
Nick Harper23290b82019-05-02 00:02:561940 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511941 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031942 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1943 failed_on_default_network_callback_, callback_.callback()));
zhongyi363c91c2017-03-23 23:16:081944 EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED, callback_.WaitForResult());
1945 EXPECT_FALSE(HasActiveSession(host_port_pair_));
1946 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
1947
1948 // Verify new requests can be sent normally without hanging.
1949 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271950 MockCryptoClientStream::COLD_START);
zhongyi363c91c2017-03-23 23:16:081951 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1952 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
Ryan Hamilton0d65a8c2019-06-07 00:46:021953 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:591954 MockQuicData socket_data2(version_);
zhongyi363c91c2017-03-23 23:16:081955 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431956 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171957 socket_data2.AddSocketDataToFactory(socket_factory_.get());
zhongyi363c91c2017-03-23 23:16:081958
zhongyi98d6a9262017-05-19 02:47:451959 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331960 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031961 request2.Request(
Nick Harper23290b82019-05-02 00:02:561962 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511963 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031964 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1965 failed_on_default_network_callback_, callback_.callback()));
zhongyi363c91c2017-03-23 23:16:081966 EXPECT_FALSE(HasActiveSession(host_port_pair_));
1967 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
1968 // Run the message loop to complete host resolution.
1969 base::RunLoop().RunUntilIdle();
1970
1971 // Complete handshake. QuicStreamFactory::Job should complete and succeed.
1972 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521973 quic::QuicSession::HANDSHAKE_CONFIRMED);
zhongyi363c91c2017-03-23 23:16:081974 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1975 EXPECT_TRUE(HasActiveSession(host_port_pair_));
1976 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
1977
1978 // Create QuicHttpStream.
Yixin Wang7891a39d2017-11-08 20:59:241979 std::unique_ptr<HttpStream> stream = CreateStream(&request2);
zhongyi363c91c2017-03-23 23:16:081980 EXPECT_TRUE(stream.get());
1981 stream.reset();
1982 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1983 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1984 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1985 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
1986}
1987
1988TEST_P(QuicStreamFactoryTest, WriteErrorInCryptoConnectWithSyncHostResolution) {
1989 Initialize();
1990 // Use unmocked crypto stream to do crypto connect.
1991 crypto_client_stream_factory_.set_handshake_mode(
Zhongyi Shi879659422018-08-02 17:58:251992 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
Renjiea0cb4a2c2018-09-26 23:37:301993 host_resolver_->set_synchronous_mode(true);
1994 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
1995 "192.168.0.1", "");
zhongyi363c91c2017-03-23 23:16:081996
Ryan Hamiltonabad59e2019-06-06 04:02:591997 MockQuicData socket_data(version_);
zhongyi363c91c2017-03-23 23:16:081998 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1999 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
2000 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:172001 socket_data.AddSocketDataToFactory(socket_factory_.get());
zhongyi363c91c2017-03-23 23:16:082002
2003 // Create request, should fail immediately.
zhongyi98d6a9262017-05-19 02:47:452004 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332005 EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED,
Zhongyi Shia6b68d112018-09-24 07:49:032006 request.Request(
Nick Harper23290b82019-05-02 00:02:562007 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:512008 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032009 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2010 failed_on_default_network_callback_, callback_.callback()));
zhongyi363c91c2017-03-23 23:16:082011 // Check no active session, or active jobs left for this server.
2012 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2013 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
2014
2015 // Verify new requests can be sent normally without hanging.
2016 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:272017 MockCryptoClientStream::COLD_START);
zhongyi363c91c2017-03-23 23:16:082018 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2019 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
Ryan Hamilton0d65a8c2019-06-07 00:46:022020 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:592021 MockQuicData socket_data2(version_);
zhongyi363c91c2017-03-23 23:16:082022 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432023 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:172024 socket_data2.AddSocketDataToFactory(socket_factory_.get());
zhongyi363c91c2017-03-23 23:16:082025
zhongyi98d6a9262017-05-19 02:47:452026 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332027 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032028 request2.Request(
Nick Harper23290b82019-05-02 00:02:562029 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:512030 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032031 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2032 failed_on_default_network_callback_, callback_.callback()));
zhongyi363c91c2017-03-23 23:16:082033 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2034 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
2035
2036 // Complete handshake.
2037 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522038 quic::QuicSession::HANDSHAKE_CONFIRMED);
zhongyi363c91c2017-03-23 23:16:082039 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2040 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2041 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
2042
2043 // Create QuicHttpStream.
Yixin Wang7891a39d2017-11-08 20:59:242044 std::unique_ptr<HttpStream> stream = CreateStream(&request2);
zhongyi363c91c2017-03-23 23:16:082045 EXPECT_TRUE(stream.get());
2046 stream.reset();
2047 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2048 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2049 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
2050 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
2051}
2052
Zhongyi Shi63574b72018-06-01 20:22:252053TEST_P(QuicStreamFactoryTest, CloseSessionsOnIPAddressChanged) {
Zhongyi Shi967d2f12019-02-08 20:58:532054 test_params_.quic_close_sessions_on_ip_change = true;
jri7046038f2015-10-22 00:29:262055 Initialize();
rch6faa4d42016-01-05 20:48:432056 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2057 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2058 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri8c44d692015-10-23 23:53:412059
Ryan Hamiltonabad59e2019-06-06 04:02:592060 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:362061 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432062 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Ryan Hamilton8d9ee76e2018-05-29 23:52:522063 socket_data.AddWrite(
2064 SYNCHRONOUS, ConstructClientRstPacket(2, quic::QUIC_RST_ACKNOWLEDGEMENT));
Renjieba55fae2018-09-20 03:05:162065 socket_data.AddWrite(
2066 SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
2067 3, true, quic::QUIC_IP_ADDRESS_CHANGED, "net error"));
Zhongyi Shi5f587cc2017-11-21 23:24:172068 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]f698a012013-05-06 20:18:592069
Ryan Hamilton0d65a8c2019-06-07 00:46:022070 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:592071 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:362072 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432073 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:172074 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]f698a012013-05-06 20:18:592075
zhongyi98d6a9262017-05-19 02:47:452076 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332077 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032078 request.Request(
Nick Harper23290b82019-05-02 00:02:562079 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:512080 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032081 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2082 failed_on_default_network_callback_, callback_.callback()));
[email protected]f698a012013-05-06 20:18:592083
robpercival214763f2016-07-01 23:27:012084 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242085 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0b2294d32013-08-02 00:46:362086 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392087 request_info.traffic_annotation =
2088 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272089 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392090 net_log_, CompletionOnceCallback()));
[email protected]f698a012013-05-06 20:18:592091
Zhongyi Shi63574b72018-06-01 20:22:252092 // Check an active session exisits for the destination.
2093 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2094 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
2095 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2096
Ryan Hamilton8e32a2b2017-08-28 20:06:522097 IPAddress last_address;
2098 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
Zhongyi Shi63574b72018-06-01 20:22:252099 // Change the IP address and verify that stream saw the error and the active
2100 // session is closed.
jri8c44d692015-10-23 23:53:412101 NotifyIPAddressChanged();
[email protected]f698a012013-05-06 20:18:592102 EXPECT_EQ(ERR_NETWORK_CHANGED,
2103 stream->ReadResponseHeaders(callback_.callback()));
jri7046038f2015-10-22 00:29:262104 EXPECT_TRUE(factory_->require_confirmation());
Ryan Hamilton8e32a2b2017-08-28 20:06:522105 EXPECT_FALSE(http_server_properties_.GetSupportsQuic(&last_address));
Zhongyi Shi63574b72018-06-01 20:22:252106 // Check no active session exists for the destination.
2107 EXPECT_FALSE(HasActiveSession(host_port_pair_));
[email protected]f698a012013-05-06 20:18:592108
2109 // Now attempting to request a stream to the same origin should create
2110 // a new session.
zhongyi98d6a9262017-05-19 02:47:452111 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332112 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032113 request2.Request(
Nick Harper23290b82019-05-02 00:02:562114 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:512115 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032116 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2117 failed_on_default_network_callback_, callback_.callback()));
[email protected]f698a012013-05-06 20:18:592118
robpercival214763f2016-07-01 23:27:012119 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242120 stream = CreateStream(&request2);
[email protected]f698a012013-05-06 20:18:592121
Zhongyi Shi63574b72018-06-01 20:22:252122 // Check a new active session exisits for the destination and the old session
2123 // is no longer live.
2124 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2125 QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
2126 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
2127
2128 stream.reset(); // Will reset stream 3.
rch37de576c2015-05-17 20:28:172129 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2130 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2131 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
2132 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]f698a012013-05-06 20:18:592133}
2134
Zhongyi Shi63574b72018-06-01 20:22:252135// Test that if goaway_session_on_ip_change is set, old sessions will be marked
2136// as going away on IP address change instead of being closed. New requests will
2137// go to a new connection.
2138TEST_P(QuicStreamFactoryTest, GoAwaySessionsOnIPAddressChanged) {
Zhongyi Shi967d2f12019-02-08 20:58:532139 test_params_.quic_goaway_sessions_on_ip_change = true;
Zhongyi Shi63574b72018-06-01 20:22:252140 Initialize();
2141 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2142 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2143 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2144
Ryan Hamiltonabad59e2019-06-06 04:02:592145 MockQuicData quic_data1(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:022146 quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Fan Yang32c5a112018-12-10 20:06:332147 quic_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:022148 SYNCHRONOUS,
2149 ConstructGetRequestPacket(
2150 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi63574b72018-06-01 20:22:252151 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
2152 quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:332153 ASYNC,
2154 ConstructOkResponsePacket(
2155 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true));
Zhongyi Shi63574b72018-06-01 20:22:252156 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
2157 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2158
Ryan Hamilton0d65a8c2019-06-07 00:46:022159 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:592160 MockQuicData quic_data2(version_);
Zhongyi Shi63574b72018-06-01 20:22:252161 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
Ryan Hamilton0d65a8c2019-06-07 00:46:022162 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Zhongyi Shi63574b72018-06-01 20:22:252163 quic_data2.AddSocketDataToFactory(socket_factory_.get());
2164
2165 // Create request and QuicHttpStream.
2166 QuicStreamRequest request(factory_.get());
2167 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032168 request.Request(
Nick Harper23290b82019-05-02 00:02:562169 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:512170 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032171 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2172 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi63574b72018-06-01 20:22:252173 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2174 std::unique_ptr<HttpStream> stream = CreateStream(&request);
2175 EXPECT_TRUE(stream.get());
2176
2177 // Cause QUIC stream to be created.
2178 HttpRequestInfo request_info;
2179 request_info.method = "GET";
2180 request_info.url = url_;
2181 request_info.traffic_annotation =
2182 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2183 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
2184 net_log_, CompletionOnceCallback()));
2185
2186 // Ensure that session is alive and active.
2187 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
2188 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2189 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2190
2191 // Send GET request on stream.
2192 HttpResponseInfo response;
2193 HttpRequestHeaders request_headers;
2194 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
2195 callback_.callback()));
2196
2197 // Receive an IP address change notification.
2198 NotifyIPAddressChanged();
2199
2200 // The connection should still be alive, but marked as going away.
2201 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2202 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2203 EXPECT_EQ(1u, session->GetNumActiveStreams());
2204
2205 // Resume the data, response should be read from the original connection.
2206 quic_data1.Resume();
2207 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
2208 EXPECT_EQ(200, response.headers->response_code());
2209 EXPECT_EQ(0u, session->GetNumActiveStreams());
2210
2211 // Second request should be sent on a new connection.
2212 QuicStreamRequest request2(factory_.get());
2213 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032214 request2.Request(
Nick Harper23290b82019-05-02 00:02:562215 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:512216 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032217 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2218 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi63574b72018-06-01 20:22:252219 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2220 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
2221 EXPECT_TRUE(stream2.get());
2222
2223 // Check an active session exisits for the destination.
2224 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2225 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2226 QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
2227 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
2228
2229 stream.reset();
2230 stream2.reset();
2231 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
2232 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
2233 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
2234 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
2235}
2236
Jana Iyengarba355772017-09-21 22:03:212237TEST_P(QuicStreamFactoryTest, OnIPAddressChangedWithConnectionMigration) {
Zhongyi Shi1a054612018-06-14 04:59:082238 InitializeConnectionMigrationV2Test(
Jana Iyengarba355772017-09-21 22:03:212239 {kDefaultNetworkForTests, kNewNetworkForTests});
2240 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2241 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2242 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2243
Ryan Hamiltonabad59e2019-06-06 04:02:592244 MockQuicData socket_data(version_);
Jana Iyengarba355772017-09-21 22:03:212245 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432246 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Ryan Hamilton8d9ee76e2018-05-29 23:52:522247 socket_data.AddWrite(
2248 SYNCHRONOUS, ConstructClientRstPacket(2, quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:172249 socket_data.AddSocketDataToFactory(socket_factory_.get());
Jana Iyengarba355772017-09-21 22:03:212250
2251 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332252 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032253 request.Request(
Nick Harper23290b82019-05-02 00:02:562254 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:512255 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032256 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2257 failed_on_default_network_callback_, callback_.callback()));
Jana Iyengarba355772017-09-21 22:03:212258
2259 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242260 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Jana Iyengarba355772017-09-21 22:03:212261 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392262 request_info.traffic_annotation =
2263 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272264 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392265 net_log_, CompletionOnceCallback()));
Jana Iyengarba355772017-09-21 22:03:212266
2267 IPAddress last_address;
2268 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
2269
2270 // Change the IP address and verify that the connection is unaffected.
2271 NotifyIPAddressChanged();
2272 EXPECT_FALSE(factory_->require_confirmation());
2273 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
2274
2275 // Attempting a new request to the same origin uses the same connection.
2276 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:512277 EXPECT_EQ(OK,
2278 request2.Request(
2279 host_port_pair_, version_.transport_version, privacy_mode_,
2280 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
2281 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2282 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:242283 stream = CreateStream(&request2);
Jana Iyengarba355772017-09-21 22:03:212284
2285 stream.reset();
2286 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2287 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2288}
2289
Zhongyi Shia0644e32018-06-21 05:19:522290TEST_P(QuicStreamFactoryTest, MigrateOnNetworkMadeDefaultWithSynchronousWrite) {
2291 TestMigrationOnNetworkMadeDefault(SYNCHRONOUS);
jri9f303712016-09-13 01:10:222292}
2293
Zhongyi Shia0644e32018-06-21 05:19:522294TEST_P(QuicStreamFactoryTest, MigrateOnNetworkMadeDefaultWithAsyncWrite) {
2295 TestMigrationOnNetworkMadeDefault(ASYNC);
jri9f303712016-09-13 01:10:222296}
2297
Zhongyi Shia0644e32018-06-21 05:19:522298// Sets up a test which attempts connection migration successfully after probing
2299// when a new network is made as default and the old default is still available.
2300// |write_mode| specifies the write mode for the last write before
2301// OnNetworkMadeDefault is delivered to session.
2302void QuicStreamFactoryTestBase::TestMigrationOnNetworkMadeDefault(
2303 IoMode write_mode) {
2304 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri7e636642016-01-14 06:57:082305 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2306 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2307 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2308
Zhongyi Shia0644e32018-06-21 05:19:522309 // Using a testing task runner so that we can control time.
2310 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
2311 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
2312
2313 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2314 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
2315
Ryan Hamiltonabad59e2019-06-06 04:02:592316 MockQuicData quic_data1(version_);
Zhongyi Shia0644e32018-06-21 05:19:522317 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
Ryan Hamilton0d65a8c2019-06-07 00:46:022318 quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shia0644e32018-06-21 05:19:522319 quic_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:022320 write_mode,
2321 ConstructGetRequestPacket(
2322 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shia0644e32018-06-21 05:19:522323 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2324
2325 // Set up the second socket data provider that is used after migration.
2326 // The response to the earlier request is read on the new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:592327 MockQuicData quic_data2(version_);
Zhongyi Shia0644e32018-06-21 05:19:522328 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:252329 quic_data2.AddWrite(SYNCHRONOUS,
2330 client_maker_.MakeConnectivityProbingPacket(3, true));
Zhongyi Shia0644e32018-06-21 05:19:522331 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
2332 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:252333 quic_data2.AddRead(ASYNC,
2334 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shia0644e32018-06-21 05:19:522335 // Ping packet to send after migration is completed.
2336 quic_data2.AddWrite(ASYNC,
2337 client_maker_.MakeAckAndPingPacket(4, false, 1, 1, 1));
2338 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:332339 ASYNC,
2340 ConstructOkResponsePacket(
2341 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shia0644e32018-06-21 05:19:522342 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:332343 quic_data2.AddWrite(
2344 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
2345 5, false, GetNthClientInitiatedBidirectionalStreamId(0),
2346 quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true));
Zhongyi Shia0644e32018-06-21 05:19:522347 quic_data2.AddSocketDataToFactory(socket_factory_.get());
jri7e636642016-01-14 06:57:082348
2349 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452350 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332351 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032352 request.Request(
Nick Harper23290b82019-05-02 00:02:562353 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:512354 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032355 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2356 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012357 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242358 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri7e636642016-01-14 06:57:082359 EXPECT_TRUE(stream.get());
2360
2361 // Cause QUIC stream to be created.
2362 HttpRequestInfo request_info;
2363 request_info.method = "GET";
bnc3d9035b32016-06-30 18:18:482364 request_info.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:392365 request_info.traffic_annotation =
2366 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272367 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392368 net_log_, CompletionOnceCallback()));
jri7e636642016-01-14 06:57:082369
2370 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502371 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri7e636642016-01-14 06:57:082372 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2373 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2374
2375 // Send GET request on stream.
2376 HttpResponseInfo response;
2377 HttpRequestHeaders request_headers;
2378 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
2379 callback_.callback()));
2380
Zhongyi Shia0644e32018-06-21 05:19:522381 // Deliver a signal that a alternate network is connected now, this should
2382 // cause the connection to start early migration on path degrading.
2383 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2384 ->SetConnectedNetworksList(
2385 {kDefaultNetworkForTests, kNewNetworkForTests});
2386 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2387 ->NotifyNetworkConnected(kNewNetworkForTests);
jri9f303712016-09-13 01:10:222388
Zhongyi Shia0644e32018-06-21 05:19:522389 // Cause the connection to report path degrading to the session.
2390 // Due to lack of alternate network, session will not mgirate connection.
2391 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
jri7e636642016-01-14 06:57:082392 scoped_mock_network_change_notifier_->mock_network_change_notifier()
jrie2661982016-08-20 08:24:342393 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri7e636642016-01-14 06:57:082394
Zhongyi Shia0644e32018-06-21 05:19:522395 // A task will be posted to migrate to the new default network.
2396 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2397 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
2398
2399 // Execute the posted task to migrate back to the default network.
2400 task_runner->RunUntilIdle();
2401 // Another task to try send a new connectivity probe is posted. And a task to
2402 // retry migrate back to default network is scheduled.
2403 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
2404 // Next connectivity probe is scheduled to be sent in 2 *
2405 // kDefaultRTTMilliSecs.
2406 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
2407 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
2408 next_task_delay);
2409
2410 // The connection should still be alive, and not marked as going away.
jri7e636642016-01-14 06:57:082411 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia0644e32018-06-21 05:19:522412 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2413 EXPECT_EQ(1u, session->GetNumActiveStreams());
2414 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
2415
2416 // Resume quic data and a connectivity probe response will be read on the new
2417 // socket, declare probing as successful. And a new task to WriteToNewSocket
2418 // will be posted to complete migration.
2419 quic_data2.Resume();
2420
2421 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2422 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri7e636642016-01-14 06:57:082423 EXPECT_EQ(1u, session->GetNumActiveStreams());
2424
Zhongyi Shia0644e32018-06-21 05:19:522425 // There should be three pending tasks, the nearest one will complete
2426 // migration to the new network.
2427 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
2428 next_task_delay = task_runner->NextPendingTaskDelay();
2429 EXPECT_EQ(base::TimeDelta(), next_task_delay);
2430 task_runner->FastForwardBy(next_task_delay);
2431
2432 // Response headers are received over the new network.
2433 EXPECT_THAT(callback_.WaitForResult(), IsOk());
jri7e636642016-01-14 06:57:082434 EXPECT_EQ(200, response.headers->response_code());
2435
Zhongyi Shia0644e32018-06-21 05:19:522436 // Now there are two pending tasks, the nearest one was to send connectivity
2437 // probe and has been cancelled due to successful migration.
2438 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
2439 next_task_delay = task_runner->NextPendingTaskDelay();
2440 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
2441 next_task_delay);
2442 task_runner->FastForwardBy(next_task_delay);
jri7e636642016-01-14 06:57:082443
Zhongyi Shia0644e32018-06-21 05:19:522444 // There's one more task to mgirate back to the default network in 0.4s, which
2445 // is also cancelled due to the success migration on the previous trial.
2446 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2447 next_task_delay = task_runner->NextPendingTaskDelay();
2448 base::TimeDelta expected_delay =
2449 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
2450 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
2451 EXPECT_EQ(expected_delay, next_task_delay);
2452 task_runner->FastForwardBy(next_task_delay);
2453 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
jri7e636642016-01-14 06:57:082454
Zhongyi Shia0644e32018-06-21 05:19:522455 // Verify that the session is still alive.
jri7e636642016-01-14 06:57:082456 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia0644e32018-06-21 05:19:522457 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri7e636642016-01-14 06:57:082458
Zhongyi Shia0644e32018-06-21 05:19:522459 stream.reset();
2460 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
2461 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
2462 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
2463 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
jri7e636642016-01-14 06:57:082464}
2465
Zhongyi Shib3bc982c2018-07-10 19:59:242466// Regression test for http://859674.
2467// This test veries that a writer will not attempt to write packets until being
2468// unblocked on both socket level and network level. In this test, a probing
2469// writer is used to send two connectivity probes to the peer: where the first
2470// one completes successfully, while a connectivity response is received before
2471// completes sending the second one. The connection migration attempt will
2472// proceed while the probing writer is blocked at the socket level, which will
2473// block the writer on the network level. Once connection migration completes
2474// successfully, the probing writer will be unblocked on the network level, it
2475// will not attempt to write new packets until the socket level is unblocked.
2476TEST_P(QuicStreamFactoryTest, MigratedToBlockedSocketAfterProbing) {
2477 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
2478 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2479 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2480 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2481
2482 // Using a testing task runner so that we can control time.
2483 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
2484 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
2485
2486 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2487 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
2488
Ryan Hamiltonabad59e2019-06-06 04:02:592489 MockQuicData quic_data1(version_);
Zhongyi Shib3bc982c2018-07-10 19:59:242490 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
Ryan Hamilton0d65a8c2019-06-07 00:46:022491 quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Fan Yang32c5a112018-12-10 20:06:332492 quic_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:022493 SYNCHRONOUS,
2494 ConstructGetRequestPacket(
2495 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shib3bc982c2018-07-10 19:59:242496 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2497
2498 // Set up the second socket data provider that is used after migration.
2499 // The response to the earlier request is read on the new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:592500 MockQuicData quic_data2(version_);
Zhongyi Shib3bc982c2018-07-10 19:59:242501 // First connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:252502 quic_data2.AddWrite(SYNCHRONOUS,
2503 client_maker_.MakeConnectivityProbingPacket(3, true));
Zhongyi Shib3bc982c2018-07-10 19:59:242504 quic_data2.AddRead(ASYNC,
2505 ERR_IO_PENDING); // Pause so that we can control time.
2506 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:252507 quic_data2.AddRead(ASYNC,
2508 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shib3bc982c2018-07-10 19:59:242509 // Second connectivity probe which will complete asynchronously.
Zhongyi Shi879659422018-08-02 17:58:252510 quic_data2.AddWrite(ASYNC,
2511 client_maker_.MakeConnectivityProbingPacket(4, true));
Zhongyi Shib3bc982c2018-07-10 19:59:242512 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:332513 ASYNC,
2514 ConstructOkResponsePacket(
2515 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shib3bc982c2018-07-10 19:59:242516 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2517 quic_data2.AddWrite(ASYNC,
2518 client_maker_.MakeAckAndPingPacket(5, false, 1, 1, 1));
Fan Yang32c5a112018-12-10 20:06:332519 quic_data2.AddWrite(
2520 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
2521 6, false, GetNthClientInitiatedBidirectionalStreamId(0),
2522 quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true));
Zhongyi Shib3bc982c2018-07-10 19:59:242523
2524 quic_data2.AddSocketDataToFactory(socket_factory_.get());
2525
2526 // Create request and QuicHttpStream.
2527 QuicStreamRequest request(factory_.get());
2528 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032529 request.Request(
Nick Harper23290b82019-05-02 00:02:562530 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:512531 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032532 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2533 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shib3bc982c2018-07-10 19:59:242534 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2535 std::unique_ptr<HttpStream> stream = CreateStream(&request);
2536 EXPECT_TRUE(stream.get());
2537
2538 // Cause QUIC stream to be created.
2539 HttpRequestInfo request_info;
2540 request_info.method = "GET";
2541 request_info.url = url_;
2542 request_info.traffic_annotation =
2543 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2544 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
2545 net_log_, CompletionOnceCallback()));
2546
2547 // Ensure that session is alive and active.
2548 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
2549 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2550 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2551
2552 // Send GET request on stream.
2553 HttpResponseInfo response;
2554 HttpRequestHeaders request_headers;
2555 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
2556 callback_.callback()));
2557
2558 // Deliver a signal that a alternate network is connected now, this should
2559 // cause the connection to start early migration on path degrading.
2560 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2561 ->SetConnectedNetworksList(
2562 {kDefaultNetworkForTests, kNewNetworkForTests});
2563 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2564 ->NotifyNetworkConnected(kNewNetworkForTests);
2565
2566 // Cause the connection to report path degrading to the session.
2567 // Due to lack of alternate network, session will not mgirate connection.
2568 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
2569 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2570 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2571
2572 // A task will be posted to migrate to the new default network.
2573 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2574 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
2575
2576 // Execute the posted task to migrate back to the default network.
2577 task_runner->RunUntilIdle();
2578 // Another task to resend a new connectivity probe is posted. And a task to
2579 // retry migrate back to default network is scheduled.
2580 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
2581 // Next connectivity probe is scheduled to be sent in 2 *
2582 // kDefaultRTTMilliSecs.
2583 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
2584 base::TimeDelta expected_delay =
2585 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
2586 EXPECT_EQ(expected_delay, next_task_delay);
2587
2588 // Fast forward to send the second connectivity probe. The write will be
2589 // asynchronous and complete after the read completes.
2590 task_runner->FastForwardBy(next_task_delay);
2591
2592 // Resume quic data and a connectivity probe response will be read on the new
2593 // socket, declare probing as successful.
2594 quic_data2.Resume();
2595
2596 // The connection should still be alive, and not marked as going away.
2597 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2598 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2599 EXPECT_EQ(1u, session->GetNumActiveStreams());
2600 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
2601
2602 // There should be three pending tasks, the nearest one will complete
2603 // migration to the new network. Second task will retry migrate back to
2604 // default but cancelled, and the third task will retry send connectivity
2605 // probe but also cancelled.
2606 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
2607 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
2608 task_runner->RunUntilIdle();
2609
2610 // Response headers are received over the new network.
2611 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2612 EXPECT_EQ(200, response.headers->response_code());
2613
2614 // Run the message loop to complete the asynchronous write of ack and ping.
2615 base::RunLoop().RunUntilIdle();
2616
2617 // Now there are two pending tasks, the nearest one was to retry migrate back
2618 // to default network and has been cancelled due to successful migration.
2619 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
2620 expected_delay =
2621 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
2622 expected_delay;
2623 next_task_delay = task_runner->NextPendingTaskDelay();
2624 EXPECT_EQ(expected_delay, next_task_delay);
2625 task_runner->FastForwardBy(next_task_delay);
2626
2627 // There's one more task to retry sending connectivity probe in 0.4s and has
2628 // also been cancelled due to the successful probing.
2629 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2630 next_task_delay = task_runner->NextPendingTaskDelay();
2631 expected_delay =
2632 base::TimeDelta::FromMilliseconds(3 * 2 * kDefaultRTTMilliSecs) -
2633 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs);
2634 EXPECT_EQ(expected_delay, next_task_delay);
2635 task_runner->FastForwardBy(next_task_delay);
2636 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
2637
2638 // Verify that the session is still alive.
2639 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2640 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2641
2642 stream.reset();
2643 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
2644 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
2645 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
2646 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
2647}
2648
Zhongyi Shib1b1fa42018-06-19 23:13:472649// This test verifies that session times out connection migration attempt
2650// with signals delivered in the following order (no alternate network is
2651// available):
2652// - default network disconnected is delivered: session attempts connection
2653// migration but found not alternate network. Session waits for a new network
Zhongyi Shie01f2db2019-02-22 19:53:232654// comes up in the next kWaitTimeForNewNetworkSecs seconds.
Zhongyi Shib1b1fa42018-06-19 23:13:472655// - no new network is connected, migration times out. Session is closed.
2656TEST_P(QuicStreamFactoryTest, MigrationTimeoutWithNoNewNetwork) {
2657 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri7e636642016-01-14 06:57:082658 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2659 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2660
Zhongyi Shib1b1fa42018-06-19 23:13:472661 // Using a testing task runner so that we can control time.
2662 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
2663 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
jri5b785512016-09-13 04:29:112664
Ryan Hamiltonabad59e2019-06-06 04:02:592665 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:362666 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432667 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:172668 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri7e636642016-01-14 06:57:082669
2670 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452671 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332672 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032673 request.Request(
Nick Harper23290b82019-05-02 00:02:562674 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:512675 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032676 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2677 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012678 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242679 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri7e636642016-01-14 06:57:082680 EXPECT_TRUE(stream.get());
2681
2682 // Cause QUIC stream to be created.
2683 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392684 request_info.traffic_annotation =
2685 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272686 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392687 net_log_, CompletionOnceCallback()));
jri7e636642016-01-14 06:57:082688
2689 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502690 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri7e636642016-01-14 06:57:082691 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2692 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2693
2694 // Trigger connection migration. Since there are no networks
jri5b785512016-09-13 04:29:112695 // to migrate to, this should cause the session to wait for a new network.
jri7e636642016-01-14 06:57:082696 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2697 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
2698
jri5b785512016-09-13 04:29:112699 // The migration will not fail until the migration alarm timeout.
2700 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shib1b1fa42018-06-19 23:13:472701 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:112702 EXPECT_EQ(1u, session->GetNumActiveStreams());
2703 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
2704 EXPECT_EQ(true, session->connection()->writer()->IsWriteBlocked());
2705
Zhongyi Shib1b1fa42018-06-19 23:13:472706 // Migration will be timed out after kWaitTimeForNewNetwokSecs.
2707 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2708 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
2709 EXPECT_EQ(base::TimeDelta::FromSeconds(kWaitTimeForNewNetworkSecs),
2710 next_task_delay);
2711 task_runner->FastForwardBy(next_task_delay);
jri5b785512016-09-13 04:29:112712
2713 // The connection should now be closed. A request for response
2714 // headers should fail.
jri7e636642016-01-14 06:57:082715 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2716 EXPECT_FALSE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:112717 EXPECT_EQ(ERR_NETWORK_CHANGED, callback_.WaitForResult());
jri7e636642016-01-14 06:57:082718
2719 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2720 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2721}
2722
Zhongyi Shi21e99532018-07-17 22:23:072723// This test verifies that connectivity probes will be sent even if there is
2724// a non-migratable stream. However, when connection migrates to the
Zhongyi Shic16b4102019-02-12 00:37:402725// successfully probed path, any non-migratable streams will be reset.
Zhongyi Shi32fe14d42019-02-28 00:25:362726TEST_P(QuicStreamFactoryTest,
2727 OnNetworkMadeDefaultNonMigratableStream_MigrateIdleSessions) {
2728 TestOnNetworkMadeDefaultNonMigratableStream(true);
2729}
2730
2731// This test verifies that connectivity probes will be sent even if there is
2732// a non-migratable stream. However, when connection migrates to the
2733// successfully probed path, any non-migratable stream will be reset. And if
2734// the connection becomes idle then, close the connection.
2735TEST_P(QuicStreamFactoryTest,
2736 OnNetworkMadeDefaultNonMigratableStream_DoNotMigrateIdleSessions) {
2737 TestOnNetworkMadeDefaultNonMigratableStream(false);
2738}
2739
2740void QuicStreamFactoryTestBase::TestOnNetworkMadeDefaultNonMigratableStream(
2741 bool migrate_idle_sessions) {
2742 test_params_.quic_migrate_idle_sessions = migrate_idle_sessions;
Zhongyi Shi5f587cc2017-11-21 23:24:172743 InitializeConnectionMigrationV2Test(
2744 {kDefaultNetworkForTests, kNewNetworkForTests});
2745 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2746 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2747
Ryan Hamiltonabad59e2019-06-06 04:02:592748 MockQuicData socket_data(version_);
Zhongyi Shi5f587cc2017-11-21 23:24:172749 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432750 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi32fe14d42019-02-28 00:25:362751 if (!migrate_idle_sessions) {
2752 socket_data.AddWrite(
2753 SYNCHRONOUS,
2754 client_maker_.MakeRstAckAndConnectionClosePacket(
2755 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
2756 quic::QUIC_STREAM_CANCELLED,
2757 quic::QuicTime::Delta::FromMilliseconds(0), 1, 1, 1,
2758 quic::QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS,
2759 "net error"));
2760 }
Renjieba55fae2018-09-20 03:05:162761
Zhongyi Shi5f587cc2017-11-21 23:24:172762 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri231c2972016-03-08 19:50:112763
Zhongyi Shi21e99532018-07-17 22:23:072764 // Set up the second socket data provider that is used for probing.
Ryan Hamiltonabad59e2019-06-06 04:02:592765 MockQuicData quic_data1(version_);
Zhongyi Shi21e99532018-07-17 22:23:072766 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:252767 quic_data1.AddWrite(SYNCHRONOUS,
2768 client_maker_.MakeConnectivityProbingPacket(2, true));
Zhongyi Shi21e99532018-07-17 22:23:072769 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
2770 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:252771 quic_data1.AddRead(ASYNC,
2772 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shi32fe14d42019-02-28 00:25:362773 if (migrate_idle_sessions) {
2774 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
2775 // A RESET will be sent to the peer to cancel the non-migratable stream.
2776 quic_data1.AddWrite(
2777 SYNCHRONOUS,
2778 client_maker_.MakeRstPacket(
2779 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
2780 quic::QUIC_STREAM_CANCELLED));
2781 // Ping packet to send after migration is completed.
2782 quic_data1.AddWrite(SYNCHRONOUS,
2783 client_maker_.MakeAckAndPingPacket(4, false, 1, 1, 1));
2784 }
Zhongyi Shi21e99532018-07-17 22:23:072785 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2786
jri231c2972016-03-08 19:50:112787 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452788 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332789 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032790 request.Request(
Nick Harper23290b82019-05-02 00:02:562791 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:512792 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032793 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2794 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012795 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242796 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri231c2972016-03-08 19:50:112797 EXPECT_TRUE(stream.get());
2798
2799 // Cause QUIC stream to be created, but marked as non-migratable.
2800 HttpRequestInfo request_info;
Zhongyi Shibb28b1f2018-07-18 02:41:262801 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Ramin Halavati683bcaa92018-02-14 08:42:392802 request_info.traffic_annotation =
2803 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272804 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392805 net_log_, CompletionOnceCallback()));
jri231c2972016-03-08 19:50:112806
2807 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502808 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri231c2972016-03-08 19:50:112809 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2810 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2811
Zhongyi Shi21e99532018-07-17 22:23:072812 // Trigger connection migration. Session will start to probe the alternative
2813 // network. Although there is a non-migratable stream, session will still be
2814 // active until probing is declared as successful.
jri231c2972016-03-08 19:50:112815 scoped_mock_network_change_notifier_->mock_network_change_notifier()
jrie2661982016-08-20 08:24:342816 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri231c2972016-03-08 19:50:112817
2818 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shi21e99532018-07-17 22:23:072819 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri231c2972016-03-08 19:50:112820 EXPECT_EQ(1u, session->GetNumActiveStreams());
2821
Zhongyi Shi21e99532018-07-17 22:23:072822 // Resume data to read a connectivity probing response, which will cause
Zhongyi Shic16b4102019-02-12 00:37:402823 // non-migtable streams to be closed.
Zhongyi Shi21e99532018-07-17 22:23:072824 quic_data1.Resume();
2825 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shi32fe14d42019-02-28 00:25:362826 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(host_port_pair_));
Zhongyi Shi21e99532018-07-17 22:23:072827 EXPECT_EQ(0u, session->GetNumActiveStreams());
jri231c2972016-03-08 19:50:112828
Zhongyi Shic16b4102019-02-12 00:37:402829 base::RunLoop().RunUntilIdle();
2830
Zhongyi Shi21e99532018-07-17 22:23:072831 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
2832 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
jri231c2972016-03-08 19:50:112833 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2834 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2835}
2836
jri9f303712016-09-13 01:10:222837TEST_P(QuicStreamFactoryTest, OnNetworkMadeDefaultConnectionMigrationDisabled) {
Zhongyi Shi5f587cc2017-11-21 23:24:172838 InitializeConnectionMigrationV2Test(
2839 {kDefaultNetworkForTests, kNewNetworkForTests});
2840 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2841 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2842
Ryan Hamiltonabad59e2019-06-06 04:02:592843 MockQuicData socket_data(version_);
Zhongyi Shi5f587cc2017-11-21 23:24:172844 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432845 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
2846 socket_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:332847 SYNCHRONOUS, client_maker_.MakeRstPacket(
2848 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
2849 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:172850 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9c541572016-03-29 17:51:482851
2852 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452853 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332854 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032855 request.Request(
Nick Harper23290b82019-05-02 00:02:562856 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:512857 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032858 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2859 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012860 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242861 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9c541572016-03-29 17:51:482862 EXPECT_TRUE(stream.get());
2863
2864 // Cause QUIC stream to be created.
2865 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392866 request_info.traffic_annotation =
2867 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272868 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392869 net_log_, CompletionOnceCallback()));
jri9c541572016-03-29 17:51:482870
2871 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502872 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri9c541572016-03-29 17:51:482873 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2874 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2875
2876 // Set session config to have connection migration disabled.
Ryan Hamilton8d9ee76e2018-05-29 23:52:522877 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
2878 session->config());
jri9c541572016-03-29 17:51:482879 EXPECT_TRUE(session->config()->DisableConnectionMigration());
2880
2881 // Trigger connection migration. Since there is a non-migratable stream,
2882 // this should cause session to continue but be marked as going away.
2883 scoped_mock_network_change_notifier_->mock_network_change_notifier()
jrie2661982016-08-20 08:24:342884 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri9c541572016-03-29 17:51:482885
2886 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2887 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2888 EXPECT_EQ(1u, session->GetNumActiveStreams());
2889
2890 stream.reset();
2891
2892 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2893 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2894}
2895
Zhongyi Shi32fe14d42019-02-28 00:25:362896TEST_P(QuicStreamFactoryTest,
2897 OnNetworkDisconnectedNonMigratableStream_DoNotMigrateIdleSessions) {
2898 TestOnNetworkDisconnectedNonMigratableStream(false);
2899}
2900
2901TEST_P(QuicStreamFactoryTest,
2902 OnNetworkDisconnectedNonMigratableStream_MigrateIdleSessions) {
2903 TestOnNetworkDisconnectedNonMigratableStream(true);
2904}
2905
2906void QuicStreamFactoryTestBase::TestOnNetworkDisconnectedNonMigratableStream(
2907 bool migrate_idle_sessions) {
2908 test_params_.quic_migrate_idle_sessions = migrate_idle_sessions;
Zhongyi Shi5f587cc2017-11-21 23:24:172909 InitializeConnectionMigrationV2Test(
2910 {kDefaultNetworkForTests, kNewNetworkForTests});
2911 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2912 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2913
Ryan Hamiltonabad59e2019-06-06 04:02:592914 MockQuicData failed_socket_data(version_);
2915 MockQuicData socket_data(version_);
Zhongyi Shi32fe14d42019-02-28 00:25:362916 if (migrate_idle_sessions) {
Zhongyi Shi32fe14d42019-02-28 00:25:362917 failed_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:022918 failed_socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi32fe14d42019-02-28 00:25:362919 // A RESET will be sent to the peer to cancel the non-migratable stream.
2920 failed_socket_data.AddWrite(
2921 SYNCHRONOUS, client_maker_.MakeRstPacket(
2922 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
2923 quic::QUIC_STREAM_CANCELLED));
2924 failed_socket_data.AddSocketDataToFactory(socket_factory_.get());
2925
2926 // Set up second socket data provider that is used after migration.
2927 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
2928 // Ping packet to send after migration.
2929 socket_data.AddWrite(
2930 SYNCHRONOUS, client_maker_.MakePingPacket(3, /*include_version=*/true));
2931 socket_data.AddSocketDataToFactory(socket_factory_.get());
2932 } else {
2933 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2934 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
2935 socket_data.AddWrite(
2936 SYNCHRONOUS, client_maker_.MakeRstPacket(
2937 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
2938 quic::QUIC_STREAM_CANCELLED));
2939 socket_data.AddSocketDataToFactory(socket_factory_.get());
2940 }
jri231c2972016-03-08 19:50:112941
2942 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452943 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332944 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032945 request.Request(
Nick Harper23290b82019-05-02 00:02:562946 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:512947 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032948 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2949 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012950 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242951 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri231c2972016-03-08 19:50:112952 EXPECT_TRUE(stream.get());
2953
2954 // Cause QUIC stream to be created, but marked as non-migratable.
2955 HttpRequestInfo request_info;
Zhongyi Shibb28b1f2018-07-18 02:41:262956 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Ramin Halavati683bcaa92018-02-14 08:42:392957 request_info.traffic_annotation =
2958 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272959 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392960 net_log_, CompletionOnceCallback()));
jri231c2972016-03-08 19:50:112961
2962 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502963 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri231c2972016-03-08 19:50:112964 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2965 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2966
2967 // Trigger connection migration. Since there is a non-migratable stream,
2968 // this should cause a RST_STREAM frame to be emitted with
Zhongyi Shic16b4102019-02-12 00:37:402969 // quic::QUIC_STREAM_CANCELLED error code.
Zhongyi Shi32fe14d42019-02-28 00:25:362970 // If migate idle session, the connection will then be migrated to the
2971 // alternate network. Otherwise, the connection will be closed.
jri231c2972016-03-08 19:50:112972 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2973 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
2974
Zhongyi Shi32fe14d42019-02-28 00:25:362975 EXPECT_EQ(migrate_idle_sessions,
2976 QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2977 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(host_port_pair_));
jri231c2972016-03-08 19:50:112978
Zhongyi Shi32fe14d42019-02-28 00:25:362979 if (migrate_idle_sessions) {
2980 EXPECT_EQ(0u, session->GetNumActiveStreams());
2981 base::RunLoop().RunUntilIdle();
Zhongyi Shic16b4102019-02-12 00:37:402982
Zhongyi Shi32fe14d42019-02-28 00:25:362983 EXPECT_TRUE(failed_socket_data.AllReadDataConsumed());
2984 EXPECT_TRUE(failed_socket_data.AllWriteDataConsumed());
2985 }
jri231c2972016-03-08 19:50:112986 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2987 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2988}
2989
jri9c541572016-03-29 17:51:482990TEST_P(QuicStreamFactoryTest,
jri9f303712016-09-13 01:10:222991 OnNetworkDisconnectedConnectionMigrationDisabled) {
Zhongyi Shi5f587cc2017-11-21 23:24:172992 InitializeConnectionMigrationV2Test(
2993 {kDefaultNetworkForTests, kNewNetworkForTests});
2994 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2995 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2996
Ryan Hamiltonabad59e2019-06-06 04:02:592997 MockQuicData socket_data(version_);
Zhongyi Shi5f587cc2017-11-21 23:24:172998 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432999 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
3000 socket_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333001 SYNCHRONOUS, client_maker_.MakeRstPacket(
3002 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
3003 quic::QUIC_RST_ACKNOWLEDGEMENT));
Zhongyi Shi5f587cc2017-11-21 23:24:173004 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9c541572016-03-29 17:51:483005
3006 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:453007 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:333008 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033009 request.Request(
Nick Harper23290b82019-05-02 00:02:563010 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:513011 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033012 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3013 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:013014 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:243015 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9c541572016-03-29 17:51:483016 EXPECT_TRUE(stream.get());
3017
3018 // Cause QUIC stream to be created.
3019 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:393020 request_info.traffic_annotation =
3021 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:273022 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:393023 net_log_, CompletionOnceCallback()));
jri9c541572016-03-29 17:51:483024
3025 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:503026 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri9c541572016-03-29 17:51:483027 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3028 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3029
3030 // Set session config to have connection migration disabled.
Ryan Hamilton8d9ee76e2018-05-29 23:52:523031 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
3032 session->config());
jri9c541572016-03-29 17:51:483033 EXPECT_TRUE(session->config()->DisableConnectionMigration());
3034
3035 // Trigger connection migration. Since there is a non-migratable stream,
3036 // this should cause a RST_STREAM frame to be emitted with
Ryan Hamilton8d9ee76e2018-05-29 23:52:523037 // quic::QUIC_RST_ACKNOWLEDGEMENT error code, and the session will be closed.
jri9c541572016-03-29 17:51:483038 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3039 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
3040
3041 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3042 EXPECT_FALSE(HasActiveSession(host_port_pair_));
3043
3044 EXPECT_TRUE(socket_data.AllReadDataConsumed());
3045 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
3046}
3047
Zhongyi Shi32fe14d42019-02-28 00:25:363048TEST_P(QuicStreamFactoryTest,
3049 OnNetworkMadeDefaultNoOpenStreams_DoNotMigrateIdleSessions) {
3050 TestOnNetworkMadeDefaultNoOpenStreams(false);
3051}
3052
3053TEST_P(QuicStreamFactoryTest,
3054 OnNetworkMadeDefaultNoOpenStreams_MigrateIdleSessions) {
3055 TestOnNetworkMadeDefaultNoOpenStreams(true);
3056}
3057
3058void QuicStreamFactoryTestBase::TestOnNetworkMadeDefaultNoOpenStreams(
3059 bool migrate_idle_sessions) {
3060 test_params_.quic_migrate_idle_sessions = migrate_idle_sessions;
Zhongyi Shi5f587cc2017-11-21 23:24:173061 InitializeConnectionMigrationV2Test(
3062 {kDefaultNetworkForTests, kNewNetworkForTests});
3063 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3064 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3065
Ryan Hamiltonabad59e2019-06-06 04:02:593066 MockQuicData socket_data(version_);
Zhongyi Shi5f587cc2017-11-21 23:24:173067 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:433068 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi32fe14d42019-02-28 00:25:363069 if (!migrate_idle_sessions) {
3070 socket_data.AddWrite(
3071 SYNCHRONOUS,
3072 client_maker_.MakeConnectionClosePacket(
3073 2, true, quic::QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS,
3074 "net error"));
3075 }
Zhongyi Shi5f587cc2017-11-21 23:24:173076 socket_data.AddSocketDataToFactory(socket_factory_.get());
3077
Ryan Hamiltonabad59e2019-06-06 04:02:593078 MockQuicData quic_data1(version_);
Zhongyi Shi32fe14d42019-02-28 00:25:363079 if (migrate_idle_sessions) {
3080 // Set up the second socket data provider that is used for probing.
3081 // Connectivity probe to be sent on the new path.
3082 quic_data1.AddWrite(SYNCHRONOUS,
3083 client_maker_.MakeConnectivityProbingPacket(2, true));
3084 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3085 // Connectivity probe to receive from the server.
3086 quic_data1.AddRead(ASYNC,
3087 server_maker_.MakeConnectivityProbingPacket(1, false));
3088 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
3089 // Ping packet to send after migration is completed.
3090 quic_data1.AddWrite(SYNCHRONOUS,
3091 client_maker_.MakeAckAndPingPacket(3, false, 1, 1, 1));
3092 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3093 }
Zhongyi Shic16b4102019-02-12 00:37:403094
Zhongyi Shi5f587cc2017-11-21 23:24:173095 // Create request and QuicHttpStream.
3096 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:333097 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033098 request.Request(
Nick Harper23290b82019-05-02 00:02:563099 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:513100 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033101 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3102 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi5f587cc2017-11-21 23:24:173103 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3104 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3105 EXPECT_TRUE(stream.get());
3106
3107 // Ensure that session is alive and active.
3108 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3109 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3110 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shic16b4102019-02-12 00:37:403111 EXPECT_EQ(0u, session->GetNumActiveStreams());
3112 EXPECT_EQ(0u, session->GetNumDrainingStreams());
Zhongyi Shi5f587cc2017-11-21 23:24:173113
3114 // Trigger connection migration.
3115 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3116 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
Zhongyi Shi32fe14d42019-02-28 00:25:363117 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(host_port_pair_));
Zhongyi Shi5f587cc2017-11-21 23:24:173118
Zhongyi Shi32fe14d42019-02-28 00:25:363119 if (migrate_idle_sessions) {
3120 quic_data1.Resume();
3121 base::RunLoop().RunUntilIdle();
3122 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
3123 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
3124 }
Zhongyi Shi5f587cc2017-11-21 23:24:173125 EXPECT_TRUE(socket_data.AllReadDataConsumed());
3126 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
3127}
3128
Zhongyi Shi32fe14d42019-02-28 00:25:363129TEST_P(QuicStreamFactoryTest,
3130 OnNetworkDisconnectedNoOpenStreams_DoNotMigateIdleSessions) {
3131 TestOnNetworkDisconnectedNoOpenStreams(false);
3132}
3133
3134TEST_P(QuicStreamFactoryTest,
3135 OnNetworkDisconnectedNoOpenStreams_MigateIdleSessions) {
3136 TestOnNetworkDisconnectedNoOpenStreams(true);
3137}
3138
3139void QuicStreamFactoryTestBase::TestOnNetworkDisconnectedNoOpenStreams(
3140 bool migrate_idle_sessions) {
3141 test_params_.quic_migrate_idle_sessions = migrate_idle_sessions;
Zhongyi Shi5f587cc2017-11-21 23:24:173142 InitializeConnectionMigrationV2Test(
3143 {kDefaultNetworkForTests, kNewNetworkForTests});
3144 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3145 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3146
Ryan Hamiltonabad59e2019-06-06 04:02:593147 MockQuicData default_socket_data(version_);
Zhongyi Shic16b4102019-02-12 00:37:403148 default_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3149 default_socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
3150 default_socket_data.AddSocketDataToFactory(socket_factory_.get());
3151
Ryan Hamiltonabad59e2019-06-06 04:02:593152 MockQuicData alternate_socket_data(version_);
Zhongyi Shi32fe14d42019-02-28 00:25:363153 if (migrate_idle_sessions) {
3154 // Set up second socket data provider that is used after migration.
3155 alternate_socket_data.AddRead(SYNCHRONOUS,
3156 ERR_IO_PENDING); // Hanging read.
3157 // Ping packet to send after migration.
3158 alternate_socket_data.AddWrite(
3159 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
3160 alternate_socket_data.AddSocketDataToFactory(socket_factory_.get());
3161 }
Zhongyi Shi5f587cc2017-11-21 23:24:173162
3163 // Create request and QuicHttpStream.
3164 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:333165 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033166 request.Request(
Nick Harper23290b82019-05-02 00:02:563167 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:513168 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033169 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3170 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi5f587cc2017-11-21 23:24:173171 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3172 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3173 EXPECT_TRUE(stream.get());
3174
Zhongyi Shic16b4102019-02-12 00:37:403175 // Ensure that session is active.
Zhongyi Shi5f587cc2017-11-21 23:24:173176 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3177
3178 // Trigger connection migration. Since there are no active streams,
3179 // the session will be closed.
3180 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3181 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
3182
Zhongyi Shi32fe14d42019-02-28 00:25:363183 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(host_port_pair_));
Zhongyi Shi5f587cc2017-11-21 23:24:173184
Zhongyi Shic16b4102019-02-12 00:37:403185 EXPECT_TRUE(default_socket_data.AllReadDataConsumed());
3186 EXPECT_TRUE(default_socket_data.AllWriteDataConsumed());
Zhongyi Shi32fe14d42019-02-28 00:25:363187 if (migrate_idle_sessions) {
3188 EXPECT_TRUE(alternate_socket_data.AllReadDataConsumed());
3189 EXPECT_TRUE(alternate_socket_data.AllWriteDataConsumed());
3190 }
Zhongyi Shi5f587cc2017-11-21 23:24:173191}
3192
Zhongyi Shi9f316b262018-06-18 22:01:163193// This test verifies session migrates to the alternate network immediately when
3194// default network disconnects with a synchronous write before migration.
3195TEST_P(QuicStreamFactoryTest, MigrateOnDefaultNetworkDisconnectedSync) {
3196 TestMigrationOnNetworkDisconnected(/*async_write_before*/ false);
3197}
3198
3199// This test verifies session migrates to the alternate network immediately when
3200// default network disconnects with an asynchronously write before migration.
3201TEST_P(QuicStreamFactoryTest, MigrateOnDefaultNetworkDisconnectedAsync) {
3202 TestMigrationOnNetworkDisconnected(/*async_write_before*/ true);
3203}
3204
3205void QuicStreamFactoryTestBase::TestMigrationOnNetworkDisconnected(
3206 bool async_write_before) {
3207 InitializeConnectionMigrationV2Test(
3208 {kDefaultNetworkForTests, kNewNetworkForTests});
3209 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3210 ->NotifyNetworkMadeDefault(kDefaultNetworkForTests);
3211 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3212 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3213 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3214
3215 // Use the test task runner.
3216 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
3217
3218 int packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:593219 MockQuicData socket_data(version_);
Zhongyi Shi9f316b262018-06-18 22:01:163220 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:023221 socket_data.AddWrite(SYNCHRONOUS,
3222 ConstructInitialSettingsPacket(packet_number++));
Zhongyi Shi9f316b262018-06-18 22:01:163223 socket_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333224 SYNCHRONOUS,
3225 ConstructGetRequestPacket(packet_number++,
3226 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:023227 true, true));
Zhongyi Shi9f316b262018-06-18 22:01:163228 if (async_write_before) {
3229 socket_data.AddWrite(ASYNC, OK);
3230 packet_number++;
3231 }
3232 socket_data.AddSocketDataToFactory(socket_factory_.get());
3233
3234 // Create request and QuicHttpStream.
3235 QuicStreamRequest request(factory_.get());
3236 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033237 request.Request(
Nick Harper23290b82019-05-02 00:02:563238 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:513239 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033240 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3241 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi9f316b262018-06-18 22:01:163242 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3243 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3244 EXPECT_TRUE(stream.get());
3245
3246 // Cause QUIC stream to be created.
3247 HttpRequestInfo request_info;
3248 request_info.method = "GET";
3249 request_info.url = url_;
3250 request_info.traffic_annotation =
3251 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3252 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3253 net_log_, CompletionOnceCallback()));
3254
3255 // Ensure that session is alive and active.
3256 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3257 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3258 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3259
3260 // Send GET request on stream.
3261 HttpResponseInfo response;
3262 HttpRequestHeaders request_headers;
3263 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3264 callback_.callback()));
3265
Zhongyi Shi22fd5f52018-06-20 17:39:093266 if (async_write_before)
Zhongyi Shi9f316b262018-06-18 22:01:163267 session->SendPing();
Zhongyi Shi9f316b262018-06-18 22:01:163268
3269 // Set up second socket data provider that is used after migration.
3270 // The response to the earlier request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:593271 MockQuicData socket_data1(version_);
Zhongyi Shi9f316b262018-06-18 22:01:163272 socket_data1.AddWrite(
3273 SYNCHRONOUS,
3274 client_maker_.MakePingPacket(packet_number++, /*include_version=*/true));
3275 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:333276 ASYNC,
3277 ConstructOkResponsePacket(
3278 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shi9f316b262018-06-18 22:01:163279 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3280 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333281 SYNCHRONOUS,
3282 client_maker_.MakeAckAndRstPacket(
3283 packet_number++, false, GetNthClientInitiatedBidirectionalStreamId(0),
3284 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi9f316b262018-06-18 22:01:163285 socket_data1.AddSocketDataToFactory(socket_factory_.get());
3286
3287 // Trigger connection migration.
3288 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3289 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
3290
3291 // The connection should still be alive, not marked as going away.
3292 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3293 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3294 EXPECT_EQ(1u, session->GetNumActiveStreams());
3295 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3296
3297 // Ensure that the session is still alive.
3298 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3299 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3300 EXPECT_EQ(1u, session->GetNumActiveStreams());
3301
3302 // Run the message loop so that data queued in the new socket is read by the
3303 // packet reader.
3304 runner_->RunNextTask();
3305
3306 // Response headers are received over the new network.
3307 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3308 EXPECT_EQ(200, response.headers->response_code());
3309
3310 // Check that the session is still alive.
3311 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3312 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3313
3314 // There should be posted tasks not executed, which is to migrate back to
3315 // default network.
3316 EXPECT_FALSE(runner_->GetPostedTasks().empty());
3317
3318 // Receive signal to mark new network as default.
3319 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3320 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3321
3322 stream.reset();
3323 EXPECT_TRUE(socket_data.AllReadDataConsumed());
3324 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
3325 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
3326 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
3327}
3328
Zhongyi Shi5f587cc2017-11-21 23:24:173329// This test receives NCN signals in the following order:
3330// - default network disconnected
3331// - after a pause, new network is connected.
3332// - new network is made default.
3333TEST_P(QuicStreamFactoryTest, NewNetworkConnectedAfterNoNetwork) {
3334 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
3335 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3336 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3337 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3338
3339 // Use the test task runner.
3340 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
3341
Ryan Hamiltonabad59e2019-06-06 04:02:593342 MockQuicData socket_data(version_);
Zhongyi Shi5f587cc2017-11-21 23:24:173343 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:023344 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:173345 socket_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:023346 SYNCHRONOUS,
3347 ConstructGetRequestPacket(
3348 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi5f587cc2017-11-21 23:24:173349 socket_data.AddSocketDataToFactory(socket_factory_.get());
3350
3351 // Create request and QuicHttpStream.
3352 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:333353 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033354 request.Request(
Nick Harper23290b82019-05-02 00:02:563355 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:513356 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033357 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3358 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi5f587cc2017-11-21 23:24:173359 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3360 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3361 EXPECT_TRUE(stream.get());
3362
3363 // Cause QUIC stream to be created.
3364 HttpRequestInfo request_info;
3365 request_info.method = "GET";
3366 request_info.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:393367 request_info.traffic_annotation =
3368 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:273369 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:393370 net_log_, CompletionOnceCallback()));
Zhongyi Shi5f587cc2017-11-21 23:24:173371
3372 // Ensure that session is alive and active.
3373 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3374 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3375 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3376
3377 // Send GET request on stream.
3378 HttpResponseInfo response;
3379 HttpRequestHeaders request_headers;
3380 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3381 callback_.callback()));
3382
3383 // Trigger connection migration. Since there are no networks
3384 // to migrate to, this should cause the session to wait for a new network.
3385 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3386 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
3387
3388 // The connection should still be alive, not marked as going away.
3389 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3390 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3391 EXPECT_EQ(1u, session->GetNumActiveStreams());
3392 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3393
3394 // Set up second socket data provider that is used after migration.
3395 // The response to the earlier request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:593396 MockQuicData socket_data1(version_);
Zhongyi Shi5f587cc2017-11-21 23:24:173397 socket_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433398 SYNCHRONOUS, client_maker_.MakePingPacket(3, /*include_version=*/true));
3399 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:333400 ASYNC,
3401 ConstructOkResponsePacket(
3402 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shi5f587cc2017-11-21 23:24:173403 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:333404 socket_data1.AddWrite(
3405 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
3406 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
3407 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:173408 socket_data1.AddSocketDataToFactory(socket_factory_.get());
3409
3410 // Add a new network and notify the stream factory of a new connected network.
3411 // This causes a PING packet to be sent over the new network.
3412 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3413 ->SetConnectedNetworksList({kNewNetworkForTests});
3414 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3415 ->NotifyNetworkConnected(kNewNetworkForTests);
3416
3417 // Ensure that the session is still alive.
3418 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3419 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3420 EXPECT_EQ(1u, session->GetNumActiveStreams());
3421
3422 // Run the message loop so that data queued in the new socket is read by the
3423 // packet reader.
3424 runner_->RunNextTask();
3425
3426 // Response headers are received over the new network.
3427 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3428 EXPECT_EQ(200, response.headers->response_code());
3429
3430 // Check that the session is still alive.
3431 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3432 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3433
3434 // There should posted tasks not executed, which is to migrate back to default
3435 // network.
3436 EXPECT_FALSE(runner_->GetPostedTasks().empty());
3437
3438 // Receive signal to mark new network as default.
3439 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3440 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3441
3442 stream.reset();
3443 EXPECT_TRUE(socket_data.AllReadDataConsumed());
3444 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
3445 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
3446 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
3447}
3448
Zhongyi Shid3d5f502018-08-10 00:22:223449// Regression test for http://crbug.com/872011.
3450// This test verifies that migrate to the probing socket will not trigger
3451// new packets being read synchronously and generate ACK frame while
3452// processing the initial connectivity probe response, which may cause a
3453// connection being closed with INTERNAL_ERROR as pending ACK frame is not
3454// allowed when processing a new packet.
Zhongyi Shi6a7323b2018-12-07 01:26:323455TEST_P(QuicStreamFactoryTest, MigrateToProbingSocket) {
Zhongyi Shid3d5f502018-08-10 00:22:223456 InitializeConnectionMigrationV2Test(
3457 {kDefaultNetworkForTests, kNewNetworkForTests});
3458 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3459 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3460 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3461
3462 // Using a testing task runner so that we can control time.
3463 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3464 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
3465
3466 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3467 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3468
3469 int packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:593470 MockQuicData quic_data1(version_);
Zhongyi Shid3d5f502018-08-10 00:22:223471 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
Ryan Hamilton0d65a8c2019-06-07 00:46:023472 quic_data1.AddWrite(SYNCHRONOUS,
3473 ConstructInitialSettingsPacket(packet_number++));
Zhongyi Shid3d5f502018-08-10 00:22:223474 quic_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333475 SYNCHRONOUS,
3476 ConstructGetRequestPacket(packet_number++,
3477 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:023478 true, true));
Zhongyi Shid3d5f502018-08-10 00:22:223479 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3480
3481 // Set up the second socket data provider that is used for probing on the
3482 // alternate network.
Ryan Hamiltonabad59e2019-06-06 04:02:593483 MockQuicData quic_data2(version_);
Zhongyi Shid3d5f502018-08-10 00:22:223484 // Connectivity probe to be sent on the new path.
3485 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(
3486 packet_number++, true));
3487 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3488 // First connectivity probe to receive from the server, which will complete
3489 // connection migraiton on path degrading.
3490 quic_data2.AddRead(ASYNC,
3491 server_maker_.MakeConnectivityProbingPacket(1, false));
3492 // Read multiple connectivity probes synchronously.
3493 quic_data2.AddRead(SYNCHRONOUS,
3494 server_maker_.MakeConnectivityProbingPacket(2, false));
3495 quic_data2.AddRead(SYNCHRONOUS,
3496 server_maker_.MakeConnectivityProbingPacket(3, false));
3497 quic_data2.AddRead(SYNCHRONOUS,
3498 server_maker_.MakeConnectivityProbingPacket(4, false));
3499 quic_data2.AddWrite(
3500 ASYNC, client_maker_.MakeAckPacket(packet_number++, 1, 4, 1, 1, true));
3501 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:333502 ASYNC,
3503 ConstructOkResponsePacket(
3504 5, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shid3d5f502018-08-10 00:22:223505 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3506 quic_data2.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333507 SYNCHRONOUS,
3508 client_maker_.MakeAckAndRstPacket(
3509 packet_number++, false, GetNthClientInitiatedBidirectionalStreamId(0),
3510 quic::QUIC_STREAM_CANCELLED, 5, 1, 1, true));
Zhongyi Shid3d5f502018-08-10 00:22:223511 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3512
3513 // Create request and QuicHttpStream.
3514 QuicStreamRequest request(factory_.get());
3515 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033516 request.Request(
Nick Harper23290b82019-05-02 00:02:563517 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:513518 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033519 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3520 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shid3d5f502018-08-10 00:22:223521 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3522 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3523 EXPECT_TRUE(stream.get());
3524
3525 // Cause QUIC stream to be created.
3526 HttpRequestInfo request_info;
3527 request_info.method = "GET";
3528 request_info.url = url_;
3529 request_info.traffic_annotation =
3530 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3531 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3532 net_log_, CompletionOnceCallback()));
3533
3534 // Ensure that session is alive and active.
3535 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3536 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3537 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3538
3539 // Send GET request on stream.
3540 HttpResponseInfo response;
3541 HttpRequestHeaders request_headers;
3542 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3543 callback_.callback()));
3544
3545 // Cause the connection to report path degrading to the session.
3546 // Session will start to probe the alternate network.
3547 session->connection()->OnPathDegradingTimeout();
3548
3549 // Next connectivity probe is scheduled to be sent in 2 *
3550 // kDefaultRTTMilliSecs.
3551 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3552 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
3553 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3554 next_task_delay);
3555
3556 // The connection should still be alive, and not marked as going away.
3557 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3558 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3559 EXPECT_EQ(1u, session->GetNumActiveStreams());
3560 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3561
3562 // Resume quic data and a connectivity probe response will be read on the new
3563 // socket.
3564 quic_data2.Resume();
3565
3566 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3567 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3568 EXPECT_EQ(1u, session->GetNumActiveStreams());
3569
3570 // There should be three pending tasks, the nearest one will complete
3571 // migration to the new network.
3572 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
3573 next_task_delay = task_runner->NextPendingTaskDelay();
3574 EXPECT_EQ(base::TimeDelta(), next_task_delay);
3575 task_runner->FastForwardBy(next_task_delay);
3576
3577 // Response headers are received over the new network.
3578 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3579 EXPECT_EQ(200, response.headers->response_code());
3580
3581 // Now there are two pending tasks, the nearest one was to send connectivity
3582 // probe and has been cancelled due to successful migration.
3583 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
3584 next_task_delay = task_runner->NextPendingTaskDelay();
3585 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3586 next_task_delay);
3587 task_runner->FastForwardBy(next_task_delay);
3588
3589 // There's one more task to mgirate back to the default network in 0.4s.
3590 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3591 next_task_delay = task_runner->NextPendingTaskDelay();
3592 base::TimeDelta expected_delay =
3593 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
3594 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
3595 EXPECT_EQ(expected_delay, next_task_delay);
3596
3597 // Deliver a signal that the alternate network now becomes default to session,
3598 // this will cancel mgirate back to default network timer.
3599 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3600 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3601
3602 task_runner->FastForwardBy(next_task_delay);
3603 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
3604
3605 // Verify that the session is still alive.
3606 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3607 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3608
3609 stream.reset();
3610 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
3611 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
3612 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
3613 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
3614}
3615
Zhongyi Shic4823bd2018-04-27 00:49:193616// This test verifies that the connection migrates to the alternate network
Zhongyi Shi22fd5f52018-06-20 17:39:093617// early when path degrading is detected with an ASYNCHRONOUS write before
3618// migration.
3619TEST_P(QuicStreamFactoryTest, MigrateEarlyOnPathDegradingAysnc) {
3620 TestMigrationOnPathDegrading(/*async_write_before_migration*/ true);
3621}
3622
3623// This test verifies that the connection migrates to the alternate network
3624// early when path degrading is detected with a SYNCHRONOUS write before
3625// migration.
3626TEST_P(QuicStreamFactoryTest, MigrateEarlyOnPathDegradingSync) {
3627 TestMigrationOnPathDegrading(/*async_write_before_migration*/ false);
3628}
3629
3630void QuicStreamFactoryTestBase::TestMigrationOnPathDegrading(
3631 bool async_write_before) {
Zhongyi Shic4823bd2018-04-27 00:49:193632 InitializeConnectionMigrationV2Test(
3633 {kDefaultNetworkForTests, kNewNetworkForTests});
3634 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3635 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3636 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3637
3638 // Using a testing task runner so that we can control time.
3639 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3640 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
3641
3642 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3643 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3644
Zhongyi Shi22fd5f52018-06-20 17:39:093645 int packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:593646 MockQuicData quic_data1(version_);
Zhongyi Shic4823bd2018-04-27 00:49:193647 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
Ryan Hamilton0d65a8c2019-06-07 00:46:023648 quic_data1.AddWrite(SYNCHRONOUS,
3649 ConstructInitialSettingsPacket(packet_number++));
Zhongyi Shi22fd5f52018-06-20 17:39:093650 quic_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333651 SYNCHRONOUS,
3652 ConstructGetRequestPacket(packet_number++,
3653 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:023654 true, true));
Zhongyi Shi22fd5f52018-06-20 17:39:093655 if (async_write_before) {
3656 quic_data1.AddWrite(ASYNC, OK);
3657 packet_number++;
3658 }
Zhongyi Shic4823bd2018-04-27 00:49:193659 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3660
3661 // Set up the second socket data provider that is used after migration.
3662 // The response to the earlier request is read on the new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:593663 MockQuicData quic_data2(version_);
Zhongyi Shic4823bd2018-04-27 00:49:193664 // Connectivity probe to be sent on the new path.
Zhongyi Shi22fd5f52018-06-20 17:39:093665 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(
Zhongyi Shi879659422018-08-02 17:58:253666 packet_number++, true));
Zhongyi Shic4823bd2018-04-27 00:49:193667 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3668 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:253669 quic_data2.AddRead(ASYNC,
3670 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shic4823bd2018-04-27 00:49:193671 // Ping packet to send after migration is completed.
Zhongyi Shi22fd5f52018-06-20 17:39:093672 quic_data2.AddWrite(ASYNC, client_maker_.MakeAckAndPingPacket(
3673 packet_number++, false, 1, 1, 1));
Ryan Hamiltona3ee93a72018-08-01 22:03:083674 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:333675 ASYNC,
3676 ConstructOkResponsePacket(
3677 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shic4823bd2018-04-27 00:49:193678 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi22fd5f52018-06-20 17:39:093679 quic_data2.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333680 SYNCHRONOUS,
3681 client_maker_.MakeAckAndRstPacket(
3682 packet_number++, false, GetNthClientInitiatedBidirectionalStreamId(0),
3683 quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true));
Zhongyi Shic4823bd2018-04-27 00:49:193684 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3685
3686 // Create request and QuicHttpStream.
3687 QuicStreamRequest request(factory_.get());
3688 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033689 request.Request(
Nick Harper23290b82019-05-02 00:02:563690 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:513691 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033692 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3693 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shic4823bd2018-04-27 00:49:193694 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3695 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3696 EXPECT_TRUE(stream.get());
3697
3698 // Cause QUIC stream to be created.
3699 HttpRequestInfo request_info;
3700 request_info.method = "GET";
3701 request_info.url = url_;
3702 request_info.traffic_annotation =
3703 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3704 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3705 net_log_, CompletionOnceCallback()));
3706
3707 // Ensure that session is alive and active.
3708 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3709 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3710 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3711
3712 // Send GET request on stream.
3713 HttpResponseInfo response;
3714 HttpRequestHeaders request_headers;
3715 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3716 callback_.callback()));
3717
Zhongyi Shi22fd5f52018-06-20 17:39:093718 if (async_write_before)
3719 session->SendPing();
3720
Zhongyi Shiaba4a832018-04-30 20:29:083721 // Cause the connection to report path degrading to the session.
3722 // Session will start to probe the alternate network.
3723 session->connection()->OnPathDegradingTimeout();
3724
3725 // Next connectivity probe is scheduled to be sent in 2 *
3726 // kDefaultRTTMilliSecs.
3727 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3728 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
3729 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3730 next_task_delay);
3731
3732 // The connection should still be alive, and not marked as going away.
3733 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3734 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3735 EXPECT_EQ(1u, session->GetNumActiveStreams());
3736 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3737
3738 // Resume quic data and a connectivity probe response will be read on the new
3739 // socket.
3740 quic_data2.Resume();
3741
3742 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3743 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3744 EXPECT_EQ(1u, session->GetNumActiveStreams());
3745
3746 // There should be three pending tasks, the nearest one will complete
3747 // migration to the new network.
3748 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
3749 next_task_delay = task_runner->NextPendingTaskDelay();
3750 EXPECT_EQ(base::TimeDelta(), next_task_delay);
3751 task_runner->FastForwardBy(next_task_delay);
3752
3753 // Response headers are received over the new network.
3754 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3755 EXPECT_EQ(200, response.headers->response_code());
3756
3757 // Now there are two pending tasks, the nearest one was to send connectivity
3758 // probe and has been cancelled due to successful migration.
3759 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
3760 next_task_delay = task_runner->NextPendingTaskDelay();
3761 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3762 next_task_delay);
3763 task_runner->FastForwardBy(next_task_delay);
3764
3765 // There's one more task to mgirate back to the default network in 0.4s.
3766 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3767 next_task_delay = task_runner->NextPendingTaskDelay();
3768 base::TimeDelta expected_delay =
3769 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
3770 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
3771 EXPECT_EQ(expected_delay, next_task_delay);
3772
3773 // Deliver a signal that the alternate network now becomes default to session,
3774 // this will cancel mgirate back to default network timer.
3775 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3776 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3777
3778 task_runner->FastForwardBy(next_task_delay);
3779 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
3780
3781 // Verify that the session is still alive.
3782 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3783 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3784
3785 stream.reset();
3786 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
3787 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
3788 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
3789 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
3790}
3791
Renjiea5722ccf2018-08-10 00:18:493792// This test verifies that the session marks itself GOAWAY on path degrading
3793// and it does not receive any new request
3794TEST_P(QuicStreamFactoryTest, GoawayOnPathDegrading) {
Zhongyi Shi967d2f12019-02-08 20:58:533795 test_params_.quic_go_away_on_path_degrading = true;
Renjiea5722ccf2018-08-10 00:18:493796 Initialize();
3797 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3798 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3799 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3800
Ryan Hamiltonabad59e2019-06-06 04:02:593801 MockQuicData quic_data1(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:023802 quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Fan Yang32c5a112018-12-10 20:06:333803 quic_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:023804 SYNCHRONOUS,
3805 ConstructGetRequestPacket(
3806 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Renjiea5722ccf2018-08-10 00:18:493807 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3808 quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:333809 ASYNC,
3810 ConstructOkResponsePacket(
3811 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true));
Renjiea5722ccf2018-08-10 00:18:493812 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
3813 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3814
Ryan Hamilton0d65a8c2019-06-07 00:46:023815 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:593816 MockQuicData quic_data2(version_);
Renjiea5722ccf2018-08-10 00:18:493817 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
Ryan Hamilton0d65a8c2019-06-07 00:46:023818 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Renjiea5722ccf2018-08-10 00:18:493819 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3820
3821 // Creat request and QuicHttpStream.
3822 QuicStreamRequest request(factory_.get());
3823 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033824 request.Request(
Nick Harper23290b82019-05-02 00:02:563825 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:513826 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033827 /*cerf_verify_flags=*/0, url_, net_log_, &net_error_details_,
3828 failed_on_default_network_callback_, callback_.callback()));
Renjiea5722ccf2018-08-10 00:18:493829 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3830 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3831 EXPECT_TRUE(stream.get());
3832
3833 // Cause QUIC stream to be created.
3834 HttpRequestInfo request_info;
3835 request_info.method = "GET";
3836 request_info.url = url_;
3837 request_info.traffic_annotation =
3838 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3839 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3840 net_log_, CompletionOnceCallback()));
3841
3842 // Ensure that session is alive and active.
3843 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3844 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3845 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3846
3847 // Send GET request on stream.
3848 HttpResponseInfo response;
3849 HttpRequestHeaders request_headers;
3850 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3851 callback_.callback()));
3852
3853 // Trigger the connection to report path degrading to the session.
3854 // Session will mark itself GOAWAY.
3855 session->connection()->OnPathDegradingTimeout();
3856
3857 // The connection should still be alive, but marked as going away.
3858 EXPECT_FALSE(HasActiveSession(host_port_pair_));
3859 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3860 EXPECT_EQ(1u, session->GetNumActiveStreams());
3861
3862 // Second request should be sent on a new connection.
3863 QuicStreamRequest request2(factory_.get());
3864 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033865 request2.Request(
Nick Harper23290b82019-05-02 00:02:563866 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:513867 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033868 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3869 failed_on_default_network_callback_, callback_.callback()));
Renjiea5722ccf2018-08-10 00:18:493870 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3871 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
3872 EXPECT_TRUE(stream2.get());
3873
3874 // Resume the data, verify old request can read response on the old session
3875 // successfully.
3876 quic_data1.Resume();
3877 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
3878 EXPECT_EQ(200, response.headers->response_code());
3879 EXPECT_EQ(0U, session->GetNumActiveStreams());
3880
3881 // Check an active session exists for the destination.
3882 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3883 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3884 QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
3885 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
3886 EXPECT_NE(session, session2);
3887
3888 stream.reset();
3889 stream2.reset();
3890 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
3891 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
3892 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
3893 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
3894}
3895
Zhongyi Shibb770d92018-06-16 02:07:003896// This test verifies that the connection will not migrate to a bad socket
3897// when path degrading is detected.
3898TEST_P(QuicStreamFactoryTest, DoNotMigrateToBadSocketOnPathDegrading) {
3899 InitializeConnectionMigrationV2Test(
3900 {kDefaultNetworkForTests, kNewNetworkForTests});
3901 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3902 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3903 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3904
3905 // Using a testing task runner so that we can control time.
3906 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3907 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
3908
3909 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3910 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3911
Ryan Hamiltonabad59e2019-06-06 04:02:593912 MockQuicData quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:023913 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
3914 quic_data.AddWrite(
3915 SYNCHRONOUS,
3916 ConstructGetRequestPacket(
3917 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Fan Yang32c5a112018-12-10 20:06:333918 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3919 quic_data.AddRead(ASYNC, ConstructOkResponsePacket(
3920 1, GetNthClientInitiatedBidirectionalStreamId(0),
3921 false, false));
3922 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3923 quic_data.AddWrite(
3924 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
3925 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
3926 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shibb770d92018-06-16 02:07:003927 quic_data.AddSocketDataToFactory(socket_factory_.get());
3928
3929 // Set up second socket that will immediately return disconnected.
3930 // The stream factory will abort probe the alternate network.
3931 MockConnect bad_connect = MockConnect(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
3932 SequencedSocketData socket_data(bad_connect, base::span<MockRead>(),
3933 base::span<MockWrite>());
3934 socket_factory_->AddSocketDataProvider(&socket_data);
3935
3936 // Create request and QuicHttpStream.
3937 QuicStreamRequest request(factory_.get());
3938 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033939 request.Request(
Nick Harper23290b82019-05-02 00:02:563940 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:513941 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033942 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3943 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shibb770d92018-06-16 02:07:003944 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3945 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3946 EXPECT_TRUE(stream.get());
3947
3948 // Cause QUIC stream to be created.
3949 HttpRequestInfo request_info;
3950 request_info.method = "GET";
3951 request_info.url = url_;
3952 request_info.traffic_annotation =
3953 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3954 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3955 net_log_, CompletionOnceCallback()));
3956
3957 // Ensure that session is alive and active.
3958 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3959 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3960 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3961
3962 // Send GET request on stream.
3963 HttpResponseInfo response;
3964 HttpRequestHeaders request_headers;
3965 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3966 callback_.callback()));
3967
3968 // Cause the connection to report path degrading to the session.
3969 // Session will start to probe the alternate network.
3970 session->connection()->OnPathDegradingTimeout();
3971
3972 // The connection should still be alive, and not marked as going away.
3973 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3974 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3975 EXPECT_EQ(1u, session->GetNumActiveStreams());
3976 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3977
3978 // Resume the data, and response header is received over the original network.
3979 quic_data.Resume();
3980 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3981 EXPECT_EQ(200, response.headers->response_code());
3982
3983 // Verify there is no pending task as probing alternate network is halted.
3984 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
3985
3986 // Verify that the session is still alive.
3987 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3988 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3989
3990 stream.reset();
3991 EXPECT_TRUE(quic_data.AllReadDataConsumed());
3992 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
3993}
3994
Zhongyi Shif5cc30392018-05-30 18:25:153995// Regression test for http://crbug.com/847569.
3996// This test verifies that the connection migrates to the alternate network
3997// early when there is no active stream but a draining stream.
Zhongyi Shib3bc982c2018-07-10 19:59:243998// The first packet being written after migration is a synchrnous write, which
3999// will cause a PING packet being sent.
4000TEST_P(QuicStreamFactoryTest, MigrateSessionWithDrainingStreamSync) {
4001 TestMigrateSessionWithDrainingStream(SYNCHRONOUS);
4002}
4003
4004// Regression test for http://crbug.com/847569.
4005// This test verifies that the connection migrates to the alternate network
4006// early when there is no active stream but a draining stream.
4007// The first packet being written after migration is an asynchronous write, no
4008// PING packet will be sent.
4009TEST_P(QuicStreamFactoryTest, MigrateSessionWithDrainingStreamAsync) {
4010 TestMigrateSessionWithDrainingStream(ASYNC);
4011}
4012
4013void QuicStreamFactoryTestBase::TestMigrateSessionWithDrainingStream(
4014 IoMode write_mode_for_queued_packet) {
Zhongyi Shif5cc30392018-05-30 18:25:154015 InitializeConnectionMigrationV2Test(
4016 {kDefaultNetworkForTests, kNewNetworkForTests});
4017 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4018 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4019 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4020
4021 // Using a testing task runner so that we can control time.
4022 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4023 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4024
4025 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4026 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
4027
Zhongyi Shib3bc982c2018-07-10 19:59:244028 int packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:594029 MockQuicData quic_data1(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:024030 quic_data1.AddWrite(SYNCHRONOUS,
4031 ConstructInitialSettingsPacket(packet_number++));
Zhongyi Shib3bc982c2018-07-10 19:59:244032 quic_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334033 SYNCHRONOUS,
4034 ConstructGetRequestPacket(packet_number++,
4035 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:024036 true, true));
Zhongyi Shif5cc30392018-05-30 18:25:154037 // Read an out of order packet with FIN to drain the stream.
4038 quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:334039 ASYNC, ConstructOkResponsePacket(
4040 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
4041 true)); // keep sending version.
Zhongyi Shif5cc30392018-05-30 18:25:154042 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4043 quic_data1.AddSocketDataToFactory(socket_factory_.get());
4044
4045 // Set up the second socket data provider that is used after migration.
Ryan Hamiltonabad59e2019-06-06 04:02:594046 MockQuicData quic_data2(version_);
Zhongyi Shif5cc30392018-05-30 18:25:154047 // Connectivity probe to be sent on the new path.
Zhongyi Shib3bc982c2018-07-10 19:59:244048 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(
Zhongyi Shi879659422018-08-02 17:58:254049 packet_number++, false));
Zhongyi Shif5cc30392018-05-30 18:25:154050 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
4051 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:254052 quic_data2.AddRead(ASYNC,
4053 server_maker_.MakeConnectivityProbingPacket(3, false));
Zhongyi Shif5cc30392018-05-30 18:25:154054 // Ping packet to send after migration is completed.
Zhongyi Shib3bc982c2018-07-10 19:59:244055 quic_data2.AddWrite(
4056 write_mode_for_queued_packet,
4057 client_maker_.MakeAckPacket(packet_number++, 2, 3, 3, 1, true));
4058 if (write_mode_for_queued_packet == SYNCHRONOUS) {
4059 quic_data2.AddWrite(ASYNC,
4060 client_maker_.MakePingPacket(packet_number++, false));
4061 }
Ryan Hamilton0d65a8c2019-06-07 00:46:024062 server_maker_.Reset();
Zhongyi Shif5cc30392018-05-30 18:25:154063 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:334064 ASYNC,
4065 ConstructOkResponsePacket(
4066 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shib3bc982c2018-07-10 19:59:244067 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeAckPacket(
4068 packet_number++, 1, 3, 1, 1, true));
Zhongyi Shif5cc30392018-05-30 18:25:154069 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4070 quic_data2.AddSocketDataToFactory(socket_factory_.get());
4071
4072 // Create request and QuicHttpStream.
4073 QuicStreamRequest request(factory_.get());
4074 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034075 request.Request(
Nick Harper23290b82019-05-02 00:02:564076 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:514077 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:034078 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4079 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shif5cc30392018-05-30 18:25:154080 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4081 std::unique_ptr<HttpStream> stream = CreateStream(&request);
4082 EXPECT_TRUE(stream.get());
4083
4084 // Cause QUIC stream to be created.
4085 HttpRequestInfo request_info;
4086 request_info.method = "GET";
4087 request_info.url = url_;
4088 request_info.traffic_annotation =
4089 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4090 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
4091 net_log_, CompletionOnceCallback()));
4092
4093 // Ensure that session is alive and active.
4094 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
4095 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4096 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4097
4098 // Send GET request on stream.
4099 HttpResponseInfo response;
4100 HttpRequestHeaders request_headers;
4101 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
4102 callback_.callback()));
4103
4104 // Run the message loop to receive the out of order packet which contains a
4105 // FIN and drains the stream.
4106 base::RunLoop().RunUntilIdle();
4107 EXPECT_EQ(0u, session->GetNumActiveStreams());
4108
4109 // Cause the connection to report path degrading to the session.
4110 // Session should still start to probe the alternate network.
4111 session->connection()->OnPathDegradingTimeout();
4112 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4113
4114 // Next connectivity probe is scheduled to be sent in 2 *
4115 // kDefaultRTTMilliSecs.
4116 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4117 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
4118 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
4119 next_task_delay);
4120
4121 // The connection should still be alive, and not marked as going away.
4122 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shif5cc30392018-05-30 18:25:154123
4124 // Resume quic data and a connectivity probe response will be read on the new
4125 // socket.
4126 quic_data2.Resume();
4127
4128 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4129 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:264130 EXPECT_EQ(0u, session->GetNumActiveStreams());
4131 EXPECT_EQ(1u, session->GetNumDrainingStreams());
Zhongyi Shif5cc30392018-05-30 18:25:154132
4133 // There should be three pending tasks, the nearest one will complete
4134 // migration to the new network.
4135 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
4136 next_task_delay = task_runner->NextPendingTaskDelay();
4137 EXPECT_EQ(base::TimeDelta(), next_task_delay);
4138 task_runner->FastForwardBy(next_task_delay);
4139
4140 // Now there are two pending tasks, the nearest one was to send connectivity
4141 // probe and has been cancelled due to successful migration.
4142 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
4143 next_task_delay = task_runner->NextPendingTaskDelay();
4144 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
4145 next_task_delay);
4146 task_runner->FastForwardBy(next_task_delay);
4147
4148 // There's one more task to mgirate back to the default network in 0.4s.
4149 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4150 next_task_delay = task_runner->NextPendingTaskDelay();
4151 base::TimeDelta expected_delay =
4152 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
4153 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
4154 EXPECT_EQ(expected_delay, next_task_delay);
4155
Zhongyi Shib3bc982c2018-07-10 19:59:244156 base::RunLoop().RunUntilIdle();
4157
Zhongyi Shif5cc30392018-05-30 18:25:154158 // Deliver a signal that the alternate network now becomes default to session,
4159 // this will cancel mgirate back to default network timer.
4160 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4161 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
4162
4163 task_runner->FastForwardBy(next_task_delay);
4164 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4165
4166 // Verify that the session is still alive.
4167 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4168 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:264169 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
Zhongyi Shif5cc30392018-05-30 18:25:154170
4171 stream.reset();
4172 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
4173 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
4174 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
4175 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
4176}
4177
Zhongyi Shiaba4a832018-04-30 20:29:084178// Regression test for http://crbug.com/835444.
4179// This test verifies that the connection migrates to the alternate network
4180// when the alternate network is connected after path has been degrading.
4181TEST_P(QuicStreamFactoryTest, MigrateOnNewNetworkConnectAfterPathDegrading) {
4182 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
4183 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4184 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4185 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4186
4187 // Using a testing task runner so that we can control time.
4188 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4189 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4190
4191 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4192 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
4193
Ryan Hamiltonabad59e2019-06-06 04:02:594194 MockQuicData quic_data1(version_);
Zhongyi Shiaba4a832018-04-30 20:29:084195 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
Ryan Hamilton0d65a8c2019-06-07 00:46:024196 quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Fan Yang32c5a112018-12-10 20:06:334197 quic_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:024198 SYNCHRONOUS,
4199 ConstructGetRequestPacket(
4200 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shiaba4a832018-04-30 20:29:084201 quic_data1.AddSocketDataToFactory(socket_factory_.get());
4202
4203 // Set up the second socket data provider that is used after migration.
4204 // The response to the earlier request is read on the new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:594205 MockQuicData quic_data2(version_);
Zhongyi Shiaba4a832018-04-30 20:29:084206 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:254207 quic_data2.AddWrite(SYNCHRONOUS,
4208 client_maker_.MakeConnectivityProbingPacket(3, true));
Zhongyi Shiaba4a832018-04-30 20:29:084209 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
4210 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:254211 quic_data2.AddRead(ASYNC,
4212 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shiaba4a832018-04-30 20:29:084213 // Ping packet to send after migration is completed.
4214 quic_data2.AddWrite(ASYNC,
4215 client_maker_.MakeAckAndPingPacket(4, false, 1, 1, 1));
4216 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:334217 ASYNC,
4218 ConstructOkResponsePacket(
4219 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shiaba4a832018-04-30 20:29:084220 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:334221 quic_data2.AddWrite(
4222 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
4223 5, false, GetNthClientInitiatedBidirectionalStreamId(0),
4224 quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true));
Zhongyi Shiaba4a832018-04-30 20:29:084225 quic_data2.AddSocketDataToFactory(socket_factory_.get());
4226
4227 // Create request and QuicHttpStream.
4228 QuicStreamRequest request(factory_.get());
4229 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034230 request.Request(
Nick Harper23290b82019-05-02 00:02:564231 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:514232 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:034233 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4234 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shiaba4a832018-04-30 20:29:084235 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4236 std::unique_ptr<HttpStream> stream = CreateStream(&request);
4237 EXPECT_TRUE(stream.get());
4238
4239 // Cause QUIC stream to be created.
4240 HttpRequestInfo request_info;
4241 request_info.method = "GET";
4242 request_info.url = url_;
4243 request_info.traffic_annotation =
4244 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4245 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
4246 net_log_, CompletionOnceCallback()));
4247
4248 // Ensure that session is alive and active.
4249 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
4250 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4251 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4252
4253 // Send GET request on stream.
4254 HttpResponseInfo response;
4255 HttpRequestHeaders request_headers;
4256 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
4257 callback_.callback()));
4258
4259 // Cause the connection to report path degrading to the session.
4260 // Due to lack of alternate network, session will not mgirate connection.
4261 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4262 session->connection()->OnPathDegradingTimeout();
4263 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4264
4265 // Deliver a signal that a alternate network is connected now, this should
4266 // cause the connection to start early migration on path degrading.
4267 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4268 ->SetConnectedNetworksList(
4269 {kDefaultNetworkForTests, kNewNetworkForTests});
4270 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4271 ->NotifyNetworkConnected(kNewNetworkForTests);
Zhongyi Shic4823bd2018-04-27 00:49:194272
4273 // Next connectivity probe is scheduled to be sent in 2 *
4274 // kDefaultRTTMilliSecs.
4275 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4276 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
4277 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
4278 next_task_delay);
4279
4280 // The connection should still be alive, and not marked as going away.
4281 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4282 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4283 EXPECT_EQ(1u, session->GetNumActiveStreams());
4284 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
4285
4286 // Resume quic data and a connectivity probe response will be read on the new
4287 // socket.
4288 quic_data2.Resume();
4289
4290 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4291 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4292 EXPECT_EQ(1u, session->GetNumActiveStreams());
4293
4294 // There should be three pending tasks, the nearest one will complete
4295 // migration to the new network.
4296 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
4297 next_task_delay = task_runner->NextPendingTaskDelay();
4298 EXPECT_EQ(base::TimeDelta(), next_task_delay);
4299 task_runner->FastForwardBy(next_task_delay);
4300
4301 // Response headers are received over the new network.
4302 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4303 EXPECT_EQ(200, response.headers->response_code());
4304
4305 // Now there are two pending tasks, the nearest one was to send connectivity
4306 // probe and has been cancelled due to successful migration.
4307 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
4308 next_task_delay = task_runner->NextPendingTaskDelay();
4309 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
4310 next_task_delay);
4311 task_runner->FastForwardBy(next_task_delay);
4312
4313 // There's one more task to mgirate back to the default network in 0.4s.
4314 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4315 next_task_delay = task_runner->NextPendingTaskDelay();
4316 base::TimeDelta expected_delay =
4317 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
4318 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
4319 EXPECT_EQ(expected_delay, next_task_delay);
4320
4321 // Deliver a signal that the alternate network now becomes default to session,
4322 // this will cancel mgirate back to default network timer.
4323 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4324 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
4325
4326 task_runner->FastForwardBy(next_task_delay);
4327 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4328
4329 // Verify that the session is still alive.
4330 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4331 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4332
4333 stream.reset();
4334 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
4335 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
4336 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
4337 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
4338}
4339
Zhongyi Shi28f6e352018-06-20 21:15:434340// This test verifies that multiple sessions are migrated on connection
4341// migration signal.
jrie3d187c2016-09-16 14:29:174342TEST_P(QuicStreamFactoryTest,
Zhongyi Shi28f6e352018-06-20 21:15:434343 MigrateMultipleSessionsToBadSocketsAfterDisconnected) {
4344 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jrie3d187c2016-09-16 14:29:174345
Ryan Hamiltonabad59e2019-06-06 04:02:594346 MockQuicData socket_data1(version_);
jrie3d187c2016-09-16 14:29:174347 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434348 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jrie3d187c2016-09-16 14:29:174349 socket_data1.AddWrite(ASYNC, OK);
Zhongyi Shi5f587cc2017-11-21 23:24:174350 socket_data1.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamilton0d65a8c2019-06-07 00:46:024351 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:594352 MockQuicData socket_data2(version_);
jrie3d187c2016-09-16 14:29:174353 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434354 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jrie3d187c2016-09-16 14:29:174355 socket_data2.AddWrite(ASYNC, OK);
Zhongyi Shi5f587cc2017-11-21 23:24:174356 socket_data2.AddSocketDataToFactory(socket_factory_.get());
jrie3d187c2016-09-16 14:29:174357
4358 HostPortPair server1(kDefaultServerHostName, 443);
4359 HostPortPair server2(kServer2HostName, 443);
4360
4361 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4362 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4363 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4364
Renjiea0cb4a2c2018-09-26 23:37:304365 host_resolver_->set_synchronous_mode(true);
4366 host_resolver_->rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
4367 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.2", "");
jrie3d187c2016-09-16 14:29:174368
4369 // Create request and QuicHttpStream to create session1.
zhongyi98d6a9262017-05-19 02:47:454370 QuicStreamRequest request1(factory_.get());
Matt Menke26e41542019-06-05 01:09:514371 EXPECT_EQ(OK,
4372 request1.Request(
4373 server1, version_.transport_version, privacy_mode_,
4374 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
4375 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4376 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:244377 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
jrie3d187c2016-09-16 14:29:174378 EXPECT_TRUE(stream1.get());
4379
4380 // Create request and QuicHttpStream to create session2.
zhongyi98d6a9262017-05-19 02:47:454381 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:514382 EXPECT_EQ(OK,
4383 request2.Request(
4384 server2, version_.transport_version, privacy_mode_,
4385 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
4386 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
4387 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:244388 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
jrie3d187c2016-09-16 14:29:174389 EXPECT_TRUE(stream2.get());
4390
4391 QuicChromiumClientSession* session1 = GetActiveSession(server1);
4392 QuicChromiumClientSession* session2 = GetActiveSession(server2);
4393 EXPECT_NE(session1, session2);
4394
4395 // Cause QUIC stream to be created and send GET so session1 has an open
4396 // stream.
4397 HttpRequestInfo request_info1;
4398 request_info1.method = "GET";
4399 request_info1.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:394400 request_info1.traffic_annotation =
4401 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274402 EXPECT_EQ(OK,
4403 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394404 net_log_, CompletionOnceCallback()));
jrie3d187c2016-09-16 14:29:174405 HttpResponseInfo response1;
4406 HttpRequestHeaders request_headers1;
4407 EXPECT_EQ(OK, stream1->SendRequest(request_headers1, &response1,
4408 callback_.callback()));
4409
4410 // Cause QUIC stream to be created and send GET so session2 has an open
4411 // stream.
4412 HttpRequestInfo request_info2;
4413 request_info2.method = "GET";
4414 request_info2.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:394415 request_info2.traffic_annotation =
4416 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274417 EXPECT_EQ(OK,
4418 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394419 net_log_, CompletionOnceCallback()));
jrie3d187c2016-09-16 14:29:174420 HttpResponseInfo response2;
4421 HttpRequestHeaders request_headers2;
4422 EXPECT_EQ(OK, stream2->SendRequest(request_headers2, &response2,
4423 callback_.callback()));
4424
4425 // Cause both sessions to be paused due to DISCONNECTED.
4426 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4427 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
4428
4429 // Ensure that both sessions are paused but alive.
4430 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session1));
4431 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
4432
Zhongyi Shi28f6e352018-06-20 21:15:434433 // Add new sockets to use post migration. Those are bad sockets and will cause
4434 // migration to fail.
jrie3d187c2016-09-16 14:29:174435 MockConnect connect_result =
4436 MockConnect(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
Ryan Sleevib8d7ea02018-05-07 20:01:014437 SequencedSocketData socket_data3(connect_result, base::span<MockRead>(),
4438 base::span<MockWrite>());
Zhongyi Shi5f587cc2017-11-21 23:24:174439 socket_factory_->AddSocketDataProvider(&socket_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:014440 SequencedSocketData socket_data4(connect_result, base::span<MockRead>(),
4441 base::span<MockWrite>());
Zhongyi Shi5f587cc2017-11-21 23:24:174442 socket_factory_->AddSocketDataProvider(&socket_data4);
jrie3d187c2016-09-16 14:29:174443
Zhongyi Shi28f6e352018-06-20 21:15:434444 // Connect the new network and cause migration to bad sockets, causing
4445 // sessions to close.
jrie3d187c2016-09-16 14:29:174446 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4447 ->SetConnectedNetworksList({kNewNetworkForTests});
4448 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4449 ->NotifyNetworkConnected(kNewNetworkForTests);
4450
4451 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session1));
4452 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
4453
4454 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
4455 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
4456 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
4457 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
4458}
4459
Zhongyi Shi6ec9b36e2018-06-20 20:32:544460// This test verifies that session attempts connection migration with signals
4461// delivered in the following order (no alternate network is available):
4462// - path degrading is detected: session attempts connection migration but no
4463// alternate network is available, session caches path degrading signal in
4464// connection and stays on the original network.
4465// - original network backs up, request is served in the orignal network,
4466// session is not marked as going away.
4467TEST_P(QuicStreamFactoryTest, MigrateOnPathDegradingWithNoNewNetwork) {
4468 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jrid36ada62016-02-06 02:42:084469 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4470 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4471
Ryan Hamiltonabad59e2019-06-06 04:02:594472 MockQuicData quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:024473 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
4474 quic_data.AddWrite(
4475 SYNCHRONOUS,
4476 ConstructGetRequestPacket(
4477 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi6ec9b36e2018-06-20 20:32:544478 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause for path degrading signal.
4479
4480 // The rest of the data will still flow in the original socket as there is no
4481 // new network after path degrading.
Fan Yang32c5a112018-12-10 20:06:334482 quic_data.AddRead(ASYNC, ConstructOkResponsePacket(
4483 1, GetNthClientInitiatedBidirectionalStreamId(0),
4484 false, false));
Zhongyi Shi6ec9b36e2018-06-20 20:32:544485 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:334486 quic_data.AddWrite(
4487 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
4488 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
4489 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi6ec9b36e2018-06-20 20:32:544490 quic_data.AddSocketDataToFactory(socket_factory_.get());
jrid36ada62016-02-06 02:42:084491
4492 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:454493 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:334494 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034495 request.Request(
Nick Harper23290b82019-05-02 00:02:564496 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:514497 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:034498 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4499 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:014500 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:244501 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jrid36ada62016-02-06 02:42:084502 EXPECT_TRUE(stream.get());
4503
4504 // Cause QUIC stream to be created.
4505 HttpRequestInfo request_info;
Zhongyi Shi6ec9b36e2018-06-20 20:32:544506 request_info.method = "GET";
4507 request_info.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:394508 request_info.traffic_annotation =
4509 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Zhongyi Shi6ec9b36e2018-06-20 20:32:544510 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394511 net_log_, CompletionOnceCallback()));
jrid36ada62016-02-06 02:42:084512
4513 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:504514 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jrid36ada62016-02-06 02:42:084515 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4516 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4517
Zhongyi Shi6ec9b36e2018-06-20 20:32:544518 // Send GET request on stream.
4519 HttpResponseInfo response;
4520 HttpRequestHeaders request_headers;
4521 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
4522 callback_.callback()));
jrid36ada62016-02-06 02:42:084523
Zhongyi Shi6ec9b36e2018-06-20 20:32:544524 // Trigger connection migration on path degrading. Since there are no networks
4525 // to migrate to, the session will remain on the original network, not marked
4526 // as going away.
4527 session->connection()->OnPathDegradingTimeout();
4528 EXPECT_TRUE(session->connection()->IsPathDegrading());
4529
4530 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4531 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4532 EXPECT_EQ(1u, session->GetNumActiveStreams());
4533 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
4534
4535 // Resume so that rest of the data will flow in the original socket.
4536 quic_data.Resume();
jrid36ada62016-02-06 02:42:084537
4538 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4539 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4540 EXPECT_EQ(1u, session->GetNumActiveStreams());
4541
4542 stream.reset();
Zhongyi Shi6ec9b36e2018-06-20 20:32:544543 EXPECT_TRUE(quic_data.AllReadDataConsumed());
4544 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
jrid36ada62016-02-06 02:42:084545}
4546
Zhongyi Shi21e99532018-07-17 22:23:074547// This test verifies that session with non-migratable stream will probe the
4548// alternate network on path degrading, and close the non-migratable streams
4549// when probe is successful.
Zhongyi Shi32fe14d42019-02-28 00:25:364550TEST_P(QuicStreamFactoryTest,
4551 MigrateSessionEarlyNonMigratableStream_DoNotMigrateIdleSessions) {
4552 TestMigrateSessionEarlyNonMigratableStream(false);
4553}
4554
4555TEST_P(QuicStreamFactoryTest,
4556 MigrateSessionEarlyNonMigratableStream_MigrateIdleSessions) {
4557 TestMigrateSessionEarlyNonMigratableStream(true);
4558}
4559
4560void QuicStreamFactoryTestBase::TestMigrateSessionEarlyNonMigratableStream(
4561 bool migrate_idle_sessions) {
4562 test_params_.quic_migrate_idle_sessions = migrate_idle_sessions;
Zhongyi Shi1a054612018-06-14 04:59:084563 InitializeConnectionMigrationV2Test(
jri231c2972016-03-08 19:50:114564 {kDefaultNetworkForTests, kNewNetworkForTests});
4565 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4566 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4567
Ryan Hamiltonabad59e2019-06-06 04:02:594568 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:364569 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434570 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi32fe14d42019-02-28 00:25:364571 if (!migrate_idle_sessions) {
4572 socket_data.AddWrite(
4573 SYNCHRONOUS,
4574 client_maker_.MakeRstAckAndConnectionClosePacket(
4575 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
4576 quic::QUIC_STREAM_CANCELLED,
4577 quic::QuicTime::Delta::FromMilliseconds(0), 1, 1, 1,
4578 quic::QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS,
4579 "net error"));
4580 }
Zhongyi Shi5f587cc2017-11-21 23:24:174581 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri231c2972016-03-08 19:50:114582
Zhongyi Shi21e99532018-07-17 22:23:074583 // Set up the second socket data provider that is used for probing.
Ryan Hamiltonabad59e2019-06-06 04:02:594584 MockQuicData quic_data1(version_);
Zhongyi Shi21e99532018-07-17 22:23:074585 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:254586 quic_data1.AddWrite(SYNCHRONOUS,
4587 client_maker_.MakeConnectivityProbingPacket(2, true));
Zhongyi Shi21e99532018-07-17 22:23:074588 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
4589 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:254590 quic_data1.AddRead(ASYNC,
4591 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shi32fe14d42019-02-28 00:25:364592 if (migrate_idle_sessions) {
4593 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
4594 // A RESET will be sent to the peer to cancel the non-migratable stream.
4595 quic_data1.AddWrite(
4596 SYNCHRONOUS,
4597 client_maker_.MakeRstPacket(
4598 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
4599 quic::QUIC_STREAM_CANCELLED));
4600 // Ping packet to send after migration is completed.
4601 quic_data1.AddWrite(SYNCHRONOUS,
4602 client_maker_.MakeAckAndPingPacket(4, false, 1, 1, 1));
4603 }
Zhongyi Shi21e99532018-07-17 22:23:074604 quic_data1.AddSocketDataToFactory(socket_factory_.get());
4605
jri231c2972016-03-08 19:50:114606 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:454607 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:334608 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034609 request.Request(
Nick Harper23290b82019-05-02 00:02:564610 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:514611 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:034612 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4613 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:014614 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:244615 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri231c2972016-03-08 19:50:114616 EXPECT_TRUE(stream.get());
4617
4618 // Cause QUIC stream to be created, but marked as non-migratable.
4619 HttpRequestInfo request_info;
Zhongyi Shibb28b1f2018-07-18 02:41:264620 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Ramin Halavati683bcaa92018-02-14 08:42:394621 request_info.traffic_annotation =
4622 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274623 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394624 net_log_, CompletionOnceCallback()));
jri231c2972016-03-08 19:50:114625
4626 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:504627 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri231c2972016-03-08 19:50:114628 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4629 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4630
4631 // Trigger connection migration. Since there is a non-migratable stream,
Zhongyi Shic16b4102019-02-12 00:37:404632 // this should cause session to migrate.
jri231c2972016-03-08 19:50:114633 session->OnPathDegrading();
4634
4635 // Run the message loop so that data queued in the new socket is read by the
4636 // packet reader.
4637 base::RunLoop().RunUntilIdle();
4638
jri231c2972016-03-08 19:50:114639 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4640 EXPECT_EQ(1u, session->GetNumActiveStreams());
4641
Zhongyi Shi21e99532018-07-17 22:23:074642 // Resume the data to read the connectivity probing response to declare probe
4643 // as successful. Non-migratable streams will be closed.
4644 quic_data1.Resume();
Zhongyi Shi32fe14d42019-02-28 00:25:364645 if (migrate_idle_sessions)
4646 base::RunLoop().RunUntilIdle();
Zhongyi Shic16b4102019-02-12 00:37:404647
Zhongyi Shi32fe14d42019-02-28 00:25:364648 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(host_port_pair_));
Zhongyi Shi21e99532018-07-17 22:23:074649 EXPECT_EQ(0u, session->GetNumActiveStreams());
jri231c2972016-03-08 19:50:114650
Zhongyi Shi21e99532018-07-17 22:23:074651 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
4652 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
jri231c2972016-03-08 19:50:114653 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4654 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4655}
4656
jri9c541572016-03-29 17:51:484657TEST_P(QuicStreamFactoryTest, MigrateSessionEarlyConnectionMigrationDisabled) {
Zhongyi Shi1a054612018-06-14 04:59:084658 InitializeConnectionMigrationV2Test(
jri9c541572016-03-29 17:51:484659 {kDefaultNetworkForTests, kNewNetworkForTests});
4660 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4661 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4662
Ryan Hamiltonabad59e2019-06-06 04:02:594663 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:364664 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434665 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
4666 socket_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334667 SYNCHRONOUS, client_maker_.MakeRstPacket(
4668 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
4669 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:174670 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9c541572016-03-29 17:51:484671
4672 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:454673 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:334674 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034675 request.Request(
Nick Harper23290b82019-05-02 00:02:564676 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:514677 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:034678 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4679 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:014680 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:244681 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9c541572016-03-29 17:51:484682 EXPECT_TRUE(stream.get());
4683
4684 // Cause QUIC stream to be created.
4685 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:394686 request_info.traffic_annotation =
4687 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274688 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394689 net_log_, CompletionOnceCallback()));
jri9c541572016-03-29 17:51:484690
4691 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:504692 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri9c541572016-03-29 17:51:484693 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4694 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4695
4696 // Set session config to have connection migration disabled.
Ryan Hamilton8d9ee76e2018-05-29 23:52:524697 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
4698 session->config());
jri9c541572016-03-29 17:51:484699 EXPECT_TRUE(session->config()->DisableConnectionMigration());
4700
4701 // Trigger connection migration. Since there is a non-migratable stream,
4702 // this should cause session to be continue without migrating.
4703 session->OnPathDegrading();
4704
4705 // Run the message loop so that data queued in the new socket is read by the
4706 // packet reader.
4707 base::RunLoop().RunUntilIdle();
4708
4709 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4710 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4711 EXPECT_EQ(1u, session->GetNumActiveStreams());
4712
4713 stream.reset();
4714
4715 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4716 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4717}
4718
Zhongyi Shi3c4c9e92018-07-02 23:16:234719// Regression test for http://crbug.com/791886.
4720// This test verifies that the old packet writer which encountered an
4721// asynchronous write error will be blocked during migration on write error. New
4722// packets would not be written until the one with write error is rewritten on
4723// the new network.
4724TEST_P(QuicStreamFactoryTest, MigrateSessionOnAysncWriteError) {
4725 InitializeConnectionMigrationV2Test(
4726 {kDefaultNetworkForTests, kNewNetworkForTests});
4727 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4728 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4729 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4730
4731 // Using a testing task runner so that we can control time.
4732 // base::RunLoop() controls mocked socket writes and reads.
4733 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4734 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4735
Ryan Hamiltonabad59e2019-06-06 04:02:594736 MockQuicData socket_data(version_);
Zhongyi Shi3c4c9e92018-07-02 23:16:234737 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:024738 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi3c4c9e92018-07-02 23:16:234739 socket_data.AddWrite(ASYNC, ERR_ADDRESS_UNREACHABLE);
4740 socket_data.AddSocketDataToFactory(socket_factory_.get());
4741
4742 // Set up second socket data provider that is used after
4743 // migration. The request is rewritten to this new socket, and the
4744 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:594745 MockQuicData socket_data1(version_);
Zhongyi Shi3c4c9e92018-07-02 23:16:234746 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:024747 SYNCHRONOUS,
4748 ConstructGetRequestPacket(
4749 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Ryan Hamilton9f2eac32019-06-27 03:15:544750 client_maker_.set_coalesce_http_frames(true);
Ryan Hamilton0d65a8c2019-06-07 00:46:024751 socket_data1.AddWrite(
4752 SYNCHRONOUS,
4753 ConstructGetRequestPacket(
4754 3, GetNthClientInitiatedBidirectionalStreamId(1),
4755 GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Fan Yang32c5a112018-12-10 20:06:334756 socket_data1.AddRead(
4757 ASYNC,
4758 ConstructOkResponsePacket(
4759 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
4760 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4761 socket_data1.AddWrite(
4762 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
4763 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
4764 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
4765 socket_data1.AddWrite(
4766 SYNCHRONOUS, client_maker_.MakeRstPacket(
4767 5, false, GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:414768 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:184769 /*include_stop_sending_if_v99=*/true));
Zhongyi Shi3c4c9e92018-07-02 23:16:234770
4771 socket_data1.AddSocketDataToFactory(socket_factory_.get());
4772
4773 // Create request #1 and QuicHttpStream.
4774 QuicStreamRequest request1(factory_.get());
4775 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034776 request1.Request(
Nick Harper23290b82019-05-02 00:02:564777 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:514778 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:034779 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4780 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi3c4c9e92018-07-02 23:16:234781 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4782 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
4783 EXPECT_TRUE(stream1.get());
4784
4785 HttpRequestInfo request_info1;
4786 request_info1.method = "GET";
4787 request_info1.url = GURL("https://www.example.org/");
4788 request_info1.traffic_annotation =
4789 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4790 EXPECT_EQ(OK,
4791 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
4792 net_log_, CompletionOnceCallback()));
4793
4794 // Request #2 returns synchronously because it pools to existing session.
4795 TestCompletionCallback callback2;
4796 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:514797 EXPECT_EQ(OK,
4798 request2.Request(
4799 host_port_pair_, version_.transport_version, privacy_mode_,
4800 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
4801 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4802 failed_on_default_network_callback_, callback2.callback()));
Zhongyi Shi3c4c9e92018-07-02 23:16:234803 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
4804 EXPECT_TRUE(stream2.get());
4805
4806 HttpRequestInfo request_info2;
4807 request_info2.method = "GET";
4808 request_info2.url = GURL("https://www.example.org/");
4809 request_info2.traffic_annotation =
4810 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4811 EXPECT_EQ(OK,
4812 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
4813 net_log_, CompletionOnceCallback()));
4814
4815 // Ensure that session is alive and active.
4816 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
4817 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4818 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4819 EXPECT_EQ(2u, session->GetNumActiveStreams());
4820
4821 // Send GET request on stream1. This should cause an async write error.
4822 HttpResponseInfo response;
4823 HttpRequestHeaders request_headers;
4824 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
4825 callback_.callback()));
4826 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4827
4828 // Run the message loop so that asynchronous write completes and a connection
4829 // migration on write error attempt is posted in QuicStreamFactory's task
4830 // runner.
4831 base::RunLoop().RunUntilIdle();
4832 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4833
4834 // Send GET request on stream. This will cause another write attempt before
4835 // migration on write error is exectued.
4836 HttpResponseInfo response2;
4837 HttpRequestHeaders request_headers2;
4838 EXPECT_EQ(OK, stream2->SendRequest(request_headers2, &response2,
4839 callback2.callback()));
4840
4841 // Run the task runner so that migration on write error is finally executed.
4842 task_runner->RunUntilIdle();
4843
Zhongyi Shia7dd46b2018-07-12 22:59:294844 // Verify the session is still alive and not marked as going away.
Zhongyi Shi3c4c9e92018-07-02 23:16:234845 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:294846 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi3c4c9e92018-07-02 23:16:234847 EXPECT_EQ(2u, session->GetNumActiveStreams());
Zhongyi Shia7dd46b2018-07-12 22:59:294848 // There should be one task posted to migrate back to the default network in
4849 // kMinRetryTimeForDefaultNetworkSecs.
4850 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4851 EXPECT_EQ(base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs),
4852 task_runner->NextPendingTaskDelay());
Zhongyi Shi3c4c9e92018-07-02 23:16:234853
4854 // Verify that response headers on the migrated socket were delivered to the
4855 // stream.
4856 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
4857 EXPECT_EQ(200, response.headers->response_code());
4858
4859 stream1.reset();
4860 stream2.reset();
4861
4862 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4863 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4864 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
4865 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
4866}
4867
Zhongyi Shia7dd46b2018-07-12 22:59:294868// Verify session is not marked as going away after connection migration on
4869// write error and migrate back to default network logic is applied to bring the
4870// migrated session back to the default network. Migration singals delivered
4871// in the following order (alternate network is always availabe):
4872// - session on the default network encountered a write error;
4873// - session successfully migrated to the non-default network;
4874// - session attempts to migrate back to default network post migration;
4875// - migration back to the default network is successful.
4876TEST_P(QuicStreamFactoryTest, MigrateBackToDefaultPostMigrationOnWriteError) {
4877 InitializeConnectionMigrationV2Test(
4878 {kDefaultNetworkForTests, kNewNetworkForTests});
4879 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4880 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4881 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4882
4883 // Using a testing task runner so that we can control time.
4884 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4885 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4886
Ryan Hamiltonabad59e2019-06-06 04:02:594887 MockQuicData socket_data(version_);
Zhongyi Shia7dd46b2018-07-12 22:59:294888 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:024889 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shia7dd46b2018-07-12 22:59:294890 socket_data.AddWrite(ASYNC, ERR_ADDRESS_UNREACHABLE);
4891 socket_data.AddSocketDataToFactory(socket_factory_.get());
4892
4893 // Set up second socket data provider that is used after
4894 // migration. The request is rewritten to this new socket, and the
4895 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:594896 MockQuicData quic_data2(version_);
Fan Yang32c5a112018-12-10 20:06:334897 quic_data2.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:024898 SYNCHRONOUS,
4899 ConstructGetRequestPacket(
4900 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shia7dd46b2018-07-12 22:59:294901 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:334902 ASYNC,
4903 ConstructOkResponsePacket(
4904 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shia7dd46b2018-07-12 22:59:294905 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4906 quic_data2.AddSocketDataToFactory(socket_factory_.get());
4907
4908 // Create request QuicHttpStream.
4909 QuicStreamRequest request1(factory_.get());
4910 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034911 request1.Request(
Nick Harper23290b82019-05-02 00:02:564912 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:514913 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:034914 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4915 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shia7dd46b2018-07-12 22:59:294916 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4917 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
4918 EXPECT_TRUE(stream1.get());
4919
4920 HttpRequestInfo request_info1;
4921 request_info1.method = "GET";
4922 request_info1.url = GURL("https://www.example.org/");
4923 request_info1.traffic_annotation =
4924 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4925 EXPECT_EQ(OK,
4926 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
4927 net_log_, CompletionOnceCallback()));
4928
4929 // Ensure that session is alive and active.
4930 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
4931 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4932 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4933 EXPECT_EQ(1u, session->GetNumActiveStreams());
4934
4935 // Send GET request. This should cause an async write error.
4936 HttpResponseInfo response;
4937 HttpRequestHeaders request_headers;
4938 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
4939 callback_.callback()));
4940 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4941
4942 // Run the message loop so that asynchronous write completes and a connection
4943 // migration on write error attempt is posted in QuicStreamFactory's task
4944 // runner.
4945 base::RunLoop().RunUntilIdle();
4946 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4947
4948 // Run the task runner so that migration on write error is finally executed.
4949 task_runner->RunUntilIdle();
4950
4951 // Verify the session is still alive and not marked as going away.
4952 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4953 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4954 EXPECT_EQ(1u, session->GetNumActiveStreams());
4955 // There should be one task posted to migrate back to the default network in
4956 // kMinRetryTimeForDefaultNetworkSecs.
4957 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4958 base::TimeDelta expected_delay =
4959 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs);
4960 EXPECT_EQ(expected_delay, task_runner->NextPendingTaskDelay());
4961
4962 // Verify that response headers on the migrated socket were delivered to the
4963 // stream.
4964 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
4965 EXPECT_EQ(200, response.headers->response_code());
4966
4967 // Set up the third socket data provider for migrate back to default network.
Ryan Hamiltonabad59e2019-06-06 04:02:594968 MockQuicData quic_data3(version_);
Zhongyi Shia7dd46b2018-07-12 22:59:294969 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:254970 quic_data3.AddWrite(SYNCHRONOUS,
4971 client_maker_.MakeConnectivityProbingPacket(3, false));
Zhongyi Shia7dd46b2018-07-12 22:59:294972 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:254973 quic_data3.AddRead(ASYNC,
4974 server_maker_.MakeConnectivityProbingPacket(2, false));
Zhongyi Shia7dd46b2018-07-12 22:59:294975 quic_data3.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4976 quic_data3.AddWrite(ASYNC, client_maker_.MakeAckPacket(4, 1, 2, 1, 1, true));
4977 quic_data3.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334978 SYNCHRONOUS, client_maker_.MakeRstPacket(
4979 5, false, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:414980 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:184981 /*include_stop_sending_if_v99=*/true));
Zhongyi Shia7dd46b2018-07-12 22:59:294982 quic_data3.AddSocketDataToFactory(socket_factory_.get());
4983
4984 // Fast forward to fire the migrate back timer and verify the session
4985 // successfully migrates back to the default network.
4986 task_runner->FastForwardBy(expected_delay);
4987
4988 // Verify the session is still alive and not marked as going away.
4989 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4990 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4991 EXPECT_EQ(1u, session->GetNumActiveStreams());
4992
4993 // There should be one task posted to one will resend a connectivity probe and
4994 // the other will retry migrate back, both are cancelled.
4995 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
4996 task_runner->FastForwardBy(
4997 base::TimeDelta::FromSeconds(2 * kMinRetryTimeForDefaultNetworkSecs));
4998 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4999
5000 stream1.reset();
5001 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5002 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5003 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
5004 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
5005 EXPECT_TRUE(quic_data3.AllReadDataConsumed());
5006 EXPECT_TRUE(quic_data3.AllWriteDataConsumed());
5007}
5008
Zhongyi Shic1449372018-08-09 09:58:585009// This test verifies that the connection will not attempt connection migration
5010// (send connectivity probes on alternate path) when path degrading is detected
5011// and handshake is not confirmed.
5012TEST_P(QuicStreamFactoryTest,
5013 NoMigrationOnPathDegradingBeforeHandshakeConfirmed) {
5014 InitializeConnectionMigrationV2Test(
5015 {kDefaultNetworkForTests, kNewNetworkForTests});
5016
5017 // Using a testing task runner.
5018 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
5019 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
5020
5021 // Use cold start mode to send crypto message for handshake.
5022 crypto_client_stream_factory_.set_handshake_mode(
5023 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
5024
Ryan Hamiltonabad59e2019-06-06 04:02:595025 MockQuicData socket_data(version_);
Zhongyi Shic1449372018-08-09 09:58:585026 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5027 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
5028 socket_data.AddSocketDataToFactory(socket_factory_.get());
5029
5030 // Create request and QuicHttpStream.
5031 QuicStreamRequest request(factory_.get());
5032 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035033 request.Request(
Nick Harper23290b82019-05-02 00:02:565034 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:515035 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035036 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5037 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shic1449372018-08-09 09:58:585038
5039 base::RunLoop().RunUntilIdle();
5040
5041 // Ensure that session is alive but not active.
5042 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5043 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5044 QuicChromiumClientSession* session = GetPendingSession(host_port_pair_);
5045 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5046 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
5047
5048 // Cause the connection to report path degrading to the session.
5049 // Session will ignore the signal as handshake is not completed.
5050 session->connection()->OnPathDegradingTimeout();
5051 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
5052
5053 EXPECT_FALSE(HasActiveSession(host_port_pair_));
Zhongyi Shi8de43832018-08-15 23:40:005054 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
Zhongyi Shic1449372018-08-09 09:58:585055 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5056 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5057}
5058
Zhongyi Shi634c1882018-08-16 04:05:595059// This test verifies that if a connection is closed with
5060// QUIC_NETWORK_IDLE_TIMEOUT before handshake is completed and there is no
5061// alternate network, no new connection will be created.
5062TEST_P(QuicStreamFactoryTest, NoAlternateNetworkBeforeHandshakeOnIdleTimeout) {
5063 TestNoAlternateNetworkBeforeHandshake(quic::QUIC_NETWORK_IDLE_TIMEOUT);
5064}
5065
5066// This test verifies that if a connection is closed with QUIC_HANDSHAKE_TIMEOUT
5067// and there is no alternate network, no new connection will be created.
5068TEST_P(QuicStreamFactoryTest, NoAlternateNetworkOnHandshakeTimeout) {
5069 TestNoAlternateNetworkBeforeHandshake(quic::QUIC_HANDSHAKE_TIMEOUT);
5070}
5071
5072void QuicStreamFactoryTestBase::TestNoAlternateNetworkBeforeHandshake(
5073 quic::QuicErrorCode quic_error) {
5074 DCHECK(quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT ||
5075 quic_error == quic::QUIC_HANDSHAKE_TIMEOUT);
5076 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
5077
5078 // Using a testing task runner.
5079 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
5080 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
5081
5082 // Use cold start mode to send crypto message for handshake.
5083 crypto_client_stream_factory_.set_handshake_mode(
5084 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
5085
Ryan Hamiltonabad59e2019-06-06 04:02:595086 MockQuicData socket_data(version_);
Zhongyi Shi634c1882018-08-16 04:05:595087 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5088 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
5089 socket_data.AddSocketDataToFactory(socket_factory_.get());
5090
5091 // Create request.
5092 QuicStreamRequest request(factory_.get());
5093 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035094 request.Request(
Nick Harper23290b82019-05-02 00:02:565095 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:515096 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035097 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5098 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi634c1882018-08-16 04:05:595099
5100 base::RunLoop().RunUntilIdle();
5101
5102 // Ensure that session is alive but not active.
5103 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5104 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5105 QuicChromiumClientSession* session = GetPendingSession(host_port_pair_);
5106 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5107 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
5108
5109 // Cause the connection to report path degrading to the session.
5110 // Session will ignore the signal as handshake is not completed.
5111 session->connection()->OnPathDegradingTimeout();
5112 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
5113 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5114 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5115
5116 // Cause the connection to close due to |quic_error| before handshake.
Victor Vasiliev076657c2019-03-12 02:46:435117 std::string error_details;
Zhongyi Shi634c1882018-08-16 04:05:595118 if (quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT) {
5119 error_details = "No recent network activity.";
5120 } else {
5121 error_details = "Handshake timeout expired.";
5122 }
5123 session->connection()->CloseConnection(
5124 quic_error, error_details, quic::ConnectionCloseBehavior::SILENT_CLOSE);
5125
5126 // A task will be posted to clean up the session in the factory.
5127 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
5128 task_runner->FastForwardUntilNoTasksRemain();
5129
5130 // No new session should be created as there is no alternate network.
5131 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5132 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
5133 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5134 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5135}
5136
Zhongyi Shi8de43832018-08-15 23:40:005137TEST_P(QuicStreamFactoryTest, NewConnectionBeforeHandshakeAfterIdleTimeout) {
5138 TestNewConnectionOnAlternateNetworkBeforeHandshake(
5139 quic::QUIC_NETWORK_IDLE_TIMEOUT);
5140}
5141
5142TEST_P(QuicStreamFactoryTest, NewConnectionAfterHandshakeTimeout) {
5143 TestNewConnectionOnAlternateNetworkBeforeHandshake(
5144 quic::QUIC_HANDSHAKE_TIMEOUT);
5145}
5146
Zhongyi Shif3fcbbe62018-08-16 22:52:085147// Sets up a test to verify that a new connection will be created on the
5148// alternate network after the initial connection fails before handshake with
5149// signals delivered in the following order (alternate network is available):
5150// - the default network is not able to complete crypto handshake;
5151// - the original connection is closed with |quic_error|;
5152// - a new connection is created on the alternate network and is able to finish
5153// crypto handshake;
5154// - the new session on the alternate network attempts to migrate back to the
5155// default network by sending probes;
5156// - default network being disconnected is delivered: session will stop probing
5157// the original network.
5158// - alternate network is made by default.
Zhongyi Shi8de43832018-08-15 23:40:005159void QuicStreamFactoryTestBase::
5160 TestNewConnectionOnAlternateNetworkBeforeHandshake(
5161 quic::QuicErrorCode quic_error) {
5162 DCHECK(quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT ||
5163 quic_error == quic::QUIC_HANDSHAKE_TIMEOUT);
Zhongyi Shi967d2f12019-02-08 20:58:535164 test_params_.quic_retry_on_alternate_network_before_handshake = true;
Zhongyi Shi8de43832018-08-15 23:40:005165 InitializeConnectionMigrationV2Test(
5166 {kDefaultNetworkForTests, kNewNetworkForTests});
5167
5168 // Using a testing task runner.
5169 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
5170 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
5171
5172 // Use cold start mode to send crypto message for handshake.
5173 crypto_client_stream_factory_.set_handshake_mode(
5174 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
5175
5176 // Socket data for connection on the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:595177 MockQuicData socket_data(version_);
Zhongyi Shi8de43832018-08-15 23:40:005178 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5179 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
5180 socket_data.AddSocketDataToFactory(socket_factory_.get());
5181
5182 // Socket data for connection on the alternate network.
Ryan Hamiltonabad59e2019-06-06 04:02:595183 MockQuicData socket_data2(version_);
Zhongyi Shi8de43832018-08-15 23:40:005184 socket_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5185 socket_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
5186 // Change the encryption level after handshake is confirmed.
5187 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamilton0d65a8c2019-06-07 00:46:025188 socket_data2.AddWrite(ASYNC, ConstructInitialSettingsPacket(2));
Zhongyi Shi8de43832018-08-15 23:40:005189 socket_data2.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335190 ASYNC, ConstructGetRequestPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:025191 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi8de43832018-08-15 23:40:005192 socket_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:335193 ASYNC,
5194 ConstructOkResponsePacket(
5195 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shi8de43832018-08-15 23:40:005196 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:335197 socket_data2.AddWrite(
5198 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
5199 5, false, GetNthClientInitiatedBidirectionalStreamId(0),
5200 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi8de43832018-08-15 23:40:005201 socket_data2.AddSocketDataToFactory(socket_factory_.get());
5202
Zhongyi Shif3fcbbe62018-08-16 22:52:085203 // Socket data for probing on the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:595204 MockQuicData probing_data(version_);
Zhongyi Shif3fcbbe62018-08-16 22:52:085205 probing_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
5206 probing_data.AddWrite(SYNCHRONOUS,
5207 client_maker_.MakeConnectivityProbingPacket(4, false));
5208 probing_data.AddSocketDataToFactory(socket_factory_.get());
5209
Zhongyi Shi8de43832018-08-15 23:40:005210 // Create request and QuicHttpStream.
5211 QuicStreamRequest request(factory_.get());
5212 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035213 request.Request(
Nick Harper23290b82019-05-02 00:02:565214 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:515215 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035216 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5217 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi8de43832018-08-15 23:40:005218
5219 base::RunLoop().RunUntilIdle();
5220
5221 // Ensure that session is alive but not active.
5222 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5223 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5224 QuicChromiumClientSession* session = GetPendingSession(host_port_pair_);
5225 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5226 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
Zhongyi Shia6b68d112018-09-24 07:49:035227 EXPECT_FALSE(failed_on_default_network_);
Zhongyi Shi8de43832018-08-15 23:40:005228
Victor Vasiliev076657c2019-03-12 02:46:435229 std::string error_details;
Zhongyi Shi8de43832018-08-15 23:40:005230 if (quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT) {
5231 error_details = "No recent network activity.";
5232 } else {
5233 error_details = "Handshake timeout expired.";
5234 }
5235 session->connection()->CloseConnection(
5236 quic_error, error_details, quic::ConnectionCloseBehavior::SILENT_CLOSE);
5237
5238 // A task will be posted to clean up the session in the factory.
5239 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
5240 task_runner->FastForwardUntilNoTasksRemain();
5241
5242 // Verify a new session is created on the alternate network.
5243 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5244 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5245 QuicChromiumClientSession* session2 = GetPendingSession(host_port_pair_);
5246 EXPECT_NE(session, session2);
Zhongyi Shia6b68d112018-09-24 07:49:035247 EXPECT_TRUE(failed_on_default_network_);
Zhongyi Shi8de43832018-08-15 23:40:005248
5249 // Confirm the handshake on the alternate network.
5250 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5251 quic::QuicSession::HANDSHAKE_CONFIRMED);
5252 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5253 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5254 // Resume the data now so that data can be sent and read.
5255 socket_data2.Resume();
5256
5257 // Create the stream.
5258 std::unique_ptr<HttpStream> stream = CreateStream(&request);
5259 EXPECT_TRUE(stream.get());
5260 HttpRequestInfo request_info;
5261 request_info.method = "GET";
5262 request_info.url = GURL("https://www.example.org/");
5263 request_info.traffic_annotation =
5264 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5265 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
5266 net_log_, CompletionOnceCallback()));
5267 // Send the request.
5268 HttpResponseInfo response;
5269 HttpRequestHeaders request_headers;
5270 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5271 callback_.callback()));
5272 // Run the message loop to finish asynchronous mock write.
5273 base::RunLoop().RunUntilIdle();
5274 // Read the response.
5275 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
5276 EXPECT_EQ(200, response.headers->response_code());
5277
Zhongyi Shif3fcbbe62018-08-16 22:52:085278 // There should be a new task posted to migrate back to the default network.
5279 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
5280 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
5281 EXPECT_EQ(base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs),
5282 next_task_delay);
5283 task_runner->FastForwardBy(next_task_delay);
5284
5285 // There should be two tasks posted. One will retry probing and the other
5286 // will retry migrate back.
5287 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
5288 next_task_delay = task_runner->NextPendingTaskDelay();
5289 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
5290 next_task_delay);
5291
5292 // Deliver the signal that the default network is disconnected.
5293 scoped_mock_network_change_notifier_->mock_network_change_notifier()
5294 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
5295 // Verify no connectivity probes will be sent as probing will be cancelled.
5296 task_runner->FastForwardUntilNoTasksRemain();
5297 // Deliver the signal that the alternate network is made default.
5298 scoped_mock_network_change_notifier_->mock_network_change_notifier()
5299 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
5300 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
5301
Zhongyi Shi8de43832018-08-15 23:40:005302 stream.reset();
5303 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5304 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5305 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
5306 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
5307}
5308
Zhongyi Shi247d6322018-07-24 07:03:355309// Test that connection will be closed with PACKET_WRITE_ERROR if a write error
5310// is triggered before handshake is confirmed and connection migration is turned
5311// on.
5312TEST_P(QuicStreamFactoryTest, MigrationOnWriteErrorBeforeHandshakeConfirmed) {
Zhongyi Shi967d2f12019-02-08 20:58:535313 DCHECK(!test_params_.quic_retry_on_alternate_network_before_handshake);
Zhongyi Shi247d6322018-07-24 07:03:355314 InitializeConnectionMigrationV2Test(
5315 {kDefaultNetworkForTests, kNewNetworkForTests});
5316
5317 // Use unmocked crypto stream to do crypto connect.
5318 crypto_client_stream_factory_.set_handshake_mode(
Zhongyi Shi879659422018-08-02 17:58:255319 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
Zhongyi Shi247d6322018-07-24 07:03:355320
Ryan Hamiltonabad59e2019-06-06 04:02:595321 MockQuicData socket_data(version_);
Zhongyi Shi247d6322018-07-24 07:03:355322 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5323 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
5324 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
5325 socket_data.AddSocketDataToFactory(socket_factory_.get());
5326
5327 // Create request, should fail after the write of the CHLO fails.
5328 QuicStreamRequest request(factory_.get());
5329 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035330 request.Request(
Nick Harper23290b82019-05-02 00:02:565331 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:515332 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035333 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5334 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi247d6322018-07-24 07:03:355335 EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED, callback_.WaitForResult());
5336 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5337 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
5338
5339 // Verify new requests can be sent normally.
5340 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:275341 MockCryptoClientStream::COLD_START);
Zhongyi Shi247d6322018-07-24 07:03:355342 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5343 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
Ryan Hamilton0d65a8c2019-06-07 00:46:025344 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:595345 MockQuicData socket_data2(version_);
Zhongyi Shi247d6322018-07-24 07:03:355346 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5347 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
5348 socket_data2.AddSocketDataToFactory(socket_factory_.get());
5349
5350 QuicStreamRequest request2(factory_.get());
5351 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035352 request2.Request(
Nick Harper23290b82019-05-02 00:02:565353 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:515354 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035355 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5356 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi247d6322018-07-24 07:03:355357 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5358 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5359 // Run the message loop to complete host resolution.
5360 base::RunLoop().RunUntilIdle();
5361
5362 // Complete handshake. QuicStreamFactory::Job should complete and succeed.
5363 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5364 quic::QuicSession::HANDSHAKE_CONFIRMED);
5365 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5366 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5367 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
5368
5369 // Create QuicHttpStream.
5370 std::unique_ptr<HttpStream> stream = CreateStream(&request2);
5371 EXPECT_TRUE(stream.get());
5372 stream.reset();
5373 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5374 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5375 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
5376 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
5377}
5378
Zhongyi Shif2524bf2019-01-27 07:44:035379// Test that if the original connection is closed with QUIC_PACKET_WRITE_ERROR
5380// before handshake is confirmed and new connection before handshake is turned
5381// on, a new connection will be retried on the alternate network.
5382TEST_P(QuicStreamFactoryTest,
5383 RetryConnectionOnWriteErrorBeforeHandshakeConfirmed) {
Zhongyi Shi967d2f12019-02-08 20:58:535384 test_params_.quic_retry_on_alternate_network_before_handshake = true;
Zhongyi Shif2524bf2019-01-27 07:44:035385 InitializeConnectionMigrationV2Test(
5386 {kDefaultNetworkForTests, kNewNetworkForTests});
5387
5388 // Use unmocked crypto stream to do crypto connect.
5389 crypto_client_stream_factory_.set_handshake_mode(
5390 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
5391
5392 // Socket data for connection on the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:595393 MockQuicData socket_data(version_);
Zhongyi Shif2524bf2019-01-27 07:44:035394 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5395 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
5396 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
5397 socket_data.AddSocketDataToFactory(socket_factory_.get());
5398
5399 // Socket data for connection on the alternate network.
Ryan Hamiltonabad59e2019-06-06 04:02:595400 MockQuicData socket_data2(version_);
Zhongyi Shif2524bf2019-01-27 07:44:035401 socket_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5402 socket_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
5403 // Change the encryption level after handshake is confirmed.
5404 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamilton0d65a8c2019-06-07 00:46:025405 socket_data2.AddWrite(ASYNC, ConstructInitialSettingsPacket(2));
Zhongyi Shif2524bf2019-01-27 07:44:035406 socket_data2.AddWrite(
5407 ASYNC, ConstructGetRequestPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:025408 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shif2524bf2019-01-27 07:44:035409 socket_data2.AddRead(
5410 ASYNC,
5411 ConstructOkResponsePacket(
5412 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
5413 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5414 socket_data2.AddWrite(
5415 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
5416 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
5417 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
5418 socket_data2.AddSocketDataToFactory(socket_factory_.get());
5419
5420 // Create request, should fail after the write of the CHLO fails.
5421 QuicStreamRequest request(factory_.get());
5422 EXPECT_EQ(ERR_IO_PENDING,
5423 request.Request(
Nick Harper23290b82019-05-02 00:02:565424 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:515425 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shif2524bf2019-01-27 07:44:035426 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5427 failed_on_default_network_callback_, callback_.callback()));
5428 // Ensure that the session is alive but not active.
5429 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5430 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5431 base::RunLoop().RunUntilIdle();
5432 QuicChromiumClientSession* session = GetPendingSession(host_port_pair_);
5433 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5434
5435 // Confirm the handshake on the alternate network.
5436 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5437 quic::QuicSession::HANDSHAKE_CONFIRMED);
5438 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5439 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5440
5441 // Resume the data now so that data can be sent and read.
5442 socket_data2.Resume();
5443
5444 // Create the stream.
5445 std::unique_ptr<HttpStream> stream = CreateStream(&request);
5446 EXPECT_TRUE(stream.get());
5447 HttpRequestInfo request_info;
5448 request_info.method = "GET";
5449 request_info.url = GURL("https://www.example.org/");
5450 request_info.traffic_annotation =
5451 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5452 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
5453 net_log_, CompletionOnceCallback()));
5454 // Send the request.
5455 HttpResponseInfo response;
5456 HttpRequestHeaders request_headers;
5457 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5458 callback_.callback()));
5459 // Run the message loop to finish asynchronous mock write.
5460 base::RunLoop().RunUntilIdle();
5461 // Read the response.
5462 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
5463 EXPECT_EQ(200, response.headers->response_code());
5464
5465 stream.reset();
5466 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5467 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5468 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
5469 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
5470}
5471
jri9f303712016-09-13 01:10:225472void QuicStreamFactoryTestBase::TestMigrationOnWriteError(
5473 IoMode write_error_mode) {
Zhongyi Shi1a054612018-06-14 04:59:085474 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:225475 {kDefaultNetworkForTests, kNewNetworkForTests});
5476 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5477 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5478 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5479
Zhongyi Shi3c4c9e92018-07-02 23:16:235480 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
5481
Ryan Hamiltonabad59e2019-06-06 04:02:595482 MockQuicData socket_data(version_);
jri9f303712016-09-13 01:10:225483 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:025484 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jri9f303712016-09-13 01:10:225485 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:175486 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:225487
5488 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:455489 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:335490 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035491 request.Request(
Nick Harper23290b82019-05-02 00:02:565492 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:515493 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035494 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5495 failed_on_default_network_callback_, callback_.callback()));
jri9f303712016-09-13 01:10:225496 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:245497 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:225498 EXPECT_TRUE(stream.get());
5499
5500 // Cause QUIC stream to be created.
5501 HttpRequestInfo request_info;
5502 request_info.method = "GET";
5503 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:395504 request_info.traffic_annotation =
5505 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:275506 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:395507 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:225508
5509 // Ensure that session is alive and active.
5510 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5511 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5512 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5513
5514 // Set up second socket data provider that is used after
5515 // migration. The request is rewritten to this new socket, and the
5516 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:595517 MockQuicData socket_data1(version_);
Fan Yang32c5a112018-12-10 20:06:335518 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:025519 SYNCHRONOUS,
5520 ConstructGetRequestPacket(
5521 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi32f2fd02018-04-16 18:23:435522 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:335523 ASYNC,
5524 ConstructOkResponsePacket(
5525 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
jri9f303712016-09-13 01:10:225526 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:335527 socket_data1.AddWrite(
5528 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
5529 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
5530 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:175531 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:225532
5533 // Send GET request on stream. This should cause a write error, which triggers
5534 // a connection migration attempt.
5535 HttpResponseInfo response;
5536 HttpRequestHeaders request_headers;
5537 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5538 callback_.callback()));
5539
5540 // Run the message loop so that the migration attempt is executed and
5541 // data queued in the new socket is read by the packet reader.
5542 base::RunLoop().RunUntilIdle();
5543
Zhongyi Shia7dd46b2018-07-12 22:59:295544 // Verify that session is alive and not marked as going awya.
jri9f303712016-09-13 01:10:225545 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:295546 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri9f303712016-09-13 01:10:225547 EXPECT_EQ(1u, session->GetNumActiveStreams());
5548
5549 // Verify that response headers on the migrated socket were delivered to the
5550 // stream.
5551 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
5552 EXPECT_EQ(200, response.headers->response_code());
5553
5554 stream.reset();
5555
5556 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5557 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5558 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
5559 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
5560}
5561
5562TEST_P(QuicStreamFactoryTest, MigrateSessionOnWriteErrorSynchronous) {
5563 TestMigrationOnWriteError(SYNCHRONOUS);
5564}
5565
5566TEST_P(QuicStreamFactoryTest, MigrateSessionOnWriteErrorAsync) {
5567 TestMigrationOnWriteError(ASYNC);
5568}
5569
5570void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorNoNewNetwork(
5571 IoMode write_error_mode) {
Zhongyi Shi1a054612018-06-14 04:59:085572 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri9f303712016-09-13 01:10:225573 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5574 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5575
jri5b785512016-09-13 04:29:115576 // Use the test task runner, to force the migration alarm timeout later.
5577 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
5578
Ryan Hamiltonabad59e2019-06-06 04:02:595579 MockQuicData socket_data(version_);
jri9f303712016-09-13 01:10:225580 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:435581 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jri9f303712016-09-13 01:10:225582 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:175583 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:225584
5585 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:455586 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:335587 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035588 request.Request(
Nick Harper23290b82019-05-02 00:02:565589 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:515590 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035591 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5592 failed_on_default_network_callback_, callback_.callback()));
jri9f303712016-09-13 01:10:225593 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:245594 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:225595 EXPECT_TRUE(stream.get());
5596
5597 // Cause QUIC stream to be created.
5598 HttpRequestInfo request_info;
5599 request_info.method = "GET";
5600 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:395601 request_info.traffic_annotation =
5602 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:275603 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:395604 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:225605
5606 // Ensure that session is alive and active.
5607 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5608 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5609 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5610
jri5b785512016-09-13 04:29:115611 // Send GET request on stream. This causes a write error, which triggers
5612 // a connection migration attempt. Since there are no networks
5613 // to migrate to, this causes the session to wait for a new network.
jri9f303712016-09-13 01:10:225614 HttpResponseInfo response;
5615 HttpRequestHeaders request_headers;
5616 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5617 callback_.callback()));
jri5b785512016-09-13 04:29:115618
5619 // Complete any pending writes. Pending async MockQuicData writes
5620 // are run on the message loop, not on the test runner.
jri9f303712016-09-13 01:10:225621 base::RunLoop().RunUntilIdle();
jri5b785512016-09-13 04:29:115622
5623 // Write error causes migration task to be posted. Spin the loop.
5624 if (write_error_mode == ASYNC)
5625 runner_->RunNextTask();
5626
5627 // Migration has not yet failed. The session should be alive and active.
5628 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5629 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5630 EXPECT_EQ(1u, session->GetNumActiveStreams());
5631 EXPECT_TRUE(session->connection()->writer()->IsWriteBlocked());
5632
5633 // The migration will not fail until the migration alarm timeout.
5634 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5635 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5636 EXPECT_EQ(1u, session->GetNumActiveStreams());
5637 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
5638
5639 // Force migration alarm timeout to run.
5640 RunTestLoopUntilIdle();
5641
5642 // The connection should be closed. A request for response headers
5643 // should fail.
jri9f303712016-09-13 01:10:225644 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5645 EXPECT_FALSE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:115646 EXPECT_EQ(ERR_NETWORK_CHANGED, callback_.WaitForResult());
5647 EXPECT_EQ(ERR_NETWORK_CHANGED,
5648 stream->ReadResponseHeaders(callback_.callback()));
jri9f303712016-09-13 01:10:225649
Zhongyi Shi59aaf072019-01-17 03:32:135650 NetErrorDetails error_details;
5651 stream->PopulateNetErrorDetails(&error_details);
5652 EXPECT_EQ(error_details.quic_connection_error,
5653 quic::QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK);
5654
jri9f303712016-09-13 01:10:225655 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5656 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5657}
5658
5659TEST_P(QuicStreamFactoryTest,
5660 MigrateSessionOnWriteErrorNoNewNetworkSynchronous) {
5661 TestMigrationOnWriteErrorNoNewNetwork(SYNCHRONOUS);
5662}
5663
5664TEST_P(QuicStreamFactoryTest, MigrateSessionOnWriteErrorNoNewNetworkAsync) {
5665 TestMigrationOnWriteErrorNoNewNetwork(ASYNC);
5666}
5667
Zhongyi Shi0439ecc72018-07-11 04:41:265668TEST_P(QuicStreamFactoryTest,
5669 MigrateSessionOnWriteErrorWithMultipleRequestsSync) {
5670 TestMigrationOnWriteErrorWithMultipleRequests(SYNCHRONOUS);
5671}
5672
5673TEST_P(QuicStreamFactoryTest,
5674 MigrateSessionOnWriteErrorWithMultipleRequestsAsync) {
5675 TestMigrationOnWriteErrorWithMultipleRequests(ASYNC);
5676}
5677
5678// Sets up a test which verifies that connection migration on write error can
5679// eventually succeed and rewrite the packet on the new network with *multiple*
5680// migratable streams.
5681void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorWithMultipleRequests(
5682 IoMode write_error_mode) {
5683 InitializeConnectionMigrationV2Test(
5684 {kDefaultNetworkForTests, kNewNetworkForTests});
5685 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5686 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5687 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5688
Ryan Hamiltonabad59e2019-06-06 04:02:595689 MockQuicData socket_data(version_);
Zhongyi Shi0439ecc72018-07-11 04:41:265690 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:025691 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi0439ecc72018-07-11 04:41:265692 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
5693 socket_data.AddSocketDataToFactory(socket_factory_.get());
5694
5695 // Set up second socket data provider that is used after
5696 // migration. The request is rewritten to this new socket, and the
5697 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:595698 MockQuicData socket_data1(version_);
Zhongyi Shi0439ecc72018-07-11 04:41:265699 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:025700 SYNCHRONOUS,
5701 ConstructGetRequestPacket(
5702 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Fan Yang32c5a112018-12-10 20:06:335703 socket_data1.AddRead(
5704 ASYNC,
5705 ConstructOkResponsePacket(
5706 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
5707 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5708 socket_data1.AddWrite(
5709 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
5710 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
5711 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
5712 socket_data1.AddWrite(
5713 SYNCHRONOUS, client_maker_.MakeRstPacket(
5714 4, false, GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:415715 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:185716 /*include_stop_sending_if_v99=*/true));
Zhongyi Shi0439ecc72018-07-11 04:41:265717
5718 socket_data1.AddSocketDataToFactory(socket_factory_.get());
5719
5720 // Create request #1 and QuicHttpStream.
5721 QuicStreamRequest request1(factory_.get());
5722 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035723 request1.Request(
Nick Harper23290b82019-05-02 00:02:565724 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:515725 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035726 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5727 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi0439ecc72018-07-11 04:41:265728 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5729 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
5730 EXPECT_TRUE(stream1.get());
5731
5732 HttpRequestInfo request_info1;
5733 request_info1.method = "GET";
5734 request_info1.url = GURL("https://www.example.org/");
5735 request_info1.traffic_annotation =
5736 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5737 EXPECT_EQ(OK,
5738 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
5739 net_log_, CompletionOnceCallback()));
5740
5741 // Second request returns synchronously because it pools to existing session.
5742 TestCompletionCallback callback2;
5743 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:515744 EXPECT_EQ(OK,
5745 request2.Request(
5746 host_port_pair_, version_.transport_version, privacy_mode_,
5747 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
5748 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5749 failed_on_default_network_callback_, callback2.callback()));
Zhongyi Shi0439ecc72018-07-11 04:41:265750 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
5751 EXPECT_TRUE(stream2.get());
5752 HttpRequestInfo request_info2;
5753 request_info2.method = "GET";
5754 request_info2.url = GURL("https://www.example.org/");
5755 request_info2.traffic_annotation =
5756 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5757 EXPECT_EQ(OK,
5758 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
5759 net_log_, CompletionOnceCallback()));
5760
5761 // Ensure that session is alive and active.
5762 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5763 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5764 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5765 EXPECT_EQ(2u, session->GetNumActiveStreams());
5766
5767 // Send GET request on stream. This should cause a write error, which triggers
5768 // a connection migration attempt.
5769 HttpResponseInfo response;
5770 HttpRequestHeaders request_headers;
5771 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
5772 callback_.callback()));
5773
5774 // Run the message loop so that the migration attempt is executed and
5775 // data queued in the new socket is read by the packet reader.
5776 base::RunLoop().RunUntilIdle();
5777
Zhongyi Shia7dd46b2018-07-12 22:59:295778 // Verify session is still alive and not marked as going away.
Zhongyi Shi0439ecc72018-07-11 04:41:265779 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:295780 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:265781 EXPECT_EQ(2u, session->GetNumActiveStreams());
5782
5783 // Verify that response headers on the migrated socket were delivered to the
5784 // stream.
5785 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
5786 EXPECT_EQ(200, response.headers->response_code());
5787
5788 stream1.reset();
5789 stream2.reset();
5790
5791 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5792 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5793 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
5794 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
5795}
5796
5797TEST_P(QuicStreamFactoryTest, MigrateOnWriteErrorWithMixedRequestsSync) {
5798 TestMigrationOnWriteErrorMixedStreams(SYNCHRONOUS);
5799}
5800
5801TEST_P(QuicStreamFactoryTest, MigrateOnWriteErrorWithMixedRequestsAsync) {
5802 TestMigrationOnWriteErrorMixedStreams(ASYNC);
5803}
5804
5805// Sets up a test that verifies connection migration manages to migrate to
5806// alternate network after encountering a SYNC/ASYNC write error based on
5807// |write_error_mode| on the original network.
5808// Note there are mixed types of unfinished requests before migration: one
5809// migratable and one non-migratable. The *migratable* one triggers write
5810// error.
5811void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorMixedStreams(
5812 IoMode write_error_mode) {
5813 InitializeConnectionMigrationV2Test(
5814 {kDefaultNetworkForTests, kNewNetworkForTests});
5815 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5816 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5817 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5818
5819 int packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595820 MockQuicData socket_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:025821
Zhongyi Shi0439ecc72018-07-11 04:41:265822 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:025823 socket_data.AddWrite(SYNCHRONOUS,
5824 ConstructInitialSettingsPacket(packet_number++));
Zhongyi Shi0439ecc72018-07-11 04:41:265825 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
5826 socket_data.AddSocketDataToFactory(socket_factory_.get());
5827
5828 // Set up second socket data provider that is used after
5829 // migration. The request is rewritten to this new socket, and the
5830 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:595831 MockQuicData socket_data1(version_);
Zhongyi Shi0439ecc72018-07-11 04:41:265832 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335833 SYNCHRONOUS,
5834 ConstructGetRequestPacket(packet_number++,
5835 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:025836 true, true));
Zhongyi Shi0439ecc72018-07-11 04:41:265837 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335838 SYNCHRONOUS,
5839 client_maker_.MakeRstPacket(packet_number++, true,
5840 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:415841 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:185842 /*include_stop_sending_if_v99=*/true));
Zhongyi Shi0439ecc72018-07-11 04:41:265843 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:335844 ASYNC,
5845 ConstructOkResponsePacket(
5846 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shi0439ecc72018-07-11 04:41:265847 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5848 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335849 SYNCHRONOUS,
5850 client_maker_.MakeAckAndRstPacket(
5851 packet_number++, false, GetNthClientInitiatedBidirectionalStreamId(0),
5852 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi0439ecc72018-07-11 04:41:265853 socket_data1.AddSocketDataToFactory(socket_factory_.get());
5854
5855 // Create request #1 and QuicHttpStream.
5856 QuicStreamRequest request1(factory_.get());
5857 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035858 request1.Request(
Nick Harper23290b82019-05-02 00:02:565859 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:515860 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035861 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5862 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi0439ecc72018-07-11 04:41:265863 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5864 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
5865 EXPECT_TRUE(stream1.get());
5866
5867 HttpRequestInfo request_info1;
5868 request_info1.method = "GET";
5869 request_info1.url = GURL("https://www.example.org/");
5870 request_info1.traffic_annotation =
5871 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5872 EXPECT_EQ(OK,
5873 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
5874 net_log_, CompletionOnceCallback()));
5875
5876 // Second request returns synchronously because it pools to existing session.
5877 TestCompletionCallback callback2;
5878 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:515879 EXPECT_EQ(OK,
5880 request2.Request(
5881 host_port_pair_, version_.transport_version, privacy_mode_,
5882 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
5883 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5884 failed_on_default_network_callback_, callback2.callback()));
Zhongyi Shi0439ecc72018-07-11 04:41:265885 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
5886 EXPECT_TRUE(stream2.get());
5887
5888 HttpRequestInfo request_info2;
5889 request_info2.method = "GET";
Zhongyi Shibb28b1f2018-07-18 02:41:265890 request_info2.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Zhongyi Shi0439ecc72018-07-11 04:41:265891 request_info2.url = GURL("https://www.example.org/");
5892 request_info2.traffic_annotation =
5893 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5894 EXPECT_EQ(OK,
5895 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
5896 net_log_, CompletionOnceCallback()));
5897
5898 // Ensure that session is alive and active.
5899 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5900 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5901 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5902 EXPECT_EQ(2u, session->GetNumActiveStreams());
5903
5904 // Send GET request on stream 1. This should cause a write error, which
5905 // triggers a connection migration attempt.
5906 HttpResponseInfo response;
5907 HttpRequestHeaders request_headers;
5908 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
5909 callback_.callback()));
5910
5911 // Run the message loop so that the migration attempt is executed and
5912 // data queued in the new socket is read by the packet reader.
5913 base::RunLoop().RunUntilIdle();
5914
Zhongyi Shia7dd46b2018-07-12 22:59:295915 // Verify that the session is still alive and not marked as going away.
5916 // Non-migratable stream should be closed due to migration.
Zhongyi Shi0439ecc72018-07-11 04:41:265917 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:295918 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:265919 EXPECT_EQ(1u, session->GetNumActiveStreams());
5920
5921 // Verify that response headers on the migrated socket were delivered to the
5922 // stream.
5923 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
5924 EXPECT_EQ(200, response.headers->response_code());
5925
5926 stream1.reset();
5927
5928 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5929 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5930 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
5931 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
5932}
5933
5934TEST_P(QuicStreamFactoryTest, MigrateOnWriteErrorWithMixedRequests2Sync) {
5935 TestMigrationOnWriteErrorMixedStreams2(SYNCHRONOUS);
5936}
5937
5938TEST_P(QuicStreamFactoryTest, MigrateOnWriteErrorWithMixedRequests2Async) {
5939 TestMigrationOnWriteErrorMixedStreams2(ASYNC);
5940}
5941
5942// The one triggers write error is a non-migratable stream.
5943// Sets up a test that verifies connection migration manages to migrate to
5944// alternate network after encountering a SYNC/ASYNC write error based on
5945// |write_error_mode| on the original network.
5946// Note there are mixed types of unfinished requests before migration: one
5947// migratable and one non-migratable. The *non-migratable* one triggers write
5948// error.
5949void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorMixedStreams2(
5950 IoMode write_error_mode) {
5951 InitializeConnectionMigrationV2Test(
5952 {kDefaultNetworkForTests, kNewNetworkForTests});
5953 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5954 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5955 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5956
5957 int packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595958 MockQuicData socket_data(version_);
Zhongyi Shi0439ecc72018-07-11 04:41:265959 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:025960 socket_data.AddWrite(SYNCHRONOUS,
5961 ConstructInitialSettingsPacket(packet_number++));
Zhongyi Shi0439ecc72018-07-11 04:41:265962 socket_data.AddWrite(write_error_mode,
5963 ERR_ADDRESS_UNREACHABLE); // Write error.
5964 socket_data.AddSocketDataToFactory(socket_factory_.get());
5965
5966 // Set up second socket data provider that is used after
5967 // migration. The request is rewritten to this new socket, and the
5968 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:595969 MockQuicData socket_data1(version_);
Zhongyi Shi0439ecc72018-07-11 04:41:265970 // The packet triggered writer error will be sent anyway even if the stream
5971 // will be cancelled later.
5972 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335973 SYNCHRONOUS,
5974 ConstructGetRequestPacket(packet_number++,
5975 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamilton0d65a8c2019-06-07 00:46:025976 true, true));
Zhongyi Shi0439ecc72018-07-11 04:41:265977 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335978 SYNCHRONOUS,
5979 client_maker_.MakeRstPacket(packet_number++, true,
5980 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:415981 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:185982 /*include_stop_sending_if_v99=*/true));
Zhongyi Shi0439ecc72018-07-11 04:41:265983 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335984 SYNCHRONOUS,
5985 ConstructGetRequestPacket(packet_number++,
5986 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:025987 true, true));
Zhongyi Shi0439ecc72018-07-11 04:41:265988 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:335989 ASYNC,
5990 ConstructOkResponsePacket(
5991 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shi0439ecc72018-07-11 04:41:265992 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5993 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335994 SYNCHRONOUS,
5995 client_maker_.MakeAckAndRstPacket(
5996 packet_number++, false, GetNthClientInitiatedBidirectionalStreamId(0),
5997 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi0439ecc72018-07-11 04:41:265998 socket_data1.AddSocketDataToFactory(socket_factory_.get());
5999
6000 // Create request #1 and QuicHttpStream.
6001 QuicStreamRequest request1(factory_.get());
6002 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036003 request1.Request(
Nick Harper23290b82019-05-02 00:02:566004 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:516005 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036006 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6007 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi0439ecc72018-07-11 04:41:266008 EXPECT_THAT(callback_.WaitForResult(), IsOk());
6009 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
6010 EXPECT_TRUE(stream1.get());
6011
6012 HttpRequestInfo request_info1;
6013 request_info1.method = "GET";
6014 request_info1.url = GURL("https://www.example.org/");
6015 request_info1.traffic_annotation =
6016 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6017 EXPECT_EQ(OK,
6018 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
6019 net_log_, CompletionOnceCallback()));
6020
6021 // Second request returns synchronously because it pools to existing session.
6022 TestCompletionCallback callback2;
6023 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:516024 EXPECT_EQ(OK,
6025 request2.Request(
6026 host_port_pair_, version_.transport_version, privacy_mode_,
6027 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
6028 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6029 failed_on_default_network_callback_, callback2.callback()));
Zhongyi Shi0439ecc72018-07-11 04:41:266030 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
6031 EXPECT_TRUE(stream2.get());
6032
6033 HttpRequestInfo request_info2;
6034 request_info2.method = "GET";
Zhongyi Shibb28b1f2018-07-18 02:41:266035 request_info2.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Zhongyi Shi0439ecc72018-07-11 04:41:266036 request_info2.url = GURL("https://www.example.org/");
6037 request_info2.traffic_annotation =
6038 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6039 EXPECT_EQ(OK,
6040 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
6041 net_log_, CompletionOnceCallback()));
6042
6043 // Ensure that session is alive and active.
6044 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6045 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6046 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6047 EXPECT_EQ(2u, session->GetNumActiveStreams());
6048
6049 // Send GET request on stream 2 which is non-migratable. This should cause a
6050 // write error, which triggers a connection migration attempt.
6051 HttpResponseInfo response2;
6052 HttpRequestHeaders request_headers2;
6053 EXPECT_EQ(OK, stream2->SendRequest(request_headers2, &response2,
6054 callback2.callback()));
6055
6056 // Run the message loop so that the migration attempt is executed and
Zhongyi Shia7dd46b2018-07-12 22:59:296057 // data queued in the new socket is read by the packet reader. Session is
6058 // still alive and not marked as going away, non-migratable stream will be
6059 // closed.
Zhongyi Shi0439ecc72018-07-11 04:41:266060 base::RunLoop().RunUntilIdle();
6061 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:296062 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:266063 EXPECT_EQ(1u, session->GetNumActiveStreams());
6064
6065 // Send GET request on stream 1.
6066 HttpResponseInfo response;
6067 HttpRequestHeaders request_headers;
6068 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
6069 callback_.callback()));
6070
6071 base::RunLoop().RunUntilIdle();
6072
6073 // Verify that response headers on the migrated socket were delivered to the
6074 // stream.
6075 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
6076 EXPECT_EQ(200, response.headers->response_code());
6077
6078 stream1.reset();
6079
6080 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6081 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6082 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6083 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6084}
6085
Zhongyi Shic16b4102019-02-12 00:37:406086// This test verifies that when a connection encounters a packet write error, it
6087// will cancel non-migratable streams, and migrate to the alternate network.
jri9f303712016-09-13 01:10:226088void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorNonMigratableStream(
Zhongyi Shi32fe14d42019-02-28 00:25:366089 IoMode write_error_mode,
6090 bool migrate_idle_sessions) {
Zhongyi Shic16b4102019-02-12 00:37:406091 DVLOG(1) << "Write error mode: "
jri9f303712016-09-13 01:10:226092 << ((write_error_mode == SYNCHRONOUS) ? "SYNCHRONOUS" : "ASYNC");
Zhongyi Shi32fe14d42019-02-28 00:25:366093 DVLOG(1) << "Migrate idle sessions: " << migrate_idle_sessions;
6094 test_params_.quic_migrate_idle_sessions = migrate_idle_sessions;
Zhongyi Shi1a054612018-06-14 04:59:086095 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:226096 {kDefaultNetworkForTests, kNewNetworkForTests});
6097 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6098 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6099
Ryan Hamiltonabad59e2019-06-06 04:02:596100 MockQuicData failed_socket_data(version_);
6101 MockQuicData socket_data(version_);
Zhongyi Shi32fe14d42019-02-28 00:25:366102 if (migrate_idle_sessions) {
Zhongyi Shi32fe14d42019-02-28 00:25:366103 // The socket data provider for the original socket before migration.
6104 failed_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:026105 failed_socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi32fe14d42019-02-28 00:25:366106 failed_socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
6107 failed_socket_data.AddSocketDataToFactory(socket_factory_.get());
6108
6109 // Set up second socket data provider that is used after migration.
6110 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
6111 // Although the write error occurs when writing a packet for the
6112 // non-migratable stream and the stream will be cancelled during migration,
6113 // the packet will still be retransimitted at the connection level.
6114 socket_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:026115 SYNCHRONOUS,
6116 ConstructGetRequestPacket(
6117 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi32fe14d42019-02-28 00:25:366118 // A RESET will be sent to the peer to cancel the non-migratable stream.
6119 socket_data.AddWrite(
6120 SYNCHRONOUS, client_maker_.MakeRstPacket(
6121 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
6122 quic::QUIC_STREAM_CANCELLED));
6123 socket_data.AddSocketDataToFactory(socket_factory_.get());
6124 } else {
6125 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6126 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
6127 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
6128 socket_data.AddSocketDataToFactory(socket_factory_.get());
6129 }
jri9f303712016-09-13 01:10:226130
6131 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456132 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336133 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036134 request.Request(
Nick Harper23290b82019-05-02 00:02:566135 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:516136 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036137 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6138 failed_on_default_network_callback_, callback_.callback()));
jri9f303712016-09-13 01:10:226139 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246140 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:226141 EXPECT_TRUE(stream.get());
6142
6143 // Cause QUIC stream to be created, but marked as non-migratable.
6144 HttpRequestInfo request_info;
Zhongyi Shibb28b1f2018-07-18 02:41:266145 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
jri9f303712016-09-13 01:10:226146 request_info.method = "GET";
6147 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396148 request_info.traffic_annotation =
6149 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276150 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396151 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:226152
6153 // Ensure that session is alive and active.
6154 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6155 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6156 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6157
6158 // Send GET request on stream. This should cause a write error, which triggers
6159 // a connection migration attempt.
6160 HttpResponseInfo response;
6161 HttpRequestHeaders request_headers;
6162 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6163 callback_.callback()));
6164
6165 // Run message loop to execute migration attempt.
6166 base::RunLoop().RunUntilIdle();
6167
Zhongyi Shi32fe14d42019-02-28 00:25:366168 // Migration closes the non-migratable stream and:
6169 // if migrate idle session is enabled, it migrates to the alternate network
6170 // successfully; otherwise the connection is closed.
6171 EXPECT_EQ(migrate_idle_sessions,
6172 QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6173 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(host_port_pair_));
jri9f303712016-09-13 01:10:226174
Zhongyi Shi32fe14d42019-02-28 00:25:366175 if (migrate_idle_sessions) {
6176 EXPECT_TRUE(failed_socket_data.AllReadDataConsumed());
6177 EXPECT_TRUE(failed_socket_data.AllWriteDataConsumed());
6178 }
jri9f303712016-09-13 01:10:226179 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6180 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6181}
6182
Zhongyi Shi32fe14d42019-02-28 00:25:366183TEST_P(
6184 QuicStreamFactoryTest,
6185 MigrateSessionOnWriteErrorNonMigratableStreamSync_DoNotMigrateIdleSessions) {
6186 TestMigrationOnWriteErrorNonMigratableStream(SYNCHRONOUS, false);
6187}
6188
6189TEST_P(
6190 QuicStreamFactoryTest,
6191 MigrateSessionOnWriteErrorNonMigratableStreamAsync_DoNotMigrateIdleSessions) {
6192 TestMigrationOnWriteErrorNonMigratableStream(ASYNC, false);
jri9f303712016-09-13 01:10:226193}
6194
6195TEST_P(QuicStreamFactoryTest,
Zhongyi Shi32fe14d42019-02-28 00:25:366196 MigrateSessionOnWriteErrorNonMigratableStreamSync_MigrateIdleSessions) {
6197 TestMigrationOnWriteErrorNonMigratableStream(SYNCHRONOUS, true);
6198}
6199
6200TEST_P(QuicStreamFactoryTest,
6201 MigrateSessionOnWriteErrorNonMigratableStreamAsync_MigrateIdleSessions) {
6202 TestMigrationOnWriteErrorNonMigratableStream(ASYNC, true);
jri9f303712016-09-13 01:10:226203}
6204
6205void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorMigrationDisabled(
6206 IoMode write_error_mode) {
Zhongyi Shi1a054612018-06-14 04:59:086207 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:226208 {kDefaultNetworkForTests, kNewNetworkForTests});
6209 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6210 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6211
Ryan Hamiltonabad59e2019-06-06 04:02:596212 MockQuicData socket_data(version_);
jri9f303712016-09-13 01:10:226213 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436214 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jri9f303712016-09-13 01:10:226215 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:176216 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:226217
6218 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456219 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336220 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036221 request.Request(
Nick Harper23290b82019-05-02 00:02:566222 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:516223 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036224 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6225 failed_on_default_network_callback_, callback_.callback()));
jri9f303712016-09-13 01:10:226226 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246227 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:226228 EXPECT_TRUE(stream.get());
6229
6230 // Cause QUIC stream to be created.
6231 HttpRequestInfo request_info;
6232 request_info.method = "GET";
6233 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396234 request_info.traffic_annotation =
6235 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276236 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396237 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:226238
6239 // Ensure that session is alive and active.
6240 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6241 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6242 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6243
6244 // Set session config to have connection migration disabled.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526245 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
6246 session->config());
jri9f303712016-09-13 01:10:226247 EXPECT_TRUE(session->config()->DisableConnectionMigration());
6248
6249 // Send GET request on stream. This should cause a write error, which triggers
6250 // a connection migration attempt.
6251 HttpResponseInfo response;
6252 HttpRequestHeaders request_headers;
6253 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6254 callback_.callback()));
6255 // Run message loop to execute migration attempt.
6256 base::RunLoop().RunUntilIdle();
6257 // Migration fails, and session is closed and deleted.
6258 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6259 EXPECT_FALSE(HasActiveSession(host_port_pair_));
6260 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6261 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6262}
6263
6264TEST_P(QuicStreamFactoryTest,
6265 MigrateSessionOnWriteErrorMigrationDisabledSynchronous) {
6266 TestMigrationOnWriteErrorMigrationDisabled(SYNCHRONOUS);
6267}
6268
6269TEST_P(QuicStreamFactoryTest,
6270 MigrateSessionOnWriteErrorMigrationDisabledAsync) {
6271 TestMigrationOnWriteErrorMigrationDisabled(ASYNC);
6272}
6273
Zhongyi Shi7f1d9212018-06-22 23:24:366274// Sets up a test which verifies that connection migration on write error can
6275// eventually succeed and rewrite the packet on the new network with singals
6276// delivered in the following order (alternate network is always availabe):
6277// - original network encounters a SYNC/ASYNC write error based on
6278// |write_error_mode_on_old_network|, the packet failed to be written is
6279// cached, session migrates immediately to the alternate network.
6280// - an immediate SYNC/ASYNC write error based on
6281// |write_error_mode_on_new_network| is encountered after migration to the
6282// alternate network, session migrates immediately to the original network.
6283// - an immediate SYNC/ASYNC write error based on
6284// |write_error_mode_on_old_network| is encountered after migration to the
6285// original network, session migrates immediately to the alternate network.
6286// - finally, session successfully sends the packet and reads the response on
6287// the alternate network.
6288// TODO(zhongyi): once https://crbug.com/855666 is fixed, this test should be
6289// modified to test that session is closed early if hopping between networks
6290// with consecutive write errors is detected.
jri9f303712016-09-13 01:10:226291void QuicStreamFactoryTestBase::TestMigrationOnMultipleWriteErrors(
Zhongyi Shi7f1d9212018-06-22 23:24:366292 IoMode write_error_mode_on_old_network,
6293 IoMode write_error_mode_on_new_network) {
6294 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:226295 {kDefaultNetworkForTests, kNewNetworkForTests});
6296 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6297 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6298 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6299
Zhongyi Shi7f1d9212018-06-22 23:24:366300 // Set up the socket data used by the original network, which encounters a
6301 // write erorr.
Ryan Hamiltonabad59e2019-06-06 04:02:596302 MockQuicData socket_data1(version_);
Zhongyi Shi7f1d9212018-06-22 23:24:366303 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:026304 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi7f1d9212018-06-22 23:24:366305 socket_data1.AddWrite(write_error_mode_on_old_network,
6306 ERR_ADDRESS_UNREACHABLE); // Write Error
6307 socket_data1.AddSocketDataToFactory(socket_factory_.get());
6308
6309 // Set up the socket data used by the alternate network, which also
6310 // encounters a write error.
Ryan Hamiltonabad59e2019-06-06 04:02:596311 MockQuicData failed_quic_data2(version_);
Zhongyi Shi7f1d9212018-06-22 23:24:366312 failed_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6313 failed_quic_data2.AddWrite(write_error_mode_on_new_network, ERR_FAILED);
6314 failed_quic_data2.AddSocketDataToFactory(socket_factory_.get());
6315
6316 // Set up the third socket data used by original network, which encounters a
6317 // write error again.
Ryan Hamiltonabad59e2019-06-06 04:02:596318 MockQuicData failed_quic_data1(version_);
Zhongyi Shi7f1d9212018-06-22 23:24:366319 failed_quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6320 failed_quic_data1.AddWrite(write_error_mode_on_old_network, ERR_FAILED);
6321 failed_quic_data1.AddSocketDataToFactory(socket_factory_.get());
6322
6323 // Set up the last socket data used by the alternate network, which will
6324 // finish migration successfully. The request is rewritten to this new socket,
6325 // and the response to the request is read on this socket.
Ryan Hamiltonabad59e2019-06-06 04:02:596326 MockQuicData socket_data2(version_);
Fan Yang32c5a112018-12-10 20:06:336327 socket_data2.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:026328 SYNCHRONOUS,
6329 ConstructGetRequestPacket(
6330 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi7f1d9212018-06-22 23:24:366331 socket_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:336332 ASYNC,
6333 ConstructOkResponsePacket(
6334 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shi7f1d9212018-06-22 23:24:366335 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:336336 socket_data2.AddWrite(
6337 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
6338 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
6339 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi7f1d9212018-06-22 23:24:366340 socket_data2.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:226341
6342 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456343 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336344 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036345 request.Request(
Nick Harper23290b82019-05-02 00:02:566346 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:516347 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036348 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6349 failed_on_default_network_callback_, callback_.callback()));
jri9f303712016-09-13 01:10:226350 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246351 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:226352 EXPECT_TRUE(stream.get());
6353
6354 // Cause QUIC stream to be created.
6355 HttpRequestInfo request_info;
6356 request_info.method = "GET";
6357 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396358 request_info.traffic_annotation =
6359 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276360 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396361 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:226362
6363 // Ensure that session is alive and active.
6364 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6365 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6366 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6367
Zhongyi Shi7f1d9212018-06-22 23:24:366368 // Send GET request on stream.
6369 // This should encounter a write error on network 1,
6370 // then migrate to network 2, which encounters another write error,
6371 // and migrate again to network 1, which encoutners one more write error.
6372 // Finally the session migrates to network 2 successfully.
jri9f303712016-09-13 01:10:226373 HttpResponseInfo response;
6374 HttpRequestHeaders request_headers;
6375 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6376 callback_.callback()));
jri9f303712016-09-13 01:10:226377
jri9f303712016-09-13 01:10:226378 base::RunLoop().RunUntilIdle();
Zhongyi Shi7f1d9212018-06-22 23:24:366379 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6380 EXPECT_EQ(1u, session->GetNumActiveStreams());
jri9f303712016-09-13 01:10:226381
Zhongyi Shi7f1d9212018-06-22 23:24:366382 // Verify that response headers on the migrated socket were delivered to the
6383 // stream.
6384 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6385 EXPECT_EQ(200, response.headers->response_code());
jri9f303712016-09-13 01:10:226386
6387 stream.reset();
Zhongyi Shi7f1d9212018-06-22 23:24:366388 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6389 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6390 EXPECT_TRUE(failed_quic_data2.AllReadDataConsumed());
6391 EXPECT_TRUE(failed_quic_data2.AllWriteDataConsumed());
6392 EXPECT_TRUE(failed_quic_data1.AllReadDataConsumed());
6393 EXPECT_TRUE(failed_quic_data1.AllWriteDataConsumed());
6394 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
6395 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
jri9f303712016-09-13 01:10:226396}
6397
6398TEST_P(QuicStreamFactoryTest, MigrateSessionOnMultipleWriteErrorsSyncSync) {
Zhongyi Shi7f1d9212018-06-22 23:24:366399 TestMigrationOnMultipleWriteErrors(
6400 /*write_error_mode_on_old_network*/ SYNCHRONOUS,
6401 /*write_error_mode_on_new_network*/ SYNCHRONOUS);
jri9f303712016-09-13 01:10:226402}
6403
6404TEST_P(QuicStreamFactoryTest, MigrateSessionOnMultipleWriteErrorsSyncAsync) {
Zhongyi Shi7f1d9212018-06-22 23:24:366405 TestMigrationOnMultipleWriteErrors(
6406 /*write_error_mode_on_old_network*/ SYNCHRONOUS,
6407 /*write_error_mode_on_new_network*/ ASYNC);
jri9f303712016-09-13 01:10:226408}
6409
6410TEST_P(QuicStreamFactoryTest, MigrateSessionOnMultipleWriteErrorsAsyncSync) {
Zhongyi Shi7f1d9212018-06-22 23:24:366411 TestMigrationOnMultipleWriteErrors(
6412 /*write_error_mode_on_old_network*/ ASYNC,
6413 /*write_error_mode_on_new_network*/ SYNCHRONOUS);
jri9f303712016-09-13 01:10:226414}
6415
6416TEST_P(QuicStreamFactoryTest, MigrateSessionOnMultipleWriteErrorsAsyncAsync) {
Zhongyi Shi7f1d9212018-06-22 23:24:366417 TestMigrationOnMultipleWriteErrors(
6418 /*write_error_mode_on_old_network*/ ASYNC,
6419 /*write_error_mode_on_new_network*/ ASYNC);
jri9f303712016-09-13 01:10:226420}
6421
Zhongyi Shi6abe33812018-07-24 19:43:116422// Verifies that a connection is closed when connection migration is triggered
6423// on network being disconnected and the handshake is not confirmed.
6424TEST_P(QuicStreamFactoryTest, NoMigrationBeforeHandshakeOnNetworkDisconnected) {
6425 InitializeConnectionMigrationV2Test(
6426 {kDefaultNetworkForTests, kNewNetworkForTests});
6427
Zhongyi Shi879659422018-08-02 17:58:256428 // Use cold start mode to do crypto connect, and send CHLO packet on wire.
Zhongyi Shi6abe33812018-07-24 19:43:116429 crypto_client_stream_factory_.set_handshake_mode(
Zhongyi Shi879659422018-08-02 17:58:256430 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
Zhongyi Shi6abe33812018-07-24 19:43:116431
Ryan Hamiltonabad59e2019-06-06 04:02:596432 MockQuicData socket_data(version_);
Zhongyi Shi879659422018-08-02 17:58:256433 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5068bb02018-08-03 02:44:096434 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
Zhongyi Shi6abe33812018-07-24 19:43:116435 socket_data.AddSocketDataToFactory(socket_factory_.get());
6436
6437 // Create request and QuicHttpStream.
6438 QuicStreamRequest request(factory_.get());
6439 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036440 request.Request(
Nick Harper23290b82019-05-02 00:02:566441 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:516442 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036443 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6444 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi6abe33812018-07-24 19:43:116445 // Deliver the network notification, which should cause the connection to be
6446 // closed.
6447 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6448 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
6449 EXPECT_EQ(ERR_NETWORK_CHANGED, callback_.WaitForResult());
Zhongyi Shi4293b142018-07-25 00:33:576450
Zhongyi Shi6abe33812018-07-24 19:43:116451 EXPECT_FALSE(HasActiveSession(host_port_pair_));
6452 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
Zhongyi Shi4293b142018-07-25 00:33:576453 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6454 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
Zhongyi Shi6abe33812018-07-24 19:43:116455}
6456
Zhongyi Shib24001c02018-06-18 20:01:526457// Sets up the connection migration test where network change notification is
6458// queued BEFORE connection migration attempt on write error is posted.
6459void QuicStreamFactoryTestBase::
6460 TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
6461 bool disconnected) {
6462 InitializeConnectionMigrationV2Test(
jried79618b2016-07-02 03:18:526463 {kDefaultNetworkForTests, kNewNetworkForTests});
6464 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6465 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6466 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6467
Ryan Hamiltonabad59e2019-06-06 04:02:596468 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:366469 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:026470 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
rcha00569732016-08-27 11:09:366471 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:176472 socket_data.AddSocketDataToFactory(socket_factory_.get());
jried79618b2016-07-02 03:18:526473
6474 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456475 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336476 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036477 request.Request(
Nick Harper23290b82019-05-02 00:02:566478 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:516479 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036480 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6481 failed_on_default_network_callback_, callback_.callback()));
jried79618b2016-07-02 03:18:526482 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246483 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jried79618b2016-07-02 03:18:526484 EXPECT_TRUE(stream.get());
6485
6486 // Cause QUIC stream to be created.
6487 HttpRequestInfo request_info;
6488 request_info.method = "GET";
6489 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396490 request_info.traffic_annotation =
6491 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276492 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396493 net_log_, CompletionOnceCallback()));
jried79618b2016-07-02 03:18:526494
6495 // Ensure that session is alive and active.
6496 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6497 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6498 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6499
6500 // Set up second socket data provider that is used after
6501 // migration. The request is rewritten to this new socket, and the
6502 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:596503 MockQuicData socket_data1(version_);
Fan Yang32c5a112018-12-10 20:06:336504 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:026505 SYNCHRONOUS,
6506 ConstructGetRequestPacket(
6507 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi32f2fd02018-04-16 18:23:436508 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:336509 ASYNC,
6510 ConstructOkResponsePacket(
6511 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
rcha00569732016-08-27 11:09:366512 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:336513 socket_data1.AddWrite(
6514 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
6515 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
6516 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:176517 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jried79618b2016-07-02 03:18:526518
jri9f303712016-09-13 01:10:226519 // First queue a network change notification in the message loop.
6520 if (disconnected) {
6521 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6522 ->QueueNetworkDisconnected(kDefaultNetworkForTests);
6523 } else {
6524 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6525 ->QueueNetworkMadeDefault(kNewNetworkForTests);
6526 }
6527 // Send GET request on stream. This should cause a write error,
6528 // which triggers a connection migration attempt. This will queue a
6529 // migration attempt behind the notification in the message loop.
jried79618b2016-07-02 03:18:526530 HttpResponseInfo response;
6531 HttpRequestHeaders request_headers;
6532 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6533 callback_.callback()));
6534
jried79618b2016-07-02 03:18:526535 base::RunLoop().RunUntilIdle();
Zhongyi Shia7dd46b2018-07-12 22:59:296536 // Verify the session is still alive and not marked as going away post
6537 // migration.
jried79618b2016-07-02 03:18:526538 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:296539 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jried79618b2016-07-02 03:18:526540 EXPECT_EQ(1u, session->GetNumActiveStreams());
6541
6542 // Verify that response headers on the migrated socket were delivered to the
6543 // stream.
6544 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6545 EXPECT_EQ(200, response.headers->response_code());
6546
6547 stream.reset();
6548
6549 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6550 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6551 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6552 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6553}
6554
Zhongyi Shib24001c02018-06-18 20:01:526555// This test verifies that session attempts connection migration successfully
6556// with signals delivered in the following order (alternate network is always
6557// available):
6558// - a notification that default network is disconnected is queued.
6559// - write error is triggered: session posts a task to attempt connection
6560// migration, |migration_pending_| set to true.
6561// - default network disconnected is delivered: session immediately migrates to
6562// the alternate network, |migration_pending_| set to false.
Zhongyi Shif3d6cddb2018-07-11 03:30:026563// - connection migration on write error attempt aborts: writer encountered
6564// error is no longer in active use.
jri9f303712016-09-13 01:10:226565TEST_P(QuicStreamFactoryTest,
Zhongyi Shib24001c02018-06-18 20:01:526566 MigrateOnNetworkDisconnectedWithWriteErrorQueuedLater) {
6567 TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
6568 /*disconnected=*/true);
jri9f303712016-09-13 01:10:226569}
6570
Zhongyi Shib24001c02018-06-18 20:01:526571// This test verifies that session attempts connection migration successfully
6572// with signals delivered in the following order (alternate network is always
6573// available):
6574// - a notification that alternate network is made default is queued.
6575// - write error is triggered: session posts a task to attempt connection
6576// migration, block future migrations.
6577// - new default notification is delivered: migrate back timer spins and task is
6578// posted to migrate to the new default network.
6579// - connection migration on write error attempt proceeds successfully: session
6580// is
6581// marked as going away, future migrations unblocked.
6582// - migrate back to default network task executed: session is already on the
6583// default network, no-op.
jri9f303712016-09-13 01:10:226584TEST_P(QuicStreamFactoryTest,
Zhongyi Shib24001c02018-06-18 20:01:526585 MigrateOnWriteErrorWithNetworkMadeDefaultQueuedEarlier) {
6586 TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
6587 /*disconnected=*/false);
jri9f303712016-09-13 01:10:226588}
6589
Zhongyi Shi1e2bc742018-06-16 02:06:076590// Sets up the connection migration test where network change notification is
6591// queued AFTER connection migration attempt on write error is posted.
6592void QuicStreamFactoryTestBase::
6593 TestMigrationOnWriteErrorWithNotificationQueuedLater(bool disconnected) {
Zhongyi Shi1a054612018-06-14 04:59:086594 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:226595 {kDefaultNetworkForTests, kNewNetworkForTests});
jried79618b2016-07-02 03:18:526596 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6597 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri9f303712016-09-13 01:10:226598 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jried79618b2016-07-02 03:18:526599
Ryan Hamiltonabad59e2019-06-06 04:02:596600 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:366601 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:026602 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
rcha00569732016-08-27 11:09:366603 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:176604 socket_data.AddSocketDataToFactory(socket_factory_.get());
jried79618b2016-07-02 03:18:526605
6606 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456607 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336608 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036609 request.Request(
Nick Harper23290b82019-05-02 00:02:566610 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:516611 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036612 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6613 failed_on_default_network_callback_, callback_.callback()));
jried79618b2016-07-02 03:18:526614 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246615 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jried79618b2016-07-02 03:18:526616 EXPECT_TRUE(stream.get());
6617
6618 // Cause QUIC stream to be created.
6619 HttpRequestInfo request_info;
6620 request_info.method = "GET";
6621 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396622 request_info.traffic_annotation =
6623 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276624 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396625 net_log_, CompletionOnceCallback()));
jried79618b2016-07-02 03:18:526626
6627 // Ensure that session is alive and active.
6628 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6629 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6630 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6631
jri9f303712016-09-13 01:10:226632 // Set up second socket data provider that is used after
6633 // migration. The request is rewritten to this new socket, and the
6634 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:596635 MockQuicData socket_data1(version_);
Fan Yang32c5a112018-12-10 20:06:336636 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:026637 SYNCHRONOUS,
6638 ConstructGetRequestPacket(
6639 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi32f2fd02018-04-16 18:23:436640 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:336641 ASYNC,
6642 ConstructOkResponsePacket(
6643 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
jri9f303712016-09-13 01:10:226644 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:336645 socket_data1.AddWrite(
6646 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
6647 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
6648 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:176649 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:226650
6651 // Send GET request on stream. This should cause a write error,
6652 // which triggers a connection migration attempt. This will queue a
6653 // migration attempt in the message loop.
jried79618b2016-07-02 03:18:526654 HttpResponseInfo response;
6655 HttpRequestHeaders request_headers;
jri9f303712016-09-13 01:10:226656 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6657 callback_.callback()));
jried79618b2016-07-02 03:18:526658
jri9f303712016-09-13 01:10:226659 // Now queue a network change notification in the message loop behind
6660 // the migration attempt.
6661 if (disconnected) {
6662 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6663 ->QueueNetworkDisconnected(kDefaultNetworkForTests);
6664 } else {
6665 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6666 ->QueueNetworkMadeDefault(kNewNetworkForTests);
6667 }
6668
6669 base::RunLoop().RunUntilIdle();
Zhongyi Shia7dd46b2018-07-12 22:59:296670 // Verify session is still alive and not marked as going away.
jri9f303712016-09-13 01:10:226671 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:296672 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri9f303712016-09-13 01:10:226673 EXPECT_EQ(1u, session->GetNumActiveStreams());
6674
6675 // Verify that response headers on the migrated socket were delivered to the
6676 // stream.
6677 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6678 EXPECT_EQ(200, response.headers->response_code());
6679
6680 stream.reset();
jried79618b2016-07-02 03:18:526681
6682 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6683 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
jri9f303712016-09-13 01:10:226684 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6685 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
jried79618b2016-07-02 03:18:526686}
6687
Zhongyi Shi1e2bc742018-06-16 02:06:076688// This test verifies that session attempts connection migration successfully
6689// with signals delivered in the following order (alternate network is always
6690// available):
6691// - write error is triggered: session posts a task to complete connection
6692// migration.
6693// - a notification that alternate network is made default is queued.
6694// - connection migration attempt proceeds successfully, session is marked as
6695// going away.
6696// - new default notification is delivered after connection migration has been
6697// completed.
jri9f303712016-09-13 01:10:226698TEST_P(QuicStreamFactoryTest,
Zhongyi Shi1e2bc742018-06-16 02:06:076699 MigrateOnWriteErrorWithNetworkMadeDefaultQueuedLater) {
6700 TestMigrationOnWriteErrorWithNotificationQueuedLater(/*disconnected=*/false);
jried79618b2016-07-02 03:18:526701}
6702
Zhongyi Shi1e2bc742018-06-16 02:06:076703// This test verifies that session attempts connection migration successfully
6704// with signals delivered in the following order (alternate network is always
6705// available):
6706// - write error is triggered: session posts a task to complete connection
6707// migration.
6708// - a notification that default network is diconnected is queued.
6709// - connection migration attempt proceeds successfully, session is marked as
6710// going away.
6711// - disconnect notification is delivered after connection migration has been
6712// completed.
jri9f303712016-09-13 01:10:226713TEST_P(QuicStreamFactoryTest,
Zhongyi Shi1e2bc742018-06-16 02:06:076714 MigrateOnWriteErrorWithNetworkDisconnectedQueuedLater) {
6715 TestMigrationOnWriteErrorWithNotificationQueuedLater(/*disconnected=*/true);
jried79618b2016-07-02 03:18:526716}
6717
Zhongyi Shia3810c52018-06-15 23:07:196718// This tests connection migration on write error with signals delivered in the
6719// following order:
6720// - a synchronous/asynchronous write error is triggered base on
Zhongyi Shif3d6cddb2018-07-11 03:30:026721// |write_error_mode|: connection migration attempt is posted.
6722// - old default network disconnects, migration waits for a new network.
Zhongyi Shia3810c52018-06-15 23:07:196723// - after a pause, new network is connected: session will migrate to new
6724// network immediately.
Zhongyi Shif3d6cddb2018-07-11 03:30:026725// - migration on writer error is exectued and aborts as writer passed in is no
6726// longer active in use.
Zhongyi Shia3810c52018-06-15 23:07:196727// - new network is made default.
jri5b785512016-09-13 04:29:116728void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorPauseBeforeConnected(
6729 IoMode write_error_mode) {
Zhongyi Shia3810c52018-06-15 23:07:196730 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri5b785512016-09-13 04:29:116731 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6732 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6733 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6734
Zhongyi Shia3810c52018-06-15 23:07:196735 // Use the test task runner.
6736 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
6737
Ryan Hamiltonabad59e2019-06-06 04:02:596738 MockQuicData socket_data(version_);
Zhongyi Shia3810c52018-06-15 23:07:196739 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
Ryan Hamilton0d65a8c2019-06-07 00:46:026740 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shia3810c52018-06-15 23:07:196741 socket_data.AddWrite(write_error_mode, ERR_FAILED);
Zhongyi Shi5f587cc2017-11-21 23:24:176742 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri5b785512016-09-13 04:29:116743
6744 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456745 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336746 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036747 request.Request(
Nick Harper23290b82019-05-02 00:02:566748 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:516749 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036750 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6751 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shia3810c52018-06-15 23:07:196752 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:246753 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri5b785512016-09-13 04:29:116754 EXPECT_TRUE(stream.get());
6755
6756 // Cause QUIC stream to be created.
6757 HttpRequestInfo request_info;
6758 request_info.method = "GET";
Zhongyi Shia3810c52018-06-15 23:07:196759 request_info.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:396760 request_info.traffic_annotation =
6761 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276762 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396763 net_log_, CompletionOnceCallback()));
jri5b785512016-09-13 04:29:116764
6765 // Ensure that session is alive and active.
6766 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6767 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6768 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6769
Zhongyi Shia3810c52018-06-15 23:07:196770 // Send GET request on stream.
jri5b785512016-09-13 04:29:116771 HttpResponseInfo response;
6772 HttpRequestHeaders request_headers;
6773 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6774 callback_.callback()));
6775
Zhongyi Shia3810c52018-06-15 23:07:196776 // The connection should still be alive, not marked as going away.
jri5b785512016-09-13 04:29:116777 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6778 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6779 EXPECT_EQ(1u, session->GetNumActiveStreams());
6780 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
6781
Zhongyi Shia3810c52018-06-15 23:07:196782 // Set up second socket data provider that is used after migration.
6783 // The response to the earlier request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:596784 MockQuicData socket_data1(version_);
Fan Yang32c5a112018-12-10 20:06:336785 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:026786 SYNCHRONOUS,
6787 ConstructGetRequestPacket(
6788 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi32f2fd02018-04-16 18:23:436789 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:336790 ASYNC,
6791 ConstructOkResponsePacket(
6792 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
jri5b785512016-09-13 04:29:116793 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:336794 socket_data1.AddWrite(
6795 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
6796 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
6797 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:176798 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri5b785512016-09-13 04:29:116799
Zhongyi Shia3810c52018-06-15 23:07:196800 // On a DISCONNECTED notification, nothing happens.
6801 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6802 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
6803 // Add a new network and notify the stream factory of a new connected network.
6804 // This causes a PING packet to be sent over the new network.
jri5b785512016-09-13 04:29:116805 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6806 ->SetConnectedNetworksList({kNewNetworkForTests});
6807 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6808 ->NotifyNetworkConnected(kNewNetworkForTests);
6809
Zhongyi Shia3810c52018-06-15 23:07:196810 // Ensure that the session is still alive.
jri5b785512016-09-13 04:29:116811 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia3810c52018-06-15 23:07:196812 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:116813 EXPECT_EQ(1u, session->GetNumActiveStreams());
6814
Zhongyi Shia3810c52018-06-15 23:07:196815 // Run the message loop migration for write error can finish.
6816 runner_->RunUntilIdle();
6817
6818 // Response headers are received over the new network.
jri5b785512016-09-13 04:29:116819 EXPECT_THAT(callback_.WaitForResult(), IsOk());
6820 EXPECT_EQ(200, response.headers->response_code());
6821
Zhongyi Shia3810c52018-06-15 23:07:196822 // Check that the session is still alive.
6823 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
jri5b785512016-09-13 04:29:116824 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shia3810c52018-06-15 23:07:196825
6826 // There should be no posted tasks not executed, no way to migrate back to
6827 // default network.
6828 EXPECT_TRUE(runner_->GetPostedTasks().empty());
6829
6830 // Receive signal to mark new network as default.
6831 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6832 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri5b785512016-09-13 04:29:116833
6834 stream.reset();
jri5b785512016-09-13 04:29:116835 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6836 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6837 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6838 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
jri5b785512016-09-13 04:29:116839}
6840
6841TEST_P(QuicStreamFactoryTest,
Zhongyi Shia3810c52018-06-15 23:07:196842 MigrateSessionOnSyncWriteErrorPauseBeforeConnected) {
jri5b785512016-09-13 04:29:116843 TestMigrationOnWriteErrorPauseBeforeConnected(SYNCHRONOUS);
6844}
6845
6846TEST_P(QuicStreamFactoryTest,
Zhongyi Shia3810c52018-06-15 23:07:196847 MigrateSessionOnAsyncWriteErrorPauseBeforeConnected) {
jri5b785512016-09-13 04:29:116848 TestMigrationOnWriteErrorPauseBeforeConnected(ASYNC);
6849}
6850
Zhongyi Shif3d6cddb2018-07-11 03:30:026851// This test verifies that when session successfully migrate to the alternate
6852// network, packet write error on the old writer will be ignored and will not
6853// trigger connection migration on write error.
6854TEST_P(QuicStreamFactoryTest, IgnoreWriteErrorFromOldWriterAfterMigration) {
6855 InitializeConnectionMigrationV2Test(
6856 {kDefaultNetworkForTests, kNewNetworkForTests});
6857 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6858 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6859 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6860
6861 // Using a testing task runner so that we can verify whether the migrate on
6862 // write error task is posted.
6863 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
6864 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
6865
Ryan Hamiltonabad59e2019-06-06 04:02:596866 MockQuicData socket_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:026867 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shif3d6cddb2018-07-11 03:30:026868 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
Ryan Hamilton9f2eac32019-06-27 03:15:546869 socket_data.AddWrite(
6870 ASYNC, ERR_ADDRESS_UNREACHABLE,
6871 ConstructGetRequestPacket(
6872 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shif3d6cddb2018-07-11 03:30:026873 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6874 socket_data.AddSocketDataToFactory(socket_factory_.get());
6875
6876 // Create request and QuicHttpStream.
6877 QuicStreamRequest request(factory_.get());
6878 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036879 request.Request(
Nick Harper23290b82019-05-02 00:02:566880 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:516881 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036882 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6883 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shif3d6cddb2018-07-11 03:30:026884 EXPECT_EQ(OK, callback_.WaitForResult());
6885 std::unique_ptr<HttpStream> stream = CreateStream(&request);
6886 EXPECT_TRUE(stream.get());
6887
6888 // Cause QUIC stream to be created.
6889 HttpRequestInfo request_info;
6890 request_info.method = "GET";
6891 request_info.url = GURL("https://www.example.org/");
6892 request_info.traffic_annotation =
6893 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6894 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
6895 net_log_, CompletionOnceCallback()));
6896
6897 // Ensure that session is alive and active.
6898 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6899 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6900 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6901
6902 // Set up second socket data provider that is used after
6903 // migration. The response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:596904 MockQuicData socket_data1(version_);
Zhongyi Shif3d6cddb2018-07-11 03:30:026905 socket_data1.AddWrite(
6906 SYNCHRONOUS, client_maker_.MakePingPacket(3, /*include_version=*/true));
6907 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:336908 ASYNC,
6909 ConstructOkResponsePacket(
6910 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shif3d6cddb2018-07-11 03:30:026911 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:336912 socket_data1.AddWrite(
6913 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
6914 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
6915 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shif3d6cddb2018-07-11 03:30:026916 socket_data1.AddSocketDataToFactory(socket_factory_.get());
6917
6918 // Send GET request on stream.
6919 HttpResponseInfo response;
6920 HttpRequestHeaders request_headers;
6921 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6922 callback_.callback()));
6923
6924 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
6925 // Now notify network is disconnected, cause the migration to complete
6926 // immediately.
6927 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6928 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
6929 // There will be two pending task, one will complete migration with no delay
6930 // and the other will attempt to migrate back to the default network with
6931 // delay.
6932 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
6933
6934 // Complete migration.
6935 task_runner->RunUntilIdle();
6936 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
6937
6938 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6939 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6940 EXPECT_EQ(1u, session->GetNumActiveStreams());
6941
6942 // Verify that response headers on the migrated socket were delivered to the
6943 // stream.
6944 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6945 EXPECT_EQ(200, response.headers->response_code());
6946
6947 // Resume the old socket data, a write error will be delivered to the old
6948 // packet writer. Verify no additional task is posted.
6949 socket_data.Resume();
6950 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
6951
6952 stream.reset();
6953 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6954 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6955 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6956}
6957
6958// This test verifies that when session successfully migrate to the alternate
6959// network, packet read error on the old reader will be ignored and will not
6960// close the connection.
6961TEST_P(QuicStreamFactoryTest, IgnoreReadErrorFromOldReaderAfterMigration) {
6962 InitializeConnectionMigrationV2Test(
6963 {kDefaultNetworkForTests, kNewNetworkForTests});
6964 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6965 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6966 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6967
6968 // Using a testing task runner.
6969 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
6970 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
6971
Ryan Hamiltonabad59e2019-06-06 04:02:596972 MockQuicData socket_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:026973 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shif3d6cddb2018-07-11 03:30:026974 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
6975 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE);
6976 socket_data.AddSocketDataToFactory(socket_factory_.get());
6977
6978 // Create request and QuicHttpStream.
6979 QuicStreamRequest request(factory_.get());
6980 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036981 request.Request(
Nick Harper23290b82019-05-02 00:02:566982 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:516983 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036984 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6985 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shif3d6cddb2018-07-11 03:30:026986 EXPECT_EQ(OK, callback_.WaitForResult());
6987 std::unique_ptr<HttpStream> stream = CreateStream(&request);
6988 EXPECT_TRUE(stream.get());
6989
6990 // Cause QUIC stream to be created.
6991 HttpRequestInfo request_info;
6992 request_info.method = "GET";
6993 request_info.url = GURL("https://www.example.org/");
6994 request_info.traffic_annotation =
6995 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6996 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
6997 net_log_, CompletionOnceCallback()));
6998
6999 // Ensure that session is alive and active.
7000 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7001 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7002 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7003
7004 // Set up second socket data provider that is used after
7005 // migration. The request is written to this new socket, and the
7006 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:597007 MockQuicData socket_data1(version_);
Zhongyi Shif3d6cddb2018-07-11 03:30:027008 socket_data1.AddWrite(
7009 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
Fan Yang32c5a112018-12-10 20:06:337010 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027011 SYNCHRONOUS,
7012 ConstructGetRequestPacket(
7013 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shif3d6cddb2018-07-11 03:30:027014 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337015 ASYNC,
7016 ConstructOkResponsePacket(
7017 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shif3d6cddb2018-07-11 03:30:027018 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:337019 socket_data1.AddWrite(
7020 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
7021 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
7022 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shif3d6cddb2018-07-11 03:30:027023 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7024
7025 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
7026 // Now notify network is disconnected, cause the migration to complete
7027 // immediately.
7028 scoped_mock_network_change_notifier_->mock_network_change_notifier()
7029 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
7030 // There will be two pending task, one will complete migration with no delay
7031 // and the other will attempt to migrate back to the default network with
7032 // delay.
7033 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
7034
7035 // Complete migration.
7036 task_runner->RunUntilIdle();
7037 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
7038
7039 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7040 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7041 EXPECT_EQ(1u, session->GetNumActiveStreams());
7042
7043 // Send GET request on stream.
7044 HttpResponseInfo response;
7045 HttpRequestHeaders request_headers;
7046 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7047 callback_.callback()));
7048
7049 // Verify that response headers on the migrated socket were delivered to the
7050 // stream.
7051 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
7052 EXPECT_EQ(OK, callback_.WaitForResult());
7053 EXPECT_EQ(200, response.headers->response_code());
7054
7055 // Resume the old socket data, a read error will be delivered to the old
7056 // packet reader. Verify that the session is not affected.
7057 socket_data.Resume();
7058 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
7059 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7060 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7061 EXPECT_EQ(1u, session->GetNumActiveStreams());
7062
7063 stream.reset();
7064 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7065 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7066 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7067 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7068}
7069
7070// This test verifies that after migration on network is executed, packet
7071// read error on the old reader will be ignored and will not close the
7072// connection.
7073TEST_P(QuicStreamFactoryTest, IgnoreReadErrorOnOldReaderDuringMigration) {
7074 InitializeConnectionMigrationV2Test(
7075 {kDefaultNetworkForTests, kNewNetworkForTests});
7076 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7077 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7078 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7079
7080 // Using a testing task runner.
7081 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7082 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7083
Ryan Hamiltonabad59e2019-06-06 04:02:597084 MockQuicData socket_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027085 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shif3d6cddb2018-07-11 03:30:027086 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
7087 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE);
7088 socket_data.AddSocketDataToFactory(socket_factory_.get());
7089
7090 // Create request and QuicHttpStream.
7091 QuicStreamRequest request(factory_.get());
7092 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:037093 request.Request(
Nick Harper23290b82019-05-02 00:02:567094 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:517095 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:037096 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7097 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shif3d6cddb2018-07-11 03:30:027098 EXPECT_EQ(OK, callback_.WaitForResult());
7099 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7100 EXPECT_TRUE(stream.get());
7101
7102 // Cause QUIC stream to be created.
7103 HttpRequestInfo request_info;
7104 request_info.method = "GET";
7105 request_info.url = GURL("https://www.example.org/");
7106 request_info.traffic_annotation =
7107 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7108 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7109 net_log_, CompletionOnceCallback()));
7110
7111 // Ensure that session is alive and active.
7112 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7113 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7114 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7115
7116 // Set up second socket data provider that is used after
7117 // migration. The request is written to this new socket, and the
7118 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:597119 MockQuicData socket_data1(version_);
Zhongyi Shif3d6cddb2018-07-11 03:30:027120 socket_data1.AddWrite(
7121 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
Fan Yang32c5a112018-12-10 20:06:337122 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027123 SYNCHRONOUS,
7124 ConstructGetRequestPacket(
7125 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shif3d6cddb2018-07-11 03:30:027126 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337127 ASYNC,
7128 ConstructOkResponsePacket(
7129 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shif3d6cddb2018-07-11 03:30:027130 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:337131 socket_data1.AddWrite(
7132 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
7133 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
7134 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shif3d6cddb2018-07-11 03:30:027135 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7136
7137 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
7138 // Now notify network is disconnected, cause the migration to complete
7139 // immediately.
7140 scoped_mock_network_change_notifier_->mock_network_change_notifier()
7141 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
7142 // There will be two pending task, one will complete migration with no delay
7143 // and the other will attempt to migrate back to the default network with
7144 // delay.
7145 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
7146
7147 // Resume the old socket data, a read error will be delivered to the old
7148 // packet reader. Verify that the session is not affected.
7149 socket_data.Resume();
7150 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
7151 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7152 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7153 EXPECT_EQ(1u, session->GetNumActiveStreams());
7154
7155 // Complete migration.
7156 task_runner->RunUntilIdle();
7157 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
7158
7159 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7160 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7161 EXPECT_EQ(1u, session->GetNumActiveStreams());
7162
7163 // Send GET request on stream.
7164 HttpResponseInfo response;
7165 HttpRequestHeaders request_headers;
7166 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7167 callback_.callback()));
7168
7169 // Verify that response headers on the migrated socket were delivered to the
7170 // stream.
7171 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
7172 EXPECT_EQ(OK, callback_.WaitForResult());
7173 EXPECT_EQ(200, response.headers->response_code());
7174
7175 stream.reset();
Zhongyi Shi99d0cdd2019-05-21 01:18:427176 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7177 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7178 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7179}
7180
7181// This test verifies that when connection migration on path degrading is
7182// enabled, and no custom retransmittable on wire timeout is specified, the
7183// default value is used.
7184TEST_P(QuicStreamFactoryTest, DefaultRetransmittableOnWireTimeoutForMigration) {
7185 InitializeConnectionMigrationV2Test(
7186 {kDefaultNetworkForTests, kNewNetworkForTests});
7187 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7188 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7189 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7190
7191 // Using a testing task runner.
7192 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7193 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7194 QuicStreamFactoryPeer::SetAlarmFactory(
7195 factory_.get(),
7196 std::make_unique<QuicChromiumAlarmFactory>(task_runner.get(), &clock_));
7197
Ryan Hamiltonabad59e2019-06-06 04:02:597198 MockQuicData socket_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027199 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi99d0cdd2019-05-21 01:18:427200 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
7201 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE);
7202 socket_data.AddSocketDataToFactory(socket_factory_.get());
7203
7204 // Set up second socket data provider that is used after
7205 // migration. The request is written to this new socket, and the
7206 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:597207 MockQuicData socket_data1(version_);
Zhongyi Shi99d0cdd2019-05-21 01:18:427208 // The PING packet sent post migration.
7209 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(2, true));
7210 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027211 SYNCHRONOUS,
7212 ConstructGetRequestPacket(
7213 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi99d0cdd2019-05-21 01:18:427214 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7215 // Read two packets so that client will send ACK immedaitely.
Ryan Hamilton9f2eac32019-06-27 03:15:547216 socket_data1.AddRead(
7217 ASYNC,
7218 ConstructOkResponsePacket(
7219 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
7220 socket_data1.AddRead(
7221 ASYNC, server_maker_.MakeDataPacket(
7222 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7223 base::StringPiece("Hello World")));
7224
Zhongyi Shi99d0cdd2019-05-21 01:18:427225 // Read an ACK from server which acks all client data.
7226 socket_data1.AddRead(SYNCHRONOUS,
7227 server_maker_.MakeAckPacket(3, 3, 1, 1, false));
7228 socket_data1.AddWrite(ASYNC, client_maker_.MakeAckPacket(4, 2, 1, 1, false));
7229 // The PING packet sent for retransmittable on wire.
7230 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(5, false));
7231 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7232 std::string header = ConstructDataHeader(6);
7233 socket_data1.AddRead(
7234 ASYNC, ConstructServerDataPacket(
7235 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177236 header + "hello!"));
Zhongyi Shi99d0cdd2019-05-21 01:18:427237 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read.
7238 socket_data1.AddWrite(
7239 SYNCHRONOUS, client_maker_.MakeRstPacket(
7240 6, false, GetNthClientInitiatedBidirectionalStreamId(0),
7241 quic::QUIC_STREAM_CANCELLED));
7242 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7243
7244 // Create request and QuicHttpStream.
7245 QuicStreamRequest request(factory_.get());
7246 EXPECT_EQ(ERR_IO_PENDING,
7247 request.Request(
7248 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:517249 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shi99d0cdd2019-05-21 01:18:427250 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7251 failed_on_default_network_callback_, callback_.callback()));
7252 EXPECT_EQ(OK, callback_.WaitForResult());
7253 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7254 EXPECT_TRUE(stream.get());
7255
7256 // Cause QUIC stream to be created.
7257 HttpRequestInfo request_info;
7258 request_info.method = "GET";
7259 request_info.url = GURL("https://www.example.org/");
7260 request_info.traffic_annotation =
7261 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7262 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7263 net_log_, CompletionOnceCallback()));
7264
7265 // Ensure that session is alive and active.
7266 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7267 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7268
7269 // Now notify network is disconnected, cause the migration to complete
7270 // immediately.
7271 scoped_mock_network_change_notifier_->mock_network_change_notifier()
7272 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
7273
7274 // Complete migration.
7275 task_runner->RunUntilIdle();
7276 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7277 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7278 EXPECT_EQ(1u, session->GetNumActiveStreams());
7279
7280 // Send GET request on stream.
7281 HttpResponseInfo response;
7282 HttpRequestHeaders request_headers;
7283 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7284 callback_.callback()));
7285 socket_data1.Resume();
7286 // Spin up the message loop to read incoming data from server till the ACK.
7287 base::RunLoop().RunUntilIdle();
7288
7289 // Ack delay time.
7290 int delay = task_runner->NextPendingTaskDelay().InMilliseconds();
7291 EXPECT_GT(kDefaultRetransmittableOnWireTimeoutMillisecs, delay);
7292 // Fire the ack alarm, since ack has been sent, no ack will be sent.
7293 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7294 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7295
7296 // Fire the ping alarm with retransmittable-on-wire timeout, send PING.
7297 delay = kDefaultRetransmittableOnWireTimeoutMillisecs - delay;
7298 EXPECT_EQ(base::TimeDelta::FromMilliseconds(delay),
7299 task_runner->NextPendingTaskDelay());
7300 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7301 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7302
7303 socket_data1.Resume();
7304
7305 // Verify that response headers on the migrated socket were delivered to the
7306 // stream.
7307 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
7308 EXPECT_EQ(200, response.headers->response_code());
7309
7310 // Resume the old socket data, a read error will be delivered to the old
7311 // packet reader. Verify that the session is not affected.
7312 socket_data.Resume();
7313 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7314 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7315 EXPECT_EQ(1u, session->GetNumActiveStreams());
7316
7317 stream.reset();
Zhongyi Shif3d6cddb2018-07-11 03:30:027318 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7319 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7320 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7321 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7322}
7323
Zhongyi Shi99d0cdd2019-05-21 01:18:427324// This test verifies that when connection migration on path degrading is
7325// enabled, and a custom retransmittable on wire timeout is specified, the
7326// custom value is used.
7327TEST_P(QuicStreamFactoryTest, CustomRetransmittableOnWireTimeoutForMigration) {
7328 int custom_timeout_value = 200;
7329 test_params_.quic_retransmittable_on_wire_timeout_milliseconds =
7330 custom_timeout_value;
7331 InitializeConnectionMigrationV2Test(
7332 {kDefaultNetworkForTests, kNewNetworkForTests});
7333 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7334 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7335 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7336
7337 // Using a testing task runner.
7338 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7339 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7340 QuicStreamFactoryPeer::SetAlarmFactory(
7341 factory_.get(),
7342 std::make_unique<QuicChromiumAlarmFactory>(task_runner.get(), &clock_));
7343
Ryan Hamiltonabad59e2019-06-06 04:02:597344 MockQuicData socket_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027345 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi99d0cdd2019-05-21 01:18:427346 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
7347 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE);
7348 socket_data.AddSocketDataToFactory(socket_factory_.get());
7349
7350 // Set up second socket data provider that is used after
7351 // migration. The request is written to this new socket, and the
7352 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:597353 MockQuicData socket_data1(version_);
Zhongyi Shi99d0cdd2019-05-21 01:18:427354 // The PING packet sent post migration.
7355 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(2, true));
7356 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027357 SYNCHRONOUS,
7358 ConstructGetRequestPacket(
7359 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi99d0cdd2019-05-21 01:18:427360 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7361 // Read two packets so that client will send ACK immedaitely.
Ryan Hamilton9f2eac32019-06-27 03:15:547362 socket_data1.AddRead(
7363 ASYNC,
7364 ConstructOkResponsePacket(
7365 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
7366 socket_data1.AddRead(
7367 ASYNC, server_maker_.MakeDataPacket(
7368 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7369 base::StringPiece("Hello World")));
Zhongyi Shi99d0cdd2019-05-21 01:18:427370 // Read an ACK from server which acks all client data.
7371 socket_data1.AddRead(SYNCHRONOUS,
7372 server_maker_.MakeAckPacket(3, 3, 1, 1, false));
7373 socket_data1.AddWrite(ASYNC, client_maker_.MakeAckPacket(4, 2, 1, 1, false));
7374 // The PING packet sent for retransmittable on wire.
7375 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(5, false));
7376 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7377 std::string header = ConstructDataHeader(6);
7378 socket_data1.AddRead(
7379 ASYNC, ConstructServerDataPacket(
7380 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177381 header + "hello!"));
Zhongyi Shi99d0cdd2019-05-21 01:18:427382 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read.
7383 socket_data1.AddWrite(
7384 SYNCHRONOUS, client_maker_.MakeRstPacket(
7385 6, false, GetNthClientInitiatedBidirectionalStreamId(0),
7386 quic::QUIC_STREAM_CANCELLED));
7387 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7388
7389 // Create request and QuicHttpStream.
7390 QuicStreamRequest request(factory_.get());
7391 EXPECT_EQ(ERR_IO_PENDING,
7392 request.Request(
7393 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:517394 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shi99d0cdd2019-05-21 01:18:427395 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7396 failed_on_default_network_callback_, callback_.callback()));
7397 EXPECT_EQ(OK, callback_.WaitForResult());
7398 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7399 EXPECT_TRUE(stream.get());
7400
7401 // Cause QUIC stream to be created.
7402 HttpRequestInfo request_info;
7403 request_info.method = "GET";
7404 request_info.url = GURL("https://www.example.org/");
7405 request_info.traffic_annotation =
7406 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7407 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7408 net_log_, CompletionOnceCallback()));
7409
7410 // Ensure that session is alive and active.
7411 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7412 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7413
7414 // Now notify network is disconnected, cause the migration to complete
7415 // immediately.
7416 scoped_mock_network_change_notifier_->mock_network_change_notifier()
7417 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
7418
7419 // Complete migration.
7420 task_runner->RunUntilIdle();
7421 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7422 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7423 EXPECT_EQ(1u, session->GetNumActiveStreams());
7424
7425 // Send GET request on stream.
7426 HttpResponseInfo response;
7427 HttpRequestHeaders request_headers;
7428 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7429 callback_.callback()));
7430 socket_data1.Resume();
7431 // Spin up the message loop to read incoming data from server till the ACK.
7432 base::RunLoop().RunUntilIdle();
7433
7434 // Ack delay time.
7435 int delay = task_runner->NextPendingTaskDelay().InMilliseconds();
7436 EXPECT_GT(custom_timeout_value, delay);
7437 // Fire the ack alarm, since ack has been sent, no ack will be sent.
7438 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7439 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7440
7441 // Fire the ping alarm with retransmittable-on-wire timeout, send PING.
7442 delay = custom_timeout_value - delay;
7443 EXPECT_EQ(base::TimeDelta::FromMilliseconds(delay),
7444 task_runner->NextPendingTaskDelay());
7445 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7446 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7447
7448 socket_data1.Resume();
7449
7450 // Verify that response headers on the migrated socket were delivered to the
7451 // stream.
7452 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
7453 EXPECT_EQ(200, response.headers->response_code());
7454
7455 // Resume the old socket data, a read error will be delivered to the old
7456 // packet reader. Verify that the session is not affected.
7457 socket_data.Resume();
7458 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7459 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7460 EXPECT_EQ(1u, session->GetNumActiveStreams());
7461
7462 stream.reset();
7463 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7464 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7465 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7466 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7467}
7468
7469// This test verifies that when no migration is enabled, but a custom value for
7470// retransmittable-on-wire timeout is specified, the ping alarm is set up to
7471// send retransmittable pings with the custom value.
7472TEST_P(QuicStreamFactoryTest, CustomRetransmittableOnWireTimeout) {
7473 int custom_timeout_value = 200;
7474 test_params_.quic_retransmittable_on_wire_timeout_milliseconds =
7475 custom_timeout_value;
7476 Initialize();
7477 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7478 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7479 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7480
7481 // Using a testing task runner.
7482 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7483 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7484 QuicStreamFactoryPeer::SetAlarmFactory(
7485 factory_.get(),
7486 std::make_unique<QuicChromiumAlarmFactory>(task_runner.get(), &clock_));
7487
Ryan Hamiltonabad59e2019-06-06 04:02:597488 MockQuicData socket_data1(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027489 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi99d0cdd2019-05-21 01:18:427490 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027491 SYNCHRONOUS,
7492 ConstructGetRequestPacket(
7493 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi99d0cdd2019-05-21 01:18:427494 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7495 // Read two packets so that client will send ACK immedaitely.
Ryan Hamilton9f2eac32019-06-27 03:15:547496 socket_data1.AddRead(
7497 ASYNC,
7498 ConstructOkResponsePacket(
7499 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
7500 socket_data1.AddRead(
7501 ASYNC, server_maker_.MakeDataPacket(
7502 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7503 base::StringPiece("Hello World")));
Zhongyi Shi99d0cdd2019-05-21 01:18:427504 // Read an ACK from server which acks all client data.
7505 socket_data1.AddRead(SYNCHRONOUS,
7506 server_maker_.MakeAckPacket(3, 2, 1, 1, false));
7507 socket_data1.AddWrite(ASYNC, client_maker_.MakeAckPacket(3, 2, 1, 1, false));
7508 // The PING packet sent for retransmittable on wire.
7509 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(4, false));
7510 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7511 std::string header = ConstructDataHeader(6);
7512 socket_data1.AddRead(
7513 ASYNC, ConstructServerDataPacket(
7514 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177515 header + "hello!"));
Zhongyi Shi99d0cdd2019-05-21 01:18:427516 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read.
7517 socket_data1.AddWrite(
7518 SYNCHRONOUS, client_maker_.MakeRstPacket(
7519 5, false, GetNthClientInitiatedBidirectionalStreamId(0),
7520 quic::QUIC_STREAM_CANCELLED));
7521 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7522
7523 // Create request and QuicHttpStream.
7524 QuicStreamRequest request(factory_.get());
7525 EXPECT_EQ(ERR_IO_PENDING,
7526 request.Request(
7527 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:517528 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shi99d0cdd2019-05-21 01:18:427529 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7530 failed_on_default_network_callback_, callback_.callback()));
7531 EXPECT_EQ(OK, callback_.WaitForResult());
7532 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7533 EXPECT_TRUE(stream.get());
7534
7535 // Cause QUIC stream to be created.
7536 HttpRequestInfo request_info;
7537 request_info.method = "GET";
7538 request_info.url = GURL("https://www.example.org/");
7539 request_info.traffic_annotation =
7540 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7541 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7542 net_log_, CompletionOnceCallback()));
7543
7544 // Ensure that session is alive and active.
7545 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7546 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7547
7548 // Complete migration.
7549 task_runner->RunUntilIdle();
7550 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7551 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7552 EXPECT_EQ(1u, session->GetNumActiveStreams());
7553
7554 // Send GET request on stream.
7555 HttpResponseInfo response;
7556 HttpRequestHeaders request_headers;
7557 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7558 callback_.callback()));
7559 socket_data1.Resume();
7560 // Spin up the message loop to read incoming data from server till the ACK.
7561 base::RunLoop().RunUntilIdle();
7562
7563 // Ack delay time.
7564 int delay = task_runner->NextPendingTaskDelay().InMilliseconds();
7565 EXPECT_GT(custom_timeout_value, delay);
7566 // Fire the ack alarm, since ack has been sent, no ack will be sent.
7567 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7568 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7569
7570 // Fire the ping alarm with retransmittable-on-wire timeout, send PING.
7571 delay = custom_timeout_value - delay;
7572 EXPECT_EQ(base::TimeDelta::FromMilliseconds(delay),
7573 task_runner->NextPendingTaskDelay());
7574 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7575 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7576
7577 socket_data1.Resume();
7578
7579 // Verify that response headers on the migrated socket were delivered to the
7580 // stream.
7581 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
7582 EXPECT_EQ(200, response.headers->response_code());
7583
7584 // Resume the old socket data, a read error will be delivered to the old
7585 // packet reader. Verify that the session is not affected.
7586 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7587 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7588 EXPECT_EQ(1u, session->GetNumActiveStreams());
7589
7590 stream.reset();
7591 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7592 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7593}
7594
7595// This test verifies that when no migration is enabled, and no custom value
7596// for retransmittable-on-wire timeout is specified, the ping alarm will not
7597// send any retransmittable pings.
7598TEST_P(QuicStreamFactoryTest, NoRetransmittableOnWireTimeout) {
7599 Initialize();
7600 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7601 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7602 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7603
7604 // Using a testing task runner.
7605 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7606 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7607 QuicStreamFactoryPeer::SetAlarmFactory(
7608 factory_.get(),
7609 std::make_unique<QuicChromiumAlarmFactory>(task_runner.get(), &clock_));
7610
Ryan Hamiltonabad59e2019-06-06 04:02:597611 MockQuicData socket_data1(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027612 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi99d0cdd2019-05-21 01:18:427613 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027614 SYNCHRONOUS,
7615 ConstructGetRequestPacket(
7616 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi99d0cdd2019-05-21 01:18:427617 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7618 // Read two packets so that client will send ACK immedaitely.
Ryan Hamilton9f2eac32019-06-27 03:15:547619 socket_data1.AddRead(
7620 ASYNC,
7621 ConstructOkResponsePacket(
7622 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
7623 socket_data1.AddRead(
7624 ASYNC, server_maker_.MakeDataPacket(
7625 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7626 base::StringPiece("Hello World")));
Zhongyi Shi99d0cdd2019-05-21 01:18:427627 // Read an ACK from server which acks all client data.
7628 socket_data1.AddRead(SYNCHRONOUS,
7629 server_maker_.MakeAckPacket(3, 2, 1, 1, false));
7630 socket_data1.AddWrite(ASYNC, client_maker_.MakeAckPacket(3, 2, 1, 1, false));
7631 std::string header = ConstructDataHeader(6);
7632 socket_data1.AddRead(
7633 ASYNC, ConstructServerDataPacket(
7634 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177635 header + "hello!"));
Zhongyi Shi99d0cdd2019-05-21 01:18:427636 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read.
7637 socket_data1.AddWrite(
7638 SYNCHRONOUS, client_maker_.MakeRstPacket(
7639 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
7640 quic::QUIC_STREAM_CANCELLED));
7641 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7642
7643 // Create request and QuicHttpStream.
7644 QuicStreamRequest request(factory_.get());
7645 EXPECT_EQ(ERR_IO_PENDING,
7646 request.Request(
7647 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:517648 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shi99d0cdd2019-05-21 01:18:427649 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7650 failed_on_default_network_callback_, callback_.callback()));
7651 EXPECT_EQ(OK, callback_.WaitForResult());
7652 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7653 EXPECT_TRUE(stream.get());
7654
7655 // Cause QUIC stream to be created.
7656 HttpRequestInfo request_info;
7657 request_info.method = "GET";
7658 request_info.url = GURL("https://www.example.org/");
7659 request_info.traffic_annotation =
7660 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7661 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7662 net_log_, CompletionOnceCallback()));
7663
7664 // Ensure that session is alive and active.
7665 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7666 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7667
7668 // Complete migration.
7669 task_runner->RunUntilIdle();
7670 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7671 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7672 EXPECT_EQ(1u, session->GetNumActiveStreams());
7673
7674 // Send GET request on stream.
7675 HttpResponseInfo response;
7676 HttpRequestHeaders request_headers;
7677 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7678 callback_.callback()));
7679 socket_data1.Resume();
7680 // Spin up the message loop to read incoming data from server till the ACK.
7681 base::RunLoop().RunUntilIdle();
7682
7683 // Ack delay time.
7684 int delay = task_runner->NextPendingTaskDelay().InMilliseconds();
7685 EXPECT_GT(kDefaultRetransmittableOnWireTimeoutMillisecs, delay);
7686 // Fire the ack alarm, since ack has been sent, no ack will be sent.
7687 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7688 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7689
7690 // Verify that the ping alarm is not set with any default value.
7691 int wrong_delay = kDefaultRetransmittableOnWireTimeoutMillisecs - delay;
7692 delay = task_runner->NextPendingTaskDelay().InMilliseconds();
7693 EXPECT_NE(wrong_delay, delay);
7694 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7695 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7696
7697 // Verify that response headers on the migrated socket were delivered to the
7698 // stream.
7699 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
7700 EXPECT_EQ(200, response.headers->response_code());
7701
7702 // Resume the old socket data, a read error will be delivered to the old
7703 // packet reader. Verify that the session is not affected.
7704 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7705 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7706 EXPECT_EQ(1u, session->GetNumActiveStreams());
7707
7708 stream.reset();
7709 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7710 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7711}
7712
7713// This test verifies that when only migration on network change is enabled, and
7714// a custom value for retransmittable-on-wire is specified, the ping alarm will
7715// send retransmittable pings to the peer with custom value.
7716TEST_P(QuicStreamFactoryTest,
7717 CustomeRetransmittableOnWireTimeoutWithMigrationOnNetworkChangeOnly) {
7718 int custom_timeout_value = 200;
7719 test_params_.quic_retransmittable_on_wire_timeout_milliseconds =
7720 custom_timeout_value;
7721 test_params_.quic_migrate_sessions_on_network_change_v2 = true;
7722 Initialize();
7723 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7724 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7725 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7726
7727 // Using a testing task runner.
7728 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7729 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7730 QuicStreamFactoryPeer::SetAlarmFactory(
7731 factory_.get(),
7732 std::make_unique<QuicChromiumAlarmFactory>(task_runner.get(), &clock_));
7733
Ryan Hamiltonabad59e2019-06-06 04:02:597734 MockQuicData socket_data1(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027735 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi99d0cdd2019-05-21 01:18:427736 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027737 SYNCHRONOUS,
7738 ConstructGetRequestPacket(
7739 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi99d0cdd2019-05-21 01:18:427740 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7741 // Read two packets so that client will send ACK immedaitely.
Ryan Hamilton9f2eac32019-06-27 03:15:547742 socket_data1.AddRead(
7743 ASYNC,
7744 ConstructOkResponsePacket(
7745 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
7746 socket_data1.AddRead(
7747 ASYNC, server_maker_.MakeDataPacket(
7748 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7749 base::StringPiece("Hello World")));
Zhongyi Shi99d0cdd2019-05-21 01:18:427750 // Read an ACK from server which acks all client data.
7751 socket_data1.AddRead(SYNCHRONOUS,
7752 server_maker_.MakeAckPacket(3, 2, 1, 1, false));
7753 socket_data1.AddWrite(ASYNC, client_maker_.MakeAckPacket(3, 2, 1, 1, false));
7754 // The PING packet sent for retransmittable on wire.
7755 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(4, false));
7756 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7757 std::string header = ConstructDataHeader(6);
7758 socket_data1.AddRead(
7759 ASYNC, ConstructServerDataPacket(
7760 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177761 header + "hello!"));
Zhongyi Shi99d0cdd2019-05-21 01:18:427762 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read.
7763 socket_data1.AddWrite(
7764 SYNCHRONOUS, client_maker_.MakeRstPacket(
7765 5, false, GetNthClientInitiatedBidirectionalStreamId(0),
7766 quic::QUIC_STREAM_CANCELLED));
7767 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7768
7769 // Create request and QuicHttpStream.
7770 QuicStreamRequest request(factory_.get());
7771 EXPECT_EQ(ERR_IO_PENDING,
7772 request.Request(
7773 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:517774 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shi99d0cdd2019-05-21 01:18:427775 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7776 failed_on_default_network_callback_, callback_.callback()));
7777 EXPECT_EQ(OK, callback_.WaitForResult());
7778 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7779 EXPECT_TRUE(stream.get());
7780
7781 // Cause QUIC stream to be created.
7782 HttpRequestInfo request_info;
7783 request_info.method = "GET";
7784 request_info.url = GURL("https://www.example.org/");
7785 request_info.traffic_annotation =
7786 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7787 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7788 net_log_, CompletionOnceCallback()));
7789
7790 // Ensure that session is alive and active.
7791 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7792 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7793
7794 // Complete migration.
7795 task_runner->RunUntilIdle();
7796 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7797 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7798 EXPECT_EQ(1u, session->GetNumActiveStreams());
7799
7800 // Send GET request on stream.
7801 HttpResponseInfo response;
7802 HttpRequestHeaders request_headers;
7803 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7804 callback_.callback()));
7805 socket_data1.Resume();
7806 // Spin up the message loop to read incoming data from server till the ACK.
7807 base::RunLoop().RunUntilIdle();
7808
7809 // Ack delay time.
7810 int delay = task_runner->NextPendingTaskDelay().InMilliseconds();
7811 EXPECT_GT(custom_timeout_value, delay);
7812 // Fire the ack alarm, since ack has been sent, no ack will be sent.
7813 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7814 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7815
7816 // Fire the ping alarm with retransmittable-on-wire timeout, send PING.
7817 delay = custom_timeout_value - delay;
7818 EXPECT_EQ(base::TimeDelta::FromMilliseconds(delay),
7819 task_runner->NextPendingTaskDelay());
7820 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7821 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7822
7823 socket_data1.Resume();
7824
7825 // Verify that response headers on the migrated socket were delivered to the
7826 // stream.
7827 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
7828 EXPECT_EQ(200, response.headers->response_code());
7829
7830 // Resume the old socket data, a read error will be delivered to the old
7831 // packet reader. Verify that the session is not affected.
7832 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7833 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7834 EXPECT_EQ(1u, session->GetNumActiveStreams());
7835
7836 stream.reset();
7837 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7838 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7839}
7840
7841// This test verifies that when only migration on network change is enabled, and
7842// no custom value for retransmittable-on-wire is specified, the ping alarm will
7843// NOT send retransmittable pings to the peer with custom value.
7844TEST_P(QuicStreamFactoryTest,
7845 NoRetransmittableOnWireTimeoutWithMigrationOnNetworkChangeOnly) {
7846 test_params_.quic_migrate_sessions_on_network_change_v2 = true;
7847 Initialize();
7848 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7849 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7850 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7851
7852 // Using a testing task runner.
7853 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7854 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7855 QuicStreamFactoryPeer::SetAlarmFactory(
7856 factory_.get(),
7857 std::make_unique<QuicChromiumAlarmFactory>(task_runner.get(), &clock_));
7858
Ryan Hamiltonabad59e2019-06-06 04:02:597859 MockQuicData socket_data1(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027860 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi99d0cdd2019-05-21 01:18:427861 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027862 SYNCHRONOUS,
7863 ConstructGetRequestPacket(
7864 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi99d0cdd2019-05-21 01:18:427865 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7866 // Read two packets so that client will send ACK immedaitely.
Ryan Hamilton9f2eac32019-06-27 03:15:547867 socket_data1.AddRead(
7868 ASYNC,
7869 ConstructOkResponsePacket(
7870 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
7871 socket_data1.AddRead(
7872 ASYNC, server_maker_.MakeDataPacket(
7873 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7874 base::StringPiece("Hello World")));
Zhongyi Shi99d0cdd2019-05-21 01:18:427875 // Read an ACK from server which acks all client data.
7876 socket_data1.AddRead(SYNCHRONOUS,
7877 server_maker_.MakeAckPacket(3, 2, 1, 1, false));
7878 socket_data1.AddWrite(ASYNC, client_maker_.MakeAckPacket(3, 2, 1, 1, false));
7879 std::string header = ConstructDataHeader(6);
7880 socket_data1.AddRead(
7881 ASYNC, ConstructServerDataPacket(
7882 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177883 header + "hello!"));
Zhongyi Shi99d0cdd2019-05-21 01:18:427884 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read.
7885 socket_data1.AddWrite(
7886 SYNCHRONOUS, client_maker_.MakeRstPacket(
7887 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
7888 quic::QUIC_STREAM_CANCELLED));
7889 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7890
7891 // Create request and QuicHttpStream.
7892 QuicStreamRequest request(factory_.get());
7893 EXPECT_EQ(ERR_IO_PENDING,
7894 request.Request(
7895 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:517896 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shi99d0cdd2019-05-21 01:18:427897 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7898 failed_on_default_network_callback_, callback_.callback()));
7899 EXPECT_EQ(OK, callback_.WaitForResult());
7900 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7901 EXPECT_TRUE(stream.get());
7902
7903 // Cause QUIC stream to be created.
7904 HttpRequestInfo request_info;
7905 request_info.method = "GET";
7906 request_info.url = GURL("https://www.example.org/");
7907 request_info.traffic_annotation =
7908 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7909 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7910 net_log_, CompletionOnceCallback()));
7911
7912 // Ensure that session is alive and active.
7913 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7914 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7915
7916 // Complete migration.
7917 task_runner->RunUntilIdle();
7918 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7919 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7920 EXPECT_EQ(1u, session->GetNumActiveStreams());
7921
7922 // Send GET request on stream.
7923 HttpResponseInfo response;
7924 HttpRequestHeaders request_headers;
7925 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7926 callback_.callback()));
7927 socket_data1.Resume();
7928 // Spin up the message loop to read incoming data from server till the ACK.
7929 base::RunLoop().RunUntilIdle();
7930
7931 // Ack delay time.
7932 int delay = task_runner->NextPendingTaskDelay().InMilliseconds();
7933 EXPECT_GT(kDefaultRetransmittableOnWireTimeoutMillisecs, delay);
7934 // Fire the ack alarm, since ack has been sent, no ack will be sent.
7935 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7936 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7937
7938 // Verify ping alarm is not set with default value.
7939 int wrong_delay = kDefaultRetransmittableOnWireTimeoutMillisecs - delay;
7940 delay = task_runner->NextPendingTaskDelay().InMilliseconds();
7941 EXPECT_NE(wrong_delay, delay);
7942 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7943 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7944
7945 // Verify that response headers on the migrated socket were delivered to the
7946 // stream.
7947 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
7948 EXPECT_EQ(200, response.headers->response_code());
7949
7950 // Resume the old socket data, a read error will be delivered to the old
7951 // packet reader. Verify that the session is not affected.
7952 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7953 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7954 EXPECT_EQ(1u, session->GetNumActiveStreams());
7955
7956 stream.reset();
7957 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7958 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7959}
7960
Zhongyi Shif3d6cddb2018-07-11 03:30:027961// This test verifies that after migration on write error is posted, packet
7962// read error on the old reader will be ignored and will not close the
7963// connection.
7964TEST_P(QuicStreamFactoryTest,
7965 IgnoreReadErrorOnOldReaderDuringPendingMigrationOnWriteError) {
7966 InitializeConnectionMigrationV2Test(
7967 {kDefaultNetworkForTests, kNewNetworkForTests});
7968 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7969 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7970 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7971
7972 // Using a testing task runner.
7973 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7974 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7975
Ryan Hamiltonabad59e2019-06-06 04:02:597976 MockQuicData socket_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027977 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shif3d6cddb2018-07-11 03:30:027978 socket_data.AddWrite(ASYNC, ERR_FAILED); // Write error.
7979 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE); // Read error.
7980 socket_data.AddSocketDataToFactory(socket_factory_.get());
7981
7982 // Create request and QuicHttpStream.
7983 QuicStreamRequest request(factory_.get());
7984 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:037985 request.Request(
Nick Harper23290b82019-05-02 00:02:567986 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:517987 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:037988 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7989 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shif3d6cddb2018-07-11 03:30:027990 EXPECT_EQ(OK, callback_.WaitForResult());
7991 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7992 EXPECT_TRUE(stream.get());
7993
7994 // Cause QUIC stream to be created.
7995 HttpRequestInfo request_info;
7996 request_info.method = "GET";
7997 request_info.url = GURL("https://www.example.org/");
7998 request_info.traffic_annotation =
7999 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8000 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
8001 net_log_, CompletionOnceCallback()));
8002
8003 // Ensure that session is alive and active.
8004 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
8005 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8006 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8007
8008 // Set up second socket data provider that is used after
8009 // migration. The request is written to this new socket, and the
8010 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:598011 MockQuicData socket_data1(version_);
Fan Yang32c5a112018-12-10 20:06:338012 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:028013 SYNCHRONOUS,
8014 ConstructGetRequestPacket(
8015 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Ryan Hamilton9f2eac32019-06-27 03:15:548016 client_maker_.set_coalesce_http_frames(true);
Zhongyi Shif3d6cddb2018-07-11 03:30:028017 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:338018 ASYNC,
8019 ConstructOkResponsePacket(
8020 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shif3d6cddb2018-07-11 03:30:028021
8022 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
8023 socket_data1.AddRead(ASYNC, ERR_FAILED); // Read error to close connection.
8024 socket_data1.AddSocketDataToFactory(socket_factory_.get());
8025
8026 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
8027 // Send GET request on stream.
8028 HttpResponseInfo response;
8029 HttpRequestHeaders request_headers;
8030 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
8031 callback_.callback()));
8032 // Run the message loop to complete asynchronous write and read with errors.
8033 base::RunLoop().RunUntilIdle();
8034 // There will be one pending task to complete migration on write error.
8035 // Verify session is not closed with read error.
8036 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
8037 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8038 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8039 EXPECT_EQ(1u, session->GetNumActiveStreams());
8040
8041 // Complete migration.
8042 task_runner->RunUntilIdle();
Zhongyi Shia7dd46b2018-07-12 22:59:298043 // There will be one more task posted attempting to migrate back to the
8044 // default network.
8045 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
Zhongyi Shif3d6cddb2018-07-11 03:30:028046 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:298047 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shif3d6cddb2018-07-11 03:30:028048 EXPECT_EQ(1u, session->GetNumActiveStreams());
8049
8050 // Verify that response headers on the migrated socket were delivered to the
8051 // stream.
8052 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
8053 EXPECT_EQ(200, response.headers->response_code());
8054
8055 // Resume to consume the read error on new socket, which will close
8056 // the connection.
8057 socket_data1.Resume();
8058
8059 EXPECT_TRUE(socket_data.AllReadDataConsumed());
8060 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
8061 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
8062 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
8063}
8064
Zhongyi Shi4ac9e1f2018-06-21 05:21:478065// Migrate on asynchronous write error, old network disconnects after alternate
8066// network connects.
8067TEST_P(QuicStreamFactoryTest,
8068 MigrateSessionOnWriteErrorWithDisconnectAfterConnectAysnc) {
8069 TestMigrationOnWriteErrorWithMultipleNotifications(
8070 ASYNC, /*disconnect_before_connect*/ false);
8071}
8072
8073// Migrate on synchronous write error, old network disconnects after alternate
8074// network connects.
8075TEST_P(QuicStreamFactoryTest,
8076 MigrateSessionOnWriteErrorWithDisconnectAfterConnectSync) {
8077 TestMigrationOnWriteErrorWithMultipleNotifications(
8078 SYNCHRONOUS, /*disconnect_before_connect*/ false);
8079}
8080
8081// Migrate on asynchronous write error, old network disconnects before alternate
8082// network connects.
8083TEST_P(QuicStreamFactoryTest,
8084 MigrateSessionOnWriteErrorWithDisconnectBeforeConnectAysnc) {
8085 TestMigrationOnWriteErrorWithMultipleNotifications(
8086 ASYNC, /*disconnect_before_connect*/ true);
8087}
8088
8089// Migrate on synchronous write error, old network disconnects before alternate
8090// network connects.
8091TEST_P(QuicStreamFactoryTest,
8092 MigrateSessionOnWriteErrorWithDisconnectBeforeConnectSync) {
8093 TestMigrationOnWriteErrorWithMultipleNotifications(
8094 SYNCHRONOUS, /*disconnect_before_connect*/ true);
8095}
8096
8097// Setps up test which verifies that session successfully migrate to alternate
8098// network with signals delivered in the following order:
8099// *NOTE* Signal (A) and (B) can reverse order based on
8100// |disconnect_before_connect|.
8101// - (No alternate network is connected) session connects to
8102// kDefaultNetworkForTests.
8103// - An async/sync write error is encountered based on |write_error_mode|:
8104// session posted task to migrate session on write error.
8105// - Posted task is executed, miration moves to pending state due to lack of
8106// alternate network.
8107// - (A) An alternate network is connected, pending migration completes.
8108// - (B) Old default network disconnects, no migration will be attempted as
Zhongyi Shi329f5cbd2018-06-22 23:51:188109// session has already migrate to the alternate network.
Zhongyi Shi4ac9e1f2018-06-21 05:21:478110// - The alternate network is made default.
jri5b785512016-09-13 04:29:118111void QuicStreamFactoryTestBase::
Zhongyi Shi4ac9e1f2018-06-21 05:21:478112 TestMigrationOnWriteErrorWithMultipleNotifications(
jri5b785512016-09-13 04:29:118113 IoMode write_error_mode,
Zhongyi Shi4ac9e1f2018-06-21 05:21:478114 bool disconnect_before_connect) {
Zhongyi Shi329f5cbd2018-06-22 23:51:188115 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri5b785512016-09-13 04:29:118116 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8117 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8118 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8119
Ryan Hamiltonabad59e2019-06-06 04:02:598120 MockQuicData socket_data(version_);
jri5b785512016-09-13 04:29:118121 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:028122 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi4ac9e1f2018-06-21 05:21:478123 socket_data.AddWrite(write_error_mode, ERR_FAILED); // Write error.
Zhongyi Shi5f587cc2017-11-21 23:24:178124 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri5b785512016-09-13 04:29:118125
8126 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:458127 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338128 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:038129 request.Request(
Nick Harper23290b82019-05-02 00:02:568130 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:518131 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:038132 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8133 failed_on_default_network_callback_, callback_.callback()));
jri5b785512016-09-13 04:29:118134 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:248135 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri5b785512016-09-13 04:29:118136 EXPECT_TRUE(stream.get());
8137
8138 // Cause QUIC stream to be created.
8139 HttpRequestInfo request_info;
8140 request_info.method = "GET";
8141 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:398142 request_info.traffic_annotation =
8143 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:278144 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:398145 net_log_, CompletionOnceCallback()));
jri5b785512016-09-13 04:29:118146
8147 // Ensure that session is alive and active.
8148 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
8149 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8150 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8151
8152 // Send GET request on stream. This should cause a write error, which triggers
8153 // a connection migration attempt.
8154 HttpResponseInfo response;
8155 HttpRequestHeaders request_headers;
8156 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
8157 callback_.callback()));
Zhongyi Shi4ac9e1f2018-06-21 05:21:478158 // Run the message loop so that posted task to migrate to socket will be
8159 // executed. A new task will be posted to wait for a new network.
jri5b785512016-09-13 04:29:118160 base::RunLoop().RunUntilIdle();
8161
8162 // In this particular code path, the network will not yet be marked
8163 // as going away and the session will still be alive.
8164 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8165 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8166 EXPECT_EQ(1u, session->GetNumActiveStreams());
8167 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
8168
8169 // Set up second socket data provider that is used after
8170 // migration. The request is rewritten to this new socket, and the
8171 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:598172 MockQuicData socket_data1(version_);
Fan Yang32c5a112018-12-10 20:06:338173 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:028174 SYNCHRONOUS,
8175 ConstructGetRequestPacket(
8176 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Ryan Hamilton9f2eac32019-06-27 03:15:548177 client_maker_.set_coalesce_http_frames(true);
Zhongyi Shi32f2fd02018-04-16 18:23:438178 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:338179 ASYNC,
8180 ConstructOkResponsePacket(
8181 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
jri5b785512016-09-13 04:29:118182 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:338183 socket_data1.AddWrite(
8184 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
8185 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
8186 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:178187 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri5b785512016-09-13 04:29:118188
8189 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8190 ->SetConnectedNetworksList(
8191 {kDefaultNetworkForTests, kNewNetworkForTests});
Zhongyi Shi4ac9e1f2018-06-21 05:21:478192 if (disconnect_before_connect) {
8193 // Now deliver a DISCONNECT notification.
jri5b785512016-09-13 04:29:118194 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8195 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
Zhongyi Shi4ac9e1f2018-06-21 05:21:478196
8197 // Now deliver a CONNECTED notification and completes migration.
jri5b785512016-09-13 04:29:118198 scoped_mock_network_change_notifier_->mock_network_change_notifier()
Zhongyi Shi4ac9e1f2018-06-21 05:21:478199 ->NotifyNetworkConnected(kNewNetworkForTests);
8200 } else {
8201 // Now deliver a CONNECTED notification and completes migration.
8202 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8203 ->NotifyNetworkConnected(kNewNetworkForTests);
8204
8205 // Now deliver a DISCONNECT notification.
8206 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8207 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
jri5b785512016-09-13 04:29:118208 }
jri5b785512016-09-13 04:29:118209 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shi329f5cbd2018-06-22 23:51:188210 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:118211 EXPECT_EQ(1u, session->GetNumActiveStreams());
8212
8213 // This is the callback for the response headers that returned
8214 // pending previously, because no result was available. Check that
8215 // the result is now available due to the successful migration.
8216 EXPECT_THAT(callback_.WaitForResult(), IsOk());
8217 EXPECT_EQ(200, response.headers->response_code());
8218
Zhongyi Shi4ac9e1f2018-06-21 05:21:478219 // Deliver a MADEDEFAULT notification.
jri5b785512016-09-13 04:29:118220 scoped_mock_network_change_notifier_->mock_network_change_notifier()
Zhongyi Shi4ac9e1f2018-06-21 05:21:478221 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri5b785512016-09-13 04:29:118222
zhongyi98d6a9262017-05-19 02:47:458223 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:518224 EXPECT_EQ(OK,
8225 request2.Request(
8226 host_port_pair_, version_.transport_version, privacy_mode_,
8227 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
8228 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8229 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:248230 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
jri5b785512016-09-13 04:29:118231 EXPECT_TRUE(stream2.get());
8232
8233 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi329f5cbd2018-06-22 23:51:188234 EXPECT_EQ(session, GetActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:118235
8236 stream.reset();
8237 stream2.reset();
8238
8239 EXPECT_TRUE(socket_data.AllReadDataConsumed());
8240 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
8241 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
8242 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
jri5b785512016-09-13 04:29:118243}
8244
Zhongyi Shic16b4102019-02-12 00:37:408245// This test verifies after session migrates off the default network, it keeps
8246// retrying migrate back to the default network until successfully gets on the
8247// default network or the idle migration period threshold is exceeded.
8248// The default threshold is 30s.
8249TEST_P(QuicStreamFactoryTest, DefaultIdleMigrationPeriod) {
Zhongyi Shi32fe14d42019-02-28 00:25:368250 test_params_.quic_migrate_idle_sessions = true;
Zhongyi Shic16b4102019-02-12 00:37:408251 InitializeConnectionMigrationV2Test(
8252 {kDefaultNetworkForTests, kNewNetworkForTests});
8253 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8254 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8255
8256 // Using a testing task runner and a test tick tock.
8257 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
8258 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
8259 QuicStreamFactoryPeer::SetTickClock(factory_.get(),
8260 task_runner->GetMockTickClock());
8261
Ryan Hamiltonabad59e2019-06-06 04:02:598262 MockQuicData default_socket_data(version_);
Zhongyi Shic16b4102019-02-12 00:37:408263 default_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
8264 default_socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
8265 default_socket_data.AddSocketDataToFactory(socket_factory_.get());
8266
8267 // Set up second socket data provider that is used after migration.
Ryan Hamiltonabad59e2019-06-06 04:02:598268 MockQuicData alternate_socket_data(version_);
Zhongyi Shic16b4102019-02-12 00:37:408269 alternate_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8270 // Ping packet to send after migration.
8271 alternate_socket_data.AddWrite(
8272 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
8273 alternate_socket_data.AddSocketDataToFactory(socket_factory_.get());
8274
8275 // Set up probing socket for migrating back to the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:598276 MockQuicData quic_data(version_); // retry count: 0.
Zhongyi Shic16b4102019-02-12 00:37:408277 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8278 quic_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8279 quic_data.AddSocketDataToFactory(socket_factory_.get());
8280
Ryan Hamiltonabad59e2019-06-06 04:02:598281 MockQuicData quic_data1(version_); // retry count: 1
Zhongyi Shic16b4102019-02-12 00:37:408282 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8283 quic_data1.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8284 quic_data1.AddSocketDataToFactory(socket_factory_.get());
8285
Ryan Hamilton0d65a8c2019-06-07 00:46:028286 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:598287 MockQuicData quic_data2(version_); // retry count: 2
Zhongyi Shic16b4102019-02-12 00:37:408288 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8289 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8290 quic_data2.AddSocketDataToFactory(socket_factory_.get());
8291
Ryan Hamilton0d65a8c2019-06-07 00:46:028292 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:598293 MockQuicData quic_data3(version_); // retry count: 3
Zhongyi Shic16b4102019-02-12 00:37:408294 quic_data3.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8295 quic_data3.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8296 quic_data3.AddSocketDataToFactory(socket_factory_.get());
8297
Ryan Hamilton0d65a8c2019-06-07 00:46:028298 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:598299 MockQuicData quic_data4(version_); // retry count: 4
Zhongyi Shic16b4102019-02-12 00:37:408300 quic_data4.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8301 quic_data4.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8302 quic_data4.AddSocketDataToFactory(socket_factory_.get());
8303
Ryan Hamilton0d65a8c2019-06-07 00:46:028304 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:598305 MockQuicData quic_data5(version_); // retry count: 5
Zhongyi Shic16b4102019-02-12 00:37:408306 quic_data5.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8307 quic_data5.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8308 quic_data5.AddSocketDataToFactory(socket_factory_.get());
8309
8310 // Create request and QuicHttpStream.
8311 QuicStreamRequest request(factory_.get());
8312 EXPECT_EQ(ERR_IO_PENDING,
8313 request.Request(
Nick Harper23290b82019-05-02 00:02:568314 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:518315 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shic16b4102019-02-12 00:37:408316 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8317 failed_on_default_network_callback_, callback_.callback()));
8318 EXPECT_THAT(callback_.WaitForResult(), IsOk());
8319 std::unique_ptr<HttpStream> stream = CreateStream(&request);
8320 EXPECT_TRUE(stream.get());
8321
8322 // Ensure that session is active.
8323 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8324
8325 // Trigger connection migration. Since there are no active streams,
8326 // the session will be closed.
8327 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8328 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
8329
8330 // The nearest task will complete migration.
8331 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
8332 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
8333 task_runner->FastForwardBy(base::TimeDelta());
8334
8335 // The migrate back timer will fire. Due to default network
8336 // being disconnected, no attempt will be exercised to migrate back.
8337 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
8338 EXPECT_EQ(base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs),
8339 task_runner->NextPendingTaskDelay());
8340 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
8341 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
8342
8343 // Deliver the signal that the old default network now backs up.
8344 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8345 ->NotifyNetworkMadeDefault(kDefaultNetworkForTests);
8346
8347 // A task is posted to migrate back to the default network immediately.
8348 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
8349 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
8350 task_runner->FastForwardBy(base::TimeDelta());
8351
8352 // Retry migrate back in 1, 2, 4, 8, 16s.
8353 // Session will be closed due to idle migration timeout.
8354 for (int i = 0; i < 5; i++) {
8355 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8356 // A task is posted to migrate back to the default network in 2^i seconds.
8357 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
8358 EXPECT_EQ(base::TimeDelta::FromSeconds(UINT64_C(1) << i),
8359 task_runner->NextPendingTaskDelay());
8360 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
8361 }
8362
8363 EXPECT_TRUE(default_socket_data.AllReadDataConsumed());
8364 EXPECT_TRUE(default_socket_data.AllWriteDataConsumed());
8365 EXPECT_TRUE(alternate_socket_data.AllReadDataConsumed());
8366 EXPECT_TRUE(alternate_socket_data.AllWriteDataConsumed());
8367}
8368
8369TEST_P(QuicStreamFactoryTest, CustomIdleMigrationPeriod) {
8370 // The customized threshold is 15s.
Zhongyi Shi32fe14d42019-02-28 00:25:368371 test_params_.quic_migrate_idle_sessions = true;
Zhongyi Shic16b4102019-02-12 00:37:408372 test_params_.quic_idle_session_migration_period =
8373 base::TimeDelta::FromSeconds(15);
8374 InitializeConnectionMigrationV2Test(
8375 {kDefaultNetworkForTests, kNewNetworkForTests});
8376 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8377 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8378
8379 // Using a testing task runner and a test tick tock.
8380 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
8381 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
8382 QuicStreamFactoryPeer::SetTickClock(factory_.get(),
8383 task_runner->GetMockTickClock());
8384
Ryan Hamiltonabad59e2019-06-06 04:02:598385 MockQuicData default_socket_data(version_);
Zhongyi Shic16b4102019-02-12 00:37:408386 default_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
8387 default_socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
8388 default_socket_data.AddSocketDataToFactory(socket_factory_.get());
8389
8390 // Set up second socket data provider that is used after migration.
Ryan Hamiltonabad59e2019-06-06 04:02:598391 MockQuicData alternate_socket_data(version_);
Zhongyi Shic16b4102019-02-12 00:37:408392 alternate_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8393 // Ping packet to send after migration.
8394 alternate_socket_data.AddWrite(
8395 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
8396 alternate_socket_data.AddSocketDataToFactory(socket_factory_.get());
8397
8398 // Set up probing socket for migrating back to the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:598399 MockQuicData quic_data(version_); // retry count: 0.
Zhongyi Shic16b4102019-02-12 00:37:408400 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8401 quic_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8402 quic_data.AddSocketDataToFactory(socket_factory_.get());
8403
Ryan Hamilton0d65a8c2019-06-07 00:46:028404 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:598405 MockQuicData quic_data1(version_); // retry count: 1
Zhongyi Shic16b4102019-02-12 00:37:408406 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8407 quic_data1.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8408 quic_data1.AddSocketDataToFactory(socket_factory_.get());
8409
Ryan Hamilton0d65a8c2019-06-07 00:46:028410 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:598411 MockQuicData quic_data2(version_); // retry count: 2
Zhongyi Shic16b4102019-02-12 00:37:408412 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8413 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8414 quic_data2.AddSocketDataToFactory(socket_factory_.get());
8415
Ryan Hamilton0d65a8c2019-06-07 00:46:028416 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:598417 MockQuicData quic_data3(version_); // retry count: 3
Zhongyi Shic16b4102019-02-12 00:37:408418 quic_data3.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8419 quic_data3.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8420 quic_data3.AddSocketDataToFactory(socket_factory_.get());
8421
Ryan Hamilton0d65a8c2019-06-07 00:46:028422 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:598423 MockQuicData quic_data4(version_); // retry count: 4
Zhongyi Shic16b4102019-02-12 00:37:408424 quic_data4.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8425 quic_data4.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8426 quic_data4.AddSocketDataToFactory(socket_factory_.get());
8427
8428 // Create request and QuicHttpStream.
8429 QuicStreamRequest request(factory_.get());
8430 EXPECT_EQ(ERR_IO_PENDING,
8431 request.Request(
Nick Harper23290b82019-05-02 00:02:568432 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:518433 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shic16b4102019-02-12 00:37:408434 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8435 failed_on_default_network_callback_, callback_.callback()));
8436 EXPECT_THAT(callback_.WaitForResult(), IsOk());
8437 std::unique_ptr<HttpStream> stream = CreateStream(&request);
8438 EXPECT_TRUE(stream.get());
8439
8440 // Ensure that session is active.
8441 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8442
8443 // Trigger connection migration. Since there are no active streams,
8444 // the session will be closed.
8445 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8446 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
8447
8448 // The nearest task will complete migration.
8449 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
8450 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
8451 task_runner->FastForwardBy(base::TimeDelta());
8452
8453 // The migrate back timer will fire. Due to default network
8454 // being disconnected, no attempt will be exercised to migrate back.
8455 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
8456 EXPECT_EQ(base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs),
8457 task_runner->NextPendingTaskDelay());
8458 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
8459 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
8460
8461 // Deliver the signal that the old default network now backs up.
8462 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8463 ->NotifyNetworkMadeDefault(kDefaultNetworkForTests);
8464
8465 // A task is posted to migrate back to the default network immediately.
8466 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
8467 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
8468 task_runner->FastForwardBy(base::TimeDelta());
8469
8470 // Retry migrate back in 1, 2, 4, 8s.
8471 // Session will be closed due to idle migration timeout.
8472 for (int i = 0; i < 4; i++) {
8473 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8474 // A task is posted to migrate back to the default network in 2^i seconds.
8475 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
8476 EXPECT_EQ(base::TimeDelta::FromSeconds(UINT64_C(1) << i),
8477 task_runner->NextPendingTaskDelay());
8478 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
8479 }
8480
8481 EXPECT_TRUE(default_socket_data.AllReadDataConsumed());
8482 EXPECT_TRUE(default_socket_data.AllWriteDataConsumed());
8483 EXPECT_TRUE(alternate_socket_data.AllReadDataConsumed());
8484 EXPECT_TRUE(alternate_socket_data.AllWriteDataConsumed());
8485}
8486
jri217455a12016-07-13 20:15:098487TEST_P(QuicStreamFactoryTest, ServerMigration) {
Zhongyi Shi967d2f12019-02-08 20:58:538488 test_params_.quic_allow_server_migration = true;
jri217455a12016-07-13 20:15:098489 Initialize();
8490
8491 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8492 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8493 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8494
Ryan Hamiltonabad59e2019-06-06 04:02:598495 MockQuicData socket_data1(version_);
rcha00569732016-08-27 11:09:368496 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:028497 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
rch5cb522462017-04-25 20:18:368498 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:028499 SYNCHRONOUS,
8500 ConstructGetRequestPacket(
8501 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi5f587cc2017-11-21 23:24:178502 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri217455a12016-07-13 20:15:098503
8504 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:458505 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338506 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:038507 request.Request(
Nick Harper23290b82019-05-02 00:02:568508 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:518509 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:038510 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8511 failed_on_default_network_callback_, callback_.callback()));
jri217455a12016-07-13 20:15:098512 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:248513 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri217455a12016-07-13 20:15:098514 EXPECT_TRUE(stream.get());
8515
8516 // Cause QUIC stream to be created.
8517 HttpRequestInfo request_info;
8518 request_info.method = "GET";
8519 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:398520 request_info.traffic_annotation =
8521 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:278522 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:398523 net_log_, CompletionOnceCallback()));
jri217455a12016-07-13 20:15:098524
8525 // Ensure that session is alive and active.
8526 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
8527 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8528 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8529
8530 // Send GET request on stream.
8531 HttpResponseInfo response;
8532 HttpRequestHeaders request_headers;
8533 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
8534 callback_.callback()));
8535
8536 IPEndPoint ip;
8537 session->GetDefaultSocket()->GetPeerAddress(&ip);
8538 DVLOG(1) << "Socket connected to: " << ip.address().ToString() << " "
8539 << ip.port();
8540
8541 // Set up second socket data provider that is used after
8542 // migration. The request is rewritten to this new socket, and the
8543 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:598544 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:368545 socket_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438546 SYNCHRONOUS, client_maker_.MakePingPacket(3, /*include_version=*/true));
8547 socket_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:338548 ASYNC,
8549 ConstructOkResponsePacket(
8550 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
rcha00569732016-08-27 11:09:368551 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:338552 socket_data2.AddWrite(
8553 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
8554 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
8555 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:178556 socket_data2.AddSocketDataToFactory(socket_factory_.get());
jri217455a12016-07-13 20:15:098557
8558 const uint8_t kTestIpAddress[] = {1, 2, 3, 4};
8559 const uint16_t kTestPort = 123;
Zhongyi Shif124a582017-11-02 00:15:048560 session->Migrate(NetworkChangeNotifier::kInvalidNetworkHandle,
8561 IPEndPoint(IPAddress(kTestIpAddress), kTestPort), true,
8562 net_log_);
jri217455a12016-07-13 20:15:098563
8564 session->GetDefaultSocket()->GetPeerAddress(&ip);
8565 DVLOG(1) << "Socket migrated to: " << ip.address().ToString() << " "
8566 << ip.port();
8567
8568 // The session should be alive and active.
8569 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8570 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8571 EXPECT_EQ(1u, session->GetNumActiveStreams());
8572
8573 // Run the message loop so that data queued in the new socket is read by the
8574 // packet reader.
8575 base::RunLoop().RunUntilIdle();
8576
8577 // Verify that response headers on the migrated socket were delivered to the
8578 // stream.
8579 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
8580 EXPECT_EQ(200, response.headers->response_code());
8581
8582 stream.reset();
8583
8584 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
8585 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
8586 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
8587 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
8588}
8589
jri053fdbd2016-08-19 02:33:058590TEST_P(QuicStreamFactoryTest, ServerMigrationIPv4ToIPv4) {
8591 // Add alternate IPv4 server address to config.
8592 IPEndPoint alt_address = IPEndPoint(IPAddress(1, 2, 3, 4), 123);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528593 quic::QuicConfig config;
Victor Vasiliev4f6fb892019-05-31 16:58:318594 config.SetAlternateServerAddressToSend(ToQuicSocketAddress(alt_address));
jri053fdbd2016-08-19 02:33:058595 VerifyServerMigration(config, alt_address);
8596}
8597
8598TEST_P(QuicStreamFactoryTest, ServerMigrationIPv6ToIPv6) {
8599 // Add a resolver rule to make initial connection to an IPv6 address.
Renjiea0cb4a2c2018-09-26 23:37:308600 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
8601 "fe80::aebc:32ff:febb:1e33", "");
jri053fdbd2016-08-19 02:33:058602 // Add alternate IPv6 server address to config.
8603 IPEndPoint alt_address = IPEndPoint(
8604 IPAddress(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), 123);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528605 quic::QuicConfig config;
Victor Vasiliev4f6fb892019-05-31 16:58:318606 config.SetAlternateServerAddressToSend(ToQuicSocketAddress(alt_address));
jri053fdbd2016-08-19 02:33:058607 VerifyServerMigration(config, alt_address);
8608}
8609
8610TEST_P(QuicStreamFactoryTest, ServerMigrationIPv6ToIPv4) {
8611 // Add a resolver rule to make initial connection to an IPv6 address.
Renjiea0cb4a2c2018-09-26 23:37:308612 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
8613 "fe80::aebc:32ff:febb:1e33", "");
jri053fdbd2016-08-19 02:33:058614 // Add alternate IPv4 server address to config.
8615 IPEndPoint alt_address = IPEndPoint(IPAddress(1, 2, 3, 4), 123);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528616 quic::QuicConfig config;
Victor Vasiliev4f6fb892019-05-31 16:58:318617 config.SetAlternateServerAddressToSend(ToQuicSocketAddress(alt_address));
jri053fdbd2016-08-19 02:33:058618 IPEndPoint expected_address(
8619 ConvertIPv4ToIPv4MappedIPv6(alt_address.address()), alt_address.port());
8620 VerifyServerMigration(config, expected_address);
8621}
8622
8623TEST_P(QuicStreamFactoryTest, ServerMigrationIPv4ToIPv6Fails) {
Zhongyi Shi967d2f12019-02-08 20:58:538624 test_params_.quic_allow_server_migration = true;
jri053fdbd2016-08-19 02:33:058625 Initialize();
8626
8627 // Add a resolver rule to make initial connection to an IPv4 address.
Renjiea0cb4a2c2018-09-26 23:37:308628 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), "1.2.3.4",
8629 "");
jri053fdbd2016-08-19 02:33:058630 // Add alternate IPv6 server address to config.
8631 IPEndPoint alt_address = IPEndPoint(
8632 IPAddress(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), 123);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528633 quic::QuicConfig config;
Victor Vasiliev4f6fb892019-05-31 16:58:318634 config.SetAlternateServerAddressToSend(ToQuicSocketAddress(alt_address));
jri053fdbd2016-08-19 02:33:058635
8636 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8637 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8638 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8639
8640 crypto_client_stream_factory_.SetConfig(config);
8641
8642 // Set up only socket data provider.
Ryan Hamiltonabad59e2019-06-06 04:02:598643 MockQuicData socket_data1(version_);
rcha00569732016-08-27 11:09:368644 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:438645 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
8646 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338647 SYNCHRONOUS, client_maker_.MakeRstPacket(
8648 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
8649 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:178650 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri053fdbd2016-08-19 02:33:058651
8652 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:458653 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338654 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:038655 request.Request(
Nick Harper23290b82019-05-02 00:02:568656 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:518657 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:038658 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8659 failed_on_default_network_callback_, callback_.callback()));
jri053fdbd2016-08-19 02:33:058660 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:248661 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri053fdbd2016-08-19 02:33:058662 EXPECT_TRUE(stream.get());
8663
8664 // Cause QUIC stream to be created.
8665 HttpRequestInfo request_info;
8666 request_info.method = "GET";
8667 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:398668 request_info.traffic_annotation =
8669 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:278670 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:398671 net_log_, CompletionOnceCallback()));
jri053fdbd2016-08-19 02:33:058672
8673 // Ensure that session is alive and active.
8674 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
8675 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8676 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8677
8678 IPEndPoint actual_address;
8679 session->GetDefaultSocket()->GetPeerAddress(&actual_address);
8680 // No migration should have happened.
8681 IPEndPoint expected_address =
8682 IPEndPoint(IPAddress(1, 2, 3, 4), kDefaultServerPort);
8683 EXPECT_EQ(actual_address, expected_address);
8684 DVLOG(1) << "Socket connected to: " << actual_address.address().ToString()
8685 << " " << actual_address.port();
8686 DVLOG(1) << "Expected address: " << expected_address.address().ToString()
8687 << " " << expected_address.port();
8688
8689 stream.reset();
8690 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
8691 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
8692}
8693
rsleevi17784692016-10-12 01:36:208694TEST_P(QuicStreamFactoryTest, OnCertDBChanged) {
jri7046038f2015-10-22 00:29:268695 Initialize();
rch6faa4d42016-01-05 20:48:438696 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8697 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8698 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8699
Ryan Hamiltonabad59e2019-06-06 04:02:598700 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:368701 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:438702 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:178703 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]d7d1e50b2013-11-25 22:08:098704
Ryan Hamilton0d65a8c2019-06-07 00:46:028705 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:598706 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:368707 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:028708 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:178709 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]d7d1e50b2013-11-25 22:08:098710
zhongyi98d6a9262017-05-19 02:47:458711 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338712 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:038713 request.Request(
Nick Harper23290b82019-05-02 00:02:568714 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:518715 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:038716 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8717 failed_on_default_network_callback_, callback_.callback()));
[email protected]d7d1e50b2013-11-25 22:08:098718
robpercival214763f2016-07-01 23:27:018719 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:248720 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Charles 'Buck' Krasic71763c9f2018-02-16 02:37:288721 EXPECT_TRUE(stream);
8722 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
[email protected]d7d1e50b2013-11-25 22:08:098723
8724 // Change the CA cert and verify that stream saw the event.
mattmfd05a1f2017-02-18 06:18:448725 factory_->OnCertDBChanged();
Charles 'Buck' Krasic71763c9f2018-02-16 02:37:288726
jri7046038f2015-10-22 00:29:268727 EXPECT_FALSE(factory_->require_confirmation());
Charles 'Buck' Krasic71763c9f2018-02-16 02:37:288728 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8729 EXPECT_FALSE(HasActiveSession(host_port_pair_));
[email protected]d7d1e50b2013-11-25 22:08:098730
8731 // Now attempting to request a stream to the same origin should create
8732 // a new session.
8733
zhongyi98d6a9262017-05-19 02:47:458734 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338735 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:038736 request2.Request(
Nick Harper23290b82019-05-02 00:02:568737 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:518738 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:038739 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8740 failed_on_default_network_callback_, callback_.callback()));
[email protected]d7d1e50b2013-11-25 22:08:098741
robpercival214763f2016-07-01 23:27:018742 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Charles 'Buck' Krasic71763c9f2018-02-16 02:37:288743 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
8744 EXPECT_TRUE(stream2);
8745 QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
8746 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8747 EXPECT_NE(session, session2);
8748 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8749 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
8750
8751 stream2.reset();
8752 stream.reset();
[email protected]d7d1e50b2013-11-25 22:08:098753
rch37de576c2015-05-17 20:28:178754 EXPECT_TRUE(socket_data.AllReadDataConsumed());
8755 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
8756 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
8757 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]d7d1e50b2013-11-25 22:08:098758}
8759
[email protected]1e960032013-12-20 19:00:208760TEST_P(QuicStreamFactoryTest, SharedCryptoConfig) {
jri7046038f2015-10-22 00:29:268761 Initialize();
rch6faa4d42016-01-05 20:48:438762
rch872e00e2016-12-02 02:48:188763 std::vector<string> cannoncial_suffixes;
[email protected]6e12d702013-11-13 00:17:178764 cannoncial_suffixes.push_back(string(".c.youtube.com"));
8765 cannoncial_suffixes.push_back(string(".googlevideo.com"));
[email protected]c49ff182013-09-28 08:33:268766
[email protected]6e12d702013-11-13 00:17:178767 for (unsigned i = 0; i < cannoncial_suffixes.size(); ++i) {
8768 string r1_host_name("r1");
8769 string r2_host_name("r2");
8770 r1_host_name.append(cannoncial_suffixes[i]);
8771 r2_host_name.append(cannoncial_suffixes[i]);
[email protected]b70fdb792013-10-25 19:04:148772
[email protected]bf4ea2f2014-03-10 22:57:538773 HostPortPair host_port_pair1(r1_host_name, 80);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528774 quic::QuicCryptoClientConfig* crypto_config =
jri7046038f2015-10-22 00:29:268775 QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
Ryan Hamilton4f0b26e2018-06-27 23:52:328776 quic::QuicServerId server_id1(host_port_pair1.host(),
8777 host_port_pair1.port(), privacy_mode_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528778 quic::QuicCryptoClientConfig::CachedState* cached1 =
[email protected]257f24f2014-04-01 09:15:378779 crypto_config->LookupOrCreate(server_id1);
[email protected]6e12d702013-11-13 00:17:178780 EXPECT_FALSE(cached1->proof_valid());
8781 EXPECT_TRUE(cached1->source_address_token().empty());
8782
8783 // Mutate the cached1 to have different data.
8784 // TODO(rtenneti): mutate other members of CachedState.
8785 cached1->set_source_address_token(r1_host_name);
8786 cached1->SetProofValid();
8787
[email protected]bf4ea2f2014-03-10 22:57:538788 HostPortPair host_port_pair2(r2_host_name, 80);
Ryan Hamilton4f0b26e2018-06-27 23:52:328789 quic::QuicServerId server_id2(host_port_pair2.host(),
8790 host_port_pair2.port(), privacy_mode_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528791 quic::QuicCryptoClientConfig::CachedState* cached2 =
[email protected]257f24f2014-04-01 09:15:378792 crypto_config->LookupOrCreate(server_id2);
[email protected]6e12d702013-11-13 00:17:178793 EXPECT_EQ(cached1->source_address_token(), cached2->source_address_token());
8794 EXPECT_TRUE(cached2->proof_valid());
8795 }
[email protected]b70fdb792013-10-25 19:04:148796}
8797
[email protected]1e960032013-12-20 19:00:208798TEST_P(QuicStreamFactoryTest, CryptoConfigWhenProofIsInvalid) {
jri7046038f2015-10-22 00:29:268799 Initialize();
rch872e00e2016-12-02 02:48:188800 std::vector<string> cannoncial_suffixes;
[email protected]6e12d702013-11-13 00:17:178801 cannoncial_suffixes.push_back(string(".c.youtube.com"));
8802 cannoncial_suffixes.push_back(string(".googlevideo.com"));
[email protected]b70fdb792013-10-25 19:04:148803
[email protected]6e12d702013-11-13 00:17:178804 for (unsigned i = 0; i < cannoncial_suffixes.size(); ++i) {
8805 string r3_host_name("r3");
8806 string r4_host_name("r4");
8807 r3_host_name.append(cannoncial_suffixes[i]);
8808 r4_host_name.append(cannoncial_suffixes[i]);
[email protected]b70fdb792013-10-25 19:04:148809
[email protected]bf4ea2f2014-03-10 22:57:538810 HostPortPair host_port_pair1(r3_host_name, 80);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528811 quic::QuicCryptoClientConfig* crypto_config =
jri7046038f2015-10-22 00:29:268812 QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
Ryan Hamilton4f0b26e2018-06-27 23:52:328813 quic::QuicServerId server_id1(host_port_pair1.host(),
8814 host_port_pair1.port(), privacy_mode_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528815 quic::QuicCryptoClientConfig::CachedState* cached1 =
[email protected]257f24f2014-04-01 09:15:378816 crypto_config->LookupOrCreate(server_id1);
[email protected]6e12d702013-11-13 00:17:178817 EXPECT_FALSE(cached1->proof_valid());
8818 EXPECT_TRUE(cached1->source_address_token().empty());
8819
8820 // Mutate the cached1 to have different data.
8821 // TODO(rtenneti): mutate other members of CachedState.
8822 cached1->set_source_address_token(r3_host_name);
8823 cached1->SetProofInvalid();
8824
[email protected]bf4ea2f2014-03-10 22:57:538825 HostPortPair host_port_pair2(r4_host_name, 80);
Ryan Hamilton4f0b26e2018-06-27 23:52:328826 quic::QuicServerId server_id2(host_port_pair2.host(),
8827 host_port_pair2.port(), privacy_mode_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528828 quic::QuicCryptoClientConfig::CachedState* cached2 =
[email protected]257f24f2014-04-01 09:15:378829 crypto_config->LookupOrCreate(server_id2);
[email protected]6e12d702013-11-13 00:17:178830 EXPECT_NE(cached1->source_address_token(), cached2->source_address_token());
8831 EXPECT_TRUE(cached2->source_address_token().empty());
8832 EXPECT_FALSE(cached2->proof_valid());
8833 }
[email protected]c49ff182013-09-28 08:33:268834}
8835
rtenneti34dffe752015-02-24 23:27:328836TEST_P(QuicStreamFactoryTest, EnableNotLoadFromDiskCache) {
jri7046038f2015-10-22 00:29:268837 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:208838 factory_->set_require_confirmation(false);
rch6faa4d42016-01-05 20:48:438839 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8840 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8841
jri7046038f2015-10-22 00:29:268842 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
rtenneti34dffe752015-02-24 23:27:328843
Ryan Hamiltonabad59e2019-06-06 04:02:598844 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:368845 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:178846 socket_data.AddSocketDataToFactory(socket_factory_.get());
rtenneti34dffe752015-02-24 23:27:328847
8848 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:278849 MockCryptoClientStream::ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:308850 host_resolver_->set_synchronous_mode(true);
8851 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
8852 "192.168.0.1", "");
rtenneti34dffe752015-02-24 23:27:328853
zhongyi98d6a9262017-05-19 02:47:458854 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:518855 EXPECT_EQ(OK,
8856 request.Request(
8857 host_port_pair_, version_.transport_version, privacy_mode_,
8858 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
8859 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8860 failed_on_default_network_callback_, callback_.callback()));
rtenneti34dffe752015-02-24 23:27:328861
8862 // If we are waiting for disk cache, we would have posted a task. Verify that
8863 // the CancelWaitForDataReady task hasn't been posted.
8864 ASSERT_EQ(0u, runner_->GetPostedTasks().size());
8865
Yixin Wang7891a39d2017-11-08 20:59:248866 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rtenneti34dffe752015-02-24 23:27:328867 EXPECT_TRUE(stream.get());
rch37de576c2015-05-17 20:28:178868 EXPECT_TRUE(socket_data.AllReadDataConsumed());
8869 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
rtenneti34dffe752015-02-24 23:27:328870}
8871
dmurph44ca4f42016-09-09 20:39:098872TEST_P(QuicStreamFactoryTest, ReducePingTimeoutOnConnectionTimeOutOpenStreams) {
Zhongyi Shi967d2f12019-02-08 20:58:538873 test_params_.quic_reduced_ping_timeout_seconds = 10;
dmurph44ca4f42016-09-09 20:39:098874 Initialize();
8875 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8876 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8877 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8878
8879 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
zhongyidd1439f62016-09-02 02:02:268880
Ryan Hamiltonabad59e2019-06-06 04:02:598881 MockQuicData socket_data(version_);
zhongyidd1439f62016-09-02 02:02:268882 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:438883 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:178884 socket_data.AddSocketDataToFactory(socket_factory_.get());
zhongyidd1439f62016-09-02 02:02:268885
Ryan Hamilton0d65a8c2019-06-07 00:46:028886 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:598887 MockQuicData socket_data2(version_);
zhongyidd1439f62016-09-02 02:02:268888 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:028889 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:178890 socket_data2.AddSocketDataToFactory(socket_factory_.get());
zhongyidd1439f62016-09-02 02:02:268891
8892 HostPortPair server2(kServer2HostName, kDefaultServerPort);
8893
8894 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:278895 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Renjiea0cb4a2c2018-09-26 23:37:308896 host_resolver_->set_synchronous_mode(true);
8897 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
8898 "192.168.0.1", "");
8899 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
zhongyidd1439f62016-09-02 02:02:268900
8901 // Quic should use default PING timeout when no previous connection times out
8902 // with open stream.
Ryan Hamilton8d9ee76e2018-05-29 23:52:528903 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(quic::kPingTimeoutSecs),
zhongyidd1439f62016-09-02 02:02:268904 QuicStreamFactoryPeer::GetPingTimeout(factory_.get()));
zhongyi98d6a9262017-05-19 02:47:458905 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:518906 EXPECT_EQ(OK,
8907 request.Request(
8908 host_port_pair_, version_.transport_version, privacy_mode_,
8909 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
8910 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8911 failed_on_default_network_callback_, callback_.callback()));
zhongyidd1439f62016-09-02 02:02:268912
8913 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528914 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(quic::kPingTimeoutSecs),
zhongyidd1439f62016-09-02 02:02:268915 session->connection()->ping_timeout());
8916
Yixin Wang7891a39d2017-11-08 20:59:248917 std::unique_ptr<HttpStream> stream = CreateStream(&request);
zhongyidd1439f62016-09-02 02:02:268918 EXPECT_TRUE(stream.get());
8919 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:398920 request_info.traffic_annotation =
8921 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:278922 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:398923 net_log_, CompletionOnceCallback()));
zhongyidd1439f62016-09-02 02:02:268924
8925 DVLOG(1)
8926 << "Created 1st session and initialized a stream. Now trigger timeout";
Ryan Hamilton8d9ee76e2018-05-29 23:52:528927 session->connection()->CloseConnection(
8928 quic::QUIC_NETWORK_IDLE_TIMEOUT, "test",
8929 quic::ConnectionCloseBehavior::SILENT_CLOSE);
zhongyidd1439f62016-09-02 02:02:268930 // Need to spin the loop now to ensure that
8931 // QuicStreamFactory::OnSessionClosed() runs.
8932 base::RunLoop run_loop;
8933 run_loop.RunUntilIdle();
8934
zhongyidd1439f62016-09-02 02:02:268935 // The first connection times out with open stream, QUIC should reduce initial
8936 // PING time for subsequent connections.
Ryan Hamilton8d9ee76e2018-05-29 23:52:528937 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(10),
zhongyidd1439f62016-09-02 02:02:268938 QuicStreamFactoryPeer::GetPingTimeout(factory_.get()));
8939
8940 // Test two-in-a-row timeouts with open streams.
8941 DVLOG(1) << "Create 2nd session and timeout with open stream";
8942 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:458943 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:518944 EXPECT_EQ(OK,
8945 request2.Request(
8946 server2, version_.transport_version, privacy_mode_,
8947 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
8948 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
8949 failed_on_default_network_callback_, callback2.callback()));
zhongyidd1439f62016-09-02 02:02:268950 QuicChromiumClientSession* session2 = GetActiveSession(server2);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528951 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(10),
zhongyidd1439f62016-09-02 02:02:268952 session2->connection()->ping_timeout());
8953
Yixin Wang7891a39d2017-11-08 20:59:248954 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
zhongyidd1439f62016-09-02 02:02:268955 EXPECT_TRUE(stream2.get());
Steven Valdezb4ff0412018-01-18 22:39:278956 EXPECT_EQ(OK,
8957 stream2->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:398958 net_log_, CompletionOnceCallback()));
zhongyidd1439f62016-09-02 02:02:268959 session2->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:528960 quic::QUIC_NETWORK_IDLE_TIMEOUT, "test",
8961 quic::ConnectionCloseBehavior::SILENT_CLOSE);
zhongyidd1439f62016-09-02 02:02:268962 // Need to spin the loop now to ensure that
8963 // QuicStreamFactory::OnSessionClosed() runs.
8964 base::RunLoop run_loop2;
8965 run_loop2.RunUntilIdle();
zhongyidd1439f62016-09-02 02:02:268966
8967 EXPECT_TRUE(socket_data.AllReadDataConsumed());
8968 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
8969 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
8970 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
8971}
8972
tbansal3b966952016-10-25 23:25:148973// Verifies that the QUIC stream factory is initialized correctly.
rtenneticd2aaa15b2015-10-10 20:29:338974TEST_P(QuicStreamFactoryTest, MaybeInitialize) {
tbansal9b1cdf32017-05-10 17:28:398975 VerifyInitialization();
rtenneti8a80a6dc2015-09-21 19:51:138976}
8977
rtennetid073dd22016-08-04 01:58:338978TEST_P(QuicStreamFactoryTest, StartCertVerifyJob) {
8979 Initialize();
8980
Ryan Hamiltonabad59e2019-06-06 04:02:598981 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:368982 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:438983 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:178984 socket_data.AddSocketDataToFactory(socket_factory_.get());
rtennetid073dd22016-08-04 01:58:338985
8986 // Save current state of |race_cert_verification|.
8987 bool race_cert_verification =
8988 QuicStreamFactoryPeer::GetRaceCertVerification(factory_.get());
8989
8990 // Load server config.
8991 HostPortPair host_port_pair(kDefaultServerHostName, kDefaultServerPort);
Ryan Hamilton4f0b26e2018-06-27 23:52:328992 quic::QuicServerId quic_server_id(host_port_pair_.host(),
8993 host_port_pair_.port(),
8994 privacy_mode_ == PRIVACY_MODE_ENABLED);
rtennetid073dd22016-08-04 01:58:338995 QuicStreamFactoryPeer::CacheDummyServerConfig(factory_.get(), quic_server_id);
8996
8997 QuicStreamFactoryPeer::SetRaceCertVerification(factory_.get(), true);
8998 EXPECT_FALSE(HasActiveCertVerifierJob(quic_server_id));
8999
9000 // Start CertVerifyJob.
Ryan Hamilton8d9ee76e2018-05-29 23:52:529001 quic::QuicAsyncStatus status = QuicStreamFactoryPeer::StartCertVerifyJob(
rtennetid073dd22016-08-04 01:58:339002 factory_.get(), quic_server_id, /*cert_verify_flags=*/0, net_log_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:529003 if (status == quic::QUIC_PENDING) {
rtennetid073dd22016-08-04 01:58:339004 // Verify CertVerifierJob has started.
9005 EXPECT_TRUE(HasActiveCertVerifierJob(quic_server_id));
9006
9007 while (HasActiveCertVerifierJob(quic_server_id)) {
9008 base::RunLoop().RunUntilIdle();
9009 }
9010 }
9011 // Verify CertVerifierJob has finished.
9012 EXPECT_FALSE(HasActiveCertVerifierJob(quic_server_id));
9013
9014 // Start a QUIC request.
zhongyi98d6a9262017-05-19 02:47:459015 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339016 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039017 request.Request(
Nick Harper23290b82019-05-02 00:02:569018 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:519019 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039020 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9021 failed_on_default_network_callback_, callback_.callback()));
rtennetid073dd22016-08-04 01:58:339022
9023 EXPECT_EQ(OK, callback_.WaitForResult());
9024
Yixin Wang7891a39d2017-11-08 20:59:249025 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rtennetid073dd22016-08-04 01:58:339026 EXPECT_TRUE(stream.get());
9027
9028 // Restore |race_cert_verification|.
9029 QuicStreamFactoryPeer::SetRaceCertVerification(factory_.get(),
9030 race_cert_verification);
9031
9032 EXPECT_TRUE(socket_data.AllReadDataConsumed());
9033 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
9034
9035 // Verify there are no outstanding CertVerifierJobs after request has
9036 // finished.
9037 EXPECT_FALSE(HasActiveCertVerifierJob(quic_server_id));
9038}
9039
rtenneti1cd3b162015-09-29 02:58:289040TEST_P(QuicStreamFactoryTest, YieldAfterPackets) {
jri7046038f2015-10-22 00:29:269041 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:209042 factory_->set_require_confirmation(false);
rch6faa4d42016-01-05 20:48:439043 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9044 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:269045 QuicStreamFactoryPeer::SetYieldAfterPackets(factory_.get(), 0);
rtenneti1cd3b162015-09-29 02:58:289046
Ryan Hamiltonabad59e2019-06-06 04:02:599047 MockQuicData socket_data(version_);
Fan Yangac867502019-01-28 21:10:239048 socket_data.AddRead(SYNCHRONOUS, ConstructClientConnectionClosePacket(1));
rcha00569732016-08-27 11:09:369049 socket_data.AddRead(ASYNC, OK);
Zhongyi Shi5f587cc2017-11-21 23:24:179050 socket_data.AddSocketDataToFactory(socket_factory_.get());
rtenneti1cd3b162015-09-29 02:58:289051
9052 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:279053 MockCryptoClientStream::ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:309054 host_resolver_->set_synchronous_mode(true);
9055 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
9056 "192.168.0.1", "");
rtenneti1cd3b162015-09-29 02:58:289057
rcha02807b42016-01-29 21:56:159058 // Set up the TaskObserver to verify QuicChromiumPacketReader::StartReading
9059 // posts a task.
rtenneti1cd3b162015-09-29 02:58:289060 // TODO(rtenneti): Change SpdySessionTestTaskObserver to NetTestTaskObserver??
rcha02807b42016-01-29 21:56:159061 SpdySessionTestTaskObserver observer("quic_chromium_packet_reader.cc",
9062 "StartReading");
rtenneti1cd3b162015-09-29 02:58:289063
zhongyi98d6a9262017-05-19 02:47:459064 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:519065 EXPECT_EQ(OK,
9066 request.Request(
9067 host_port_pair_, version_.transport_version, privacy_mode_,
9068 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
9069 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9070 failed_on_default_network_callback_, callback_.callback()));
rtenneti1cd3b162015-09-29 02:58:289071
rcha02807b42016-01-29 21:56:159072 // Call run_loop so that QuicChromiumPacketReader::OnReadComplete() gets
9073 // called.
rtenneti1cd3b162015-09-29 02:58:289074 base::RunLoop run_loop;
9075 run_loop.RunUntilIdle();
9076
9077 // Verify task that the observer's executed_count is 1, which indicates
rcha02807b42016-01-29 21:56:159078 // QuicChromiumPacketReader::StartReading() has posted only one task and
9079 // yielded the read.
rtenneti1cd3b162015-09-29 02:58:289080 EXPECT_EQ(1u, observer.executed_count());
9081
Yixin Wang7891a39d2017-11-08 20:59:249082 std::unique_ptr<HttpStream> stream = CreateStream(&request);
xunjieli2608f9b2016-03-14 13:39:239083 EXPECT_FALSE(stream.get()); // Session is already closed.
rtenneti1cd3b162015-09-29 02:58:289084 EXPECT_TRUE(socket_data.AllReadDataConsumed());
9085 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
9086}
9087
9088TEST_P(QuicStreamFactoryTest, YieldAfterDuration) {
jri7046038f2015-10-22 00:29:269089 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:209090 factory_->set_require_confirmation(false);
rch6faa4d42016-01-05 20:48:439091 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9092 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rtenneti1cd3b162015-09-29 02:58:289093 QuicStreamFactoryPeer::SetYieldAfterDuration(
Ryan Hamilton8d9ee76e2018-05-29 23:52:529094 factory_.get(), quic::QuicTime::Delta::FromMilliseconds(-1));
rtenneti1cd3b162015-09-29 02:58:289095
Ryan Hamiltonabad59e2019-06-06 04:02:599096 MockQuicData socket_data(version_);
Fan Yangac867502019-01-28 21:10:239097 socket_data.AddRead(SYNCHRONOUS, ConstructClientConnectionClosePacket(1));
rcha00569732016-08-27 11:09:369098 socket_data.AddRead(ASYNC, OK);
Zhongyi Shi5f587cc2017-11-21 23:24:179099 socket_data.AddSocketDataToFactory(socket_factory_.get());
rtenneti1cd3b162015-09-29 02:58:289100
9101 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:279102 MockCryptoClientStream::ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:309103 host_resolver_->set_synchronous_mode(true);
9104 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
9105 "192.168.0.1", "");
rtenneti1cd3b162015-09-29 02:58:289106
rcha02807b42016-01-29 21:56:159107 // Set up the TaskObserver to verify QuicChromiumPacketReader::StartReading
9108 // posts a task.
rtenneti1cd3b162015-09-29 02:58:289109 // TODO(rtenneti): Change SpdySessionTestTaskObserver to NetTestTaskObserver??
rcha02807b42016-01-29 21:56:159110 SpdySessionTestTaskObserver observer("quic_chromium_packet_reader.cc",
9111 "StartReading");
rtenneti1cd3b162015-09-29 02:58:289112
zhongyi98d6a9262017-05-19 02:47:459113 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:519114 EXPECT_EQ(OK,
9115 request.Request(
9116 host_port_pair_, version_.transport_version, privacy_mode_,
9117 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
9118 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9119 failed_on_default_network_callback_, callback_.callback()));
rtenneti1cd3b162015-09-29 02:58:289120
rcha02807b42016-01-29 21:56:159121 // Call run_loop so that QuicChromiumPacketReader::OnReadComplete() gets
9122 // called.
rtenneti1cd3b162015-09-29 02:58:289123 base::RunLoop run_loop;
9124 run_loop.RunUntilIdle();
9125
9126 // Verify task that the observer's executed_count is 1, which indicates
rcha02807b42016-01-29 21:56:159127 // QuicChromiumPacketReader::StartReading() has posted only one task and
9128 // yielded the read.
rtenneti1cd3b162015-09-29 02:58:289129 EXPECT_EQ(1u, observer.executed_count());
9130
Yixin Wang7891a39d2017-11-08 20:59:249131 std::unique_ptr<HttpStream> stream = CreateStream(&request);
xunjieli2608f9b2016-03-14 13:39:239132 EXPECT_FALSE(stream.get()); // Session is already closed.
rtenneti1cd3b162015-09-29 02:58:289133 EXPECT_TRUE(socket_data.AllReadDataConsumed());
9134 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
9135}
9136
ckrasic3865ee0f2016-02-29 22:04:569137TEST_P(QuicStreamFactoryTest, ServerPushSessionAffinity) {
9138 Initialize();
9139 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9140 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9141
Ryan Hamiltonabad59e2019-06-06 04:02:599142 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:369143 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:439144 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:179145 socket_data.AddSocketDataToFactory(socket_factory_.get());
ckrasic3865ee0f2016-02-29 22:04:569146
zhongyi98d6a9262017-05-19 02:47:459147 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339148 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039149 request.Request(
Nick Harper23290b82019-05-02 00:02:569150 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:519151 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039152 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9153 failed_on_default_network_callback_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:569154
robpercival214763f2016-07-01 23:27:019155 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:249156 std::unique_ptr<HttpStream> stream = CreateStream(&request);
ckrasic3865ee0f2016-02-29 22:04:569157 EXPECT_TRUE(stream.get());
9158
9159 EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumPushStreamsCreated(factory_.get()));
9160
bnc5fdc07162016-05-23 17:36:039161 string url = "https://www.example.org/";
ckrasic3865ee0f2016-02-29 22:04:569162
bnc912a04b2016-04-20 14:19:509163 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
ckrasic3865ee0f2016-02-29 22:04:569164
Ryan Hamilton8d9ee76e2018-05-29 23:52:529165 quic::QuicClientPromisedInfo promised(
Fan Yang32c5a112018-12-10 20:06:339166 session, GetNthServerInitiatedUnidirectionalStreamId(0), kDefaultUrl);
ckrasic3865ee0f2016-02-29 22:04:569167 (*QuicStreamFactoryPeer::GetPushPromiseIndex(factory_.get())
bnc3d9035b32016-06-30 18:18:489168 ->promised_by_url())[kDefaultUrl] = &promised;
ckrasic3865ee0f2016-02-29 22:04:569169
zhongyi98d6a9262017-05-19 02:47:459170 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:519171 EXPECT_EQ(OK,
9172 request2.Request(
9173 host_port_pair_, version_.transport_version, privacy_mode_,
9174 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
9175 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9176 failed_on_default_network_callback_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:569177
9178 EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumPushStreamsCreated(factory_.get()));
9179}
9180
9181TEST_P(QuicStreamFactoryTest, ServerPushPrivacyModeMismatch) {
9182 Initialize();
9183 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9184 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9185 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9186
Ryan Hamiltonabad59e2019-06-06 04:02:599187 MockQuicData socket_data1(version_);
rcha00569732016-08-27 11:09:369188 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:439189 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
9190 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:339191 SYNCHRONOUS, client_maker_.MakeRstPacket(
9192 2, true, GetNthServerInitiatedUnidirectionalStreamId(0),
9193 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:179194 socket_data1.AddSocketDataToFactory(socket_factory_.get());
ckrasic3865ee0f2016-02-29 22:04:569195
Ryan Hamilton0d65a8c2019-06-07 00:46:029196 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:599197 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:369198 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:439199 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:179200 socket_data2.AddSocketDataToFactory(socket_factory_.get());
ckrasic3865ee0f2016-02-29 22:04:569201
zhongyi98d6a9262017-05-19 02:47:459202 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339203 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039204 request.Request(
Nick Harper23290b82019-05-02 00:02:569205 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:519206 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039207 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9208 failed_on_default_network_callback_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:569209
robpercival214763f2016-07-01 23:27:019210 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:249211 std::unique_ptr<HttpStream> stream = CreateStream(&request);
ckrasic3865ee0f2016-02-29 22:04:569212 EXPECT_TRUE(stream.get());
9213
9214 EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumPushStreamsCreated(factory_.get()));
9215
bnc5fdc07162016-05-23 17:36:039216 string url = "https://www.example.org/";
bnc912a04b2016-04-20 14:19:509217 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
ckrasic3865ee0f2016-02-29 22:04:569218
Ryan Hamilton8d9ee76e2018-05-29 23:52:529219 quic::QuicClientPromisedInfo promised(
Fan Yang32c5a112018-12-10 20:06:339220 session, GetNthServerInitiatedUnidirectionalStreamId(0), kDefaultUrl);
ckrasic3865ee0f2016-02-29 22:04:569221
Ryan Hamilton8d9ee76e2018-05-29 23:52:529222 quic::QuicClientPushPromiseIndex* index =
ckrasic3865ee0f2016-02-29 22:04:569223 QuicStreamFactoryPeer::GetPushPromiseIndex(factory_.get());
9224
bnc3d9035b32016-06-30 18:18:489225 (*index->promised_by_url())[kDefaultUrl] = &promised;
9226 EXPECT_EQ(index->GetPromised(kDefaultUrl), &promised);
ckrasic3865ee0f2016-02-29 22:04:569227
9228 // Doing the request should not use the push stream, but rather
9229 // cancel it because the privacy modes do not match.
zhongyi98d6a9262017-05-19 02:47:459230 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:519231 EXPECT_EQ(
9232 ERR_IO_PENDING,
9233 request2.Request(
9234 host_port_pair_, version_.transport_version, PRIVACY_MODE_ENABLED,
9235 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
9236 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9237 failed_on_default_network_callback_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:569238
9239 EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumPushStreamsCreated(factory_.get()));
bnc3d9035b32016-06-30 18:18:489240 EXPECT_EQ(index->GetPromised(kDefaultUrl), nullptr);
ckrasic3865ee0f2016-02-29 22:04:569241
robpercival214763f2016-07-01 23:27:019242 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:249243 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
ckrasic3865ee0f2016-02-29 22:04:569244 EXPECT_TRUE(stream2.get());
9245
9246 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
9247 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
9248 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
9249 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
9250}
9251
Ryan Hamilton8d9ee76e2018-05-29 23:52:529252// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:459253// even if destination is different.
9254TEST_P(QuicStreamFactoryTest, PoolByOrigin) {
9255 Initialize();
9256
9257 HostPortPair destination1("first.example.com", 443);
9258 HostPortPair destination2("second.example.com", 443);
9259
9260 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9261 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9262
Ryan Hamiltonabad59e2019-06-06 04:02:599263 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:369264 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:439265 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:179266 socket_data.AddSocketDataToFactory(socket_factory_.get());
bnc359ed2a2016-04-29 20:43:459267
zhongyi98d6a9262017-05-19 02:47:459268 QuicStreamRequest request1(factory_.get());
Nick Harper23290b82019-05-02 00:02:569269 EXPECT_EQ(ERR_IO_PENDING,
9270 request1.Request(
9271 destination1, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:519272 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Nick Harper23290b82019-05-02 00:02:569273 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9274 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:019275 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:249276 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
bnc359ed2a2016-04-29 20:43:459277 EXPECT_TRUE(stream1.get());
9278 EXPECT_TRUE(HasActiveSession(host_port_pair_));
9279
9280 // Second request returns synchronously because it pools to existing session.
9281 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:459282 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:519283 EXPECT_EQ(OK,
9284 request2.Request(
9285 destination2, version_.transport_version, privacy_mode_,
9286 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
9287 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9288 failed_on_default_network_callback_, callback2.callback()));
Yixin Wang7891a39d2017-11-08 20:59:249289 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
bnc359ed2a2016-04-29 20:43:459290 EXPECT_TRUE(stream2.get());
9291
rchf0b18c8a2017-05-05 19:31:579292 QuicChromiumClientSession::Handle* session1 =
9293 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
9294 QuicChromiumClientSession::Handle* session2 =
9295 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
9296 EXPECT_TRUE(session1->SharesSameSession(*session2));
Ryan Hamilton4f0b26e2018-06-27 23:52:329297 EXPECT_EQ(quic::QuicServerId(host_port_pair_.host(), host_port_pair_.port(),
9298 privacy_mode_ == PRIVACY_MODE_ENABLED),
bnc359ed2a2016-04-29 20:43:459299 session1->server_id());
9300
9301 EXPECT_TRUE(socket_data.AllReadDataConsumed());
9302 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
9303}
9304
9305class QuicStreamFactoryWithDestinationTest
9306 : public QuicStreamFactoryTestBase,
9307 public ::testing::TestWithParam<PoolingTestParams> {
9308 protected:
9309 QuicStreamFactoryWithDestinationTest()
Yixin Wang079ad542018-01-11 04:06:059310 : QuicStreamFactoryTestBase(
9311 GetParam().version,
9312 GetParam().client_headers_include_h2_stream_dependency),
bnc359ed2a2016-04-29 20:43:459313 destination_type_(GetParam().destination_type),
9314 hanging_read_(SYNCHRONOUS, ERR_IO_PENDING, 0) {}
9315
9316 HostPortPair GetDestination() {
9317 switch (destination_type_) {
9318 case SAME_AS_FIRST:
9319 return origin1_;
9320 case SAME_AS_SECOND:
9321 return origin2_;
9322 case DIFFERENT:
9323 return HostPortPair(kDifferentHostname, 443);
9324 default:
9325 NOTREACHED();
9326 return HostPortPair();
9327 }
9328 }
9329
9330 void AddHangingSocketData() {
9331 std::unique_ptr<SequencedSocketData> sequenced_socket_data(
Ryan Sleevib8d7ea02018-05-07 20:01:019332 new SequencedSocketData(base::make_span(&hanging_read_, 1),
9333 base::span<MockWrite>()));
Zhongyi Shi5f587cc2017-11-21 23:24:179334 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
bnc359ed2a2016-04-29 20:43:459335 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
9336 }
9337
9338 bool AllDataConsumed() {
9339 for (const auto& socket_data_ptr : sequenced_socket_data_vector_) {
9340 if (!socket_data_ptr->AllReadDataConsumed() ||
9341 !socket_data_ptr->AllWriteDataConsumed()) {
9342 return false;
9343 }
9344 }
9345 return true;
9346 }
9347
9348 DestinationType destination_type_;
9349 HostPortPair origin1_;
9350 HostPortPair origin2_;
9351 MockRead hanging_read_;
rch872e00e2016-12-02 02:48:189352 std::vector<std::unique_ptr<SequencedSocketData>>
9353 sequenced_socket_data_vector_;
bnc359ed2a2016-04-29 20:43:459354};
9355
Victor Costane635086f2019-01-27 05:20:309356INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
9357 QuicStreamFactoryWithDestinationTest,
9358 ::testing::ValuesIn(GetPoolingTestParams()));
bnc359ed2a2016-04-29 20:43:459359
9360// A single QUIC request fails because the certificate does not match the origin
9361// hostname, regardless of whether it matches the alternative service hostname.
9362TEST_P(QuicStreamFactoryWithDestinationTest, InvalidCertificate) {
9363 if (destination_type_ == DIFFERENT)
9364 return;
9365
9366 Initialize();
9367
9368 GURL url("https://mail.example.com/");
9369 origin1_ = HostPortPair::FromURL(url);
9370
9371 // Not used for requests, but this provides a test case where the certificate
9372 // is valid for the hostname of the alternative service.
9373 origin2_ = HostPortPair("mail.example.org", 433);
9374
9375 HostPortPair destination = GetDestination();
9376
9377 scoped_refptr<X509Certificate> cert(
9378 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:249379 ASSERT_FALSE(cert->VerifyNameMatch(origin1_.host()));
9380 ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host()));
bnc359ed2a2016-04-29 20:43:459381
9382 ProofVerifyDetailsChromium verify_details;
9383 verify_details.cert_verify_result.verified_cert = cert;
9384 verify_details.cert_verify_result.is_issued_by_known_root = true;
9385 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9386
9387 AddHangingSocketData();
9388
zhongyi98d6a9262017-05-19 02:47:459389 QuicStreamRequest request(factory_.get());
Nick Harper23290b82019-05-02 00:02:569390 EXPECT_EQ(ERR_IO_PENDING,
9391 request.Request(
9392 destination, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:519393 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Nick Harper23290b82019-05-02 00:02:569394 /*cert_verify_flags=*/0, url, net_log_, &net_error_details_,
9395 failed_on_default_network_callback_, callback_.callback()));
bnc359ed2a2016-04-29 20:43:459396
robpercival214763f2016-07-01 23:27:019397 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_QUIC_HANDSHAKE_FAILED));
bnc359ed2a2016-04-29 20:43:459398
9399 EXPECT_TRUE(AllDataConsumed());
9400}
9401
9402// QuicStreamRequest is pooled based on |destination| if certificate matches.
9403TEST_P(QuicStreamFactoryWithDestinationTest, SharedCertificate) {
9404 Initialize();
9405
9406 GURL url1("https://www.example.org/");
9407 GURL url2("https://mail.example.org/");
9408 origin1_ = HostPortPair::FromURL(url1);
9409 origin2_ = HostPortPair::FromURL(url2);
9410
9411 HostPortPair destination = GetDestination();
9412
9413 scoped_refptr<X509Certificate> cert(
9414 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:249415 ASSERT_TRUE(cert->VerifyNameMatch(origin1_.host()));
9416 ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host()));
9417 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:459418
9419 ProofVerifyDetailsChromium verify_details;
9420 verify_details.cert_verify_result.verified_cert = cert;
9421 verify_details.cert_verify_result.is_issued_by_known_root = true;
9422 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9423
fayang3bcb8b502016-12-07 21:44:379424 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:529425 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Ryan Hamilton0d65a8c2019-06-07 00:46:029426 client_maker_.MakeInitialSettingsPacket(1));
bnceb9aa7112017-01-05 01:03:469427 MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(),
9428 settings_packet->length(), 1)};
fayang3bcb8b502016-12-07 21:44:379429 std::unique_ptr<SequencedSocketData> sequenced_socket_data(
Ryan Sleevib8d7ea02018-05-07 20:01:019430 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:179431 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
fayang3bcb8b502016-12-07 21:44:379432 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
bnc359ed2a2016-04-29 20:43:459433
zhongyi98d6a9262017-05-19 02:47:459434 QuicStreamRequest request1(factory_.get());
Nick Harper23290b82019-05-02 00:02:569435 EXPECT_EQ(ERR_IO_PENDING,
9436 request1.Request(
9437 destination, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:519438 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Nick Harper23290b82019-05-02 00:02:569439 /*cert_verify_flags=*/0, url1, net_log_, &net_error_details_,
9440 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:019441 EXPECT_THAT(callback_.WaitForResult(), IsOk());
fayang3bcb8b502016-12-07 21:44:379442
Yixin Wang7891a39d2017-11-08 20:59:249443 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
bnc359ed2a2016-04-29 20:43:459444 EXPECT_TRUE(stream1.get());
9445 EXPECT_TRUE(HasActiveSession(origin1_));
9446
9447 // Second request returns synchronously because it pools to existing session.
9448 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:459449 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:519450 EXPECT_EQ(OK,
9451 request2.Request(
9452 destination, version_.transport_version, privacy_mode_,
9453 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
9454 /*cert_verify_flags=*/0, url2, net_log_, &net_error_details_,
9455 failed_on_default_network_callback_, callback2.callback()));
Yixin Wang7891a39d2017-11-08 20:59:249456 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
bnc359ed2a2016-04-29 20:43:459457 EXPECT_TRUE(stream2.get());
9458
rchf0b18c8a2017-05-05 19:31:579459 QuicChromiumClientSession::Handle* session1 =
9460 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
9461 QuicChromiumClientSession::Handle* session2 =
9462 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
9463 EXPECT_TRUE(session1->SharesSameSession(*session2));
bnc359ed2a2016-04-29 20:43:459464
Ryan Hamilton4f0b26e2018-06-27 23:52:329465 EXPECT_EQ(quic::QuicServerId(origin1_.host(), origin1_.port(),
9466 privacy_mode_ == PRIVACY_MODE_ENABLED),
9467 session1->server_id());
bnc359ed2a2016-04-29 20:43:459468
9469 EXPECT_TRUE(AllDataConsumed());
9470}
9471
bnc47eba7d2016-07-01 00:43:389472// QuicStreamRequest is not pooled if PrivacyMode differs.
9473TEST_P(QuicStreamFactoryWithDestinationTest, DifferentPrivacyMode) {
9474 Initialize();
9475
9476 GURL url1("https://www.example.org/");
9477 GURL url2("https://mail.example.org/");
9478 origin1_ = HostPortPair::FromURL(url1);
9479 origin2_ = HostPortPair::FromURL(url2);
9480
9481 HostPortPair destination = GetDestination();
9482
9483 scoped_refptr<X509Certificate> cert(
9484 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:249485 ASSERT_TRUE(cert->VerifyNameMatch(origin1_.host()));
9486 ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host()));
9487 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc47eba7d2016-07-01 00:43:389488
9489 ProofVerifyDetailsChromium verify_details1;
9490 verify_details1.cert_verify_result.verified_cert = cert;
9491 verify_details1.cert_verify_result.is_issued_by_known_root = true;
9492 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
9493
9494 ProofVerifyDetailsChromium verify_details2;
9495 verify_details2.cert_verify_result.verified_cert = cert;
9496 verify_details2.cert_verify_result.is_issued_by_known_root = true;
9497 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
9498
fayang3bcb8b502016-12-07 21:44:379499 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:529500 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Ryan Hamilton0d65a8c2019-06-07 00:46:029501 client_maker_.MakeInitialSettingsPacket(1));
bnceb9aa7112017-01-05 01:03:469502 MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(),
9503 settings_packet->length(), 1)};
fayang3bcb8b502016-12-07 21:44:379504 std::unique_ptr<SequencedSocketData> sequenced_socket_data(
Ryan Sleevib8d7ea02018-05-07 20:01:019505 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:179506 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
fayang3bcb8b502016-12-07 21:44:379507 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
9508 std::unique_ptr<SequencedSocketData> sequenced_socket_data1(
Ryan Sleevib8d7ea02018-05-07 20:01:019509 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:179510 socket_factory_->AddSocketDataProvider(sequenced_socket_data1.get());
fayang3bcb8b502016-12-07 21:44:379511 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data1));
bnc47eba7d2016-07-01 00:43:389512
zhongyi98d6a9262017-05-19 02:47:459513 QuicStreamRequest request1(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339514 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039515 request1.Request(
Nick Harper23290b82019-05-02 00:02:569516 destination, version_.transport_version, PRIVACY_MODE_DISABLED,
Matt Menke26e41542019-06-05 01:09:519517 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039518 /*cert_verify_flags=*/0, url1, net_log_, &net_error_details_,
9519 failed_on_default_network_callback_, callback_.callback()));
bnc47eba7d2016-07-01 00:43:389520 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:249521 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
bnc47eba7d2016-07-01 00:43:389522 EXPECT_TRUE(stream1.get());
9523 EXPECT_TRUE(HasActiveSession(origin1_));
9524
9525 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:459526 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339527 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039528 request2.Request(
Nick Harper23290b82019-05-02 00:02:569529 destination, version_.transport_version, PRIVACY_MODE_ENABLED,
Matt Menke26e41542019-06-05 01:09:519530 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039531 /*cert_verify_flags=*/0, url2, net_log_, &net_error_details_,
9532 failed_on_default_network_callback_, callback2.callback()));
bnc47eba7d2016-07-01 00:43:389533 EXPECT_EQ(OK, callback2.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:249534 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
bnc47eba7d2016-07-01 00:43:389535 EXPECT_TRUE(stream2.get());
9536
9537 // |request2| does not pool to the first session, because PrivacyMode does not
9538 // match. Instead, another session is opened to the same destination, but
Ryan Hamilton8d9ee76e2018-05-29 23:52:529539 // with a different quic::QuicServerId.
rchf0b18c8a2017-05-05 19:31:579540 QuicChromiumClientSession::Handle* session1 =
9541 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
9542 QuicChromiumClientSession::Handle* session2 =
9543 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
9544 EXPECT_FALSE(session1->SharesSameSession(*session2));
bnc47eba7d2016-07-01 00:43:389545
Ryan Hamilton4f0b26e2018-06-27 23:52:329546 EXPECT_EQ(quic::QuicServerId(origin1_.host(), origin1_.port(), false),
bnc47eba7d2016-07-01 00:43:389547 session1->server_id());
Ryan Hamilton4f0b26e2018-06-27 23:52:329548 EXPECT_EQ(quic::QuicServerId(origin2_.host(), origin2_.port(), true),
bnc47eba7d2016-07-01 00:43:389549 session2->server_id());
9550
9551 EXPECT_TRUE(AllDataConsumed());
9552}
9553
bnc359ed2a2016-04-29 20:43:459554// QuicStreamRequest is not pooled if certificate does not match its origin.
9555TEST_P(QuicStreamFactoryWithDestinationTest, DisjointCertificate) {
9556 Initialize();
9557
9558 GURL url1("https://news.example.org/");
9559 GURL url2("https://mail.example.com/");
9560 origin1_ = HostPortPair::FromURL(url1);
9561 origin2_ = HostPortPair::FromURL(url2);
9562
9563 HostPortPair destination = GetDestination();
9564
9565 scoped_refptr<X509Certificate> cert1(
9566 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:249567 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_.host()));
9568 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_.host()));
9569 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:459570
9571 ProofVerifyDetailsChromium verify_details1;
9572 verify_details1.cert_verify_result.verified_cert = cert1;
9573 verify_details1.cert_verify_result.is_issued_by_known_root = true;
9574 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
9575
9576 scoped_refptr<X509Certificate> cert2(
9577 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:249578 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_.host()));
9579 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:459580
9581 ProofVerifyDetailsChromium verify_details2;
9582 verify_details2.cert_verify_result.verified_cert = cert2;
9583 verify_details2.cert_verify_result.is_issued_by_known_root = true;
9584 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
9585
fayang3bcb8b502016-12-07 21:44:379586 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:529587 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Ryan Hamilton0d65a8c2019-06-07 00:46:029588 client_maker_.MakeInitialSettingsPacket(1));
bnceb9aa7112017-01-05 01:03:469589 MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(),
9590 settings_packet->length(), 1)};
fayang3bcb8b502016-12-07 21:44:379591 std::unique_ptr<SequencedSocketData> sequenced_socket_data(
Ryan Sleevib8d7ea02018-05-07 20:01:019592 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:179593 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
fayang3bcb8b502016-12-07 21:44:379594 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
9595 std::unique_ptr<SequencedSocketData> sequenced_socket_data1(
Ryan Sleevib8d7ea02018-05-07 20:01:019596 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:179597 socket_factory_->AddSocketDataProvider(sequenced_socket_data1.get());
fayang3bcb8b502016-12-07 21:44:379598 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data1));
bnc359ed2a2016-04-29 20:43:459599
zhongyi98d6a9262017-05-19 02:47:459600 QuicStreamRequest request1(factory_.get());
Nick Harper23290b82019-05-02 00:02:569601 EXPECT_EQ(ERR_IO_PENDING,
9602 request1.Request(
9603 destination, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:519604 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Nick Harper23290b82019-05-02 00:02:569605 /*cert_verify_flags=*/0, url1, net_log_, &net_error_details_,
9606 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:019607 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:249608 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
bnc359ed2a2016-04-29 20:43:459609 EXPECT_TRUE(stream1.get());
9610 EXPECT_TRUE(HasActiveSession(origin1_));
9611
9612 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:459613 QuicStreamRequest request2(factory_.get());
Nick Harper23290b82019-05-02 00:02:569614 EXPECT_EQ(ERR_IO_PENDING,
9615 request2.Request(
9616 destination, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:519617 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Nick Harper23290b82019-05-02 00:02:569618 /*cert_verify_flags=*/0, url2, net_log_, &net_error_details_,
9619 failed_on_default_network_callback_, callback2.callback()));
robpercival214763f2016-07-01 23:27:019620 EXPECT_THAT(callback2.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:249621 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
bnc359ed2a2016-04-29 20:43:459622 EXPECT_TRUE(stream2.get());
9623
9624 // |request2| does not pool to the first session, because the certificate does
9625 // not match. Instead, another session is opened to the same destination, but
Ryan Hamilton8d9ee76e2018-05-29 23:52:529626 // with a different quic::QuicServerId.
rchf0b18c8a2017-05-05 19:31:579627 QuicChromiumClientSession::Handle* session1 =
9628 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
9629 QuicChromiumClientSession::Handle* session2 =
9630 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
9631 EXPECT_FALSE(session1->SharesSameSession(*session2));
bnc359ed2a2016-04-29 20:43:459632
Ryan Hamilton4f0b26e2018-06-27 23:52:329633 EXPECT_EQ(quic::QuicServerId(origin1_.host(), origin1_.port(),
9634 privacy_mode_ == PRIVACY_MODE_ENABLED),
9635 session1->server_id());
9636 EXPECT_EQ(quic::QuicServerId(origin2_.host(), origin2_.port(),
9637 privacy_mode_ == PRIVACY_MODE_ENABLED),
9638 session2->server_id());
bnc359ed2a2016-04-29 20:43:459639
9640 EXPECT_TRUE(AllDataConsumed());
9641}
9642
msramek992625ec2016-08-04 18:33:589643// This test verifies that QuicStreamFactory::ClearCachedStatesInCryptoConfig
9644// correctly transform an origin filter to a ServerIdFilter. Whether the
9645// deletion itself works correctly is tested in QuicCryptoClientConfigTest.
9646TEST_P(QuicStreamFactoryTest, ClearCachedStatesInCryptoConfig) {
9647 Initialize();
Ryan Hamilton8d9ee76e2018-05-29 23:52:529648 quic::QuicCryptoClientConfig* crypto_config =
msramek992625ec2016-08-04 18:33:589649 QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
9650
9651 struct TestCase {
9652 TestCase(const std::string& host,
9653 int port,
9654 PrivacyMode privacy_mode,
Ryan Hamilton8d9ee76e2018-05-29 23:52:529655 quic::QuicCryptoClientConfig* crypto_config)
msramek992625ec2016-08-04 18:33:589656 : server_id(host, port, privacy_mode),
9657 state(crypto_config->LookupOrCreate(server_id)) {
rch872e00e2016-12-02 02:48:189658 std::vector<string> certs(1);
msramek992625ec2016-08-04 18:33:589659 certs[0] = "cert";
9660 state->SetProof(certs, "cert_sct", "chlo_hash", "signature");
9661 state->set_source_address_token("TOKEN");
9662 state->SetProofValid();
9663
9664 EXPECT_FALSE(state->certs().empty());
9665 }
9666
Ryan Hamilton8d9ee76e2018-05-29 23:52:529667 quic::QuicServerId server_id;
9668 quic::QuicCryptoClientConfig::CachedState* state;
msramek992625ec2016-08-04 18:33:589669 } test_cases[] = {
9670 TestCase("www.google.com", 443, privacy_mode_, crypto_config),
9671 TestCase("www.example.com", 443, privacy_mode_, crypto_config),
9672 TestCase("www.example.com", 4433, privacy_mode_, crypto_config)};
9673
9674 // Clear cached states for the origin https://www.example.com:4433.
9675 GURL origin("https://www.example.com:4433");
csharrisonebeca8e2016-10-18 02:35:369676 factory_->ClearCachedStatesInCryptoConfig(base::Bind(
9677 static_cast<bool (*)(const GURL&, const GURL&)>(::operator==), origin));
msramek992625ec2016-08-04 18:33:589678 EXPECT_FALSE(test_cases[0].state->certs().empty());
9679 EXPECT_FALSE(test_cases[1].state->certs().empty());
9680 EXPECT_TRUE(test_cases[2].state->certs().empty());
9681
9682 // Clear all cached states.
9683 factory_->ClearCachedStatesInCryptoConfig(
9684 base::Callback<bool(const GURL&)>());
9685 EXPECT_TRUE(test_cases[0].state->certs().empty());
9686 EXPECT_TRUE(test_cases[1].state->certs().empty());
9687 EXPECT_TRUE(test_cases[2].state->certs().empty());
9688}
9689
Yixin Wang46a425f2017-08-10 23:02:209690// Passes connection options and client connection options to QuicStreamFactory,
Ryan Hamilton8d9ee76e2018-05-29 23:52:529691// then checks that its internal quic::QuicConfig is correct.
Yixin Wang46a425f2017-08-10 23:02:209692TEST_P(QuicStreamFactoryTest, ConfigConnectionOptions) {
Zhongyi Shi967d2f12019-02-08 20:58:539693 test_params_.quic_connection_options.push_back(quic::kTIME);
9694 test_params_.quic_connection_options.push_back(quic::kTBBR);
9695 test_params_.quic_connection_options.push_back(quic::kREJ);
Yixin Wang46a425f2017-08-10 23:02:209696
Zhongyi Shi967d2f12019-02-08 20:58:539697 test_params_.quic_client_connection_options.push_back(quic::kTBBR);
9698 test_params_.quic_client_connection_options.push_back(quic::k1RTT);
Yixin Wang46a425f2017-08-10 23:02:209699
9700 Initialize();
9701
Ryan Hamilton8d9ee76e2018-05-29 23:52:529702 const quic::QuicConfig* config =
9703 QuicStreamFactoryPeer::GetConfig(factory_.get());
Zhongyi Shi967d2f12019-02-08 20:58:539704 EXPECT_EQ(test_params_.quic_connection_options,
9705 config->SendConnectionOptions());
Yixin Wang46a425f2017-08-10 23:02:209706 EXPECT_TRUE(config->HasClientRequestedIndependentOption(
Ryan Hamilton8d9ee76e2018-05-29 23:52:529707 quic::kTBBR, quic::Perspective::IS_CLIENT));
Yixin Wang46a425f2017-08-10 23:02:209708 EXPECT_TRUE(config->HasClientRequestedIndependentOption(
Ryan Hamilton8d9ee76e2018-05-29 23:52:529709 quic::k1RTT, quic::Perspective::IS_CLIENT));
Yixin Wang46a425f2017-08-10 23:02:209710}
9711
Yixin Wang247ea642017-11-15 01:15:509712// Verifies that the host resolver uses the request priority passed to
9713// QuicStreamRequest::Request().
9714TEST_P(QuicStreamFactoryTest, HostResolverUsesRequestPriority) {
9715 Initialize();
9716 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9717 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9718
Ryan Hamiltonabad59e2019-06-06 04:02:599719 MockQuicData socket_data(version_);
Yixin Wang247ea642017-11-15 01:15:509720 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:439721 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:179722 socket_data.AddSocketDataToFactory(socket_factory_.get());
Yixin Wang247ea642017-11-15 01:15:509723
9724 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339725 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039726 request.Request(
Nick Harper23290b82019-05-02 00:02:569727 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:519728 MAXIMUM_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039729 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9730 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang247ea642017-11-15 01:15:509731
9732 EXPECT_THAT(callback_.WaitForResult(), IsOk());
9733 std::unique_ptr<HttpStream> stream = CreateStream(&request);
9734 EXPECT_TRUE(stream.get());
9735
Renjiea0cb4a2c2018-09-26 23:37:309736 EXPECT_EQ(MAXIMUM_PRIORITY, host_resolver_->last_request_priority());
Yixin Wang247ea642017-11-15 01:15:509737
9738 EXPECT_TRUE(socket_data.AllReadDataConsumed());
9739 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
9740}
9741
Lily Chenf11e1292018-11-29 16:42:099742TEST_P(QuicStreamFactoryTest, HostResolverRequestReprioritizedOnSetPriority) {
9743 Initialize();
9744 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9745 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9746
Ryan Hamiltonabad59e2019-06-06 04:02:599747 MockQuicData socket_data(version_);
Lily Chenf11e1292018-11-29 16:42:099748 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9749 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
9750 socket_data.AddSocketDataToFactory(socket_factory_.get());
9751
9752 QuicStreamRequest request(factory_.get());
9753 EXPECT_EQ(ERR_IO_PENDING,
9754 request.Request(
Nick Harper23290b82019-05-02 00:02:569755 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:519756 MAXIMUM_PRIORITY, SocketTag(), NetworkIsolationKey(),
Lily Chenf11e1292018-11-29 16:42:099757 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9758 failed_on_default_network_callback_, callback_.callback()));
9759
9760 EXPECT_EQ(MAXIMUM_PRIORITY, host_resolver_->last_request_priority());
9761 EXPECT_EQ(MAXIMUM_PRIORITY, host_resolver_->request_priority(1));
9762
9763 QuicStreamRequest request2(factory_.get());
9764 EXPECT_EQ(ERR_IO_PENDING,
9765 request2.Request(
Nick Harper23290b82019-05-02 00:02:569766 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:519767 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Lily Chenf11e1292018-11-29 16:42:099768 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
9769 failed_on_default_network_callback_, callback_.callback()));
9770 EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_->last_request_priority());
9771 EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_->request_priority(2));
9772
9773 request.SetPriority(LOWEST);
9774 EXPECT_EQ(LOWEST, host_resolver_->request_priority(1));
9775 EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_->request_priority(2));
9776}
9777
Zhongyi Shi967d2f12019-02-08 20:58:539778// Passes |quic_max_time_before_crypto_handshake_seconds| and
9779// |quic_max_idle_time_before_crypto_handshake_seconds| to QuicStreamFactory,
Ryan Hamilton8d9ee76e2018-05-29 23:52:529780// checks that its internal quic::QuicConfig is correct.
Yixin Wang469da562017-11-15 21:34:589781TEST_P(QuicStreamFactoryTest, ConfigMaxTimeBeforeCryptoHandshake) {
Zhongyi Shi967d2f12019-02-08 20:58:539782 test_params_.quic_max_time_before_crypto_handshake_seconds = 11;
9783 test_params_.quic_max_idle_time_before_crypto_handshake_seconds = 13;
Yixin Wang469da562017-11-15 21:34:589784 Initialize();
9785
Ryan Hamilton8d9ee76e2018-05-29 23:52:529786 const quic::QuicConfig* config =
9787 QuicStreamFactoryPeer::GetConfig(factory_.get());
9788 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(11),
Yixin Wang469da562017-11-15 21:34:589789 config->max_time_before_crypto_handshake());
Ryan Hamilton8d9ee76e2018-05-29 23:52:529790 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(13),
Yixin Wang469da562017-11-15 21:34:589791 config->max_idle_time_before_crypto_handshake());
9792}
9793
Yixin Wang7c5d11a82017-12-21 02:40:009794// Verify ResultAfterHostResolutionCallback behavior when host resolution
9795// succeeds asynchronously, then crypto handshake fails synchronously.
9796TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackAsyncSync) {
9797 Initialize();
9798 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9799 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9800
Renjiea0cb4a2c2018-09-26 23:37:309801 host_resolver_->set_ondemand_mode(true);
Yixin Wang7c5d11a82017-12-21 02:40:009802
Ryan Hamiltonabad59e2019-06-06 04:02:599803 MockQuicData socket_data(version_);
Yixin Wang7c5d11a82017-12-21 02:40:009804 socket_data.AddRead(SYNCHRONOUS, ERR_FAILED);
9805 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
9806 socket_data.AddSocketDataToFactory(socket_factory_.get());
9807
9808 QuicStreamRequest request(factory_.get());
9809 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039810 request.Request(
Nick Harper23290b82019-05-02 00:02:569811 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:519812 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039813 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9814 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:009815
9816 TestCompletionCallback host_resolution_callback;
9817 EXPECT_TRUE(
9818 request.WaitForHostResolution(host_resolution_callback.callback()));
9819
9820 // |host_resolver_| has not finished host resolution at this point, so
9821 // |host_resolution_callback| should not have a result.
9822 base::RunLoop().RunUntilIdle();
9823 EXPECT_FALSE(host_resolution_callback.have_result());
9824
9825 // Allow |host_resolver_| to finish host resolution.
9826 // Since the request fails immediately after host resolution (getting
9827 // ERR_FAILED from socket reads/writes), |host_resolution_callback| should be
9828 // called with ERR_QUIC_PROTOCOL_ERROR since that's the next result in
9829 // forming the connection.
Renjiea0cb4a2c2018-09-26 23:37:309830 host_resolver_->ResolveAllPending();
Yixin Wang7c5d11a82017-12-21 02:40:009831 base::RunLoop().RunUntilIdle();
9832 EXPECT_TRUE(host_resolution_callback.have_result());
9833 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, host_resolution_callback.WaitForResult());
9834
9835 // Calling WaitForHostResolution() a second time should return
9836 // false since host resolution has finished already.
9837 EXPECT_FALSE(
9838 request.WaitForHostResolution(host_resolution_callback.callback()));
9839
9840 EXPECT_TRUE(callback_.have_result());
9841 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
9842}
9843
9844// Verify ResultAfterHostResolutionCallback behavior when host resolution
9845// succeeds asynchronously, then crypto handshake fails asynchronously.
9846TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackAsyncAsync) {
9847 Initialize();
9848 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9849 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9850
Renjiea0cb4a2c2018-09-26 23:37:309851 host_resolver_->set_ondemand_mode(true);
Yixin Wang7c5d11a82017-12-21 02:40:009852 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:279853 MockCryptoClientStream::ZERO_RTT);
Yixin Wang7c5d11a82017-12-21 02:40:009854 factory_->set_require_confirmation(true);
9855
Ryan Hamiltonabad59e2019-06-06 04:02:599856 MockQuicData socket_data(version_);
Yixin Wang7c5d11a82017-12-21 02:40:009857 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
9858 socket_data.AddRead(ASYNC, ERR_FAILED);
9859 socket_data.AddWrite(ASYNC, ERR_FAILED);
9860 socket_data.AddSocketDataToFactory(socket_factory_.get());
9861
9862 QuicStreamRequest request(factory_.get());
9863 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039864 request.Request(
Nick Harper23290b82019-05-02 00:02:569865 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:519866 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039867 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9868 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:009869
9870 TestCompletionCallback host_resolution_callback;
9871 EXPECT_TRUE(
9872 request.WaitForHostResolution(host_resolution_callback.callback()));
9873
9874 // |host_resolver_| has not finished host resolution at this point, so
9875 // |host_resolution_callback| should not have a result.
9876 base::RunLoop().RunUntilIdle();
9877 EXPECT_FALSE(host_resolution_callback.have_result());
9878
9879 // Allow |host_resolver_| to finish host resolution. Since crypto handshake
9880 // will hang after host resolution, |host_resolution_callback| should run with
9881 // ERR_IO_PENDING since that's the next result in forming the connection.
Renjiea0cb4a2c2018-09-26 23:37:309882 host_resolver_->ResolveAllPending();
Yixin Wang7c5d11a82017-12-21 02:40:009883 base::RunLoop().RunUntilIdle();
9884 EXPECT_TRUE(host_resolution_callback.have_result());
9885 EXPECT_EQ(ERR_IO_PENDING, host_resolution_callback.WaitForResult());
9886
9887 // Calling WaitForHostResolution() a second time should return
9888 // false since host resolution has finished already.
9889 EXPECT_FALSE(
9890 request.WaitForHostResolution(host_resolution_callback.callback()));
9891
9892 EXPECT_FALSE(callback_.have_result());
9893 socket_data.GetSequencedSocketData()->Resume();
9894 base::RunLoop().RunUntilIdle();
9895 EXPECT_TRUE(callback_.have_result());
9896 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
9897}
9898
9899// Verify ResultAfterHostResolutionCallback behavior when host resolution
9900// succeeds synchronously, then crypto handshake fails synchronously.
9901TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackSyncSync) {
9902 Initialize();
9903 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9904 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9905
Renjiea0cb4a2c2018-09-26 23:37:309906 host_resolver_->set_synchronous_mode(true);
Yixin Wang7c5d11a82017-12-21 02:40:009907
Ryan Hamiltonabad59e2019-06-06 04:02:599908 MockQuicData socket_data(version_);
Yixin Wang7c5d11a82017-12-21 02:40:009909 socket_data.AddRead(SYNCHRONOUS, ERR_FAILED);
9910 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
9911 socket_data.AddSocketDataToFactory(socket_factory_.get());
9912
9913 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339914 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR,
Zhongyi Shia6b68d112018-09-24 07:49:039915 request.Request(
Nick Harper23290b82019-05-02 00:02:569916 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:519917 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039918 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9919 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:009920
9921 // WaitForHostResolution() should return false since host
9922 // resolution has finished already.
9923 TestCompletionCallback host_resolution_callback;
9924 EXPECT_FALSE(
9925 request.WaitForHostResolution(host_resolution_callback.callback()));
9926 base::RunLoop().RunUntilIdle();
9927 EXPECT_FALSE(host_resolution_callback.have_result());
9928 EXPECT_FALSE(callback_.have_result());
9929}
9930
9931// Verify ResultAfterHostResolutionCallback behavior when host resolution
9932// succeeds synchronously, then crypto handshake fails asynchronously.
9933TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackSyncAsync) {
9934 Initialize();
9935 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9936 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9937
9938 // Host resolution will succeed synchronously, but Request() as a whole
9939 // will fail asynchronously.
Renjiea0cb4a2c2018-09-26 23:37:309940 host_resolver_->set_synchronous_mode(true);
Yixin Wang7c5d11a82017-12-21 02:40:009941 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:279942 MockCryptoClientStream::ZERO_RTT);
Yixin Wang7c5d11a82017-12-21 02:40:009943 factory_->set_require_confirmation(true);
9944
Ryan Hamiltonabad59e2019-06-06 04:02:599945 MockQuicData socket_data(version_);
Yixin Wang7c5d11a82017-12-21 02:40:009946 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
9947 socket_data.AddRead(ASYNC, ERR_FAILED);
9948 socket_data.AddWrite(ASYNC, ERR_FAILED);
9949 socket_data.AddSocketDataToFactory(socket_factory_.get());
9950
9951 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339952 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039953 request.Request(
Nick Harper23290b82019-05-02 00:02:569954 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:519955 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039956 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9957 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:009958
9959 // WaitForHostResolution() should return false since host
9960 // resolution has finished already.
9961 TestCompletionCallback host_resolution_callback;
9962 EXPECT_FALSE(
9963 request.WaitForHostResolution(host_resolution_callback.callback()));
9964 base::RunLoop().RunUntilIdle();
9965 EXPECT_FALSE(host_resolution_callback.have_result());
9966
9967 EXPECT_FALSE(callback_.have_result());
9968 socket_data.GetSequencedSocketData()->Resume();
9969 base::RunLoop().RunUntilIdle();
9970 EXPECT_TRUE(callback_.have_result());
9971 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
9972}
9973
9974// Verify ResultAfterHostResolutionCallback behavior when host resolution fails
9975// synchronously.
9976TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackFailSync) {
9977 Initialize();
9978 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9979 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9980
9981 // Host resolution will fail synchronously.
Renjiea0cb4a2c2018-09-26 23:37:309982 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
9983 host_resolver_->set_synchronous_mode(true);
Yixin Wang7c5d11a82017-12-21 02:40:009984
9985 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339986 EXPECT_EQ(ERR_NAME_NOT_RESOLVED,
Zhongyi Shia6b68d112018-09-24 07:49:039987 request.Request(
Nick Harper23290b82019-05-02 00:02:569988 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:519989 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039990 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9991 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:009992
9993 // WaitForHostResolution() should return false since host
9994 // resolution has failed already.
9995 TestCompletionCallback host_resolution_callback;
9996 EXPECT_FALSE(
9997 request.WaitForHostResolution(host_resolution_callback.callback()));
9998 base::RunLoop().RunUntilIdle();
9999 EXPECT_FALSE(host_resolution_callback.have_result());
10000}
10001
10002// Verify ResultAfterHostResolutionCallback behavior when host resolution fails
10003// asynchronously.
10004TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackFailAsync) {
10005 Initialize();
10006 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10007 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10008
Renjiea0cb4a2c2018-09-26 23:37:3010009 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
Yixin Wang7c5d11a82017-12-21 02:40:0010010
10011 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:3310012 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:0310013 request.Request(
Nick Harper23290b82019-05-02 00:02:5610014 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110015 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:0310016 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10017 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:0010018
10019 TestCompletionCallback host_resolution_callback;
10020 EXPECT_TRUE(
10021 request.WaitForHostResolution(host_resolution_callback.callback()));
10022
10023 // Allow |host_resolver_| to fail host resolution. |host_resolution_callback|
10024 // Should run with ERR_NAME_NOT_RESOLVED since that's the error host
10025 // resolution failed with.
10026 base::RunLoop().RunUntilIdle();
10027 EXPECT_TRUE(host_resolution_callback.have_result());
10028 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, host_resolution_callback.WaitForResult());
10029
10030 EXPECT_TRUE(callback_.have_result());
10031 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, callback_.WaitForResult());
10032}
10033
Renjiea0cb4a2c2018-09-26 23:37:3010034// With dns race experiment turned on, and DNS resolve succeeds synchronously,
10035// the final connection is established through the resolved DNS. No racing
10036// connection.
10037TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceAndHostResolutionSync) {
Zhongyi Shi967d2f12019-02-08 20:58:5310038 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010039 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10040 Initialize();
10041 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10042 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10043
10044 // Set an address in resolver for synchronous return.
10045 host_resolver_->set_synchronous_mode(true);
10046 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10047 kNonCachedIPAddress, "");
10048
10049 // Set up a different address in stale resolver cache.
10050 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10051 HostCache::Entry entry(OK,
10052 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10053 HostCache::Entry::SOURCE_DNS);
10054 base::TimeDelta zero;
10055 HostCache* cache = host_resolver_->GetHostCache();
10056 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10057 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810058 cache->Invalidate();
Renjie8d2d8d91b2018-09-29 00:29:0310059
Ryan Hamiltonabad59e2019-06-06 04:02:5910060 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010061 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10062 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10063 quic_data.AddSocketDataToFactory(socket_factory_.get());
10064
10065 QuicStreamRequest request(factory_.get());
10066 EXPECT_THAT(request.Request(
Nick Harper23290b82019-05-02 00:02:5610067 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110068 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010069 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10070 failed_on_default_network_callback_, callback_.callback()),
10071 IsOk());
10072 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10073 EXPECT_TRUE(stream.get());
10074 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Victor Vasilievbee79ea2019-05-15 01:25:4810075 EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress);
Renjiea0cb4a2c2018-09-26 23:37:3010076
10077 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10078 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10079}
10080
10081// With dns race experiment on, DNS resolve returns async, no matching cache in
10082// host resolver, connection should be successful and through resolved DNS. No
10083// racing connection.
10084TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceAndHostResolutionAsync) {
Renjiea0cb4a2c2018-09-26 23:37:3010085 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10086 Initialize();
10087 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10088 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10089
10090 // Set an address in resolver for asynchronous return.
10091 host_resolver_->set_ondemand_mode(true);
10092 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10093 kNonCachedIPAddress, "");
10094
Ryan Hamiltonabad59e2019-06-06 04:02:5910095 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010096 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10097 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10098 quic_data.AddSocketDataToFactory(socket_factory_.get());
10099
10100 QuicStreamRequest request(factory_.get());
10101 EXPECT_EQ(ERR_IO_PENDING,
10102 request.Request(
Nick Harper23290b82019-05-02 00:02:5610103 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110104 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010105 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10106 failed_on_default_network_callback_, callback_.callback()));
10107 TestCompletionCallback host_resolution_callback;
10108 EXPECT_TRUE(
10109 request.WaitForHostResolution(host_resolution_callback.callback()));
10110 base::RunLoop().RunUntilIdle();
10111 EXPECT_FALSE(host_resolution_callback.have_result());
10112
10113 // Cause the host resolution to return.
10114 host_resolver_->ResolveAllPending();
10115 EXPECT_THAT(host_resolution_callback.WaitForResult(), IsOk());
10116 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10117
10118 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10119 EXPECT_TRUE(stream.get());
10120 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
10121
Victor Vasilievbee79ea2019-05-15 01:25:4810122 EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress);
Renjiea0cb4a2c2018-09-26 23:37:3010123
10124 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10125 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10126}
10127
10128// With dns race experiment on, DNS resolve returns async, stale dns used,
10129// connects synchrounously, and then the resolved DNS matches.
10130TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveAsyncStaleMatch) {
Zhongyi Shi967d2f12019-02-08 20:58:5310131 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010132 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10133 Initialize();
10134 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10135 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10136
10137 // Set an address in resolver for asynchronous return.
10138 host_resolver_->set_ondemand_mode(true);
10139 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10140 kCachedIPAddress.ToString(), "");
10141
10142 // Set up the same address in the stale resolver cache.
10143 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10144 HostCache::Entry entry(OK,
10145 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10146 HostCache::Entry::SOURCE_DNS);
10147 base::TimeDelta zero;
10148 HostCache* cache = host_resolver_->GetHostCache();
10149 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10150 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810151 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010152
Ryan Hamiltonabad59e2019-06-06 04:02:5910153 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010154 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10155 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10156 quic_data.AddSocketDataToFactory(socket_factory_.get());
10157
10158 QuicStreamRequest request(factory_.get());
10159 EXPECT_EQ(ERR_IO_PENDING,
10160 request.Request(
Nick Harper23290b82019-05-02 00:02:5610161 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110162 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010163 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10164 failed_on_default_network_callback_, callback_.callback()));
10165
10166 // Check that the racing job is running.
10167 EXPECT_TRUE(HasLiveSession(host_port_pair_));
10168 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10169
10170 // Resolve dns and return.
10171 host_resolver_->ResolveAllPending();
10172 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10173 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10174 EXPECT_TRUE(stream.get());
10175
10176 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
10177
Victor Vasilievbee79ea2019-05-15 01:25:4810178 EXPECT_EQ(session->peer_address().host().ToString(),
10179 kCachedIPAddress.ToString());
Renjiea0cb4a2c2018-09-26 23:37:3010180
10181 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10182 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10183}
10184
10185// With dns race experiment on, dns resolve async, stale dns used, connect
10186// async, and then the result matches.
10187TEST_P(QuicStreamFactoryTest,
10188 ResultAfterDNSRaceHostResolveAsyncConnectAsyncStaleMatch) {
Zhongyi Shi967d2f12019-02-08 20:58:5310189 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010190 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10191 Initialize();
10192 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10193 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10194
10195 // Set an address in resolver for asynchronous return.
10196 host_resolver_->set_ondemand_mode(true);
10197 factory_->set_require_confirmation(true);
10198 crypto_client_stream_factory_.set_handshake_mode(
10199 MockCryptoClientStream::ZERO_RTT);
10200 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10201 kCachedIPAddress.ToString(), "");
10202
10203 // Set up the same address in the stale resolver cache.
10204 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10205 HostCache::Entry entry(OK,
10206 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10207 HostCache::Entry::SOURCE_DNS);
10208 base::TimeDelta zero;
10209 HostCache* cache = host_resolver_->GetHostCache();
10210 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10211 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810212 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010213
Ryan Hamiltonabad59e2019-06-06 04:02:5910214 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010215 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10216 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10217 quic_data.AddSocketDataToFactory(socket_factory_.get());
10218
10219 QuicStreamRequest request(factory_.get());
10220 EXPECT_EQ(ERR_IO_PENDING,
10221 request.Request(
Nick Harper23290b82019-05-02 00:02:5610222 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110223 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010224 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10225 failed_on_default_network_callback_, callback_.callback()));
10226
10227 // Send Crypto handshake so connect will call back.
10228 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
10229 quic::QuicSession::HANDSHAKE_CONFIRMED);
10230 base::RunLoop().RunUntilIdle();
10231
10232 // Check that the racing job is running.
10233 EXPECT_TRUE(HasLiveSession(host_port_pair_));
10234 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10235
10236 // Resolve dns and call back, make sure job finishes.
10237 host_resolver_->ResolveAllPending();
10238 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10239
10240 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10241 EXPECT_TRUE(stream.get());
10242
10243 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
10244
Victor Vasilievbee79ea2019-05-15 01:25:4810245 EXPECT_EQ(session->peer_address().host().ToString(),
10246 kCachedIPAddress.ToString());
Renjiea0cb4a2c2018-09-26 23:37:3010247
10248 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10249 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10250}
10251
10252// With dns race experiment on, dns resolve async, stale dns used, dns resolve
10253// return, then connection finishes and matches with the result.
10254TEST_P(QuicStreamFactoryTest,
10255 ResultAfterDNSRaceHostResolveAsyncStaleMatchConnectAsync) {
Zhongyi Shi967d2f12019-02-08 20:58:5310256 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010257 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10258 Initialize();
10259 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10260 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10261
10262 // Set an address in resolver for asynchronous return.
10263 host_resolver_->set_ondemand_mode(true);
10264 factory_->set_require_confirmation(true);
10265 crypto_client_stream_factory_.set_handshake_mode(
10266 MockCryptoClientStream::ZERO_RTT);
10267 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10268 kCachedIPAddress.ToString(), "");
10269
10270 // Set up the same address in the stale resolver cache.
10271 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10272 HostCache::Entry entry(OK,
10273 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10274 HostCache::Entry::SOURCE_DNS);
10275 base::TimeDelta zero;
10276 HostCache* cache = host_resolver_->GetHostCache();
10277 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10278 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810279 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010280
Ryan Hamiltonabad59e2019-06-06 04:02:5910281 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010282 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10283 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10284 quic_data.AddSocketDataToFactory(socket_factory_.get());
10285
10286 QuicStreamRequest request(factory_.get());
10287 EXPECT_EQ(ERR_IO_PENDING,
10288 request.Request(
Nick Harper23290b82019-05-02 00:02:5610289 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110290 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010291 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10292 failed_on_default_network_callback_, callback_.callback()));
10293
10294 // Finish dns async, check we still need to wait for stale connection async.
10295 host_resolver_->ResolveAllPending();
10296 base::RunLoop().RunUntilIdle();
10297 EXPECT_FALSE(callback_.have_result());
10298
10299 // Finish stale connection async, and the stale connection should pass dns
10300 // validation.
10301 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
10302 quic::QuicSession::HANDSHAKE_CONFIRMED);
10303 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10304 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10305 EXPECT_TRUE(stream.get());
10306
10307 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Victor Vasilievbee79ea2019-05-15 01:25:4810308 EXPECT_EQ(session->peer_address().host().ToString(),
10309 kCachedIPAddress.ToString());
Renjiea0cb4a2c2018-09-26 23:37:3010310
10311 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10312 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10313}
10314
10315// With dns race experiment on, dns resolve async, stale used and connects
10316// sync, but dns no match
10317TEST_P(QuicStreamFactoryTest,
10318 ResultAfterDNSRaceHostResolveAsyncStaleSyncNoMatch) {
Zhongyi Shi967d2f12019-02-08 20:58:5310319 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010320 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10321 Initialize();
10322 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10323 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10324
10325 // Set an address in resolver for asynchronous return.
10326 host_resolver_->set_ondemand_mode(true);
10327 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10328 kNonCachedIPAddress, "");
10329
10330 // Set up a different address in the stale resolver cache.
10331 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10332 HostCache::Entry entry(OK,
10333 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10334 HostCache::Entry::SOURCE_DNS);
10335 base::TimeDelta zero;
10336 HostCache* cache = host_resolver_->GetHostCache();
10337 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10338 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810339 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010340
10341 // Socket for the stale connection which will invoke connection closure.
Ryan Hamiltonabad59e2019-06-06 04:02:5910342 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010343 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10344 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10345 quic_data.AddWrite(
Renjief5fcb172019-02-05 01:59:3310346 SYNCHRONOUS,
10347 client_maker_.MakeConnectionClosePacket(
10348 2, true, quic::QUIC_STALE_CONNECTION_CANCELLED, "net error"));
Renjiea0cb4a2c2018-09-26 23:37:3010349 quic_data.AddSocketDataToFactory(socket_factory_.get());
10350
10351 // Socket for the new connection.
Ryan Hamilton0d65a8c2019-06-07 00:46:0210352 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:5910353 MockQuicData quic_data2(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010354 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10355 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10356 quic_data2.AddSocketDataToFactory(socket_factory_.get());
10357
10358 QuicStreamRequest request(factory_.get());
10359 EXPECT_EQ(ERR_IO_PENDING,
10360 request.Request(
Nick Harper23290b82019-05-02 00:02:5610361 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110362 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010363 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10364 failed_on_default_network_callback_, callback_.callback()));
10365
10366 // Check the stale connection is running.
10367 EXPECT_TRUE(HasLiveSession(host_port_pair_));
10368 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10369
10370 // Finish dns resolution and check the job has finished.
10371 host_resolver_->ResolveAllPending();
10372 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10373
10374 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10375 EXPECT_TRUE(stream.get());
10376
10377 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
10378
Victor Vasilievbee79ea2019-05-15 01:25:4810379 EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress);
Renjiea0cb4a2c2018-09-26 23:37:3010380
10381 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10382 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10383 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
10384 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
10385}
10386
10387// With dns race experiment on, dns resolve async, stale used and connects
10388// async, finishes before dns, but no match
10389TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleAsyncResolveAsyncNoMatch) {
Zhongyi Shi967d2f12019-02-08 20:58:5310390 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010391 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10392 Initialize();
10393 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10394 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10395
10396 // Set an address in resolver for asynchronous return.
10397 host_resolver_->set_ondemand_mode(true);
10398 factory_->set_require_confirmation(true);
10399 crypto_client_stream_factory_.set_handshake_mode(
10400 MockCryptoClientStream::ZERO_RTT);
10401 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10402 kNonCachedIPAddress, "");
10403
10404 // Set up a different address in the stale resolvercache.
10405 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10406 HostCache::Entry entry(OK,
10407 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10408 HostCache::Entry::SOURCE_DNS);
10409 base::TimeDelta zero;
10410 HostCache* cache = host_resolver_->GetHostCache();
10411 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10412 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810413 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010414
Ryan Hamiltonabad59e2019-06-06 04:02:5910415 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010416 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10417 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10418 quic_data.AddWrite(
Renjief5fcb172019-02-05 01:59:3310419 SYNCHRONOUS,
10420 client_maker_.MakeConnectionClosePacket(
10421 2, true, quic::QUIC_STALE_CONNECTION_CANCELLED, "net error"));
Renjiea0cb4a2c2018-09-26 23:37:3010422 quic_data.AddSocketDataToFactory(socket_factory_.get());
10423
Ryan Hamilton0d65a8c2019-06-07 00:46:0210424 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:5910425 MockQuicData quic_data2(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010426 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10427 quic_data2.AddSocketDataToFactory(socket_factory_.get());
10428
10429 QuicStreamRequest request(factory_.get());
10430 EXPECT_EQ(ERR_IO_PENDING,
10431 request.Request(
Nick Harper23290b82019-05-02 00:02:5610432 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110433 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010434 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10435 failed_on_default_network_callback_, callback_.callback()));
10436
10437 // Finish the stale connection.
10438 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
10439 quic::QuicSession::HANDSHAKE_CONFIRMED);
10440 base::RunLoop().RunUntilIdle();
10441 EXPECT_TRUE(HasLiveSession(host_port_pair_));
10442 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10443
10444 // Finish host resolution and check the job is done.
10445 host_resolver_->ResolveAllPending();
10446 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10447
10448 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10449 EXPECT_TRUE(stream.get());
10450
10451 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Victor Vasilievbee79ea2019-05-15 01:25:4810452 EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress);
Renjiea0cb4a2c2018-09-26 23:37:3010453
10454 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10455 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10456 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
10457 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
10458}
10459
10460// With dns race experiment on, dns resolve async, stale used and connects
10461// async, dns finishes first, but no match
10462TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceResolveAsyncStaleAsyncNoMatch) {
Zhongyi Shi967d2f12019-02-08 20:58:5310463 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010464 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10465 Initialize();
10466 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10467 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10468
10469 // Set an address in resolver for asynchronous return.
10470 host_resolver_->set_ondemand_mode(true);
10471 factory_->set_require_confirmation(true);
10472 crypto_client_stream_factory_.set_handshake_mode(
10473 MockCryptoClientStream::ZERO_RTT);
10474 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10475 kNonCachedIPAddress, "");
10476
10477 // Set up a different address in the stale resolver cache.
10478 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10479 HostCache::Entry entry(OK,
10480 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10481 HostCache::Entry::SOURCE_DNS);
10482 base::TimeDelta zero;
10483 HostCache* cache = host_resolver_->GetHostCache();
10484 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10485 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810486 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010487
Ryan Hamiltonabad59e2019-06-06 04:02:5910488 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010489 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Michael Warres167db3e2019-03-01 21:38:0310490 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:3010491 quic_data.AddWrite(
Renjief5fcb172019-02-05 01:59:3310492 SYNCHRONOUS,
10493 client_maker_.MakeConnectionClosePacket(
10494 1, true, quic::QUIC_STALE_CONNECTION_CANCELLED, "net error"));
Renjiea0cb4a2c2018-09-26 23:37:3010495 quic_data.AddSocketDataToFactory(socket_factory_.get());
10496
Ryan Hamilton0d65a8c2019-06-07 00:46:0210497 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:5910498 MockQuicData quic_data2(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010499 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie8d2d8d91b2018-09-29 00:29:0310500 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
10501 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Renjiea0cb4a2c2018-09-26 23:37:3010502 quic_data2.AddSocketDataToFactory(socket_factory_.get());
10503
10504 QuicStreamRequest request(factory_.get());
10505 EXPECT_EQ(ERR_IO_PENDING,
10506 request.Request(
Nick Harper23290b82019-05-02 00:02:5610507 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110508 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010509 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10510 failed_on_default_network_callback_, callback_.callback()));
10511 // Finish dns resolution, but need to wait for stale connection.
10512 host_resolver_->ResolveAllPending();
Renjie8d2d8d91b2018-09-29 00:29:0310513 base::RunLoop().RunUntilIdle();
Renjiea0cb4a2c2018-09-26 23:37:3010514 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
10515 quic::QuicSession::HANDSHAKE_CONFIRMED);
10516 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10517
10518 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10519 EXPECT_TRUE(stream.get());
10520
10521 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Victor Vasilievbee79ea2019-05-15 01:25:4810522 EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress);
Renjiea0cb4a2c2018-09-26 23:37:3010523
10524 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10525 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10526 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
10527 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
10528}
10529
10530// With dns race experiment on, dns resolve returns error sync, same behavior
10531// as experiment is not on
10532TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveError) {
Zhongyi Shi967d2f12019-02-08 20:58:5310533 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010534 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10535 Initialize();
10536 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10537 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10538
10539 // Set synchronous failure in resolver.
10540 host_resolver_->set_synchronous_mode(true);
10541 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
10542
Ryan Hamiltonabad59e2019-06-06 04:02:5910543 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010544 quic_data.AddSocketDataToFactory(socket_factory_.get());
10545 QuicStreamRequest request(factory_.get());
10546
10547 EXPECT_EQ(ERR_NAME_NOT_RESOLVED,
10548 request.Request(
Nick Harper23290b82019-05-02 00:02:5610549 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110550 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010551 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10552 failed_on_default_network_callback_, callback_.callback()));
10553}
10554
10555// With dns race experiment on, no cache available, dns resolve returns error
10556// async
10557TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveAsyncError) {
Zhongyi Shi967d2f12019-02-08 20:58:5310558 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010559 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10560 Initialize();
10561 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10562 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10563
10564 // Set asynchronous failure in resolver.
10565 host_resolver_->set_ondemand_mode(true);
10566 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
10567
Ryan Hamiltonabad59e2019-06-06 04:02:5910568 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010569 quic_data.AddSocketDataToFactory(socket_factory_.get());
10570 QuicStreamRequest request(factory_.get());
10571
10572 EXPECT_EQ(ERR_IO_PENDING,
10573 request.Request(
Nick Harper23290b82019-05-02 00:02:5610574 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110575 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010576 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10577 failed_on_default_network_callback_, callback_.callback()));
10578
10579 // Resolve and expect result that shows the resolution error.
10580 host_resolver_->ResolveAllPending();
10581 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
10582}
10583
10584// With dns race experiment on, dns resolve async, staled used and connects
10585// sync, dns returns error and no connection is established.
10586TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleSyncHostResolveError) {
Zhongyi Shi967d2f12019-02-08 20:58:5310587 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010588 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10589 Initialize();
10590 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10591 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10592
10593 // Set asynchronous failure in resolver.
10594 host_resolver_->set_ondemand_mode(true);
10595 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
10596
10597 // Set up an address in the stale cache.
10598 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10599 HostCache::Entry entry(OK,
10600 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10601 HostCache::Entry::SOURCE_DNS);
10602 base::TimeDelta zero;
10603 HostCache* cache = host_resolver_->GetHostCache();
10604 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10605 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810606 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010607
10608 // Socket for the stale connection which is supposed to disconnect.
Ryan Hamiltonabad59e2019-06-06 04:02:5910609 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010610 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10611 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10612 quic_data.AddWrite(
Renjief5fcb172019-02-05 01:59:3310613 SYNCHRONOUS,
10614 client_maker_.MakeConnectionClosePacket(
10615 2, true, quic::QUIC_STALE_CONNECTION_CANCELLED, "net error"));
Renjiea0cb4a2c2018-09-26 23:37:3010616 quic_data.AddSocketDataToFactory(socket_factory_.get());
10617
10618 QuicStreamRequest request(factory_.get());
10619 EXPECT_EQ(ERR_IO_PENDING,
10620 request.Request(
Nick Harper23290b82019-05-02 00:02:5610621 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110622 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010623 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10624 failed_on_default_network_callback_, callback_.callback()));
10625
10626 // Check that the stale connection is running.
10627 EXPECT_TRUE(HasLiveSession(host_port_pair_));
10628 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10629
10630 // Finish host resolution.
10631 host_resolver_->ResolveAllPending();
10632 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
10633
Renjiea0cb4a2c2018-09-26 23:37:3010634 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10635 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10636}
10637
10638// With dns race experiment on, dns resolve async, stale used and connection
Renjie99ec24b2019-04-26 17:44:3410639// return error, then dns matches.
10640// This serves as a regression test for crbug.com/956374.
Renjiea0cb4a2c2018-09-26 23:37:3010641TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleErrorDNSMatches) {
Zhongyi Shi967d2f12019-02-08 20:58:5310642 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010643 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10644 Initialize();
10645 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10646 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10647
10648 // Set an address in host resolver for asynchronous return.
10649 host_resolver_->set_ondemand_mode(true);
10650 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10651 kCachedIPAddress.ToString(), "");
10652
10653 // Set up the same address in the stale resolver cache.
10654 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10655 HostCache::Entry entry(OK,
10656 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10657 HostCache::Entry::SOURCE_DNS);
10658 base::TimeDelta zero;
10659 HostCache* cache = host_resolver_->GetHostCache();
10660 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10661 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810662 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010663
10664 // Simulate synchronous connect failure.
Ryan Hamiltonabad59e2019-06-06 04:02:5910665 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010666 quic_data.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
10667 quic_data.AddSocketDataToFactory(socket_factory_.get());
10668
Ryan Hamilton0d65a8c2019-06-07 00:46:0210669 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:5910670 MockQuicData quic_data2(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010671 quic_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
10672 quic_data2.AddSocketDataToFactory(socket_factory_.get());
10673
10674 QuicStreamRequest request(factory_.get());
10675 EXPECT_EQ(ERR_IO_PENDING,
10676 request.Request(
Nick Harper23290b82019-05-02 00:02:5610677 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110678 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010679 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10680 failed_on_default_network_callback_, callback_.callback()));
10681 EXPECT_FALSE(HasLiveSession(host_port_pair_));
10682 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10683
10684 host_resolver_->ResolveAllPending();
10685 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_ADDRESS_IN_USE));
10686}
10687
10688// With dns race experiment on, dns resolve async, stale used and connection
10689// returns error, dns no match, new connection is established
10690TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleErrorDNSNoMatch) {
Zhongyi Shi967d2f12019-02-08 20:58:5310691 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010692 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10693 Initialize();
10694 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10695 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10696
10697 // Set an address in host resolver.
10698 host_resolver_->set_ondemand_mode(true);
10699 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10700 kNonCachedIPAddress, "");
10701
10702 // Set up a different address in stale resolver cache.
10703 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10704 HostCache::Entry entry(OK,
10705 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10706 HostCache::Entry::SOURCE_DNS);
10707 base::TimeDelta zero;
10708 HostCache* cache = host_resolver_->GetHostCache();
10709 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10710 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810711 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010712
10713 // Add failure for the stale connection.
Ryan Hamiltonabad59e2019-06-06 04:02:5910714 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010715 quic_data.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
10716 quic_data.AddSocketDataToFactory(socket_factory_.get());
10717
Ryan Hamilton0d65a8c2019-06-07 00:46:0210718 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:5910719 MockQuicData quic_data2(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010720 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10721 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10722 quic_data2.AddSocketDataToFactory(socket_factory_.get());
10723
10724 QuicStreamRequest request(factory_.get());
10725 EXPECT_EQ(ERR_IO_PENDING,
10726 request.Request(
Nick Harper23290b82019-05-02 00:02:5610727 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110728 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010729 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10730 failed_on_default_network_callback_, callback_.callback()));
10731
10732 // Check that the stale connection fails.
10733 EXPECT_FALSE(HasLiveSession(host_port_pair_));
10734 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10735
10736 // Finish host resolution and check the job finishes ok.
10737 host_resolver_->ResolveAllPending();
10738 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10739
10740 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10741 EXPECT_TRUE(stream.get());
10742
10743 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
10744
Victor Vasilievbee79ea2019-05-15 01:25:4810745 EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress);
Renjiea0cb4a2c2018-09-26 23:37:3010746
10747 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
10748 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
10749}
10750
10751// With dns race experiment on, dns resolve async, stale used and connection
10752// returns error, dns no match, new connection error
10753TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleErrorDNSNoMatchError) {
Zhongyi Shi967d2f12019-02-08 20:58:5310754 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010755 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10756 Initialize();
10757 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10758 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10759
10760 // Set an address in host resolver asynchronously.
10761 host_resolver_->set_ondemand_mode(true);
10762 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10763 kNonCachedIPAddress, "");
10764
10765 // Set up a different address in the stale cache.
10766 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10767 HostCache::Entry entry(OK,
10768 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10769 HostCache::Entry::SOURCE_DNS);
10770 base::TimeDelta zero;
10771 HostCache* cache = host_resolver_->GetHostCache();
10772 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10773 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810774 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010775
10776 // Add failure for stale connection.
Ryan Hamiltonabad59e2019-06-06 04:02:5910777 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010778 quic_data.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
10779 quic_data.AddSocketDataToFactory(socket_factory_.get());
10780
10781 // Add failure for resolved dns connection.
Ryan Hamilton0d65a8c2019-06-07 00:46:0210782 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:5910783 MockQuicData quic_data2(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010784 quic_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
10785 quic_data2.AddSocketDataToFactory(socket_factory_.get());
10786
10787 QuicStreamRequest request(factory_.get());
10788 EXPECT_EQ(ERR_IO_PENDING,
10789 request.Request(
Nick Harper23290b82019-05-02 00:02:5610790 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110791 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010792 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10793 failed_on_default_network_callback_, callback_.callback()));
10794
10795 // Check the stale connection fails.
10796 EXPECT_FALSE(HasLiveSession(host_port_pair_));
10797 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10798
10799 // Check the resolved dns connection fails.
10800 host_resolver_->ResolveAllPending();
10801 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_ADDRESS_IN_USE));
10802}
10803
10804// With dns race experiment on, dns resolve async and stale connect async, dns
10805// resolve returns error and then preconnect finishes
10806TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceResolveAsyncErrorStaleAsync) {
Zhongyi Shi967d2f12019-02-08 20:58:5310807 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010808 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10809 Initialize();
10810 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10811 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10812
10813 // Add asynchronous failure in host resolver.
10814 host_resolver_->set_ondemand_mode(true);
10815 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
10816 factory_->set_require_confirmation(true);
10817 crypto_client_stream_factory_.set_handshake_mode(
10818 MockCryptoClientStream::ZERO_RTT);
10819
10820 // Set up an address in stale resolver cache.
10821 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10822 HostCache::Entry entry(OK,
10823 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10824 HostCache::Entry::SOURCE_DNS);
10825 base::TimeDelta zero;
10826 HostCache* cache = host_resolver_->GetHostCache();
10827 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10828 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810829 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010830
10831 // Socket data for stale connection which is supposed to disconnect.
Ryan Hamiltonabad59e2019-06-06 04:02:5910832 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010833 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Michael Warres167db3e2019-03-01 21:38:0310834 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:3010835 quic_data.AddWrite(
Renjief5fcb172019-02-05 01:59:3310836 SYNCHRONOUS,
10837 client_maker_.MakeConnectionClosePacket(
10838 1, true, quic::QUIC_STALE_CONNECTION_CANCELLED, "net error"));
Renjiea0cb4a2c2018-09-26 23:37:3010839 quic_data.AddSocketDataToFactory(socket_factory_.get());
10840
10841 QuicStreamRequest request(factory_.get());
10842 EXPECT_EQ(ERR_IO_PENDING,
10843 request.Request(
Nick Harper23290b82019-05-02 00:02:5610844 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110845 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010846 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10847 failed_on_default_network_callback_, callback_.callback()));
10848
10849 // host resolution returned but stale connection hasn't finished yet.
10850 host_resolver_->ResolveAllPending();
10851 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
10852
10853 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10854 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10855}
10856
10857// With dns race experiment on, dns resolve async and stale connect async, dns
Renjiea0cb4a2c2018-09-26 23:37:3010858// resolve returns error and then preconnect fails.
10859TEST_P(QuicStreamFactoryTest,
10860 ResultAfterDNSRaceResolveAsyncErrorStaleAsyncError) {
Zhongyi Shi967d2f12019-02-08 20:58:5310861 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010862 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10863 Initialize();
10864 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10865 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10866
10867 // Add asynchronous failure to host resolver.
10868 host_resolver_->set_ondemand_mode(true);
10869 factory_->set_require_confirmation(true);
10870 crypto_client_stream_factory_.set_handshake_mode(
10871 MockCryptoClientStream::ZERO_RTT);
10872 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
10873
10874 // Set up an address in stale resolver cache.
10875 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10876 HostCache::Entry entry(OK,
10877 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10878 HostCache::Entry::SOURCE_DNS);
10879 base::TimeDelta zero;
10880 HostCache* cache = host_resolver_->GetHostCache();
10881 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10882 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810883 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010884
Ryan Hamiltonabad59e2019-06-06 04:02:5910885 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010886 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Michael Warres167db3e2019-03-01 21:38:0310887 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:3010888 quic_data.AddWrite(
Renjief5fcb172019-02-05 01:59:3310889 SYNCHRONOUS,
10890 client_maker_.MakeConnectionClosePacket(
10891 1, true, quic::QUIC_STALE_CONNECTION_CANCELLED, "net error"));
Renjiea0cb4a2c2018-09-26 23:37:3010892 quic_data.AddSocketDataToFactory(socket_factory_.get());
10893
10894 QuicStreamRequest request(factory_.get());
10895 EXPECT_EQ(ERR_IO_PENDING,
10896 request.Request(
Nick Harper23290b82019-05-02 00:02:5610897 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110898 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010899 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10900 failed_on_default_network_callback_, callback_.callback()));
10901
10902 // Host Resolution returns failure but stale connection hasn't finished.
10903 host_resolver_->ResolveAllPending();
10904
10905 // Check that the final error is on resolution failure.
10906 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
10907
10908 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10909}
10910
10911// With dns race experiment on, test that host resolution callback behaves
10912// normal as experiment is not on
10913TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveAsync) {
Zhongyi Shi967d2f12019-02-08 20:58:5310914 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010915 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10916 Initialize();
10917 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10918 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10919
10920 host_resolver_->set_ondemand_mode(true);
10921 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10922 kNonCachedIPAddress, "");
10923
Ryan Hamiltonabad59e2019-06-06 04:02:5910924 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010925 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10926 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10927 quic_data.AddSocketDataToFactory(socket_factory_.get());
10928
10929 QuicStreamRequest request(factory_.get());
10930 EXPECT_EQ(ERR_IO_PENDING,
10931 request.Request(
Nick Harper23290b82019-05-02 00:02:5610932 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110933 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010934 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10935 failed_on_default_network_callback_, callback_.callback()));
10936
10937 // Check that expect_on_host_resolution_ is properlly set.
10938 TestCompletionCallback host_resolution_callback;
10939 EXPECT_TRUE(
10940 request.WaitForHostResolution(host_resolution_callback.callback()));
10941 base::RunLoop().RunUntilIdle();
10942 EXPECT_FALSE(host_resolution_callback.have_result());
10943
10944 host_resolver_->ResolveAllPending();
10945 EXPECT_THAT(host_resolution_callback.WaitForResult(), IsOk());
10946
10947 // Check that expect_on_host_resolution_ is flipped back.
10948 EXPECT_FALSE(
10949 request.WaitForHostResolution(host_resolution_callback.callback()));
10950
10951 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10952 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10953}
10954
Renjiea0522f062019-04-29 18:52:2110955TEST_P(QuicStreamFactoryTest, ConfigInitialRttForHandshake) {
10956 int kInitialRtt = 400;
10957 test_params_.quic_initial_rtt_for_handshake_milliseconds = kInitialRtt;
10958 crypto_client_stream_factory_.set_handshake_mode(
10959 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
10960 Initialize();
10961 factory_->set_require_confirmation(true);
10962 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10963 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10964
10965 // Using a testing task runner so that we can control time.
10966 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
10967
10968 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
10969 QuicStreamFactoryPeer::SetAlarmFactory(
10970 factory_.get(),
10971 std::make_unique<QuicChromiumAlarmFactory>(task_runner.get(), &clock_));
10972
Ryan Hamiltonabad59e2019-06-06 04:02:5910973 MockQuicData socket_data(version_);
Renjiea0522f062019-04-29 18:52:2110974 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10975 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
10976 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(2));
10977 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamilton0d65a8c2019-06-07 00:46:0210978 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(3));
10979
Renjiea0522f062019-04-29 18:52:2110980 socket_data.AddSocketDataToFactory(socket_factory_.get());
10981
10982 QuicStreamRequest request(factory_.get());
10983 EXPECT_EQ(ERR_IO_PENDING,
10984 request.Request(
Nick Harper23290b82019-05-02 00:02:5610985 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110986 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0522f062019-04-29 18:52:2110987 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10988 failed_on_default_network_callback_, callback_.callback()));
10989 base::RunLoop().RunUntilIdle();
10990
10991 EXPECT_FALSE(HasActiveSession(host_port_pair_));
10992 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10993
10994 // The pending task is scheduled for handshake timeout retransmission,
10995 // which is 2 * 400ms for v99 and 1.5 * 400ms for others.
Nick Harper23290b82019-05-02 00:02:5610996 int handshake_timeout = version_.transport_version == quic::QUIC_VERSION_99
10997 ? 2 * kInitialRtt
10998 : 1.5 * kInitialRtt;
Renjiea0522f062019-04-29 18:52:2110999 EXPECT_EQ(base::TimeDelta::FromMilliseconds(handshake_timeout),
11000 task_runner->NextPendingTaskDelay());
11001
11002 // The alarm factory dependes on |clock_|, so clock is advanced to trigger
11003 // retransmission alarm.
11004 clock_.AdvanceTime(
11005 quic::QuicTime::Delta::FromMilliseconds(handshake_timeout));
11006 task_runner->FastForwardBy(
11007 base::TimeDelta::FromMilliseconds(handshake_timeout));
11008
11009 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
11010 quic::QuicSession::HANDSHAKE_CONFIRMED);
11011
11012 EXPECT_THAT(callback_.WaitForResult(), IsOk());
11013
11014 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
11015 EXPECT_EQ(400000u, session->config()->GetInitialRoundTripTimeUsToSend());
11016 EXPECT_TRUE(socket_data.AllReadDataConsumed());
11017 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
11018}
11019
Paul Jensen8e3c5d32018-02-19 17:06:3311020// Test that QuicStreamRequests with similar and different tags results in
11021// reused and unique QUIC streams using appropriately tagged sockets.
11022TEST_P(QuicStreamFactoryTest, Tag) {
11023 MockTaggingClientSocketFactory* socket_factory =
11024 new MockTaggingClientSocketFactory();
11025 socket_factory_.reset(socket_factory);
11026 Initialize();
11027 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
11028 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
11029
11030 // Prepare to establish two QUIC sessions.
Ryan Hamiltonabad59e2019-06-06 04:02:5911031 MockQuicData socket_data(version_);
Paul Jensen8e3c5d32018-02-19 17:06:3311032 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:4311033 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Paul Jensen8e3c5d32018-02-19 17:06:3311034 socket_data.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamilton0d65a8c2019-06-07 00:46:0211035 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:5911036 MockQuicData socket_data2(version_);
Paul Jensen8e3c5d32018-02-19 17:06:3311037 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:4311038 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Paul Jensen8e3c5d32018-02-19 17:06:3311039 socket_data2.AddSocketDataToFactory(socket_factory_.get());
11040
11041#if defined(OS_ANDROID)
11042 SocketTag tag1(SocketTag::UNSET_UID, 0x12345678);
11043 SocketTag tag2(getuid(), 0x87654321);
11044#else
11045 // On non-Android platforms we can only use the default constructor.
11046 SocketTag tag1, tag2;
11047#endif
11048
11049 // Request a stream with |tag1|.
11050 QuicStreamRequest request1(factory_.get());
Zhongyi Shia6b68d112018-09-24 07:49:0311051 int rv = request1.Request(
Nick Harper23290b82019-05-02 00:02:5611052 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5111053 DEFAULT_PRIORITY, tag1, NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:0311054 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
11055 failed_on_default_network_callback_, callback_.callback());
Paul Jensen8e3c5d32018-02-19 17:06:3311056 EXPECT_THAT(callback_.GetResult(rv), IsOk());
11057 EXPECT_EQ(socket_factory->GetLastProducedUDPSocket()->tag(), tag1);
11058 EXPECT_TRUE(socket_factory->GetLastProducedUDPSocket()
11059 ->tagged_before_data_transferred());
11060 std::unique_ptr<QuicChromiumClientSession::Handle> stream1 =
11061 request1.ReleaseSessionHandle();
11062 EXPECT_TRUE(stream1);
11063 EXPECT_TRUE(stream1->IsConnected());
11064
11065 // Request a stream with |tag1| and verify underlying session is reused.
11066 QuicStreamRequest request2(factory_.get());
Zhongyi Shia6b68d112018-09-24 07:49:0311067 rv = request2.Request(
Nick Harper23290b82019-05-02 00:02:5611068 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5111069 DEFAULT_PRIORITY, tag1, NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:0311070 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
11071 failed_on_default_network_callback_, callback_.callback());
Paul Jensen8e3c5d32018-02-19 17:06:3311072 EXPECT_THAT(callback_.GetResult(rv), IsOk());
11073 std::unique_ptr<QuicChromiumClientSession::Handle> stream2 =
11074 request2.ReleaseSessionHandle();
11075 EXPECT_TRUE(stream2);
11076 EXPECT_TRUE(stream2->IsConnected());
11077 EXPECT_TRUE(stream2->SharesSameSession(*stream1));
11078
11079 // Request a stream with |tag2| and verify a new session is created.
11080 QuicStreamRequest request3(factory_.get());
Zhongyi Shia6b68d112018-09-24 07:49:0311081 rv = request3.Request(
Nick Harper23290b82019-05-02 00:02:5611082 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5111083 DEFAULT_PRIORITY, tag2, NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:0311084 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
11085 failed_on_default_network_callback_, callback_.callback());
Paul Jensen8e3c5d32018-02-19 17:06:3311086 EXPECT_THAT(callback_.GetResult(rv), IsOk());
11087 EXPECT_EQ(socket_factory->GetLastProducedUDPSocket()->tag(), tag2);
11088 EXPECT_TRUE(socket_factory->GetLastProducedUDPSocket()
11089 ->tagged_before_data_transferred());
11090 std::unique_ptr<QuicChromiumClientSession::Handle> stream3 =
11091 request3.ReleaseSessionHandle();
11092 EXPECT_TRUE(stream3);
11093 EXPECT_TRUE(stream3->IsConnected());
11094#if defined(OS_ANDROID)
11095 EXPECT_FALSE(stream3->SharesSameSession(*stream1));
11096#else
11097 // Same tag should reuse session.
11098 EXPECT_TRUE(stream3->SharesSameSession(*stream1));
11099#endif
11100}
11101
[email protected]e13201d82012-12-12 05:00:3211102} // namespace test
[email protected]e13201d82012-12-12 05:00:3211103} // namespace net