blob: e9aa621b55a1ed27153c9fad5a59a6f468a367a4 [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) {
Ryan Hamilton9ef8c102019-06-28 03:58:52182 // TODO(rch): crbug.com/978745 - Make this work with TLS
183 if (version.handshake_protocol != quic::PROTOCOL_TLS1_3) {
184 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, false});
185 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, true});
186 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, false});
187 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, true});
188 params.push_back(PoolingTestParams{version, DIFFERENT, false});
189 params.push_back(PoolingTestParams{version, DIFFERENT, true});
190 }
rtenneti14abd312015-02-06 21:56:01191 }
192 return params;
193}
194
bnc912a04b2016-04-20 14:19:50195} // namespace
[email protected]3c772402013-12-18 21:38:11196
bnc359ed2a2016-04-29 20:43:45197class QuicHttpStreamPeer {
198 public:
rchf0b18c8a2017-05-05 19:31:57199 static QuicChromiumClientSession::Handle* GetSessionHandle(
200 HttpStream* stream) {
201 return static_cast<QuicHttpStream*>(stream)->quic_session();
bnc359ed2a2016-04-29 20:43:45202 }
203};
204
Zhongyi Shi5f587cc2017-11-21 23:24:17205// TestConnectionMigrationSocketFactory will vend sockets with incremental port
206// number.
207class TestConnectionMigrationSocketFactory : public MockClientSocketFactory {
208 public:
209 TestConnectionMigrationSocketFactory() : next_source_port_num_(1u) {}
210 ~TestConnectionMigrationSocketFactory() override {}
211
212 std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
213 DatagramSocket::BindType bind_type,
Zhongyi Shi5f587cc2017-11-21 23:24:17214 NetLog* net_log,
215 const NetLogSource& source) override {
216 SocketDataProvider* data_provider = mock_data().GetNext();
217 std::unique_ptr<MockUDPClientSocket> socket(
218 new MockUDPClientSocket(data_provider, net_log));
219 socket->set_source_port(next_source_port_num_++);
220 return std::move(socket);
221 }
222
223 private:
224 uint16_t next_source_port_num_;
225
226 DISALLOW_COPY_AND_ASSIGN(TestConnectionMigrationSocketFactory);
227};
228
Bence Béky98447b12018-05-08 03:14:01229class QuicStreamFactoryTestBase : public WithScopedTaskEnvironment {
[email protected]e13201d82012-12-12 05:00:32230 protected:
Nick Harper23290b82019-05-02 00:02:56231 QuicStreamFactoryTestBase(quic::ParsedQuicVersion version,
Yixin Wang079ad542018-01-11 04:06:05232 bool client_headers_include_h2_stream_dependency)
Renjiea0cb4a2c2018-09-26 23:37:30233 : host_resolver_(new MockHostResolver),
234 ssl_config_service_(new MockSSLConfigService),
Zhongyi Shi5f587cc2017-11-21 23:24:17235 socket_factory_(new MockClientSocketFactory),
nharper642ae4b2016-06-30 00:40:36236 random_generator_(0),
rchbf4c26d2017-04-16 23:17:55237 runner_(new TestTaskRunner(&clock_)),
bnc359ed2a2016-04-29 20:43:45238 version_(version),
David Schinazic8281052019-01-24 06:14:17239 client_maker_(
240 version_,
241 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
242 &clock_,
243 kDefaultServerHostName,
244 quic::Perspective::IS_CLIENT,
Zhongyi Shi967d2f12019-02-08 20:58:53245 client_headers_include_h2_stream_dependency),
David Schinazic8281052019-01-24 06:14:17246 server_maker_(
247 version_,
248 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
249 &clock_,
250 kDefaultServerHostName,
251 quic::Perspective::IS_SERVER,
252 false),
Ryan Sleevi987d2d92017-12-19 19:22:14253 cert_verifier_(std::make_unique<MockCertVerifier>()),
Ryan Sleevi987d2d92017-12-19 19:22:14254 cert_transparency_verifier_(std::make_unique<DoNothingCTVerifier>()),
jri7e636642016-01-14 06:57:08255 scoped_mock_network_change_notifier_(nullptr),
jri7046038f2015-10-22 00:29:26256 factory_(nullptr),
[email protected]bf4ea2f2014-03-10 22:57:53257 host_port_pair_(kDefaultServerHostName, kDefaultServerPort),
ckrasic3865ee0f2016-02-29 22:04:56258 url_(kDefaultUrl),
259 url2_(kServer2Url),
260 url3_(kServer3Url),
261 url4_(kServer4Url),
jri7046038f2015-10-22 00:29:26262 privacy_mode_(PRIVACY_MODE_DISABLED),
Zhongyi Shia6b68d112018-09-24 07:49:03263 failed_on_default_network_callback_(base::BindRepeating(
264 &QuicStreamFactoryTestBase::OnFailedOnDefaultNetwork,
265 base::Unretained(this))),
266 failed_on_default_network_(false),
Zhongyi Shi967d2f12019-02-08 20:58:53267 store_server_configs_in_properties_(false) {
268 test_params_.quic_headers_include_h2_stream_dependency =
269 client_headers_include_h2_stream_dependency;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52270 clock_.AdvanceTime(quic::QuicTime::Delta::FromSeconds(1));
bnc359ed2a2016-04-29 20:43:45271 }
272
jri7046038f2015-10-22 00:29:26273 void Initialize() {
bnc359ed2a2016-04-29 20:43:45274 DCHECK(!factory_);
jri7046038f2015-10-22 00:29:26275 factory_.reset(new QuicStreamFactory(
Renjiea0cb4a2c2018-09-26 23:37:30276 net_log_.net_log(), host_resolver_.get(), ssl_config_service_.get(),
Zhongyi Shi5f587cc2017-11-21 23:24:17277 socket_factory_.get(), &http_server_properties_, cert_verifier_.get(),
Nick Harperecf319d2018-10-16 07:58:54278 &ct_policy_enforcer_, &transport_security_state_,
279 cert_transparency_verifier_.get(),
jri7046038f2015-10-22 00:29:26280 /*SocketPerformanceWatcherFactory*/ nullptr,
rchbf4c26d2017-04-16 23:17:55281 &crypto_client_stream_factory_, &random_generator_, &clock_,
Zhongyi Shi967d2f12019-02-08 20:58:53282 test_params_.quic_max_packet_length, test_params_.quic_user_agent_id,
283 store_server_configs_in_properties_,
284 test_params_.quic_close_sessions_on_ip_change,
285 test_params_.quic_goaway_sessions_on_ip_change,
286 test_params_.mark_quic_broken_when_network_blackholes,
287 test_params_.quic_idle_connection_timeout_seconds,
288 test_params_.quic_reduced_ping_timeout_seconds,
Zhongyi Shie01f2db2019-02-22 19:53:23289 test_params_.quic_retransmittable_on_wire_timeout_milliseconds,
Zhongyi Shi967d2f12019-02-08 20:58:53290 test_params_.quic_max_time_before_crypto_handshake_seconds,
291 test_params_.quic_max_idle_time_before_crypto_handshake_seconds,
292 test_params_.quic_migrate_sessions_on_network_change_v2,
293 test_params_.quic_migrate_sessions_early_v2,
294 test_params_.quic_retry_on_alternate_network_before_handshake,
Zhongyi Shi32fe14d42019-02-28 00:25:36295 test_params_.quic_migrate_idle_sessions,
Zhongyi Shic16b4102019-02-12 00:37:40296 test_params_.quic_idle_session_migration_period,
Zhongyi Shi967d2f12019-02-08 20:58:53297 test_params_.quic_max_time_on_non_default_network,
298 test_params_.quic_max_migrations_to_non_default_network_on_write_error,
299 test_params_
300 .quic_max_migrations_to_non_default_network_on_path_degrading,
301 test_params_.quic_allow_server_migration,
302 test_params_.quic_race_stale_dns_on_connection,
303 test_params_.quic_go_away_on_path_degrading,
304 test_params_.quic_race_cert_verification,
305 test_params_.quic_estimate_initial_rtt,
306 test_params_.quic_headers_include_h2_stream_dependency,
307 test_params_.quic_connection_options,
308 test_params_.quic_client_connection_options,
Renjiea0522f062019-04-29 18:52:21309 test_params_.quic_enable_socket_recv_optimization,
310 test_params_.quic_initial_rtt_for_handshake_milliseconds));
[email protected]e13201d82012-12-12 05:00:32311 }
312
Zhongyi Shi5f587cc2017-11-21 23:24:17313 void InitializeConnectionMigrationV2Test(
314 NetworkChangeNotifier::NetworkList connected_networks) {
315 scoped_mock_network_change_notifier_.reset(
316 new ScopedMockNetworkChangeNotifier());
317 MockNetworkChangeNotifier* mock_ncn =
318 scoped_mock_network_change_notifier_->mock_network_change_notifier();
319 mock_ncn->ForceNetworkHandlesSupported();
320 mock_ncn->SetConnectedNetworksList(connected_networks);
Zhongyi Shi967d2f12019-02-08 20:58:53321 test_params_.quic_migrate_sessions_on_network_change_v2 = true;
322 test_params_.quic_migrate_sessions_early_v2 = true;
Zhongyi Shi5f587cc2017-11-21 23:24:17323 socket_factory_.reset(new TestConnectionMigrationSocketFactory);
324 Initialize();
325 }
326
Yixin Wang7891a39d2017-11-08 20:59:24327 std::unique_ptr<HttpStream> CreateStream(QuicStreamRequest* request) {
328 std::unique_ptr<QuicChromiumClientSession::Handle> session =
329 request->ReleaseSessionHandle();
330 if (!session || !session->IsConnected())
331 return nullptr;
332
333 return std::make_unique<QuicHttpStream>(std::move(session));
334 }
335
bnccb7ff3c2015-05-21 20:51:55336 bool HasActiveSession(const HostPortPair& host_port_pair) {
Ryan Hamilton4f0b26e2018-06-27 23:52:32337 quic::QuicServerId server_id(host_port_pair.host(), host_port_pair.port(),
338 false);
bnc5fdc07162016-05-23 17:36:03339 return QuicStreamFactoryPeer::HasActiveSession(factory_.get(), server_id);
bnccb7ff3c2015-05-21 20:51:55340 }
341
Renjiea0cb4a2c2018-09-26 23:37:30342 bool HasLiveSession(const HostPortPair& host_port_pair) {
343 quic::QuicServerId server_id(host_port_pair.host(), host_port_pair.port(),
344 false);
345 return QuicStreamFactoryPeer::HasLiveSession(factory_.get(), host_port_pair,
346 server_id);
347 }
348
zhongyi363c91c2017-03-23 23:16:08349 bool HasActiveJob(const HostPortPair& host_port_pair,
350 const PrivacyMode privacy_mode) {
Ryan Hamilton4f0b26e2018-06-27 23:52:32351 quic::QuicServerId server_id(host_port_pair.host(), host_port_pair.port(),
352 privacy_mode == PRIVACY_MODE_ENABLED);
zhongyi363c91c2017-03-23 23:16:08353 return QuicStreamFactoryPeer::HasActiveJob(factory_.get(), server_id);
354 }
355
Ryan Hamilton8d9ee76e2018-05-29 23:52:52356 bool HasActiveCertVerifierJob(const quic::QuicServerId& server_id) {
rtennetid073dd22016-08-04 01:58:33357 return QuicStreamFactoryPeer::HasActiveCertVerifierJob(factory_.get(),
358 server_id);
359 }
360
Zhongyi Shic1449372018-08-09 09:58:58361 // Get the pending, not activated session, if there is only one session alive.
362 QuicChromiumClientSession* GetPendingSession(
363 const HostPortPair& host_port_pair) {
364 quic::QuicServerId server_id(host_port_pair.host(), host_port_pair.port(),
365 false);
366 return QuicStreamFactoryPeer::GetPendingSession(factory_.get(), server_id,
367 host_port_pair);
368 }
369
bnc912a04b2016-04-20 14:19:50370 QuicChromiumClientSession* GetActiveSession(
371 const HostPortPair& host_port_pair) {
Ryan Hamilton4f0b26e2018-06-27 23:52:32372 quic::QuicServerId server_id(host_port_pair.host(), host_port_pair.port(),
373 false);
bnc5fdc07162016-05-23 17:36:03374 return QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server_id);
bnc912a04b2016-04-20 14:19:50375 }
376
[email protected]bf4ea2f2014-03-10 22:57:53377 int GetSourcePortForNewSession(const HostPortPair& destination) {
[email protected]d8e2abf82014-03-06 10:30:10378 return GetSourcePortForNewSessionInner(destination, false);
379 }
380
rjshaded5ced072015-12-18 19:26:02381 int GetSourcePortForNewSessionAndGoAway(const HostPortPair& destination) {
[email protected]d8e2abf82014-03-06 10:30:10382 return GetSourcePortForNewSessionInner(destination, true);
383 }
384
[email protected]bf4ea2f2014-03-10 22:57:53385 int GetSourcePortForNewSessionInner(const HostPortPair& destination,
[email protected]d8e2abf82014-03-06 10:30:10386 bool goaway_received) {
[email protected]3c772402013-12-18 21:38:11387 // Should only be called if there is no active session for this destination.
bnccb7ff3c2015-05-21 20:51:55388 EXPECT_FALSE(HasActiveSession(destination));
Zhongyi Shi5f587cc2017-11-21 23:24:17389 size_t socket_count = socket_factory_->udp_client_socket_ports().size();
[email protected]3c772402013-12-18 21:38:11390
Ryan Hamiltonabad59e2019-06-06 04:02:59391 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:36392 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:43393 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:17394 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]3c772402013-12-18 21:38:11395
zhongyi98d6a9262017-05-19 02:47:45396 QuicStreamRequest request(factory_.get());
ckrasic3865ee0f2016-02-29 22:04:56397 GURL url("https://" + destination.host() + "/");
Nick Harper23290b82019-05-02 00:02:56398 EXPECT_EQ(ERR_IO_PENDING,
399 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:52400 destination, version_, privacy_mode_, DEFAULT_PRIORITY,
401 SocketTag(), NetworkIsolationKey(),
Nick Harper23290b82019-05-02 00:02:56402 /*cert_verify_flags=*/0, url, net_log_, &net_error_details_,
403 failed_on_default_network_callback_, callback_.callback()));
[email protected]3c772402013-12-18 21:38:11404
robpercival214763f2016-07-01 23:27:01405 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:24406 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]3c772402013-12-18 21:38:11407 EXPECT_TRUE(stream.get());
408 stream.reset();
409
bnc912a04b2016-04-20 14:19:50410 QuicChromiumClientSession* session = GetActiveSession(destination);
[email protected]3c772402013-12-18 21:38:11411
Zhongyi Shi5f587cc2017-11-21 23:24:17412 if (socket_count + 1 != socket_factory_->udp_client_socket_ports().size()) {
mmenke651bae7f2015-12-18 21:26:45413 ADD_FAILURE();
[email protected]3c772402013-12-18 21:38:11414 return 0;
415 }
416
[email protected]d8e2abf82014-03-06 10:30:10417 if (goaway_received) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:52418 quic::QuicGoAwayFrame goaway(quic::kInvalidControlFrameId,
419 quic::QUIC_NO_ERROR, 1, "");
rtenneti9bd5d4b2015-08-21 05:44:52420 session->connection()->OnGoAwayFrame(goaway);
[email protected]d8e2abf82014-03-06 10:30:10421 }
[email protected]3c772402013-12-18 21:38:11422
jri7046038f2015-10-22 00:29:26423 factory_->OnSessionClosed(session);
bnccb7ff3c2015-05-21 20:51:55424 EXPECT_FALSE(HasActiveSession(destination));
rch37de576c2015-05-17 20:28:17425 EXPECT_TRUE(socket_data.AllReadDataConsumed());
426 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
Zhongyi Shi5f587cc2017-11-21 23:24:17427 return socket_factory_->udp_client_socket_ports()[socket_count];
[email protected]3c772402013-12-18 21:38:11428 }
429
Ryan Hamilton8d9ee76e2018-05-29 23:52:52430 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23431 ConstructClientConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03432 return client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52433 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
rtenneti1cd3b162015-09-29 02:58:28434 }
435
Ryan Hamilton8d9ee76e2018-05-29 23:52:52436 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
Fan Yangac867502019-01-28 21:10:23437 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52438 quic::QuicRstStreamErrorCode error_code) {
Fan Yang32c5a112018-12-10 20:06:33439 quic::QuicStreamId stream_id =
440 GetNthClientInitiatedBidirectionalStreamId(0);
fayang3bcb8b502016-12-07 21:44:37441 return client_maker_.MakeRstPacket(packet_number, true, stream_id,
Jana Iyengarba355772017-09-21 22:03:21442 error_code);
fayang3bcb8b502016-12-07 21:44:37443 }
444
bncf8bf0722015-05-19 20:04:13445 static ProofVerifyDetailsChromium DefaultProofVerifyDetails() {
rch6faa4d42016-01-05 20:48:43446 // Load a certificate that is valid for *.example.org
bncf8bf0722015-05-19 20:04:13447 scoped_refptr<X509Certificate> test_cert(
rch6faa4d42016-01-05 20:48:43448 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bncf8bf0722015-05-19 20:04:13449 EXPECT_TRUE(test_cert.get());
450 ProofVerifyDetailsChromium verify_details;
451 verify_details.cert_verify_result.verified_cert = test_cert;
452 verify_details.cert_verify_result.is_issued_by_known_root = true;
453 return verify_details;
454 }
455
jri8c44d692015-10-23 23:53:41456 void NotifyIPAddressChanged() {
457 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
jri7e636642016-01-14 06:57:08458 // Spin the message loop so the notification is delivered.
fdoray92e35a72016-06-10 15:54:55459 base::RunLoop().RunUntilIdle();
jri8c44d692015-10-23 23:53:41460 }
461
Ryan Hamilton8d9ee76e2018-05-29 23:52:52462 std::unique_ptr<quic::QuicEncryptedPacket> ConstructGetRequestPacket(
Fan Yangac867502019-01-28 21:10:23463 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52464 quic::QuicStreamId stream_id,
jri7e636642016-01-14 06:57:08465 bool should_include_version,
466 bool fin) {
Ryan Hamilton0239aac2018-05-19 00:03:13467 spdy::SpdyHeaderBlock headers =
alyssar2adf3ac2016-05-03 17:12:58468 client_maker_.GetRequestHeaders("GET", "https", "/");
Ryan Hamilton0239aac2018-05-19 00:03:13469 spdy::SpdyPriority priority =
jri7e636642016-01-14 06:57:08470 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
471 size_t spdy_headers_frame_len;
alyssar2adf3ac2016-05-03 17:12:58472 return client_maker_.MakeRequestHeadersPacket(
jri7e636642016-01-14 06:57:08473 packet_number, stream_id, should_include_version, fin, priority,
Yixin Wang7a3f1b8d2018-01-17 21:40:48474 std::move(headers), 0, &spdy_headers_frame_len);
jri7e636642016-01-14 06:57:08475 }
476
Ryan Hamilton8d9ee76e2018-05-29 23:52:52477 std::unique_ptr<quic::QuicEncryptedPacket> ConstructGetRequestPacket(
Fan Yangac867502019-01-28 21:10:23478 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52479 quic::QuicStreamId stream_id,
Zhongyi Shi3c4c9e92018-07-02 23:16:23480 quic::QuicStreamId parent_stream_id,
fayang3bcb8b502016-12-07 21:44:37481 bool should_include_version,
Ryan Hamilton0d65a8c2019-06-07 00:46:02482 bool fin) {
Ryan Hamilton0239aac2018-05-19 00:03:13483 spdy::SpdyHeaderBlock headers =
fayang3bcb8b502016-12-07 21:44:37484 client_maker_.GetRequestHeaders("GET", "https", "/");
Ryan Hamilton0239aac2018-05-19 00:03:13485 spdy::SpdyPriority priority =
fayang3bcb8b502016-12-07 21:44:37486 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
487 size_t spdy_headers_frame_len;
488 return client_maker_.MakeRequestHeadersPacket(
489 packet_number, stream_id, should_include_version, fin, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02490 std::move(headers), parent_stream_id, &spdy_headers_frame_len);
fayang3bcb8b502016-12-07 21:44:37491 }
492
Ryan Hamilton8d9ee76e2018-05-29 23:52:52493 std::unique_ptr<quic::QuicEncryptedPacket> ConstructOkResponsePacket(
Fan Yangac867502019-01-28 21:10:23494 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52495 quic::QuicStreamId stream_id,
jri7e636642016-01-14 06:57:08496 bool should_include_version,
497 bool fin) {
Ryan Hamilton0239aac2018-05-19 00:03:13498 spdy::SpdyHeaderBlock headers = server_maker_.GetResponseHeaders("200 OK");
jri7e636642016-01-14 06:57:08499 size_t spdy_headers_frame_len;
alyssar2adf3ac2016-05-03 17:12:58500 return server_maker_.MakeResponseHeadersPacket(
bnc086b39e12016-06-24 13:05:26501 packet_number, stream_id, should_include_version, fin,
502 std::move(headers), &spdy_headers_frame_len);
jri7e636642016-01-14 06:57:08503 }
504
Ryan Hamilton8d9ee76e2018-05-29 23:52:52505 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket() {
Ryan Hamilton0d65a8c2019-06-07 00:46:02506 return client_maker_.MakeInitialSettingsPacket(1);
rch5cb522462017-04-25 20:18:36507 }
508
Ryan Hamilton8d9ee76e2018-05-29 23:52:52509 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:02510 uint64_t packet_number) {
511 return client_maker_.MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:37512 }
513
jri053fdbd2016-08-19 02:33:05514 // Helper method for server migration tests.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52515 void VerifyServerMigration(const quic::QuicConfig& config,
bnc6a0348c2017-05-22 18:56:19516 IPEndPoint expected_address) {
Zhongyi Shi967d2f12019-02-08 20:58:53517 test_params_.quic_allow_server_migration = true;
jri053fdbd2016-08-19 02:33:05518 Initialize();
519
520 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
521 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri053fdbd2016-08-19 02:33:05522 crypto_client_stream_factory_.SetConfig(config);
523
524 // Set up first socket data provider.
Ryan Hamiltonabad59e2019-06-06 04:02:59525 MockQuicData socket_data1(version_);
rcha00569732016-08-27 11:09:36526 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:17527 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri053fdbd2016-08-19 02:33:05528
Ryan Hamilton9f2eac32019-06-27 03:15:54529 client_maker_.set_coalesce_http_frames(true);
rcha00569732016-08-27 11:09:36530 // Set up second socket data provider that is used after
531 // migration.
Ryan Hamiltonabad59e2019-06-06 04:02:59532 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:36533 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:43534 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
fayang3bcb8b502016-12-07 21:44:37535 socket_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:43536 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
537 socket_data2.AddWrite(
Fan Yang32c5a112018-12-10 20:06:33538 SYNCHRONOUS, client_maker_.MakeRstPacket(
539 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
540 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:17541 socket_data2.AddSocketDataToFactory(socket_factory_.get());
jri053fdbd2016-08-19 02:33:05542
543 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:45544 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:33545 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:03546 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:52547 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
548 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:03549 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
550 failed_on_default_network_callback_, callback_.callback()));
jri053fdbd2016-08-19 02:33:05551 EXPECT_EQ(OK, callback_.WaitForResult());
bnceb9aa7112017-01-05 01:03:46552
553 // Run QuicChromiumClientSession::WriteToNewSocket()
554 // posted by QuicChromiumClientSession::MigrateToSocket().
555 base::RunLoop().RunUntilIdle();
556
Yixin Wang7891a39d2017-11-08 20:59:24557 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri053fdbd2016-08-19 02:33:05558 EXPECT_TRUE(stream.get());
559
560 // Cause QUIC stream to be created.
561 HttpRequestInfo request_info;
562 request_info.method = "GET";
563 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:39564 request_info.traffic_annotation =
565 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:27566 EXPECT_EQ(OK,
567 stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:39568 net_log_, CompletionOnceCallback()));
jri053fdbd2016-08-19 02:33:05569 // Ensure that session is alive and active.
570 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
571 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
572 EXPECT_TRUE(HasActiveSession(host_port_pair_));
573
574 IPEndPoint actual_address;
575 session->GetDefaultSocket()->GetPeerAddress(&actual_address);
576 EXPECT_EQ(actual_address, expected_address);
577 DVLOG(1) << "Socket connected to: " << actual_address.address().ToString()
578 << " " << actual_address.port();
579 DVLOG(1) << "Expected address: " << expected_address.address().ToString()
580 << " " << expected_address.port();
581
582 stream.reset();
583 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
584 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
585 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
586 }
587
tbansal3b966952016-10-25 23:25:14588 // Verifies that the QUIC stream factory is initialized correctly.
tbansal9b1cdf32017-05-10 17:28:39589 void VerifyInitialization() {
rch431dd4452017-04-19 15:22:35590 store_server_configs_in_properties_ = true;
Zhongyi Shi967d2f12019-02-08 20:58:53591 test_params_.quic_idle_connection_timeout_seconds = 500;
tbansal3b966952016-10-25 23:25:14592 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:20593 factory_->set_require_confirmation(false);
tbansal3b966952016-10-25 23:25:14594 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
595 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rch431dd4452017-04-19 15:22:35596 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
597 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:27598 MockCryptoClientStream::ZERO_RTT);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52599 const quic::QuicConfig* config =
600 QuicStreamFactoryPeer::GetConfig(factory_.get());
ckrasic32b17dcd2016-10-31 06:15:35601 EXPECT_EQ(500, config->IdleNetworkTimeout().ToSeconds());
tbansal3b966952016-10-25 23:25:14602
603 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
604
bnc3472afd2016-11-17 15:27:21605 const AlternativeService alternative_service1(
606 kProtoQUIC, host_port_pair_.host(), host_port_pair_.port());
tbansal3b966952016-10-25 23:25:14607 AlternativeServiceInfoVector alternative_service_info_vector;
608 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
609 alternative_service_info_vector.push_back(
zhongyie537a002017-06-27 16:48:21610 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
611 alternative_service1, expiration, {version_}));
tbansal3b966952016-10-25 23:25:14612 http_server_properties_.SetAlternativeServices(
613 url::SchemeHostPort(url_), alternative_service_info_vector);
614
615 HostPortPair host_port_pair2(kServer2HostName, kDefaultServerPort);
616 url::SchemeHostPort server2("https", kServer2HostName, kDefaultServerPort);
bnc3472afd2016-11-17 15:27:21617 const AlternativeService alternative_service2(
618 kProtoQUIC, host_port_pair2.host(), host_port_pair2.port());
tbansal3b966952016-10-25 23:25:14619 AlternativeServiceInfoVector alternative_service_info_vector2;
620 alternative_service_info_vector2.push_back(
zhongyie537a002017-06-27 16:48:21621 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
622 alternative_service2, expiration, {version_}));
tbansal9b1cdf32017-05-10 17:28:39623
624 http_server_properties_.SetAlternativeServices(
625 server2, alternative_service_info_vector2);
626 // Verify that the properties of both QUIC servers are stored in the
627 // HTTP properties map.
628 EXPECT_EQ(2U, http_server_properties_.alternative_service_map().size());
tbansal3b966952016-10-25 23:25:14629
630 http_server_properties_.SetMaxServerConfigsStoredInProperties(
Yixin Wang4a227aa22017-11-30 21:33:01631 kDefaultMaxQuicServerEntries);
tbansal3b966952016-10-25 23:25:14632
Ryan Hamilton8d9ee76e2018-05-29 23:52:52633 quic::QuicServerId quic_server_id(kDefaultServerHostName, 443,
634 PRIVACY_MODE_DISABLED);
rch431dd4452017-04-19 15:22:35635 std::unique_ptr<QuicServerInfo> quic_server_info =
Jeremy Roman0579ed62017-08-29 15:56:19636 std::make_unique<PropertiesBasedQuicServerInfo>(
rch431dd4452017-04-19 15:22:35637 quic_server_id, &http_server_properties_);
tbansal3b966952016-10-25 23:25:14638
639 // Update quic_server_info's server_config and persist it.
640 QuicServerInfo::State* state = quic_server_info->mutable_state();
641 // Minimum SCFG that passes config validation checks.
642 const char scfg[] = {// SCFG
643 0x53, 0x43, 0x46, 0x47,
644 // num entries
645 0x01, 0x00,
646 // padding
647 0x00, 0x00,
648 // EXPY
649 0x45, 0x58, 0x50, 0x59,
650 // EXPY end offset
651 0x08, 0x00, 0x00, 0x00,
652 // Value
653 '1', '2', '3', '4', '5', '6', '7', '8'};
654
655 // Create temporary strings becasue Persist() clears string data in |state|.
656 string server_config(reinterpret_cast<const char*>(&scfg), sizeof(scfg));
657 string source_address_token("test_source_address_token");
658 string cert_sct("test_cert_sct");
659 string chlo_hash("test_chlo_hash");
660 string signature("test_signature");
661 string test_cert("test_cert");
rch872e00e2016-12-02 02:48:18662 std::vector<string> certs;
tbansal3b966952016-10-25 23:25:14663 certs.push_back(test_cert);
664 state->server_config = server_config;
665 state->source_address_token = source_address_token;
666 state->cert_sct = cert_sct;
667 state->chlo_hash = chlo_hash;
668 state->server_config_sig = signature;
669 state->certs = certs;
670
671 quic_server_info->Persist();
672
Ryan Hamilton8d9ee76e2018-05-29 23:52:52673 quic::QuicServerId quic_server_id2(kServer2HostName, 443,
674 PRIVACY_MODE_DISABLED);
rch431dd4452017-04-19 15:22:35675 std::unique_ptr<QuicServerInfo> quic_server_info2 =
Jeremy Roman0579ed62017-08-29 15:56:19676 std::make_unique<PropertiesBasedQuicServerInfo>(
rch431dd4452017-04-19 15:22:35677 quic_server_id2, &http_server_properties_);
tbansal3b966952016-10-25 23:25:14678 // Update quic_server_info2's server_config and persist it.
679 QuicServerInfo::State* state2 = quic_server_info2->mutable_state();
680
681 // Minimum SCFG that passes config validation checks.
682 const char scfg2[] = {// SCFG
683 0x53, 0x43, 0x46, 0x47,
684 // num entries
685 0x01, 0x00,
686 // padding
687 0x00, 0x00,
688 // EXPY
689 0x45, 0x58, 0x50, 0x59,
690 // EXPY end offset
691 0x08, 0x00, 0x00, 0x00,
692 // Value
693 '8', '7', '3', '4', '5', '6', '2', '1'};
694
695 // Create temporary strings becasue Persist() clears string data in
696 // |state2|.
697 string server_config2(reinterpret_cast<const char*>(&scfg2), sizeof(scfg2));
698 string source_address_token2("test_source_address_token2");
699 string cert_sct2("test_cert_sct2");
700 string chlo_hash2("test_chlo_hash2");
701 string signature2("test_signature2");
702 string test_cert2("test_cert2");
rch872e00e2016-12-02 02:48:18703 std::vector<string> certs2;
tbansal3b966952016-10-25 23:25:14704 certs2.push_back(test_cert2);
705 state2->server_config = server_config2;
706 state2->source_address_token = source_address_token2;
707 state2->cert_sct = cert_sct2;
708 state2->chlo_hash = chlo_hash2;
709 state2->server_config_sig = signature2;
710 state2->certs = certs2;
711
712 quic_server_info2->Persist();
713
tbansal3b966952016-10-25 23:25:14714 // Verify the MRU order is maintained.
715 const QuicServerInfoMap& quic_server_info_map =
716 http_server_properties_.quic_server_info_map();
717 EXPECT_EQ(2u, quic_server_info_map.size());
jdoerrie22a91d8b92018-10-05 08:43:26718 auto quic_server_info_map_it = quic_server_info_map.begin();
tbansal3b966952016-10-25 23:25:14719 EXPECT_EQ(quic_server_info_map_it->first, quic_server_id2);
720 ++quic_server_info_map_it;
721 EXPECT_EQ(quic_server_info_map_it->first, quic_server_id);
722
Renjiea0cb4a2c2018-09-26 23:37:30723 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
724 "192.168.0.1", "");
rch431dd4452017-04-19 15:22:35725
726 // Create a session and verify that the cached state is loaded.
Ryan Hamiltonabad59e2019-06-06 04:02:59727 MockQuicData socket_data(version_);
rch431dd4452017-04-19 15:22:35728 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:17729 socket_data.AddSocketDataToFactory(socket_factory_.get());
rch431dd4452017-04-19 15:22:35730
zhongyi98d6a9262017-05-19 02:47:45731 QuicStreamRequest request(factory_.get());
Yixin Wang247ea642017-11-15 01:15:50732 EXPECT_EQ(ERR_IO_PENDING,
Ryan Hamilton4f0b26e2018-06-27 23:52:32733 request.Request(
734 HostPortPair(quic_server_id.host(), quic_server_id.port()),
Ryan Hamilton9ef8c102019-06-28 03:58:52735 version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
736 NetworkIsolationKey(),
Ryan Hamilton4f0b26e2018-06-27 23:52:32737 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
Zhongyi Shia6b68d112018-09-24 07:49:03738 failed_on_default_network_callback_, callback_.callback()));
rch431dd4452017-04-19 15:22:35739 EXPECT_THAT(callback_.WaitForResult(), IsOk());
740
tbansal3b966952016-10-25 23:25:14741 EXPECT_FALSE(QuicStreamFactoryPeer::CryptoConfigCacheIsEmpty(
742 factory_.get(), quic_server_id));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52743 quic::QuicCryptoClientConfig* crypto_config =
tbansal3b966952016-10-25 23:25:14744 QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
Ryan Hamilton8d9ee76e2018-05-29 23:52:52745 quic::QuicCryptoClientConfig::CachedState* cached =
tbansal3b966952016-10-25 23:25:14746 crypto_config->LookupOrCreate(quic_server_id);
747 EXPECT_FALSE(cached->server_config().empty());
748 EXPECT_TRUE(cached->GetServerConfig());
749 EXPECT_EQ(server_config, cached->server_config());
750 EXPECT_EQ(source_address_token, cached->source_address_token());
751 EXPECT_EQ(cert_sct, cached->cert_sct());
752 EXPECT_EQ(chlo_hash, cached->chlo_hash());
753 EXPECT_EQ(signature, cached->signature());
754 ASSERT_EQ(1U, cached->certs().size());
755 EXPECT_EQ(test_cert, cached->certs()[0]);
756
rch431dd4452017-04-19 15:22:35757 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
758
759 // Create a session and verify that the cached state is loaded.
Ryan Hamiltonabad59e2019-06-06 04:02:59760 MockQuicData socket_data2(version_);
rch431dd4452017-04-19 15:22:35761 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:17762 socket_data2.AddSocketDataToFactory(socket_factory_.get());
rch431dd4452017-04-19 15:22:35763
Renjiea0cb4a2c2018-09-26 23:37:30764 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
765 "192.168.0.2", "");
rch431dd4452017-04-19 15:22:35766
zhongyi98d6a9262017-05-19 02:47:45767 QuicStreamRequest request2(factory_.get());
rch431dd4452017-04-19 15:22:35768 EXPECT_EQ(ERR_IO_PENDING,
Ryan Hamilton4f0b26e2018-06-27 23:52:32769 request2.Request(
770 HostPortPair(quic_server_id2.host(), quic_server_id2.port()),
Ryan Hamilton9ef8c102019-06-28 03:58:52771 version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
772 NetworkIsolationKey(),
Ryan Hamilton4f0b26e2018-06-27 23:52:32773 /*cert_verify_flags=*/0, GURL("https://mail.example.org/"),
Zhongyi Shia6b68d112018-09-24 07:49:03774 net_log_, &net_error_details_,
775 failed_on_default_network_callback_, callback_.callback()));
rch431dd4452017-04-19 15:22:35776 EXPECT_THAT(callback_.WaitForResult(), IsOk());
777
tbansal3b966952016-10-25 23:25:14778 EXPECT_FALSE(QuicStreamFactoryPeer::CryptoConfigCacheIsEmpty(
779 factory_.get(), quic_server_id2));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52780 quic::QuicCryptoClientConfig::CachedState* cached2 =
tbansal3b966952016-10-25 23:25:14781 crypto_config->LookupOrCreate(quic_server_id2);
782 EXPECT_FALSE(cached2->server_config().empty());
783 EXPECT_TRUE(cached2->GetServerConfig());
784 EXPECT_EQ(server_config2, cached2->server_config());
785 EXPECT_EQ(source_address_token2, cached2->source_address_token());
786 EXPECT_EQ(cert_sct2, cached2->cert_sct());
787 EXPECT_EQ(chlo_hash2, cached2->chlo_hash());
788 EXPECT_EQ(signature2, cached2->signature());
789 ASSERT_EQ(1U, cached->certs().size());
790 EXPECT_EQ(test_cert2, cached2->certs()[0]);
791 }
792
jri5b785512016-09-13 04:29:11793 void RunTestLoopUntilIdle() {
794 while (!runner_->GetPostedTasks().empty())
795 runner_->RunNextTask();
796 }
797
Fan Yang32c5a112018-12-10 20:06:33798 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56799 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
800 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36801 }
802
Zhongyi Shi99d0cdd2019-05-21 01:18:42803 std::string ConstructDataHeader(size_t body_len) {
804 if (version_.transport_version != quic::QUIC_VERSION_99) {
805 return "";
806 }
807 quic::HttpEncoder encoder;
808 std::unique_ptr<char[]> buffer;
809 auto header_length = encoder.SerializeDataFrameHeader(body_len, &buffer);
810 return std::string(buffer.get(), header_length);
811 }
812
813 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
814 uint64_t packet_number,
815 quic::QuicStreamId stream_id,
816 bool should_include_version,
817 bool fin,
Zhongyi Shi99d0cdd2019-05-21 01:18:42818 quic::QuicStringPiece data) {
Ryan Hamilton7505eb92019-06-08 00:22:17819 return server_maker_.MakeDataPacket(packet_number, stream_id,
820 should_include_version, fin, data);
Zhongyi Shi99d0cdd2019-05-21 01:18:42821 }
822
Fan Yang32c5a112018-12-10 20:06:33823 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56824 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
825 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36826 }
827
Zhongyi Shia6b68d112018-09-24 07:49:03828 void OnFailedOnDefaultNetwork(int rv) { failed_on_default_network_ = true; }
829
jri9f303712016-09-13 01:10:22830 // Helper methods for tests of connection migration on write error.
Zhongyi Shi32fe14d42019-02-28 00:25:36831 void TestMigrationOnWriteErrorNonMigratableStream(IoMode write_error_mode,
832 bool migrate_idle_sessions);
Zhongyi Shi0439ecc72018-07-11 04:41:26833 // Migratable stream triggers write error.
834 void TestMigrationOnWriteErrorMixedStreams(IoMode write_error_mode);
835 // Non-migratable stream triggers write error.
836 void TestMigrationOnWriteErrorMixedStreams2(IoMode write_error_mode);
jri9f303712016-09-13 01:10:22837 void TestMigrationOnWriteErrorMigrationDisabled(IoMode write_error_mode);
838 void TestMigrationOnWriteError(IoMode write_error_mode);
Zhongyi Shi0439ecc72018-07-11 04:41:26839 void TestMigrationOnWriteErrorWithMultipleRequests(IoMode write_error_mode);
jri9f303712016-09-13 01:10:22840 void TestMigrationOnWriteErrorNoNewNetwork(IoMode write_error_mode);
Zhongyi Shi7f1d9212018-06-22 23:24:36841 void TestMigrationOnMultipleWriteErrors(
842 IoMode write_error_mode_on_old_network,
843 IoMode write_error_mode_on_new_network);
Zhongyi Shib24001c02018-06-18 20:01:52844 void TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
845 bool disconnected);
Zhongyi Shi1e2bc742018-06-16 02:06:07846 void TestMigrationOnWriteErrorWithNotificationQueuedLater(bool disconnected);
Zhongyi Shi9f316b262018-06-18 22:01:16847 void TestMigrationOnNetworkDisconnected(bool async_write_before);
Zhongyi Shia0644e32018-06-21 05:19:52848 void TestMigrationOnNetworkMadeDefault(IoMode write_mode);
Zhongyi Shi22fd5f52018-06-20 17:39:09849 void TestMigrationOnPathDegrading(bool async_write_before);
Zhongyi Shib3bc982c2018-07-10 19:59:24850 void TestMigrateSessionWithDrainingStream(
851 IoMode write_mode_for_queued_packet);
jri5b785512016-09-13 04:29:11852 void TestMigrationOnWriteErrorPauseBeforeConnected(IoMode write_error_mode);
Zhongyi Shi4ac9e1f2018-06-21 05:21:47853 void TestMigrationOnWriteErrorWithMultipleNotifications(
jri5b785512016-09-13 04:29:11854 IoMode write_error_mode,
Zhongyi Shi4ac9e1f2018-06-21 05:21:47855 bool disconnect_before_connect);
Zhongyi Shi634c1882018-08-16 04:05:59856 void TestNoAlternateNetworkBeforeHandshake(quic::QuicErrorCode error);
Zhongyi Shi8de43832018-08-15 23:40:00857 void TestNewConnectionOnAlternateNetworkBeforeHandshake(
858 quic::QuicErrorCode error);
Zhongyi Shi32fe14d42019-02-28 00:25:36859 void TestOnNetworkMadeDefaultNonMigratableStream(bool migrate_idle_sessions);
860 void TestMigrateSessionEarlyNonMigratableStream(bool migrate_idle_sessions);
861 void TestOnNetworkDisconnectedNoOpenStreams(bool migrate_idle_sessions);
862 void TestOnNetworkMadeDefaultNoOpenStreams(bool migrate_idle_sessions);
863 void TestOnNetworkDisconnectedNonMigratableStream(bool migrate_idle_sessions);
jri9f303712016-09-13 01:10:22864
Jana Iyengarf6b13d82017-09-04 02:09:10865 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Renjiea0cb4a2c2018-09-26 23:37:30866 std::unique_ptr<MockHostResolverBase> host_resolver_;
Ryan Sleevib8449e02018-07-15 04:31:07867 std::unique_ptr<SSLConfigService> ssl_config_service_;
Zhongyi Shi5f587cc2017-11-21 23:24:17868 std::unique_ptr<MockClientSocketFactory> socket_factory_;
[email protected]e8ff26842013-03-22 21:02:05869 MockCryptoClientStreamFactory crypto_client_stream_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52870 quic::test::MockRandom random_generator_;
871 quic::MockClock clock_;
rtenneti38f5cd52014-10-28 20:28:28872 scoped_refptr<TestTaskRunner> runner_;
Nick Harper23290b82019-05-02 00:02:56873 const quic::ParsedQuicVersion version_;
alyssar2adf3ac2016-05-03 17:12:58874 QuicTestPacketMaker client_maker_;
875 QuicTestPacketMaker server_maker_;
rtenneticcab42b2015-10-09 06:38:16876 HttpServerPropertiesImpl http_server_properties_;
danakjad1777e2016-04-16 00:56:42877 std::unique_ptr<CertVerifier> cert_verifier_;
[email protected]080b77932014-08-04 01:22:46878 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42879 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:23880 DefaultCTPolicyEnforcer ct_policy_enforcer_;
danakjad1777e2016-04-16 00:56:42881 std::unique_ptr<ScopedMockNetworkChangeNotifier>
jri7e636642016-01-14 06:57:08882 scoped_mock_network_change_notifier_;
danakjad1777e2016-04-16 00:56:42883 std::unique_ptr<QuicStreamFactory> factory_;
[email protected]bf4ea2f2014-03-10 22:57:53884 HostPortPair host_port_pair_;
ckrasic3865ee0f2016-02-29 22:04:56885 GURL url_;
886 GURL url2_;
887 GURL url3_;
888 GURL url4_;
889
[email protected]9dd3ff0f2014-03-26 09:51:28890 PrivacyMode privacy_mode_;
tfarina42834112016-09-22 13:38:20891 NetLogWithSource net_log_;
[email protected]e13201d82012-12-12 05:00:32892 TestCompletionCallback callback_;
Zhongyi Shia6b68d112018-09-24 07:49:03893 const CompletionRepeatingCallback failed_on_default_network_callback_;
894 bool failed_on_default_network_;
Ryan Hamilton75f197262017-08-17 14:00:07895 NetErrorDetails net_error_details_;
jri7046038f2015-10-22 00:29:26896
897 // Variables to configure QuicStreamFactory.
Zhongyi Shi967d2f12019-02-08 20:58:53898 HttpNetworkSession::Params test_params_;
rch431dd4452017-04-19 15:22:35899 bool store_server_configs_in_properties_;
[email protected]e13201d82012-12-12 05:00:32900};
901
bnc359ed2a2016-04-29 20:43:45902class QuicStreamFactoryTest : public QuicStreamFactoryTestBase,
903 public ::testing::TestWithParam<TestParams> {
904 protected:
Yixin Wang079ad542018-01-11 04:06:05905 QuicStreamFactoryTest()
906 : QuicStreamFactoryTestBase(
907 GetParam().version,
908 GetParam().client_headers_include_h2_stream_dependency) {}
bnc359ed2a2016-04-29 20:43:45909};
910
Victor Costane635086f2019-01-27 05:20:30911INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
912 QuicStreamFactoryTest,
913 ::testing::ValuesIn(GetTestParams()));
[email protected]1e960032013-12-20 19:00:20914
[email protected]1e960032013-12-20 19:00:20915TEST_P(QuicStreamFactoryTest, Create) {
jri7046038f2015-10-22 00:29:26916 Initialize();
rch6faa4d42016-01-05 20:48:43917 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
918 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:26919
Ryan Hamiltonabad59e2019-06-06 04:02:59920 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:36921 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:43922 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:17923 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]e13201d82012-12-12 05:00:32924
zhongyi98d6a9262017-05-19 02:47:45925 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:33926 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:03927 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:52928 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
929 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:03930 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
931 failed_on_default_network_callback_, callback_.callback()));
[email protected]e13201d82012-12-12 05:00:32932
robpercival214763f2016-07-01 23:27:01933 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:24934 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0edce6a2013-05-08 18:02:40935 EXPECT_TRUE(stream.get());
[email protected]e13201d82012-12-12 05:00:32936
Renjiea0cb4a2c2018-09-26 23:37:30937 EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_->last_request_priority());
Yixin Wang247ea642017-11-15 01:15:50938
zhongyi98d6a9262017-05-19 02:47:45939 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:51940 EXPECT_EQ(OK,
941 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:52942 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
943 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:51944 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
945 failed_on_default_network_callback_, callback_.callback()));
rch68a80eb2017-04-25 05:24:24946 // Will reset stream 3.
Yixin Wang7891a39d2017-11-08 20:59:24947 stream = CreateStream(&request2);
rch68a80eb2017-04-25 05:24:24948
949 EXPECT_TRUE(stream.get());
950
951 // TODO(rtenneti): We should probably have a tests that HTTP and HTTPS result
952 // in streams on different sessions.
zhongyi98d6a9262017-05-19 02:47:45953 QuicStreamRequest request3(factory_.get());
Matt Menke26e41542019-06-05 01:09:51954 EXPECT_EQ(OK,
955 request3.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:52956 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
957 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:51958 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
959 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:24960 stream = CreateStream(&request3); // Will reset stream 5.
Ryan Hamiltona12722b2017-08-12 02:23:20961 stream.reset(); // Will reset stream 7.
[email protected]e13201d82012-12-12 05:00:32962
rch37de576c2015-05-17 20:28:17963 EXPECT_TRUE(socket_data.AllReadDataConsumed());
964 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]e13201d82012-12-12 05:00:32965}
966
[email protected]8bd2b812014-03-26 04:01:17967TEST_P(QuicStreamFactoryTest, CreateZeroRtt) {
jri7046038f2015-10-22 00:29:26968 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:20969 factory_->set_require_confirmation(false);
rch6faa4d42016-01-05 20:48:43970 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
971 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:26972
Ryan Hamiltonabad59e2019-06-06 04:02:59973 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:36974 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:17975 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]8bd2b812014-03-26 04:01:17976
977 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:27978 MockCryptoClientStream::ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:30979 host_resolver_->set_synchronous_mode(true);
980 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
981 "192.168.0.1", "");
[email protected]8bd2b812014-03-26 04:01:17982
zhongyi98d6a9262017-05-19 02:47:45983 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:51984 EXPECT_EQ(OK,
985 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:52986 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
987 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:51988 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
989 failed_on_default_network_callback_, callback_.callback()));
[email protected]8bd2b812014-03-26 04:01:17990
Yixin Wang7891a39d2017-11-08 20:59:24991 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]8bd2b812014-03-26 04:01:17992 EXPECT_TRUE(stream.get());
rch37de576c2015-05-17 20:28:17993 EXPECT_TRUE(socket_data.AllReadDataConsumed());
994 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]8bd2b812014-03-26 04:01:17995}
996
rchd6163f32017-01-30 23:50:38997TEST_P(QuicStreamFactoryTest, DefaultInitialRtt) {
998 Initialize();
999 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1000 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1001
Ryan Hamiltonabad59e2019-06-06 04:02:591002 MockQuicData socket_data(version_);
rchd6163f32017-01-30 23:50:381003 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431004 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171005 socket_data.AddSocketDataToFactory(socket_factory_.get());
rchd6163f32017-01-30 23:50:381006
zhongyi98d6a9262017-05-19 02:47:451007 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331008 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031009 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521010 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1011 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031012 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1013 failed_on_default_network_callback_, callback_.callback()));
rchd6163f32017-01-30 23:50:381014
1015 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241016 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rchd6163f32017-01-30 23:50:381017 EXPECT_TRUE(stream.get());
1018
1019 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Ryan Hamiltona12722b2017-08-12 02:23:201020 EXPECT_TRUE(session->require_confirmation());
rchd6163f32017-01-30 23:50:381021 EXPECT_EQ(100000u, session->connection()->GetStats().srtt_us);
1022 ASSERT_FALSE(session->config()->HasInitialRoundTripTimeUsToSend());
1023}
1024
Helen Li0e823912017-09-25 19:48:301025TEST_P(QuicStreamFactoryTest, FactoryDestroyedWhenJobPending) {
1026 Initialize();
1027 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1028 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1029
Ryan Hamiltonabad59e2019-06-06 04:02:591030 MockQuicData socket_data(version_);
Helen Li0e823912017-09-25 19:48:301031 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431032 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171033 socket_data.AddSocketDataToFactory(socket_factory_.get());
Helen Li0e823912017-09-25 19:48:301034
1035 auto request = std::make_unique<QuicStreamRequest>(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331036 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031037 request->Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521038 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1039 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031040 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1041 failed_on_default_network_callback_, callback_.callback()));
Helen Li0e823912017-09-25 19:48:301042 request.reset();
1043 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
1044 // Tearing down a QuicStreamFactory with a pending Job should not cause any
1045 // crash. crbug.com/768343.
1046 factory_.reset();
1047}
1048
Ryan Hamiltona12722b2017-08-12 02:23:201049TEST_P(QuicStreamFactoryTest, RequireConfirmation) {
1050 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271051 MockCryptoClientStream::ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:301052 host_resolver_->set_synchronous_mode(true);
1053 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
1054 "192.168.0.1", "");
Ryan Hamiltona12722b2017-08-12 02:23:201055 Initialize();
1056 factory_->set_require_confirmation(true);
1057 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1058 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1059
Ryan Hamiltonabad59e2019-06-06 04:02:591060 MockQuicData socket_data(version_);
Ryan Hamiltona12722b2017-08-12 02:23:201061 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431062 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171063 socket_data.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamiltona12722b2017-08-12 02:23:201064
1065 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331066 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031067 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521068 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1069 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031070 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1071 failed_on_default_network_callback_, callback_.callback()));
Ryan Hamiltona12722b2017-08-12 02:23:201072
Ryan Hamilton8e32a2b2017-08-28 20:06:521073 IPAddress last_address;
1074 EXPECT_FALSE(http_server_properties_.GetSupportsQuic(&last_address));
1075
Ryan Hamiltona12722b2017-08-12 02:23:201076 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521077 quic::QuicSession::HANDSHAKE_CONFIRMED);
Ryan Hamiltona12722b2017-08-12 02:23:201078
Ryan Hamilton8e32a2b2017-08-28 20:06:521079 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
1080
Ryan Hamiltona12722b2017-08-12 02:23:201081 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241082 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Ryan Hamiltona12722b2017-08-12 02:23:201083 EXPECT_TRUE(stream.get());
1084
1085 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1086 EXPECT_TRUE(session->require_confirmation());
1087}
1088
1089TEST_P(QuicStreamFactoryTest, DontRequireConfirmationFromSameIP) {
1090 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271091 MockCryptoClientStream::ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:301092 host_resolver_->set_synchronous_mode(true);
1093 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
1094 "192.168.0.1", "");
Ryan Hamiltona12722b2017-08-12 02:23:201095 Initialize();
1096 factory_->set_require_confirmation(true);
1097 http_server_properties_.SetSupportsQuic(IPAddress(192, 0, 2, 33));
1098
1099 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1100 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1101
Ryan Hamiltonabad59e2019-06-06 04:02:591102 MockQuicData socket_data(version_);
Ryan Hamiltona12722b2017-08-12 02:23:201103 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431104 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171105 socket_data.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamiltona12722b2017-08-12 02:23:201106
1107 QuicStreamRequest request(factory_.get());
Zhongyi Shia6b68d112018-09-24 07:49:031108 EXPECT_THAT(request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521109 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1110 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031111 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1112 failed_on_default_network_callback_, callback_.callback()),
Paul Jensen8e3c5d32018-02-19 17:06:331113 IsOk());
Ryan Hamiltona12722b2017-08-12 02:23:201114
Ryan Hamilton8e32a2b2017-08-28 20:06:521115 IPAddress last_address;
1116 EXPECT_FALSE(http_server_properties_.GetSupportsQuic(&last_address));
1117
Yixin Wang7891a39d2017-11-08 20:59:241118 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Ryan Hamiltona12722b2017-08-12 02:23:201119 EXPECT_TRUE(stream.get());
1120
1121 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1122 EXPECT_FALSE(session->require_confirmation());
Ryan Hamilton8e32a2b2017-08-28 20:06:521123
1124 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521125 quic::QuicSession::HANDSHAKE_CONFIRMED);
Ryan Hamilton8e32a2b2017-08-28 20:06:521126
1127 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
Ryan Hamiltona12722b2017-08-12 02:23:201128}
1129
rchd6163f32017-01-30 23:50:381130TEST_P(QuicStreamFactoryTest, CachedInitialRtt) {
1131 ServerNetworkStats stats;
1132 stats.srtt = base::TimeDelta::FromMilliseconds(10);
1133 http_server_properties_.SetServerNetworkStats(url::SchemeHostPort(url_),
1134 stats);
Zhongyi Shi967d2f12019-02-08 20:58:531135 test_params_.quic_estimate_initial_rtt = true;
rchd6163f32017-01-30 23:50:381136
1137 Initialize();
1138 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1139 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1140
Ryan Hamiltonabad59e2019-06-06 04:02:591141 MockQuicData socket_data(version_);
rchd6163f32017-01-30 23:50:381142 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431143 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171144 socket_data.AddSocketDataToFactory(socket_factory_.get());
rchd6163f32017-01-30 23:50:381145
zhongyi98d6a9262017-05-19 02:47:451146 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331147 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031148 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521149 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1150 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031151 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1152 failed_on_default_network_callback_, callback_.callback()));
rchd6163f32017-01-30 23:50:381153
1154 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241155 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rchd6163f32017-01-30 23:50:381156 EXPECT_TRUE(stream.get());
1157
1158 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1159 EXPECT_EQ(10000u, session->connection()->GetStats().srtt_us);
1160 ASSERT_TRUE(session->config()->HasInitialRoundTripTimeUsToSend());
1161 EXPECT_EQ(10000u, session->config()->GetInitialRoundTripTimeUsToSend());
1162}
1163
1164TEST_P(QuicStreamFactoryTest, 2gInitialRtt) {
1165 ScopedMockNetworkChangeNotifier notifier;
1166 notifier.mock_network_change_notifier()->SetConnectionType(
1167 NetworkChangeNotifier::CONNECTION_2G);
Zhongyi Shi967d2f12019-02-08 20:58:531168 test_params_.quic_estimate_initial_rtt = true;
rchd6163f32017-01-30 23:50:381169
1170 Initialize();
1171 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1172 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1173
Ryan Hamiltonabad59e2019-06-06 04:02:591174 MockQuicData socket_data(version_);
rchd6163f32017-01-30 23:50:381175 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431176 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171177 socket_data.AddSocketDataToFactory(socket_factory_.get());
rchd6163f32017-01-30 23:50:381178
zhongyi98d6a9262017-05-19 02:47:451179 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331180 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031181 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521182 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1183 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031184 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1185 failed_on_default_network_callback_, callback_.callback()));
rchd6163f32017-01-30 23:50:381186
1187 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241188 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rchd6163f32017-01-30 23:50:381189 EXPECT_TRUE(stream.get());
1190
1191 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1192 EXPECT_EQ(1200000u, session->connection()->GetStats().srtt_us);
1193 ASSERT_TRUE(session->config()->HasInitialRoundTripTimeUsToSend());
1194 EXPECT_EQ(1200000u, session->config()->GetInitialRoundTripTimeUsToSend());
1195}
1196
1197TEST_P(QuicStreamFactoryTest, 3gInitialRtt) {
1198 ScopedMockNetworkChangeNotifier notifier;
1199 notifier.mock_network_change_notifier()->SetConnectionType(
1200 NetworkChangeNotifier::CONNECTION_3G);
Zhongyi Shi967d2f12019-02-08 20:58:531201 test_params_.quic_estimate_initial_rtt = true;
rchd6163f32017-01-30 23:50:381202
1203 Initialize();
1204 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1205 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1206
Ryan Hamiltonabad59e2019-06-06 04:02:591207 MockQuicData socket_data(version_);
rchd6163f32017-01-30 23:50:381208 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431209 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171210 socket_data.AddSocketDataToFactory(socket_factory_.get());
rchd6163f32017-01-30 23:50:381211
zhongyi98d6a9262017-05-19 02:47:451212 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331213 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031214 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521215 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1216 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031217 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1218 failed_on_default_network_callback_, callback_.callback()));
rchd6163f32017-01-30 23:50:381219
1220 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241221 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rchd6163f32017-01-30 23:50:381222 EXPECT_TRUE(stream.get());
1223
1224 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1225 EXPECT_EQ(400000u, session->connection()->GetStats().srtt_us);
1226 ASSERT_TRUE(session->config()->HasInitialRoundTripTimeUsToSend());
1227 EXPECT_EQ(400000u, session->config()->GetInitialRoundTripTimeUsToSend());
1228}
1229
rch68955482015-09-24 00:14:391230TEST_P(QuicStreamFactoryTest, GoAway) {
jri7046038f2015-10-22 00:29:261231 Initialize();
rch6faa4d42016-01-05 20:48:431232 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1233 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:261234
Ryan Hamiltonabad59e2019-06-06 04:02:591235 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361236 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431237 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171238 socket_data.AddSocketDataToFactory(socket_factory_.get());
rch68955482015-09-24 00:14:391239
zhongyi98d6a9262017-05-19 02:47:451240 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331241 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031242 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521243 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1244 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031245 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1246 failed_on_default_network_callback_, callback_.callback()));
rch68955482015-09-24 00:14:391247
robpercival214763f2016-07-01 23:27:011248 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241249 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rch68955482015-09-24 00:14:391250 EXPECT_TRUE(stream.get());
1251
bnc912a04b2016-04-20 14:19:501252 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
rch68955482015-09-24 00:14:391253
Ryan Hamilton8d9ee76e2018-05-29 23:52:521254 session->OnGoAway(quic::QuicGoAwayFrame());
rch68955482015-09-24 00:14:391255
bnc912a04b2016-04-20 14:19:501256 EXPECT_FALSE(HasActiveSession(host_port_pair_));
rch68955482015-09-24 00:14:391257
1258 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1259 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1260}
1261
zhongyi6b5a3892016-03-12 04:46:201262TEST_P(QuicStreamFactoryTest, GoAwayForConnectionMigrationWithPortOnly) {
1263 Initialize();
1264 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1265 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1266
Ryan Hamiltonabad59e2019-06-06 04:02:591267 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361268 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431269 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171270 socket_data.AddSocketDataToFactory(socket_factory_.get());
zhongyi6b5a3892016-03-12 04:46:201271
zhongyi98d6a9262017-05-19 02:47:451272 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331273 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031274 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521275 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1276 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031277 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1278 failed_on_default_network_callback_, callback_.callback()));
zhongyi6b5a3892016-03-12 04:46:201279
robpercival214763f2016-07-01 23:27:011280 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241281 std::unique_ptr<HttpStream> stream = CreateStream(&request);
zhongyi6b5a3892016-03-12 04:46:201282 EXPECT_TRUE(stream.get());
1283
bnc912a04b2016-04-20 14:19:501284 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
zhongyi6b5a3892016-03-12 04:46:201285
Ryan Hamilton8d9ee76e2018-05-29 23:52:521286 session->OnGoAway(quic::QuicGoAwayFrame(
1287 quic::kInvalidControlFrameId, quic::QUIC_ERROR_MIGRATING_PORT, 0,
1288 "peer connection migration due to port change only"));
zhongyi6b5a3892016-03-12 04:46:201289 NetErrorDetails details;
1290 EXPECT_FALSE(details.quic_port_migration_detected);
1291 session->PopulateNetErrorDetails(&details);
1292 EXPECT_TRUE(details.quic_port_migration_detected);
1293 details.quic_port_migration_detected = false;
1294 stream->PopulateNetErrorDetails(&details);
1295 EXPECT_TRUE(details.quic_port_migration_detected);
1296
bnc912a04b2016-04-20 14:19:501297 EXPECT_FALSE(HasActiveSession(host_port_pair_));
zhongyi6b5a3892016-03-12 04:46:201298
1299 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1300 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1301}
1302
[email protected]5db452202014-08-19 05:22:151303TEST_P(QuicStreamFactoryTest, Pooling) {
jri7046038f2015-10-22 00:29:261304 Initialize();
rch6faa4d42016-01-05 20:48:431305 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1306 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:261307
Ryan Hamiltonabad59e2019-06-06 04:02:591308 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361309 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431310 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171311 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]eed749f92013-12-23 18:57:381312
rch6faa4d42016-01-05 20:48:431313 HostPortPair server2(kServer2HostName, kDefaultServerPort);
Renjiea0cb4a2c2018-09-26 23:37:301314 host_resolver_->set_synchronous_mode(true);
1315 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
1316 "192.168.0.1", "");
1317 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]eed749f92013-12-23 18:57:381318
zhongyi98d6a9262017-05-19 02:47:451319 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:511320 EXPECT_EQ(OK,
1321 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521322 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1323 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:511324 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1325 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241326 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]eed749f92013-12-23 18:57:381327 EXPECT_TRUE(stream.get());
1328
1329 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451330 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:511331 EXPECT_EQ(OK,
1332 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521333 server2, version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
1334 NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:511335 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
1336 failed_on_default_network_callback_, callback.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241337 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]eed749f92013-12-23 18:57:381338 EXPECT_TRUE(stream2.get());
1339
bnc912a04b2016-04-20 14:19:501340 EXPECT_EQ(GetActiveSession(host_port_pair_), GetActiveSession(server2));
[email protected]eed749f92013-12-23 18:57:381341
rch37de576c2015-05-17 20:28:171342 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1343 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]eed749f92013-12-23 18:57:381344}
1345
jri94ddc3142016-08-26 01:32:431346TEST_P(QuicStreamFactoryTest, PoolingWithServerMigration) {
1347 // Set up session to migrate.
Renjiea0cb4a2c2018-09-26 23:37:301348 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
1349 "192.168.0.1", "");
jri94ddc3142016-08-26 01:32:431350 IPEndPoint alt_address = IPEndPoint(IPAddress(1, 2, 3, 4), 443);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521351 quic::QuicConfig config;
Victor Vasiliev4f6fb892019-05-31 16:58:311352 config.SetAlternateServerAddressToSend(ToQuicSocketAddress(alt_address));
jri94ddc3142016-08-26 01:32:431353
1354 VerifyServerMigration(config, alt_address);
1355
1356 // Close server-migrated session.
1357 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Renjieba55fae2018-09-20 03:05:161358 session->CloseSessionOnError(0u, quic::QUIC_NO_ERROR,
1359 quic::ConnectionCloseBehavior::SILENT_CLOSE);
jri94ddc3142016-08-26 01:32:431360
Ryan Hamilton0d65a8c2019-06-07 00:46:021361 client_maker_.Reset();
Ryan Hamilton9f2eac32019-06-27 03:15:541362 client_maker_.set_coalesce_http_frames(false);
jri94ddc3142016-08-26 01:32:431363 // Set up server IP, socket, proof, and config for new session.
1364 HostPortPair server2(kServer2HostName, kDefaultServerPort);
Renjiea0cb4a2c2018-09-26 23:37:301365 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
jri94ddc3142016-08-26 01:32:431366
1367 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521368 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Ryan Hamilton0d65a8c2019-06-07 00:46:021369 client_maker_.MakeInitialSettingsPacket(1));
bnceb9aa7112017-01-05 01:03:461370 MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(),
1371 settings_packet->length(), 1)};
fayang3bcb8b502016-12-07 21:44:371372
Ryan Sleevib8d7ea02018-05-07 20:01:011373 SequencedSocketData socket_data(reads, writes);
Ryan Hamilton0d65a8c2019-06-07 00:46:021374 QuicPacketPrinter printer(version_);
1375 socket_data.set_printer(&printer);
Zhongyi Shi5f587cc2017-11-21 23:24:171376 socket_factory_->AddSocketDataProvider(&socket_data);
jri94ddc3142016-08-26 01:32:431377
1378 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1379 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521380 quic::QuicConfig config2;
jri94ddc3142016-08-26 01:32:431381 crypto_client_stream_factory_.SetConfig(config2);
1382
1383 // Create new request to cause new session creation.
1384 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451385 QuicStreamRequest request2(factory_.get());
jri94ddc3142016-08-26 01:32:431386 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031387 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521388 server2, version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
1389 NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031390 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
1391 failed_on_default_network_callback_, callback.callback()));
jri94ddc3142016-08-26 01:32:431392 EXPECT_EQ(OK, callback.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:241393 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
jri94ddc3142016-08-26 01:32:431394 EXPECT_TRUE(stream2.get());
1395
1396 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1397 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1398 // EXPECT_EQ(GetActiveSession(host_port_pair_), GetActiveSession(server2));
1399}
1400
[email protected]eed749f92013-12-23 18:57:381401TEST_P(QuicStreamFactoryTest, NoPoolingAfterGoAway) {
jri7046038f2015-10-22 00:29:261402 Initialize();
rch6faa4d42016-01-05 20:48:431403 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1404 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1405 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:261406
Ryan Hamiltonabad59e2019-06-06 04:02:591407 MockQuicData socket_data1(version_);
rcha00569732016-08-27 11:09:361408 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431409 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171410 socket_data1.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamilton0d65a8c2019-06-07 00:46:021411 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:591412 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:361413 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431414 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171415 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]eed749f92013-12-23 18:57:381416
rch6faa4d42016-01-05 20:48:431417 HostPortPair server2(kServer2HostName, kDefaultServerPort);
Renjiea0cb4a2c2018-09-26 23:37:301418 host_resolver_->set_synchronous_mode(true);
1419 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
1420 "192.168.0.1", "");
1421 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]eed749f92013-12-23 18:57:381422
zhongyi98d6a9262017-05-19 02:47:451423 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:511424 EXPECT_EQ(OK,
1425 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521426 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1427 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:511428 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1429 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241430 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]eed749f92013-12-23 18:57:381431 EXPECT_TRUE(stream.get());
1432
1433 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451434 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:511435 EXPECT_EQ(OK,
1436 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521437 server2, version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
1438 NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:511439 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
1440 failed_on_default_network_callback_, callback.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241441 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]eed749f92013-12-23 18:57:381442 EXPECT_TRUE(stream2.get());
1443
bnc912a04b2016-04-20 14:19:501444 factory_->OnSessionGoingAway(GetActiveSession(host_port_pair_));
1445 EXPECT_FALSE(HasActiveSession(host_port_pair_));
1446 EXPECT_FALSE(HasActiveSession(server2));
[email protected]eed749f92013-12-23 18:57:381447
1448 TestCompletionCallback callback3;
zhongyi98d6a9262017-05-19 02:47:451449 QuicStreamRequest request3(factory_.get());
Matt Menke26e41542019-06-05 01:09:511450 EXPECT_EQ(OK,
1451 request3.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521452 server2, version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
1453 NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:511454 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
1455 failed_on_default_network_callback_, callback3.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241456 std::unique_ptr<HttpStream> stream3 = CreateStream(&request3);
[email protected]eed749f92013-12-23 18:57:381457 EXPECT_TRUE(stream3.get());
1458
bnc912a04b2016-04-20 14:19:501459 EXPECT_TRUE(HasActiveSession(server2));
[email protected]eed749f92013-12-23 18:57:381460
rch37de576c2015-05-17 20:28:171461 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
1462 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
1463 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1464 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]eed749f92013-12-23 18:57:381465}
1466
[email protected]5db452202014-08-19 05:22:151467TEST_P(QuicStreamFactoryTest, HttpsPooling) {
jri7046038f2015-10-22 00:29:261468 Initialize();
rch6faa4d42016-01-05 20:48:431469
Ryan Hamiltonabad59e2019-06-06 04:02:591470 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361471 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431472 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171473 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]eed749f92013-12-23 18:57:381474
rch6faa4d42016-01-05 20:48:431475 HostPortPair server1(kDefaultServerHostName, 443);
1476 HostPortPair server2(kServer2HostName, 443);
[email protected]eed749f92013-12-23 18:57:381477
bncf8bf0722015-05-19 20:04:131478 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
bnc20daf9a2015-05-15 17:11:011479 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
[email protected]eed749f92013-12-23 18:57:381480
Renjiea0cb4a2c2018-09-26 23:37:301481 host_resolver_->set_synchronous_mode(true);
1482 host_resolver_->rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
1483 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]eed749f92013-12-23 18:57:381484
zhongyi98d6a9262017-05-19 02:47:451485 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:511486 EXPECT_EQ(OK,
1487 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521488 server1, version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
1489 NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:511490 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1491 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241492 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]eed749f92013-12-23 18:57:381493 EXPECT_TRUE(stream.get());
1494
1495 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451496 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:511497 EXPECT_EQ(OK,
1498 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521499 server2, version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
1500 NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:511501 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
1502 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241503 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]eed749f92013-12-23 18:57:381504 EXPECT_TRUE(stream2.get());
1505
bnc912a04b2016-04-20 14:19:501506 EXPECT_EQ(GetActiveSession(server1), GetActiveSession(server2));
[email protected]eed749f92013-12-23 18:57:381507
rch37de576c2015-05-17 20:28:171508 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1509 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]eed749f92013-12-23 18:57:381510}
1511
[email protected]5db452202014-08-19 05:22:151512TEST_P(QuicStreamFactoryTest, HttpsPoolingWithMatchingPins) {
jri7046038f2015-10-22 00:29:261513 Initialize();
Ryan Hamiltonabad59e2019-06-06 04:02:591514 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361515 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431516 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171517 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]5db452202014-08-19 05:22:151518
rch6faa4d42016-01-05 20:48:431519 HostPortPair server1(kDefaultServerHostName, 443);
1520 HostPortPair server2(kServer2HostName, 443);
Matt Mueller230996f12018-10-22 19:39:441521 transport_security_state_.EnableStaticPinsForTesting();
1522 ScopedTransportSecurityStateSource scoped_security_state_source;
[email protected]5db452202014-08-19 05:22:151523
Matt Mueller230996f12018-10-22 19:39:441524 HashValue primary_pin(HASH_VALUE_SHA256);
1525 EXPECT_TRUE(primary_pin.FromString(
1526 "sha256/Nn8jk5By4Vkq6BeOVZ7R7AC6XUUBZsWmUbJR1f1Y5FY="));
bncf8bf0722015-05-19 20:04:131527 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
Matt Mueller230996f12018-10-22 19:39:441528 verify_details.cert_verify_result.public_key_hashes.push_back(primary_pin);
bnc20daf9a2015-05-15 17:11:011529 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
[email protected]5db452202014-08-19 05:22:151530
Renjiea0cb4a2c2018-09-26 23:37:301531 host_resolver_->set_synchronous_mode(true);
1532 host_resolver_->rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
1533 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]5db452202014-08-19 05:22:151534
zhongyi98d6a9262017-05-19 02:47:451535 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:511536 EXPECT_EQ(OK,
1537 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521538 server1, version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
1539 NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:511540 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1541 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241542 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]5db452202014-08-19 05:22:151543 EXPECT_TRUE(stream.get());
1544
1545 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451546 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:511547 EXPECT_EQ(OK,
1548 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521549 server2, version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
1550 NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:511551 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
1552 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241553 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]5db452202014-08-19 05:22:151554 EXPECT_TRUE(stream2.get());
1555
bnc912a04b2016-04-20 14:19:501556 EXPECT_EQ(GetActiveSession(server1), GetActiveSession(server2));
[email protected]5db452202014-08-19 05:22:151557
rch37de576c2015-05-17 20:28:171558 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1559 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]5db452202014-08-19 05:22:151560}
1561
1562TEST_P(QuicStreamFactoryTest, NoHttpsPoolingWithDifferentPins) {
jri7046038f2015-10-22 00:29:261563 Initialize();
rcha00569732016-08-27 11:09:361564
Ryan Hamiltonabad59e2019-06-06 04:02:591565 MockQuicData socket_data1(version_);
rcha00569732016-08-27 11:09:361566 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431567 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171568 socket_data1.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamilton0d65a8c2019-06-07 00:46:021569 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:591570 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:361571 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431572 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171573 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]5db452202014-08-19 05:22:151574
rch6faa4d42016-01-05 20:48:431575 HostPortPair server1(kDefaultServerHostName, 443);
1576 HostPortPair server2(kServer2HostName, 443);
Matt Mueller230996f12018-10-22 19:39:441577 transport_security_state_.EnableStaticPinsForTesting();
1578 ScopedTransportSecurityStateSource scoped_security_state_source;
[email protected]5db452202014-08-19 05:22:151579
bncf8bf0722015-05-19 20:04:131580 ProofVerifyDetailsChromium verify_details1 = DefaultProofVerifyDetails();
Matt Mueller230996f12018-10-22 19:39:441581 uint8_t bad_pin = 3;
bnc20daf9a2015-05-15 17:11:011582 verify_details1.cert_verify_result.public_key_hashes.push_back(
1583 test::GetTestHashValue(bad_pin));
1584 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
1585
Matt Mueller230996f12018-10-22 19:39:441586 HashValue primary_pin(HASH_VALUE_SHA256);
1587 EXPECT_TRUE(primary_pin.FromString(
1588 "sha256/Nn8jk5By4Vkq6BeOVZ7R7AC6XUUBZsWmUbJR1f1Y5FY="));
bncf8bf0722015-05-19 20:04:131589 ProofVerifyDetailsChromium verify_details2 = DefaultProofVerifyDetails();
Matt Mueller230996f12018-10-22 19:39:441590 verify_details2.cert_verify_result.public_key_hashes.push_back(primary_pin);
bnc20daf9a2015-05-15 17:11:011591 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
[email protected]5db452202014-08-19 05:22:151592
Renjiea0cb4a2c2018-09-26 23:37:301593 host_resolver_->set_synchronous_mode(true);
1594 host_resolver_->rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
1595 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]5db452202014-08-19 05:22:151596
zhongyi98d6a9262017-05-19 02:47:451597 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:511598 EXPECT_EQ(OK,
1599 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521600 server1, version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
1601 NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:511602 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1603 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241604 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]5db452202014-08-19 05:22:151605 EXPECT_TRUE(stream.get());
1606
1607 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451608 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:511609 EXPECT_EQ(OK,
1610 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521611 server2, version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
1612 NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:511613 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
1614 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241615 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]5db452202014-08-19 05:22:151616 EXPECT_TRUE(stream2.get());
1617
bnc912a04b2016-04-20 14:19:501618 EXPECT_NE(GetActiveSession(server1), GetActiveSession(server2));
[email protected]5db452202014-08-19 05:22:151619
rch37de576c2015-05-17 20:28:171620 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
1621 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
1622 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1623 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]5db452202014-08-19 05:22:151624}
1625
[email protected]1e960032013-12-20 19:00:201626TEST_P(QuicStreamFactoryTest, Goaway) {
jri7046038f2015-10-22 00:29:261627 Initialize();
rch6faa4d42016-01-05 20:48:431628 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1629 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1630 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1631
Ryan Hamiltonabad59e2019-06-06 04:02:591632 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361633 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431634 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171635 socket_data.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamilton0d65a8c2019-06-07 00:46:021636 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:591637 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:361638 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431639 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171640 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]4d283b32013-10-17 12:57:271641
zhongyi98d6a9262017-05-19 02:47:451642 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331643 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031644 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521645 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1646 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031647 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1648 failed_on_default_network_callback_, callback_.callback()));
[email protected]4d283b32013-10-17 12:57:271649
robpercival214763f2016-07-01 23:27:011650 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241651 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]4d283b32013-10-17 12:57:271652 EXPECT_TRUE(stream.get());
1653
1654 // Mark the session as going away. Ensure that while it is still alive
1655 // that it is no longer active.
bnc912a04b2016-04-20 14:19:501656 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri7046038f2015-10-22 00:29:261657 factory_->OnSessionGoingAway(session);
1658 EXPECT_EQ(true,
1659 QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
bnc912a04b2016-04-20 14:19:501660 EXPECT_FALSE(HasActiveSession(host_port_pair_));
[email protected]4d283b32013-10-17 12:57:271661
1662 // Create a new request for the same destination and verify that a
1663 // new session is created.
zhongyi98d6a9262017-05-19 02:47:451664 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331665 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031666 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521667 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1668 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031669 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1670 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:011671 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241672 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]4d283b32013-10-17 12:57:271673 EXPECT_TRUE(stream2.get());
1674
bnc912a04b2016-04-20 14:19:501675 EXPECT_TRUE(HasActiveSession(host_port_pair_));
1676 EXPECT_NE(session, GetActiveSession(host_port_pair_));
jri7046038f2015-10-22 00:29:261677 EXPECT_EQ(true,
1678 QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
[email protected]4d283b32013-10-17 12:57:271679
1680 stream2.reset();
1681 stream.reset();
1682
rch37de576c2015-05-17 20:28:171683 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1684 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1685 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1686 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]4d283b32013-10-17 12:57:271687}
1688
[email protected]1e960032013-12-20 19:00:201689TEST_P(QuicStreamFactoryTest, MaxOpenStream) {
jri7046038f2015-10-22 00:29:261690 Initialize();
rch6faa4d42016-01-05 20:48:431691 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1692 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1693
Fan Yang32c5a112018-12-10 20:06:331694 quic::QuicStreamId stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
Ryan Hamiltonabad59e2019-06-06 04:02:591695 MockQuicData socket_data(version_);
Zhongyi Shi32f2fd02018-04-16 18:23:431696 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Nick Harper23290b82019-05-02 00:02:561697 if (version_.transport_version == quic::QUIC_VERSION_99) {
David Schinazicc1bc592019-04-24 19:40:311698 socket_data.AddWrite(SYNCHRONOUS, client_maker_.MakeStreamsBlockedPacket(
Ryan Hamilton4aeec562019-05-17 21:22:521699 2, true, 51,
David Schinazicc1bc592019-04-24 19:40:311700 /*unidirectional=*/false));
Frank Kastenholzc9b9bea2018-12-03 20:13:471701 socket_data.AddWrite(
1702 SYNCHRONOUS, client_maker_.MakeRstPacket(3, true, stream_id,
1703 quic::QUIC_STREAM_CANCELLED));
1704 socket_data.AddRead(
1705 ASYNC, server_maker_.MakeRstPacket(1, false, stream_id,
1706 quic::QUIC_STREAM_CANCELLED));
Fan Yang32c5a112018-12-10 20:06:331707 socket_data.AddRead(
Ryan Hamilton4aeec562019-05-17 21:22:521708 ASYNC, server_maker_.MakeMaxStreamsPacket(4, true, 52,
David Schinazicc1bc592019-04-24 19:40:311709 /*unidirectional=*/false));
Frank Kastenholzc9b9bea2018-12-03 20:13:471710 } else {
1711 socket_data.AddWrite(
1712 SYNCHRONOUS, client_maker_.MakeRstPacket(2, true, stream_id,
1713 quic::QUIC_STREAM_CANCELLED));
1714 socket_data.AddRead(
1715 ASYNC, server_maker_.MakeRstPacket(1, false, stream_id,
1716 quic::QUIC_STREAM_CANCELLED));
Frank Kastenholz878763bf2018-11-28 19:14:481717 }
rcha00569732016-08-27 11:09:361718 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:171719 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]0b2294d32013-08-02 00:46:361720
1721 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:391722 request_info.traffic_annotation =
1723 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1724
xunjieli1d2b4272017-04-25 22:37:171725 std::vector<std::unique_ptr<HttpStream>> streams;
Ryan Hamilton9835e662018-08-02 05:36:271726 // The MockCryptoClientStream sets max_open_streams to be
Ryan Hamilton8d9ee76e2018-05-29 23:52:521727 // quic::kDefaultMaxStreamsPerConnection / 2.
1728 for (size_t i = 0; i < quic::kDefaultMaxStreamsPerConnection / 2; i++) {
zhongyi98d6a9262017-05-19 02:47:451729 QuicStreamRequest request(factory_.get());
Zhongyi Shia6b68d112018-09-24 07:49:031730 int rv = request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521731 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
1732 NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031733 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1734 failed_on_default_network_callback_, callback_.callback());
[email protected]0b2294d32013-08-02 00:46:361735 if (i == 0) {
robpercival214763f2016-07-01 23:27:011736 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1737 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]0b2294d32013-08-02 00:46:361738 } else {
robpercival214763f2016-07-01 23:27:011739 EXPECT_THAT(rv, IsOk());
[email protected]0b2294d32013-08-02 00:46:361740 }
Yixin Wang7891a39d2017-11-08 20:59:241741 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0b2294d32013-08-02 00:46:361742 EXPECT_TRUE(stream);
Steven Valdezb4ff0412018-01-18 22:39:271743 EXPECT_EQ(OK,
1744 stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:391745 net_log_, CompletionOnceCallback()));
avib3635452016-10-21 18:33:531746 streams.push_back(std::move(stream));
[email protected]0b2294d32013-08-02 00:46:361747 }
1748
zhongyi98d6a9262017-05-19 02:47:451749 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:511750 EXPECT_EQ(OK,
1751 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521752 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1753 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:511754 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1755 failed_on_default_network_callback_, CompletionOnceCallback()));
Yixin Wang7891a39d2017-11-08 20:59:241756 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0b2294d32013-08-02 00:46:361757 EXPECT_TRUE(stream);
rjshaded5ced072015-12-18 19:26:021758 EXPECT_EQ(ERR_IO_PENDING,
Steven Valdezb4ff0412018-01-18 22:39:271759 stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
1760 net_log_, callback_.callback()));
[email protected]0b2294d32013-08-02 00:46:361761
1762 // Close the first stream.
1763 streams.front()->Close(false);
ckrasicea295fe2015-10-31 05:03:271764 // Trigger exchange of RSTs that in turn allow progress for the last
1765 // stream.
Frank Kastenholz878763bf2018-11-28 19:14:481766 base::RunLoop().RunUntilIdle();
robpercival214763f2016-07-01 23:27:011767 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]0b2294d32013-08-02 00:46:361768
rch37de576c2015-05-17 20:28:171769 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1770 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
ckrasicea295fe2015-10-31 05:03:271771
1772 // Force close of the connection to suppress the generation of RST
1773 // packets when streams are torn down, which wouldn't be relevant to
1774 // this test anyway.
bnc912a04b2016-04-20 14:19:501775 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521776 session->connection()->CloseConnection(
1777 quic::QUIC_PUBLIC_RESET, "test",
1778 quic::ConnectionCloseBehavior::SILENT_CLOSE);
[email protected]0b2294d32013-08-02 00:46:361779}
1780
[email protected]1e960032013-12-20 19:00:201781TEST_P(QuicStreamFactoryTest, ResolutionErrorInCreate) {
jri7046038f2015-10-22 00:29:261782 Initialize();
Ryan Hamiltonabad59e2019-06-06 04:02:591783 MockQuicData socket_data(version_);
Zhongyi Shi5f587cc2017-11-21 23:24:171784 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]e13201d82012-12-12 05:00:321785
Renjiea0cb4a2c2018-09-26 23:37:301786 host_resolver_->rules()->AddSimulatedFailure(kDefaultServerHostName);
[email protected]e13201d82012-12-12 05:00:321787
zhongyi98d6a9262017-05-19 02:47:451788 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331789 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031790 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521791 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1792 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031793 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1794 failed_on_default_network_callback_, callback_.callback()));
[email protected]e13201d82012-12-12 05:00:321795
robpercival214763f2016-07-01 23:27:011796 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
[email protected]e13201d82012-12-12 05:00:321797
rch37de576c2015-05-17 20:28:171798 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1799 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]e13201d82012-12-12 05:00:321800}
1801
[email protected]1e960032013-12-20 19:00:201802TEST_P(QuicStreamFactoryTest, ConnectErrorInCreate) {
jri7046038f2015-10-22 00:29:261803 Initialize();
rcha00569732016-08-27 11:09:361804
Ryan Hamiltonabad59e2019-06-06 04:02:591805 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361806 socket_data.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
Zhongyi Shi5f587cc2017-11-21 23:24:171807 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]3c772402013-12-18 21:38:111808
zhongyi98d6a9262017-05-19 02:47:451809 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331810 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031811 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521812 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1813 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031814 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1815 failed_on_default_network_callback_, callback_.callback()));
[email protected]3c772402013-12-18 21:38:111816
robpercival214763f2016-07-01 23:27:011817 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_ADDRESS_IN_USE));
[email protected]3c772402013-12-18 21:38:111818
rch37de576c2015-05-17 20:28:171819 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1820 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]3c772402013-12-18 21:38:111821}
1822
[email protected]1e960032013-12-20 19:00:201823TEST_P(QuicStreamFactoryTest, CancelCreate) {
jri7046038f2015-10-22 00:29:261824 Initialize();
Ryan Hamiltonabad59e2019-06-06 04:02:591825 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361826 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431827 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171828 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]e13201d82012-12-12 05:00:321829 {
zhongyi98d6a9262017-05-19 02:47:451830 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331831 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031832 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521833 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1834 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031835 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1836 failed_on_default_network_callback_, callback_.callback()));
[email protected]e13201d82012-12-12 05:00:321837 }
1838
mmenke651bae7f2015-12-18 21:26:451839 base::RunLoop().RunUntilIdle();
[email protected]e13201d82012-12-12 05:00:321840
zhongyi98d6a9262017-05-19 02:47:451841 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:511842 EXPECT_EQ(OK,
1843 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521844 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1845 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:511846 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1847 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241848 std::unique_ptr<HttpStream> stream = CreateStream(&request2);
rch68a80eb2017-04-25 05:24:241849
[email protected]e13201d82012-12-12 05:00:321850 EXPECT_TRUE(stream.get());
1851 stream.reset();
1852
rch37de576c2015-05-17 20:28:171853 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1854 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]e13201d82012-12-12 05:00:321855}
1856
[email protected]1e960032013-12-20 19:00:201857TEST_P(QuicStreamFactoryTest, CloseAllSessions) {
jri7046038f2015-10-22 00:29:261858 Initialize();
rch6faa4d42016-01-05 20:48:431859 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1860 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1861 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1862
Ryan Hamiltonabad59e2019-06-06 04:02:591863 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361864 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431865 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Ryan Hamilton8d9ee76e2018-05-29 23:52:521866 socket_data.AddWrite(
1867 SYNCHRONOUS, ConstructClientRstPacket(2, quic::QUIC_RST_ACKNOWLEDGEMENT));
Renjieba55fae2018-09-20 03:05:161868 socket_data.AddWrite(SYNCHRONOUS,
1869 client_maker_.MakeConnectionClosePacket(
Ryan Hamilton1556a722019-06-19 21:04:171870 3, true, quic::QUIC_PEER_GOING_AWAY, "net error"));
Zhongyi Shi5f587cc2017-11-21 23:24:171871 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]56dfb902013-01-03 23:17:551872
Ryan Hamilton0d65a8c2019-06-07 00:46:021873 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:591874 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:361875 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431876 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171877 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]56dfb902013-01-03 23:17:551878
zhongyi98d6a9262017-05-19 02:47:451879 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331880 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031881 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521882 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1883 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031884 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1885 failed_on_default_network_callback_, callback_.callback()));
[email protected]56dfb902013-01-03 23:17:551886
robpercival214763f2016-07-01 23:27:011887 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241888 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0b2294d32013-08-02 00:46:361889 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:391890 request_info.traffic_annotation =
1891 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:271892 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:391893 net_log_, CompletionOnceCallback()));
[email protected]56dfb902013-01-03 23:17:551894
1895 // Close the session and verify that stream saw the error.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521896 factory_->CloseAllSessions(ERR_INTERNET_DISCONNECTED,
Ryan Hamilton1556a722019-06-19 21:04:171897 quic::QUIC_PEER_GOING_AWAY);
[email protected]56dfb902013-01-03 23:17:551898 EXPECT_EQ(ERR_INTERNET_DISCONNECTED,
1899 stream->ReadResponseHeaders(callback_.callback()));
1900
1901 // Now attempting to request a stream to the same origin should create
1902 // a new session.
1903
zhongyi98d6a9262017-05-19 02:47:451904 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331905 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031906 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521907 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1908 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031909 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1910 failed_on_default_network_callback_, callback_.callback()));
[email protected]56dfb902013-01-03 23:17:551911
robpercival214763f2016-07-01 23:27:011912 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241913 stream = CreateStream(&request2);
[email protected]56dfb902013-01-03 23:17:551914 stream.reset(); // Will reset stream 3.
1915
rch37de576c2015-05-17 20:28:171916 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1917 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1918 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1919 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]56dfb902013-01-03 23:17:551920}
1921
zhongyi363c91c2017-03-23 23:16:081922// Regression test for crbug.com/700617. Test a write error during the
1923// crypto handshake will not hang QuicStreamFactory::Job and should
1924// report QUIC_HANDSHAKE_FAILED to upper layers. Subsequent
1925// QuicStreamRequest should succeed without hanging.
1926TEST_P(QuicStreamFactoryTest,
1927 WriteErrorInCryptoConnectWithAsyncHostResolution) {
1928 Initialize();
1929 // Use unmocked crypto stream to do crypto connect.
1930 crypto_client_stream_factory_.set_handshake_mode(
Zhongyi Shi879659422018-08-02 17:58:251931 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
zhongyi363c91c2017-03-23 23:16:081932
Ryan Hamiltonabad59e2019-06-06 04:02:591933 MockQuicData socket_data(version_);
zhongyi363c91c2017-03-23 23:16:081934 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1935 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
1936 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:171937 socket_data.AddSocketDataToFactory(socket_factory_.get());
zhongyi363c91c2017-03-23 23:16:081938
1939 // Create request, should fail after the write of the CHLO fails.
zhongyi98d6a9262017-05-19 02:47:451940 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331941 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031942 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521943 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1944 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031945 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1946 failed_on_default_network_callback_, callback_.callback()));
zhongyi363c91c2017-03-23 23:16:081947 EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED, callback_.WaitForResult());
1948 EXPECT_FALSE(HasActiveSession(host_port_pair_));
1949 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
1950
1951 // Verify new requests can be sent normally without hanging.
1952 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271953 MockCryptoClientStream::COLD_START);
zhongyi363c91c2017-03-23 23:16:081954 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1955 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
Ryan Hamilton0d65a8c2019-06-07 00:46:021956 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:591957 MockQuicData socket_data2(version_);
zhongyi363c91c2017-03-23 23:16:081958 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431959 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171960 socket_data2.AddSocketDataToFactory(socket_factory_.get());
zhongyi363c91c2017-03-23 23:16:081961
zhongyi98d6a9262017-05-19 02:47:451962 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331963 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031964 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521965 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1966 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031967 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1968 failed_on_default_network_callback_, callback_.callback()));
zhongyi363c91c2017-03-23 23:16:081969 EXPECT_FALSE(HasActiveSession(host_port_pair_));
1970 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
1971 // Run the message loop to complete host resolution.
1972 base::RunLoop().RunUntilIdle();
1973
1974 // Complete handshake. QuicStreamFactory::Job should complete and succeed.
1975 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521976 quic::QuicSession::HANDSHAKE_CONFIRMED);
zhongyi363c91c2017-03-23 23:16:081977 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1978 EXPECT_TRUE(HasActiveSession(host_port_pair_));
1979 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
1980
1981 // Create QuicHttpStream.
Yixin Wang7891a39d2017-11-08 20:59:241982 std::unique_ptr<HttpStream> stream = CreateStream(&request2);
zhongyi363c91c2017-03-23 23:16:081983 EXPECT_TRUE(stream.get());
1984 stream.reset();
1985 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1986 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1987 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1988 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
1989}
1990
1991TEST_P(QuicStreamFactoryTest, WriteErrorInCryptoConnectWithSyncHostResolution) {
1992 Initialize();
1993 // Use unmocked crypto stream to do crypto connect.
1994 crypto_client_stream_factory_.set_handshake_mode(
Zhongyi Shi879659422018-08-02 17:58:251995 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
Renjiea0cb4a2c2018-09-26 23:37:301996 host_resolver_->set_synchronous_mode(true);
1997 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
1998 "192.168.0.1", "");
zhongyi363c91c2017-03-23 23:16:081999
Ryan Hamiltonabad59e2019-06-06 04:02:592000 MockQuicData socket_data(version_);
zhongyi363c91c2017-03-23 23:16:082001 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2002 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
2003 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:172004 socket_data.AddSocketDataToFactory(socket_factory_.get());
zhongyi363c91c2017-03-23 23:16:082005
2006 // Create request, should fail immediately.
zhongyi98d6a9262017-05-19 02:47:452007 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332008 EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED,
Zhongyi Shia6b68d112018-09-24 07:49:032009 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:522010 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
2011 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032012 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2013 failed_on_default_network_callback_, callback_.callback()));
zhongyi363c91c2017-03-23 23:16:082014 // Check no active session, or active jobs left for this server.
2015 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2016 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
2017
2018 // Verify new requests can be sent normally without hanging.
2019 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:272020 MockCryptoClientStream::COLD_START);
zhongyi363c91c2017-03-23 23:16:082021 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2022 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
Ryan Hamilton0d65a8c2019-06-07 00:46:022023 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:592024 MockQuicData socket_data2(version_);
zhongyi363c91c2017-03-23 23:16:082025 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432026 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:172027 socket_data2.AddSocketDataToFactory(socket_factory_.get());
zhongyi363c91c2017-03-23 23:16:082028
zhongyi98d6a9262017-05-19 02:47:452029 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332030 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032031 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:522032 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
2033 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032034 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2035 failed_on_default_network_callback_, callback_.callback()));
zhongyi363c91c2017-03-23 23:16:082036 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2037 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
2038
2039 // Complete handshake.
2040 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522041 quic::QuicSession::HANDSHAKE_CONFIRMED);
zhongyi363c91c2017-03-23 23:16:082042 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2043 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2044 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
2045
2046 // Create QuicHttpStream.
Yixin Wang7891a39d2017-11-08 20:59:242047 std::unique_ptr<HttpStream> stream = CreateStream(&request2);
zhongyi363c91c2017-03-23 23:16:082048 EXPECT_TRUE(stream.get());
2049 stream.reset();
2050 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2051 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2052 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
2053 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
2054}
2055
Zhongyi Shi63574b72018-06-01 20:22:252056TEST_P(QuicStreamFactoryTest, CloseSessionsOnIPAddressChanged) {
Zhongyi Shi967d2f12019-02-08 20:58:532057 test_params_.quic_close_sessions_on_ip_change = true;
jri7046038f2015-10-22 00:29:262058 Initialize();
rch6faa4d42016-01-05 20:48:432059 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2060 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2061 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri8c44d692015-10-23 23:53:412062
Ryan Hamiltonabad59e2019-06-06 04:02:592063 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:362064 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432065 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Ryan Hamilton8d9ee76e2018-05-29 23:52:522066 socket_data.AddWrite(
2067 SYNCHRONOUS, ConstructClientRstPacket(2, quic::QUIC_RST_ACKNOWLEDGEMENT));
Renjieba55fae2018-09-20 03:05:162068 socket_data.AddWrite(
2069 SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
2070 3, true, quic::QUIC_IP_ADDRESS_CHANGED, "net error"));
Zhongyi Shi5f587cc2017-11-21 23:24:172071 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]f698a012013-05-06 20:18:592072
Ryan Hamilton0d65a8c2019-06-07 00:46:022073 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:592074 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:362075 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432076 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:172077 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]f698a012013-05-06 20:18:592078
zhongyi98d6a9262017-05-19 02:47:452079 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332080 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032081 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:522082 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
2083 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032084 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2085 failed_on_default_network_callback_, callback_.callback()));
[email protected]f698a012013-05-06 20:18:592086
robpercival214763f2016-07-01 23:27:012087 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242088 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0b2294d32013-08-02 00:46:362089 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392090 request_info.traffic_annotation =
2091 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272092 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392093 net_log_, CompletionOnceCallback()));
[email protected]f698a012013-05-06 20:18:592094
Zhongyi Shi63574b72018-06-01 20:22:252095 // Check an active session exisits for the destination.
2096 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2097 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
2098 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2099
Ryan Hamilton8e32a2b2017-08-28 20:06:522100 IPAddress last_address;
2101 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
Zhongyi Shi63574b72018-06-01 20:22:252102 // Change the IP address and verify that stream saw the error and the active
2103 // session is closed.
jri8c44d692015-10-23 23:53:412104 NotifyIPAddressChanged();
[email protected]f698a012013-05-06 20:18:592105 EXPECT_EQ(ERR_NETWORK_CHANGED,
2106 stream->ReadResponseHeaders(callback_.callback()));
jri7046038f2015-10-22 00:29:262107 EXPECT_TRUE(factory_->require_confirmation());
Ryan Hamilton8e32a2b2017-08-28 20:06:522108 EXPECT_FALSE(http_server_properties_.GetSupportsQuic(&last_address));
Zhongyi Shi63574b72018-06-01 20:22:252109 // Check no active session exists for the destination.
2110 EXPECT_FALSE(HasActiveSession(host_port_pair_));
[email protected]f698a012013-05-06 20:18:592111
2112 // Now attempting to request a stream to the same origin should create
2113 // a new session.
zhongyi98d6a9262017-05-19 02:47:452114 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332115 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032116 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:522117 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
2118 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032119 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2120 failed_on_default_network_callback_, callback_.callback()));
[email protected]f698a012013-05-06 20:18:592121
robpercival214763f2016-07-01 23:27:012122 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242123 stream = CreateStream(&request2);
[email protected]f698a012013-05-06 20:18:592124
Zhongyi Shi63574b72018-06-01 20:22:252125 // Check a new active session exisits for the destination and the old session
2126 // is no longer live.
2127 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2128 QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
2129 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
2130
2131 stream.reset(); // Will reset stream 3.
rch37de576c2015-05-17 20:28:172132 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2133 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2134 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
2135 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]f698a012013-05-06 20:18:592136}
2137
Zhongyi Shi63574b72018-06-01 20:22:252138// Test that if goaway_session_on_ip_change is set, old sessions will be marked
2139// as going away on IP address change instead of being closed. New requests will
2140// go to a new connection.
2141TEST_P(QuicStreamFactoryTest, GoAwaySessionsOnIPAddressChanged) {
Zhongyi Shi967d2f12019-02-08 20:58:532142 test_params_.quic_goaway_sessions_on_ip_change = true;
Zhongyi Shi63574b72018-06-01 20:22:252143 Initialize();
2144 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2145 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2146 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2147
Ryan Hamiltonabad59e2019-06-06 04:02:592148 MockQuicData quic_data1(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:022149 quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Fan Yang32c5a112018-12-10 20:06:332150 quic_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:022151 SYNCHRONOUS,
2152 ConstructGetRequestPacket(
2153 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi63574b72018-06-01 20:22:252154 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
2155 quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:332156 ASYNC,
2157 ConstructOkResponsePacket(
2158 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true));
Zhongyi Shi63574b72018-06-01 20:22:252159 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
2160 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2161
Ryan Hamilton0d65a8c2019-06-07 00:46:022162 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:592163 MockQuicData quic_data2(version_);
Zhongyi Shi63574b72018-06-01 20:22:252164 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
Ryan Hamilton0d65a8c2019-06-07 00:46:022165 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Zhongyi Shi63574b72018-06-01 20:22:252166 quic_data2.AddSocketDataToFactory(socket_factory_.get());
2167
2168 // Create request and QuicHttpStream.
2169 QuicStreamRequest request(factory_.get());
2170 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032171 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:522172 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
2173 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032174 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2175 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi63574b72018-06-01 20:22:252176 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2177 std::unique_ptr<HttpStream> stream = CreateStream(&request);
2178 EXPECT_TRUE(stream.get());
2179
2180 // Cause QUIC stream to be created.
2181 HttpRequestInfo request_info;
2182 request_info.method = "GET";
2183 request_info.url = url_;
2184 request_info.traffic_annotation =
2185 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2186 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
2187 net_log_, CompletionOnceCallback()));
2188
2189 // Ensure that session is alive and active.
2190 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
2191 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2192 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2193
2194 // Send GET request on stream.
2195 HttpResponseInfo response;
2196 HttpRequestHeaders request_headers;
2197 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
2198 callback_.callback()));
2199
2200 // Receive an IP address change notification.
2201 NotifyIPAddressChanged();
2202
2203 // The connection should still be alive, but marked as going away.
2204 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2205 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2206 EXPECT_EQ(1u, session->GetNumActiveStreams());
2207
2208 // Resume the data, response should be read from the original connection.
2209 quic_data1.Resume();
2210 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
2211 EXPECT_EQ(200, response.headers->response_code());
2212 EXPECT_EQ(0u, session->GetNumActiveStreams());
2213
2214 // Second request should be sent on a new connection.
2215 QuicStreamRequest request2(factory_.get());
2216 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032217 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:522218 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
2219 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032220 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2221 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi63574b72018-06-01 20:22:252222 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2223 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
2224 EXPECT_TRUE(stream2.get());
2225
2226 // Check an active session exisits for the destination.
2227 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2228 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2229 QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
2230 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
2231
2232 stream.reset();
2233 stream2.reset();
2234 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
2235 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
2236 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
2237 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
2238}
2239
Jana Iyengarba355772017-09-21 22:03:212240TEST_P(QuicStreamFactoryTest, OnIPAddressChangedWithConnectionMigration) {
Zhongyi Shi1a054612018-06-14 04:59:082241 InitializeConnectionMigrationV2Test(
Jana Iyengarba355772017-09-21 22:03:212242 {kDefaultNetworkForTests, kNewNetworkForTests});
2243 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2244 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2245 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2246
Ryan Hamiltonabad59e2019-06-06 04:02:592247 MockQuicData socket_data(version_);
Jana Iyengarba355772017-09-21 22:03:212248 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432249 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Ryan Hamilton8d9ee76e2018-05-29 23:52:522250 socket_data.AddWrite(
2251 SYNCHRONOUS, ConstructClientRstPacket(2, quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:172252 socket_data.AddSocketDataToFactory(socket_factory_.get());
Jana Iyengarba355772017-09-21 22:03:212253
2254 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332255 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032256 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:522257 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
2258 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032259 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2260 failed_on_default_network_callback_, callback_.callback()));
Jana Iyengarba355772017-09-21 22:03:212261
2262 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242263 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Jana Iyengarba355772017-09-21 22:03:212264 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392265 request_info.traffic_annotation =
2266 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272267 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392268 net_log_, CompletionOnceCallback()));
Jana Iyengarba355772017-09-21 22:03:212269
2270 IPAddress last_address;
2271 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
2272
2273 // Change the IP address and verify that the connection is unaffected.
2274 NotifyIPAddressChanged();
2275 EXPECT_FALSE(factory_->require_confirmation());
2276 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
2277
2278 // Attempting a new request to the same origin uses the same connection.
2279 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:512280 EXPECT_EQ(OK,
2281 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:522282 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
2283 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:512284 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2285 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:242286 stream = CreateStream(&request2);
Jana Iyengarba355772017-09-21 22:03:212287
2288 stream.reset();
2289 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2290 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2291}
2292
Zhongyi Shia0644e32018-06-21 05:19:522293TEST_P(QuicStreamFactoryTest, MigrateOnNetworkMadeDefaultWithSynchronousWrite) {
2294 TestMigrationOnNetworkMadeDefault(SYNCHRONOUS);
jri9f303712016-09-13 01:10:222295}
2296
Zhongyi Shia0644e32018-06-21 05:19:522297TEST_P(QuicStreamFactoryTest, MigrateOnNetworkMadeDefaultWithAsyncWrite) {
2298 TestMigrationOnNetworkMadeDefault(ASYNC);
jri9f303712016-09-13 01:10:222299}
2300
Zhongyi Shia0644e32018-06-21 05:19:522301// Sets up a test which attempts connection migration successfully after probing
2302// when a new network is made as default and the old default is still available.
2303// |write_mode| specifies the write mode for the last write before
2304// OnNetworkMadeDefault is delivered to session.
2305void QuicStreamFactoryTestBase::TestMigrationOnNetworkMadeDefault(
2306 IoMode write_mode) {
2307 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri7e636642016-01-14 06:57:082308 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2309 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2310 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2311
Zhongyi Shia0644e32018-06-21 05:19:522312 // Using a testing task runner so that we can control time.
2313 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
2314 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
2315
2316 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2317 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
2318
Ryan Hamiltonabad59e2019-06-06 04:02:592319 MockQuicData quic_data1(version_);
Zhongyi Shia0644e32018-06-21 05:19:522320 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
Ryan Hamilton0d65a8c2019-06-07 00:46:022321 quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shia0644e32018-06-21 05:19:522322 quic_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:022323 write_mode,
2324 ConstructGetRequestPacket(
2325 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shia0644e32018-06-21 05:19:522326 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2327
2328 // Set up the second socket data provider that is used after migration.
2329 // The response to the earlier request is read on the new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:592330 MockQuicData quic_data2(version_);
Zhongyi Shia0644e32018-06-21 05:19:522331 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:252332 quic_data2.AddWrite(SYNCHRONOUS,
2333 client_maker_.MakeConnectivityProbingPacket(3, true));
Zhongyi Shia0644e32018-06-21 05:19:522334 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
2335 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:252336 quic_data2.AddRead(ASYNC,
2337 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shia0644e32018-06-21 05:19:522338 // Ping packet to send after migration is completed.
2339 quic_data2.AddWrite(ASYNC,
2340 client_maker_.MakeAckAndPingPacket(4, false, 1, 1, 1));
2341 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:332342 ASYNC,
2343 ConstructOkResponsePacket(
2344 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shia0644e32018-06-21 05:19:522345 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:332346 quic_data2.AddWrite(
2347 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
2348 5, false, GetNthClientInitiatedBidirectionalStreamId(0),
2349 quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true));
Zhongyi Shia0644e32018-06-21 05:19:522350 quic_data2.AddSocketDataToFactory(socket_factory_.get());
jri7e636642016-01-14 06:57:082351
2352 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452353 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332354 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032355 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:522356 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
2357 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032358 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2359 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012360 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242361 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri7e636642016-01-14 06:57:082362 EXPECT_TRUE(stream.get());
2363
2364 // Cause QUIC stream to be created.
2365 HttpRequestInfo request_info;
2366 request_info.method = "GET";
bnc3d9035b32016-06-30 18:18:482367 request_info.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:392368 request_info.traffic_annotation =
2369 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272370 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392371 net_log_, CompletionOnceCallback()));
jri7e636642016-01-14 06:57:082372
2373 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502374 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri7e636642016-01-14 06:57:082375 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2376 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2377
2378 // Send GET request on stream.
2379 HttpResponseInfo response;
2380 HttpRequestHeaders request_headers;
2381 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
2382 callback_.callback()));
2383
Zhongyi Shia0644e32018-06-21 05:19:522384 // Deliver a signal that a alternate network is connected now, this should
2385 // cause the connection to start early migration on path degrading.
2386 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2387 ->SetConnectedNetworksList(
2388 {kDefaultNetworkForTests, kNewNetworkForTests});
2389 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2390 ->NotifyNetworkConnected(kNewNetworkForTests);
jri9f303712016-09-13 01:10:222391
Zhongyi Shia0644e32018-06-21 05:19:522392 // Cause the connection to report path degrading to the session.
2393 // Due to lack of alternate network, session will not mgirate connection.
2394 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
jri7e636642016-01-14 06:57:082395 scoped_mock_network_change_notifier_->mock_network_change_notifier()
jrie2661982016-08-20 08:24:342396 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri7e636642016-01-14 06:57:082397
Zhongyi Shia0644e32018-06-21 05:19:522398 // A task will be posted to migrate to the new default network.
2399 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2400 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
2401
2402 // Execute the posted task to migrate back to the default network.
2403 task_runner->RunUntilIdle();
2404 // Another task to try send a new connectivity probe is posted. And a task to
2405 // retry migrate back to default network is scheduled.
2406 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
2407 // Next connectivity probe is scheduled to be sent in 2 *
2408 // kDefaultRTTMilliSecs.
2409 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
2410 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
2411 next_task_delay);
2412
2413 // The connection should still be alive, and not marked as going away.
jri7e636642016-01-14 06:57:082414 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia0644e32018-06-21 05:19:522415 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2416 EXPECT_EQ(1u, session->GetNumActiveStreams());
2417 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
2418
2419 // Resume quic data and a connectivity probe response will be read on the new
2420 // socket, declare probing as successful. And a new task to WriteToNewSocket
2421 // will be posted to complete migration.
2422 quic_data2.Resume();
2423
2424 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2425 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri7e636642016-01-14 06:57:082426 EXPECT_EQ(1u, session->GetNumActiveStreams());
2427
Zhongyi Shia0644e32018-06-21 05:19:522428 // There should be three pending tasks, the nearest one will complete
2429 // migration to the new network.
2430 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
2431 next_task_delay = task_runner->NextPendingTaskDelay();
2432 EXPECT_EQ(base::TimeDelta(), next_task_delay);
2433 task_runner->FastForwardBy(next_task_delay);
2434
2435 // Response headers are received over the new network.
2436 EXPECT_THAT(callback_.WaitForResult(), IsOk());
jri7e636642016-01-14 06:57:082437 EXPECT_EQ(200, response.headers->response_code());
2438
Zhongyi Shia0644e32018-06-21 05:19:522439 // Now there are two pending tasks, the nearest one was to send connectivity
2440 // probe and has been cancelled due to successful migration.
2441 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
2442 next_task_delay = task_runner->NextPendingTaskDelay();
2443 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
2444 next_task_delay);
2445 task_runner->FastForwardBy(next_task_delay);
jri7e636642016-01-14 06:57:082446
Zhongyi Shia0644e32018-06-21 05:19:522447 // There's one more task to mgirate back to the default network in 0.4s, which
2448 // is also cancelled due to the success migration on the previous trial.
2449 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2450 next_task_delay = task_runner->NextPendingTaskDelay();
2451 base::TimeDelta expected_delay =
2452 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
2453 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
2454 EXPECT_EQ(expected_delay, next_task_delay);
2455 task_runner->FastForwardBy(next_task_delay);
2456 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
jri7e636642016-01-14 06:57:082457
Zhongyi Shia0644e32018-06-21 05:19:522458 // Verify that the session is still alive.
jri7e636642016-01-14 06:57:082459 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia0644e32018-06-21 05:19:522460 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri7e636642016-01-14 06:57:082461
Zhongyi Shia0644e32018-06-21 05:19:522462 stream.reset();
2463 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
2464 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
2465 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
2466 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
jri7e636642016-01-14 06:57:082467}
2468
Zhongyi Shib3bc982c2018-07-10 19:59:242469// Regression test for http://859674.
2470// This test veries that a writer will not attempt to write packets until being
2471// unblocked on both socket level and network level. In this test, a probing
2472// writer is used to send two connectivity probes to the peer: where the first
2473// one completes successfully, while a connectivity response is received before
2474// completes sending the second one. The connection migration attempt will
2475// proceed while the probing writer is blocked at the socket level, which will
2476// block the writer on the network level. Once connection migration completes
2477// successfully, the probing writer will be unblocked on the network level, it
2478// will not attempt to write new packets until the socket level is unblocked.
2479TEST_P(QuicStreamFactoryTest, MigratedToBlockedSocketAfterProbing) {
2480 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
2481 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2482 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2483 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2484
2485 // Using a testing task runner so that we can control time.
2486 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
2487 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
2488
2489 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2490 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
2491
Ryan Hamiltonabad59e2019-06-06 04:02:592492 MockQuicData quic_data1(version_);
Zhongyi Shib3bc982c2018-07-10 19:59:242493 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
Ryan Hamilton0d65a8c2019-06-07 00:46:022494 quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Fan Yang32c5a112018-12-10 20:06:332495 quic_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:022496 SYNCHRONOUS,
2497 ConstructGetRequestPacket(
2498 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shib3bc982c2018-07-10 19:59:242499 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2500
2501 // Set up the second socket data provider that is used after migration.
2502 // The response to the earlier request is read on the new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:592503 MockQuicData quic_data2(version_);
Zhongyi Shib3bc982c2018-07-10 19:59:242504 // First connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:252505 quic_data2.AddWrite(SYNCHRONOUS,
2506 client_maker_.MakeConnectivityProbingPacket(3, true));
Zhongyi Shib3bc982c2018-07-10 19:59:242507 quic_data2.AddRead(ASYNC,
2508 ERR_IO_PENDING); // Pause so that we can control time.
2509 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:252510 quic_data2.AddRead(ASYNC,
2511 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shib3bc982c2018-07-10 19:59:242512 // Second connectivity probe which will complete asynchronously.
Zhongyi Shi879659422018-08-02 17:58:252513 quic_data2.AddWrite(ASYNC,
2514 client_maker_.MakeConnectivityProbingPacket(4, true));
Zhongyi Shib3bc982c2018-07-10 19:59:242515 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:332516 ASYNC,
2517 ConstructOkResponsePacket(
2518 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shib3bc982c2018-07-10 19:59:242519 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2520 quic_data2.AddWrite(ASYNC,
2521 client_maker_.MakeAckAndPingPacket(5, false, 1, 1, 1));
Fan Yang32c5a112018-12-10 20:06:332522 quic_data2.AddWrite(
2523 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
2524 6, false, GetNthClientInitiatedBidirectionalStreamId(0),
2525 quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true));
Zhongyi Shib3bc982c2018-07-10 19:59:242526
2527 quic_data2.AddSocketDataToFactory(socket_factory_.get());
2528
2529 // Create request and QuicHttpStream.
2530 QuicStreamRequest request(factory_.get());
2531 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032532 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:522533 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
2534 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032535 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2536 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shib3bc982c2018-07-10 19:59:242537 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2538 std::unique_ptr<HttpStream> stream = CreateStream(&request);
2539 EXPECT_TRUE(stream.get());
2540
2541 // Cause QUIC stream to be created.
2542 HttpRequestInfo request_info;
2543 request_info.method = "GET";
2544 request_info.url = url_;
2545 request_info.traffic_annotation =
2546 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2547 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
2548 net_log_, CompletionOnceCallback()));
2549
2550 // Ensure that session is alive and active.
2551 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
2552 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2553 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2554
2555 // Send GET request on stream.
2556 HttpResponseInfo response;
2557 HttpRequestHeaders request_headers;
2558 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
2559 callback_.callback()));
2560
2561 // Deliver a signal that a alternate network is connected now, this should
2562 // cause the connection to start early migration on path degrading.
2563 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2564 ->SetConnectedNetworksList(
2565 {kDefaultNetworkForTests, kNewNetworkForTests});
2566 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2567 ->NotifyNetworkConnected(kNewNetworkForTests);
2568
2569 // Cause the connection to report path degrading to the session.
2570 // Due to lack of alternate network, session will not mgirate connection.
2571 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
2572 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2573 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2574
2575 // A task will be posted to migrate to the new default network.
2576 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2577 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
2578
2579 // Execute the posted task to migrate back to the default network.
2580 task_runner->RunUntilIdle();
2581 // Another task to resend a new connectivity probe is posted. And a task to
2582 // retry migrate back to default network is scheduled.
2583 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
2584 // Next connectivity probe is scheduled to be sent in 2 *
2585 // kDefaultRTTMilliSecs.
2586 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
2587 base::TimeDelta expected_delay =
2588 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
2589 EXPECT_EQ(expected_delay, next_task_delay);
2590
2591 // Fast forward to send the second connectivity probe. The write will be
2592 // asynchronous and complete after the read completes.
2593 task_runner->FastForwardBy(next_task_delay);
2594
2595 // Resume quic data and a connectivity probe response will be read on the new
2596 // socket, declare probing as successful.
2597 quic_data2.Resume();
2598
2599 // The connection should still be alive, and not marked as going away.
2600 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2601 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2602 EXPECT_EQ(1u, session->GetNumActiveStreams());
2603 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
2604
2605 // There should be three pending tasks, the nearest one will complete
2606 // migration to the new network. Second task will retry migrate back to
2607 // default but cancelled, and the third task will retry send connectivity
2608 // probe but also cancelled.
2609 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
2610 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
2611 task_runner->RunUntilIdle();
2612
2613 // Response headers are received over the new network.
2614 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2615 EXPECT_EQ(200, response.headers->response_code());
2616
2617 // Run the message loop to complete the asynchronous write of ack and ping.
2618 base::RunLoop().RunUntilIdle();
2619
2620 // Now there are two pending tasks, the nearest one was to retry migrate back
2621 // to default network and has been cancelled due to successful migration.
2622 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
2623 expected_delay =
2624 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
2625 expected_delay;
2626 next_task_delay = task_runner->NextPendingTaskDelay();
2627 EXPECT_EQ(expected_delay, next_task_delay);
2628 task_runner->FastForwardBy(next_task_delay);
2629
2630 // There's one more task to retry sending connectivity probe in 0.4s and has
2631 // also been cancelled due to the successful probing.
2632 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2633 next_task_delay = task_runner->NextPendingTaskDelay();
2634 expected_delay =
2635 base::TimeDelta::FromMilliseconds(3 * 2 * kDefaultRTTMilliSecs) -
2636 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs);
2637 EXPECT_EQ(expected_delay, next_task_delay);
2638 task_runner->FastForwardBy(next_task_delay);
2639 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
2640
2641 // Verify that the session is still alive.
2642 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2643 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2644
2645 stream.reset();
2646 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
2647 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
2648 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
2649 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
2650}
2651
Zhongyi Shib1b1fa42018-06-19 23:13:472652// This test verifies that session times out connection migration attempt
2653// with signals delivered in the following order (no alternate network is
2654// available):
2655// - default network disconnected is delivered: session attempts connection
2656// migration but found not alternate network. Session waits for a new network
Zhongyi Shie01f2db2019-02-22 19:53:232657// comes up in the next kWaitTimeForNewNetworkSecs seconds.
Zhongyi Shib1b1fa42018-06-19 23:13:472658// - no new network is connected, migration times out. Session is closed.
2659TEST_P(QuicStreamFactoryTest, MigrationTimeoutWithNoNewNetwork) {
2660 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri7e636642016-01-14 06:57:082661 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2662 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2663
Zhongyi Shib1b1fa42018-06-19 23:13:472664 // Using a testing task runner so that we can control time.
2665 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
2666 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
jri5b785512016-09-13 04:29:112667
Ryan Hamiltonabad59e2019-06-06 04:02:592668 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:362669 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432670 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:172671 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri7e636642016-01-14 06:57:082672
2673 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452674 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332675 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032676 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:522677 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
2678 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032679 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2680 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012681 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242682 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri7e636642016-01-14 06:57:082683 EXPECT_TRUE(stream.get());
2684
2685 // Cause QUIC stream to be created.
2686 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392687 request_info.traffic_annotation =
2688 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272689 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392690 net_log_, CompletionOnceCallback()));
jri7e636642016-01-14 06:57:082691
2692 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502693 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri7e636642016-01-14 06:57:082694 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2695 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2696
2697 // Trigger connection migration. Since there are no networks
jri5b785512016-09-13 04:29:112698 // to migrate to, this should cause the session to wait for a new network.
jri7e636642016-01-14 06:57:082699 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2700 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
2701
jri5b785512016-09-13 04:29:112702 // The migration will not fail until the migration alarm timeout.
2703 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shib1b1fa42018-06-19 23:13:472704 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:112705 EXPECT_EQ(1u, session->GetNumActiveStreams());
2706 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
2707 EXPECT_EQ(true, session->connection()->writer()->IsWriteBlocked());
2708
Zhongyi Shib1b1fa42018-06-19 23:13:472709 // Migration will be timed out after kWaitTimeForNewNetwokSecs.
2710 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2711 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
2712 EXPECT_EQ(base::TimeDelta::FromSeconds(kWaitTimeForNewNetworkSecs),
2713 next_task_delay);
2714 task_runner->FastForwardBy(next_task_delay);
jri5b785512016-09-13 04:29:112715
2716 // The connection should now be closed. A request for response
2717 // headers should fail.
jri7e636642016-01-14 06:57:082718 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2719 EXPECT_FALSE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:112720 EXPECT_EQ(ERR_NETWORK_CHANGED, callback_.WaitForResult());
jri7e636642016-01-14 06:57:082721
2722 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2723 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2724}
2725
Zhongyi Shi21e99532018-07-17 22:23:072726// This test verifies that connectivity probes will be sent even if there is
2727// a non-migratable stream. However, when connection migrates to the
Zhongyi Shic16b4102019-02-12 00:37:402728// successfully probed path, any non-migratable streams will be reset.
Zhongyi Shi32fe14d42019-02-28 00:25:362729TEST_P(QuicStreamFactoryTest,
2730 OnNetworkMadeDefaultNonMigratableStream_MigrateIdleSessions) {
2731 TestOnNetworkMadeDefaultNonMigratableStream(true);
2732}
2733
2734// This test verifies that connectivity probes will be sent even if there is
2735// a non-migratable stream. However, when connection migrates to the
2736// successfully probed path, any non-migratable stream will be reset. And if
2737// the connection becomes idle then, close the connection.
2738TEST_P(QuicStreamFactoryTest,
2739 OnNetworkMadeDefaultNonMigratableStream_DoNotMigrateIdleSessions) {
2740 TestOnNetworkMadeDefaultNonMigratableStream(false);
2741}
2742
2743void QuicStreamFactoryTestBase::TestOnNetworkMadeDefaultNonMigratableStream(
2744 bool migrate_idle_sessions) {
2745 test_params_.quic_migrate_idle_sessions = migrate_idle_sessions;
Zhongyi Shi5f587cc2017-11-21 23:24:172746 InitializeConnectionMigrationV2Test(
2747 {kDefaultNetworkForTests, kNewNetworkForTests});
2748 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2749 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2750
Ryan Hamiltonabad59e2019-06-06 04:02:592751 MockQuicData socket_data(version_);
Zhongyi Shi5f587cc2017-11-21 23:24:172752 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432753 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi32fe14d42019-02-28 00:25:362754 if (!migrate_idle_sessions) {
2755 socket_data.AddWrite(
2756 SYNCHRONOUS,
2757 client_maker_.MakeRstAckAndConnectionClosePacket(
2758 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
2759 quic::QUIC_STREAM_CANCELLED,
2760 quic::QuicTime::Delta::FromMilliseconds(0), 1, 1, 1,
2761 quic::QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS,
2762 "net error"));
2763 }
Renjieba55fae2018-09-20 03:05:162764
Zhongyi Shi5f587cc2017-11-21 23:24:172765 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri231c2972016-03-08 19:50:112766
Zhongyi Shi21e99532018-07-17 22:23:072767 // Set up the second socket data provider that is used for probing.
Ryan Hamiltonabad59e2019-06-06 04:02:592768 MockQuicData quic_data1(version_);
Zhongyi Shi21e99532018-07-17 22:23:072769 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:252770 quic_data1.AddWrite(SYNCHRONOUS,
2771 client_maker_.MakeConnectivityProbingPacket(2, true));
Zhongyi Shi21e99532018-07-17 22:23:072772 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
2773 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:252774 quic_data1.AddRead(ASYNC,
2775 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shi32fe14d42019-02-28 00:25:362776 if (migrate_idle_sessions) {
2777 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
2778 // A RESET will be sent to the peer to cancel the non-migratable stream.
2779 quic_data1.AddWrite(
2780 SYNCHRONOUS,
2781 client_maker_.MakeRstPacket(
2782 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
2783 quic::QUIC_STREAM_CANCELLED));
2784 // Ping packet to send after migration is completed.
2785 quic_data1.AddWrite(SYNCHRONOUS,
2786 client_maker_.MakeAckAndPingPacket(4, false, 1, 1, 1));
2787 }
Zhongyi Shi21e99532018-07-17 22:23:072788 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2789
jri231c2972016-03-08 19:50:112790 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452791 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332792 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032793 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:522794 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
2795 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032796 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2797 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012798 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242799 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri231c2972016-03-08 19:50:112800 EXPECT_TRUE(stream.get());
2801
2802 // Cause QUIC stream to be created, but marked as non-migratable.
2803 HttpRequestInfo request_info;
Zhongyi Shibb28b1f2018-07-18 02:41:262804 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Ramin Halavati683bcaa92018-02-14 08:42:392805 request_info.traffic_annotation =
2806 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272807 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392808 net_log_, CompletionOnceCallback()));
jri231c2972016-03-08 19:50:112809
2810 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502811 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri231c2972016-03-08 19:50:112812 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2813 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2814
Zhongyi Shi21e99532018-07-17 22:23:072815 // Trigger connection migration. Session will start to probe the alternative
2816 // network. Although there is a non-migratable stream, session will still be
2817 // active until probing is declared as successful.
jri231c2972016-03-08 19:50:112818 scoped_mock_network_change_notifier_->mock_network_change_notifier()
jrie2661982016-08-20 08:24:342819 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri231c2972016-03-08 19:50:112820
2821 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shi21e99532018-07-17 22:23:072822 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri231c2972016-03-08 19:50:112823 EXPECT_EQ(1u, session->GetNumActiveStreams());
2824
Zhongyi Shi21e99532018-07-17 22:23:072825 // Resume data to read a connectivity probing response, which will cause
Zhongyi Shic16b4102019-02-12 00:37:402826 // non-migtable streams to be closed.
Zhongyi Shi21e99532018-07-17 22:23:072827 quic_data1.Resume();
2828 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shi32fe14d42019-02-28 00:25:362829 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(host_port_pair_));
Zhongyi Shi21e99532018-07-17 22:23:072830 EXPECT_EQ(0u, session->GetNumActiveStreams());
jri231c2972016-03-08 19:50:112831
Zhongyi Shic16b4102019-02-12 00:37:402832 base::RunLoop().RunUntilIdle();
2833
Zhongyi Shi21e99532018-07-17 22:23:072834 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
2835 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
jri231c2972016-03-08 19:50:112836 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2837 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2838}
2839
jri9f303712016-09-13 01:10:222840TEST_P(QuicStreamFactoryTest, OnNetworkMadeDefaultConnectionMigrationDisabled) {
Zhongyi Shi5f587cc2017-11-21 23:24:172841 InitializeConnectionMigrationV2Test(
2842 {kDefaultNetworkForTests, kNewNetworkForTests});
2843 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2844 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2845
Ryan Hamiltonabad59e2019-06-06 04:02:592846 MockQuicData socket_data(version_);
Zhongyi Shi5f587cc2017-11-21 23:24:172847 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432848 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
2849 socket_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:332850 SYNCHRONOUS, client_maker_.MakeRstPacket(
2851 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
2852 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:172853 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9c541572016-03-29 17:51:482854
2855 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452856 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332857 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032858 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:522859 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
2860 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032861 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2862 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012863 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242864 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9c541572016-03-29 17:51:482865 EXPECT_TRUE(stream.get());
2866
2867 // Cause QUIC stream to be created.
2868 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392869 request_info.traffic_annotation =
2870 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272871 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392872 net_log_, CompletionOnceCallback()));
jri9c541572016-03-29 17:51:482873
2874 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502875 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri9c541572016-03-29 17:51:482876 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2877 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2878
2879 // Set session config to have connection migration disabled.
Ryan Hamilton8d9ee76e2018-05-29 23:52:522880 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
2881 session->config());
jri9c541572016-03-29 17:51:482882 EXPECT_TRUE(session->config()->DisableConnectionMigration());
2883
2884 // Trigger connection migration. Since there is a non-migratable stream,
2885 // this should cause session to continue but be marked as going away.
2886 scoped_mock_network_change_notifier_->mock_network_change_notifier()
jrie2661982016-08-20 08:24:342887 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri9c541572016-03-29 17:51:482888
2889 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2890 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2891 EXPECT_EQ(1u, session->GetNumActiveStreams());
2892
2893 stream.reset();
2894
2895 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2896 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2897}
2898
Zhongyi Shi32fe14d42019-02-28 00:25:362899TEST_P(QuicStreamFactoryTest,
2900 OnNetworkDisconnectedNonMigratableStream_DoNotMigrateIdleSessions) {
2901 TestOnNetworkDisconnectedNonMigratableStream(false);
2902}
2903
2904TEST_P(QuicStreamFactoryTest,
2905 OnNetworkDisconnectedNonMigratableStream_MigrateIdleSessions) {
2906 TestOnNetworkDisconnectedNonMigratableStream(true);
2907}
2908
2909void QuicStreamFactoryTestBase::TestOnNetworkDisconnectedNonMigratableStream(
2910 bool migrate_idle_sessions) {
2911 test_params_.quic_migrate_idle_sessions = migrate_idle_sessions;
Zhongyi Shi5f587cc2017-11-21 23:24:172912 InitializeConnectionMigrationV2Test(
2913 {kDefaultNetworkForTests, kNewNetworkForTests});
2914 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2915 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2916
Ryan Hamiltonabad59e2019-06-06 04:02:592917 MockQuicData failed_socket_data(version_);
2918 MockQuicData socket_data(version_);
Zhongyi Shi32fe14d42019-02-28 00:25:362919 if (migrate_idle_sessions) {
Zhongyi Shi32fe14d42019-02-28 00:25:362920 failed_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:022921 failed_socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi32fe14d42019-02-28 00:25:362922 // A RESET will be sent to the peer to cancel the non-migratable stream.
2923 failed_socket_data.AddWrite(
2924 SYNCHRONOUS, client_maker_.MakeRstPacket(
2925 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
2926 quic::QUIC_STREAM_CANCELLED));
2927 failed_socket_data.AddSocketDataToFactory(socket_factory_.get());
2928
2929 // Set up second socket data provider that is used after migration.
2930 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
2931 // Ping packet to send after migration.
2932 socket_data.AddWrite(
2933 SYNCHRONOUS, client_maker_.MakePingPacket(3, /*include_version=*/true));
2934 socket_data.AddSocketDataToFactory(socket_factory_.get());
2935 } else {
2936 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2937 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
2938 socket_data.AddWrite(
2939 SYNCHRONOUS, client_maker_.MakeRstPacket(
2940 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
2941 quic::QUIC_STREAM_CANCELLED));
2942 socket_data.AddSocketDataToFactory(socket_factory_.get());
2943 }
jri231c2972016-03-08 19:50:112944
2945 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452946 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332947 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032948 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:522949 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
2950 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032951 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2952 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012953 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242954 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri231c2972016-03-08 19:50:112955 EXPECT_TRUE(stream.get());
2956
2957 // Cause QUIC stream to be created, but marked as non-migratable.
2958 HttpRequestInfo request_info;
Zhongyi Shibb28b1f2018-07-18 02:41:262959 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Ramin Halavati683bcaa92018-02-14 08:42:392960 request_info.traffic_annotation =
2961 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272962 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392963 net_log_, CompletionOnceCallback()));
jri231c2972016-03-08 19:50:112964
2965 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502966 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri231c2972016-03-08 19:50:112967 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2968 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2969
2970 // Trigger connection migration. Since there is a non-migratable stream,
2971 // this should cause a RST_STREAM frame to be emitted with
Zhongyi Shic16b4102019-02-12 00:37:402972 // quic::QUIC_STREAM_CANCELLED error code.
Zhongyi Shi32fe14d42019-02-28 00:25:362973 // If migate idle session, the connection will then be migrated to the
2974 // alternate network. Otherwise, the connection will be closed.
jri231c2972016-03-08 19:50:112975 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2976 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
2977
Zhongyi Shi32fe14d42019-02-28 00:25:362978 EXPECT_EQ(migrate_idle_sessions,
2979 QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2980 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(host_port_pair_));
jri231c2972016-03-08 19:50:112981
Zhongyi Shi32fe14d42019-02-28 00:25:362982 if (migrate_idle_sessions) {
2983 EXPECT_EQ(0u, session->GetNumActiveStreams());
2984 base::RunLoop().RunUntilIdle();
Zhongyi Shic16b4102019-02-12 00:37:402985
Zhongyi Shi32fe14d42019-02-28 00:25:362986 EXPECT_TRUE(failed_socket_data.AllReadDataConsumed());
2987 EXPECT_TRUE(failed_socket_data.AllWriteDataConsumed());
2988 }
jri231c2972016-03-08 19:50:112989 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2990 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2991}
2992
jri9c541572016-03-29 17:51:482993TEST_P(QuicStreamFactoryTest,
jri9f303712016-09-13 01:10:222994 OnNetworkDisconnectedConnectionMigrationDisabled) {
Zhongyi Shi5f587cc2017-11-21 23:24:172995 InitializeConnectionMigrationV2Test(
2996 {kDefaultNetworkForTests, kNewNetworkForTests});
2997 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2998 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2999
Ryan Hamiltonabad59e2019-06-06 04:02:593000 MockQuicData socket_data(version_);
Zhongyi Shi5f587cc2017-11-21 23:24:173001 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:433002 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
3003 socket_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333004 SYNCHRONOUS, client_maker_.MakeRstPacket(
3005 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
3006 quic::QUIC_RST_ACKNOWLEDGEMENT));
Zhongyi Shi5f587cc2017-11-21 23:24:173007 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9c541572016-03-29 17:51:483008
3009 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:453010 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:333011 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033012 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:523013 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
3014 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033015 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3016 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:013017 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:243018 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9c541572016-03-29 17:51:483019 EXPECT_TRUE(stream.get());
3020
3021 // Cause QUIC stream to be created.
3022 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:393023 request_info.traffic_annotation =
3024 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:273025 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:393026 net_log_, CompletionOnceCallback()));
jri9c541572016-03-29 17:51:483027
3028 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:503029 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri9c541572016-03-29 17:51:483030 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3031 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3032
3033 // Set session config to have connection migration disabled.
Ryan Hamilton8d9ee76e2018-05-29 23:52:523034 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
3035 session->config());
jri9c541572016-03-29 17:51:483036 EXPECT_TRUE(session->config()->DisableConnectionMigration());
3037
3038 // Trigger connection migration. Since there is a non-migratable stream,
3039 // this should cause a RST_STREAM frame to be emitted with
Ryan Hamilton8d9ee76e2018-05-29 23:52:523040 // quic::QUIC_RST_ACKNOWLEDGEMENT error code, and the session will be closed.
jri9c541572016-03-29 17:51:483041 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3042 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
3043
3044 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3045 EXPECT_FALSE(HasActiveSession(host_port_pair_));
3046
3047 EXPECT_TRUE(socket_data.AllReadDataConsumed());
3048 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
3049}
3050
Zhongyi Shi32fe14d42019-02-28 00:25:363051TEST_P(QuicStreamFactoryTest,
3052 OnNetworkMadeDefaultNoOpenStreams_DoNotMigrateIdleSessions) {
3053 TestOnNetworkMadeDefaultNoOpenStreams(false);
3054}
3055
3056TEST_P(QuicStreamFactoryTest,
3057 OnNetworkMadeDefaultNoOpenStreams_MigrateIdleSessions) {
3058 TestOnNetworkMadeDefaultNoOpenStreams(true);
3059}
3060
3061void QuicStreamFactoryTestBase::TestOnNetworkMadeDefaultNoOpenStreams(
3062 bool migrate_idle_sessions) {
3063 test_params_.quic_migrate_idle_sessions = migrate_idle_sessions;
Zhongyi Shi5f587cc2017-11-21 23:24:173064 InitializeConnectionMigrationV2Test(
3065 {kDefaultNetworkForTests, kNewNetworkForTests});
3066 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3067 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3068
Ryan Hamiltonabad59e2019-06-06 04:02:593069 MockQuicData socket_data(version_);
Zhongyi Shi5f587cc2017-11-21 23:24:173070 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:433071 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi32fe14d42019-02-28 00:25:363072 if (!migrate_idle_sessions) {
3073 socket_data.AddWrite(
3074 SYNCHRONOUS,
3075 client_maker_.MakeConnectionClosePacket(
3076 2, true, quic::QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS,
3077 "net error"));
3078 }
Zhongyi Shi5f587cc2017-11-21 23:24:173079 socket_data.AddSocketDataToFactory(socket_factory_.get());
3080
Ryan Hamiltonabad59e2019-06-06 04:02:593081 MockQuicData quic_data1(version_);
Zhongyi Shi32fe14d42019-02-28 00:25:363082 if (migrate_idle_sessions) {
3083 // Set up the second socket data provider that is used for probing.
3084 // Connectivity probe to be sent on the new path.
3085 quic_data1.AddWrite(SYNCHRONOUS,
3086 client_maker_.MakeConnectivityProbingPacket(2, true));
3087 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3088 // Connectivity probe to receive from the server.
3089 quic_data1.AddRead(ASYNC,
3090 server_maker_.MakeConnectivityProbingPacket(1, false));
3091 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
3092 // Ping packet to send after migration is completed.
3093 quic_data1.AddWrite(SYNCHRONOUS,
3094 client_maker_.MakeAckAndPingPacket(3, false, 1, 1, 1));
3095 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3096 }
Zhongyi Shic16b4102019-02-12 00:37:403097
Zhongyi Shi5f587cc2017-11-21 23:24:173098 // Create request and QuicHttpStream.
3099 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:333100 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033101 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:523102 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
3103 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033104 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3105 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi5f587cc2017-11-21 23:24:173106 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3107 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3108 EXPECT_TRUE(stream.get());
3109
3110 // Ensure that session is alive and active.
3111 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3112 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3113 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shic16b4102019-02-12 00:37:403114 EXPECT_EQ(0u, session->GetNumActiveStreams());
3115 EXPECT_EQ(0u, session->GetNumDrainingStreams());
Zhongyi Shi5f587cc2017-11-21 23:24:173116
3117 // Trigger connection migration.
3118 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3119 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
Zhongyi Shi32fe14d42019-02-28 00:25:363120 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(host_port_pair_));
Zhongyi Shi5f587cc2017-11-21 23:24:173121
Zhongyi Shi32fe14d42019-02-28 00:25:363122 if (migrate_idle_sessions) {
3123 quic_data1.Resume();
3124 base::RunLoop().RunUntilIdle();
3125 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
3126 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
3127 }
Zhongyi Shi5f587cc2017-11-21 23:24:173128 EXPECT_TRUE(socket_data.AllReadDataConsumed());
3129 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
3130}
3131
Zhongyi Shi32fe14d42019-02-28 00:25:363132TEST_P(QuicStreamFactoryTest,
3133 OnNetworkDisconnectedNoOpenStreams_DoNotMigateIdleSessions) {
3134 TestOnNetworkDisconnectedNoOpenStreams(false);
3135}
3136
3137TEST_P(QuicStreamFactoryTest,
3138 OnNetworkDisconnectedNoOpenStreams_MigateIdleSessions) {
3139 TestOnNetworkDisconnectedNoOpenStreams(true);
3140}
3141
3142void QuicStreamFactoryTestBase::TestOnNetworkDisconnectedNoOpenStreams(
3143 bool migrate_idle_sessions) {
3144 test_params_.quic_migrate_idle_sessions = migrate_idle_sessions;
Zhongyi Shi5f587cc2017-11-21 23:24:173145 InitializeConnectionMigrationV2Test(
3146 {kDefaultNetworkForTests, kNewNetworkForTests});
3147 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3148 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3149
Ryan Hamiltonabad59e2019-06-06 04:02:593150 MockQuicData default_socket_data(version_);
Zhongyi Shic16b4102019-02-12 00:37:403151 default_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3152 default_socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
3153 default_socket_data.AddSocketDataToFactory(socket_factory_.get());
3154
Ryan Hamiltonabad59e2019-06-06 04:02:593155 MockQuicData alternate_socket_data(version_);
Zhongyi Shi32fe14d42019-02-28 00:25:363156 if (migrate_idle_sessions) {
3157 // Set up second socket data provider that is used after migration.
3158 alternate_socket_data.AddRead(SYNCHRONOUS,
3159 ERR_IO_PENDING); // Hanging read.
3160 // Ping packet to send after migration.
3161 alternate_socket_data.AddWrite(
3162 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
3163 alternate_socket_data.AddSocketDataToFactory(socket_factory_.get());
3164 }
Zhongyi Shi5f587cc2017-11-21 23:24:173165
3166 // Create request and QuicHttpStream.
3167 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:333168 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033169 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:523170 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
3171 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033172 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3173 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi5f587cc2017-11-21 23:24:173174 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3175 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3176 EXPECT_TRUE(stream.get());
3177
Zhongyi Shic16b4102019-02-12 00:37:403178 // Ensure that session is active.
Zhongyi Shi5f587cc2017-11-21 23:24:173179 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3180
3181 // Trigger connection migration. Since there are no active streams,
3182 // the session will be closed.
3183 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3184 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
3185
Zhongyi Shi32fe14d42019-02-28 00:25:363186 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(host_port_pair_));
Zhongyi Shi5f587cc2017-11-21 23:24:173187
Zhongyi Shic16b4102019-02-12 00:37:403188 EXPECT_TRUE(default_socket_data.AllReadDataConsumed());
3189 EXPECT_TRUE(default_socket_data.AllWriteDataConsumed());
Zhongyi Shi32fe14d42019-02-28 00:25:363190 if (migrate_idle_sessions) {
3191 EXPECT_TRUE(alternate_socket_data.AllReadDataConsumed());
3192 EXPECT_TRUE(alternate_socket_data.AllWriteDataConsumed());
3193 }
Zhongyi Shi5f587cc2017-11-21 23:24:173194}
3195
Zhongyi Shi9f316b262018-06-18 22:01:163196// This test verifies session migrates to the alternate network immediately when
3197// default network disconnects with a synchronous write before migration.
3198TEST_P(QuicStreamFactoryTest, MigrateOnDefaultNetworkDisconnectedSync) {
3199 TestMigrationOnNetworkDisconnected(/*async_write_before*/ false);
3200}
3201
3202// This test verifies session migrates to the alternate network immediately when
3203// default network disconnects with an asynchronously write before migration.
3204TEST_P(QuicStreamFactoryTest, MigrateOnDefaultNetworkDisconnectedAsync) {
3205 TestMigrationOnNetworkDisconnected(/*async_write_before*/ true);
3206}
3207
3208void QuicStreamFactoryTestBase::TestMigrationOnNetworkDisconnected(
3209 bool async_write_before) {
3210 InitializeConnectionMigrationV2Test(
3211 {kDefaultNetworkForTests, kNewNetworkForTests});
3212 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3213 ->NotifyNetworkMadeDefault(kDefaultNetworkForTests);
3214 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3215 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3216 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3217
3218 // Use the test task runner.
3219 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
3220
3221 int packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:593222 MockQuicData socket_data(version_);
Zhongyi Shi9f316b262018-06-18 22:01:163223 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:023224 socket_data.AddWrite(SYNCHRONOUS,
3225 ConstructInitialSettingsPacket(packet_number++));
Zhongyi Shi9f316b262018-06-18 22:01:163226 socket_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333227 SYNCHRONOUS,
3228 ConstructGetRequestPacket(packet_number++,
3229 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:023230 true, true));
Zhongyi Shi9f316b262018-06-18 22:01:163231 if (async_write_before) {
3232 socket_data.AddWrite(ASYNC, OK);
3233 packet_number++;
3234 }
3235 socket_data.AddSocketDataToFactory(socket_factory_.get());
3236
3237 // Create request and QuicHttpStream.
3238 QuicStreamRequest request(factory_.get());
3239 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033240 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:523241 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
3242 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033243 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3244 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi9f316b262018-06-18 22:01:163245 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3246 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3247 EXPECT_TRUE(stream.get());
3248
3249 // Cause QUIC stream to be created.
3250 HttpRequestInfo request_info;
3251 request_info.method = "GET";
3252 request_info.url = url_;
3253 request_info.traffic_annotation =
3254 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3255 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3256 net_log_, CompletionOnceCallback()));
3257
3258 // Ensure that session is alive and active.
3259 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3260 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3261 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3262
3263 // Send GET request on stream.
3264 HttpResponseInfo response;
3265 HttpRequestHeaders request_headers;
3266 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3267 callback_.callback()));
3268
Zhongyi Shi22fd5f52018-06-20 17:39:093269 if (async_write_before)
Zhongyi Shi9f316b262018-06-18 22:01:163270 session->SendPing();
Zhongyi Shi9f316b262018-06-18 22:01:163271
3272 // Set up second socket data provider that is used after migration.
3273 // The response to the earlier request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:593274 MockQuicData socket_data1(version_);
Zhongyi Shi9f316b262018-06-18 22:01:163275 socket_data1.AddWrite(
3276 SYNCHRONOUS,
3277 client_maker_.MakePingPacket(packet_number++, /*include_version=*/true));
3278 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:333279 ASYNC,
3280 ConstructOkResponsePacket(
3281 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shi9f316b262018-06-18 22:01:163282 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3283 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333284 SYNCHRONOUS,
3285 client_maker_.MakeAckAndRstPacket(
3286 packet_number++, false, GetNthClientInitiatedBidirectionalStreamId(0),
3287 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi9f316b262018-06-18 22:01:163288 socket_data1.AddSocketDataToFactory(socket_factory_.get());
3289
3290 // Trigger connection migration.
3291 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3292 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
3293
3294 // The connection should still be alive, not marked as going away.
3295 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3296 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3297 EXPECT_EQ(1u, session->GetNumActiveStreams());
3298 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3299
3300 // Ensure that the session is still alive.
3301 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3302 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3303 EXPECT_EQ(1u, session->GetNumActiveStreams());
3304
3305 // Run the message loop so that data queued in the new socket is read by the
3306 // packet reader.
3307 runner_->RunNextTask();
3308
3309 // Response headers are received over the new network.
3310 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3311 EXPECT_EQ(200, response.headers->response_code());
3312
3313 // Check that the session is still alive.
3314 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3315 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3316
3317 // There should be posted tasks not executed, which is to migrate back to
3318 // default network.
3319 EXPECT_FALSE(runner_->GetPostedTasks().empty());
3320
3321 // Receive signal to mark new network as default.
3322 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3323 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3324
3325 stream.reset();
3326 EXPECT_TRUE(socket_data.AllReadDataConsumed());
3327 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
3328 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
3329 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
3330}
3331
Zhongyi Shi5f587cc2017-11-21 23:24:173332// This test receives NCN signals in the following order:
3333// - default network disconnected
3334// - after a pause, new network is connected.
3335// - new network is made default.
3336TEST_P(QuicStreamFactoryTest, NewNetworkConnectedAfterNoNetwork) {
3337 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
3338 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3339 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3340 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3341
3342 // Use the test task runner.
3343 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
3344
Ryan Hamiltonabad59e2019-06-06 04:02:593345 MockQuicData socket_data(version_);
Zhongyi Shi5f587cc2017-11-21 23:24:173346 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:023347 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:173348 socket_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:023349 SYNCHRONOUS,
3350 ConstructGetRequestPacket(
3351 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi5f587cc2017-11-21 23:24:173352 socket_data.AddSocketDataToFactory(socket_factory_.get());
3353
3354 // Create request and QuicHttpStream.
3355 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:333356 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033357 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:523358 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
3359 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033360 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3361 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi5f587cc2017-11-21 23:24:173362 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3363 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3364 EXPECT_TRUE(stream.get());
3365
3366 // Cause QUIC stream to be created.
3367 HttpRequestInfo request_info;
3368 request_info.method = "GET";
3369 request_info.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:393370 request_info.traffic_annotation =
3371 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:273372 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:393373 net_log_, CompletionOnceCallback()));
Zhongyi Shi5f587cc2017-11-21 23:24:173374
3375 // Ensure that session is alive and active.
3376 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3377 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3378 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3379
3380 // Send GET request on stream.
3381 HttpResponseInfo response;
3382 HttpRequestHeaders request_headers;
3383 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3384 callback_.callback()));
3385
3386 // Trigger connection migration. Since there are no networks
3387 // to migrate to, this should cause the session to wait for a new network.
3388 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3389 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
3390
3391 // The connection should still be alive, not marked as going away.
3392 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3393 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3394 EXPECT_EQ(1u, session->GetNumActiveStreams());
3395 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3396
3397 // Set up second socket data provider that is used after migration.
3398 // The response to the earlier request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:593399 MockQuicData socket_data1(version_);
Zhongyi Shi5f587cc2017-11-21 23:24:173400 socket_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433401 SYNCHRONOUS, client_maker_.MakePingPacket(3, /*include_version=*/true));
3402 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:333403 ASYNC,
3404 ConstructOkResponsePacket(
3405 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shi5f587cc2017-11-21 23:24:173406 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:333407 socket_data1.AddWrite(
3408 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
3409 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
3410 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:173411 socket_data1.AddSocketDataToFactory(socket_factory_.get());
3412
3413 // Add a new network and notify the stream factory of a new connected network.
3414 // This causes a PING packet to be sent over the new network.
3415 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3416 ->SetConnectedNetworksList({kNewNetworkForTests});
3417 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3418 ->NotifyNetworkConnected(kNewNetworkForTests);
3419
3420 // Ensure that the session is still alive.
3421 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3422 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3423 EXPECT_EQ(1u, session->GetNumActiveStreams());
3424
3425 // Run the message loop so that data queued in the new socket is read by the
3426 // packet reader.
3427 runner_->RunNextTask();
3428
3429 // Response headers are received over the new network.
3430 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3431 EXPECT_EQ(200, response.headers->response_code());
3432
3433 // Check that the session is still alive.
3434 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3435 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3436
3437 // There should posted tasks not executed, which is to migrate back to default
3438 // network.
3439 EXPECT_FALSE(runner_->GetPostedTasks().empty());
3440
3441 // Receive signal to mark new network as default.
3442 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3443 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3444
3445 stream.reset();
3446 EXPECT_TRUE(socket_data.AllReadDataConsumed());
3447 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
3448 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
3449 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
3450}
3451
Zhongyi Shid3d5f502018-08-10 00:22:223452// Regression test for http://crbug.com/872011.
3453// This test verifies that migrate to the probing socket will not trigger
3454// new packets being read synchronously and generate ACK frame while
3455// processing the initial connectivity probe response, which may cause a
3456// connection being closed with INTERNAL_ERROR as pending ACK frame is not
3457// allowed when processing a new packet.
Zhongyi Shi6a7323b2018-12-07 01:26:323458TEST_P(QuicStreamFactoryTest, MigrateToProbingSocket) {
Zhongyi Shid3d5f502018-08-10 00:22:223459 InitializeConnectionMigrationV2Test(
3460 {kDefaultNetworkForTests, kNewNetworkForTests});
3461 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3462 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3463 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3464
3465 // Using a testing task runner so that we can control time.
3466 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3467 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
3468
3469 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3470 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3471
3472 int packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:593473 MockQuicData quic_data1(version_);
Zhongyi Shid3d5f502018-08-10 00:22:223474 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
Ryan Hamilton0d65a8c2019-06-07 00:46:023475 quic_data1.AddWrite(SYNCHRONOUS,
3476 ConstructInitialSettingsPacket(packet_number++));
Zhongyi Shid3d5f502018-08-10 00:22:223477 quic_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333478 SYNCHRONOUS,
3479 ConstructGetRequestPacket(packet_number++,
3480 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:023481 true, true));
Zhongyi Shid3d5f502018-08-10 00:22:223482 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3483
3484 // Set up the second socket data provider that is used for probing on the
3485 // alternate network.
Ryan Hamiltonabad59e2019-06-06 04:02:593486 MockQuicData quic_data2(version_);
Zhongyi Shid3d5f502018-08-10 00:22:223487 // Connectivity probe to be sent on the new path.
3488 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(
3489 packet_number++, true));
3490 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3491 // First connectivity probe to receive from the server, which will complete
3492 // connection migraiton on path degrading.
3493 quic_data2.AddRead(ASYNC,
3494 server_maker_.MakeConnectivityProbingPacket(1, false));
3495 // Read multiple connectivity probes synchronously.
3496 quic_data2.AddRead(SYNCHRONOUS,
3497 server_maker_.MakeConnectivityProbingPacket(2, false));
3498 quic_data2.AddRead(SYNCHRONOUS,
3499 server_maker_.MakeConnectivityProbingPacket(3, false));
3500 quic_data2.AddRead(SYNCHRONOUS,
3501 server_maker_.MakeConnectivityProbingPacket(4, false));
3502 quic_data2.AddWrite(
3503 ASYNC, client_maker_.MakeAckPacket(packet_number++, 1, 4, 1, 1, true));
3504 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:333505 ASYNC,
3506 ConstructOkResponsePacket(
3507 5, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shid3d5f502018-08-10 00:22:223508 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3509 quic_data2.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333510 SYNCHRONOUS,
3511 client_maker_.MakeAckAndRstPacket(
3512 packet_number++, false, GetNthClientInitiatedBidirectionalStreamId(0),
3513 quic::QUIC_STREAM_CANCELLED, 5, 1, 1, true));
Zhongyi Shid3d5f502018-08-10 00:22:223514 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3515
3516 // Create request and QuicHttpStream.
3517 QuicStreamRequest request(factory_.get());
3518 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033519 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:523520 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
3521 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033522 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3523 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shid3d5f502018-08-10 00:22:223524 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3525 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3526 EXPECT_TRUE(stream.get());
3527
3528 // Cause QUIC stream to be created.
3529 HttpRequestInfo request_info;
3530 request_info.method = "GET";
3531 request_info.url = url_;
3532 request_info.traffic_annotation =
3533 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3534 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3535 net_log_, CompletionOnceCallback()));
3536
3537 // Ensure that session is alive and active.
3538 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3539 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3540 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3541
3542 // Send GET request on stream.
3543 HttpResponseInfo response;
3544 HttpRequestHeaders request_headers;
3545 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3546 callback_.callback()));
3547
3548 // Cause the connection to report path degrading to the session.
3549 // Session will start to probe the alternate network.
3550 session->connection()->OnPathDegradingTimeout();
3551
3552 // Next connectivity probe is scheduled to be sent in 2 *
3553 // kDefaultRTTMilliSecs.
3554 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3555 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
3556 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3557 next_task_delay);
3558
3559 // The connection should still be alive, and not marked as going away.
3560 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3561 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3562 EXPECT_EQ(1u, session->GetNumActiveStreams());
3563 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3564
3565 // Resume quic data and a connectivity probe response will be read on the new
3566 // socket.
3567 quic_data2.Resume();
3568
3569 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3570 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3571 EXPECT_EQ(1u, session->GetNumActiveStreams());
3572
3573 // There should be three pending tasks, the nearest one will complete
3574 // migration to the new network.
3575 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
3576 next_task_delay = task_runner->NextPendingTaskDelay();
3577 EXPECT_EQ(base::TimeDelta(), next_task_delay);
3578 task_runner->FastForwardBy(next_task_delay);
3579
3580 // Response headers are received over the new network.
3581 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3582 EXPECT_EQ(200, response.headers->response_code());
3583
3584 // Now there are two pending tasks, the nearest one was to send connectivity
3585 // probe and has been cancelled due to successful migration.
3586 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
3587 next_task_delay = task_runner->NextPendingTaskDelay();
3588 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3589 next_task_delay);
3590 task_runner->FastForwardBy(next_task_delay);
3591
3592 // There's one more task to mgirate back to the default network in 0.4s.
3593 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3594 next_task_delay = task_runner->NextPendingTaskDelay();
3595 base::TimeDelta expected_delay =
3596 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
3597 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
3598 EXPECT_EQ(expected_delay, next_task_delay);
3599
3600 // Deliver a signal that the alternate network now becomes default to session,
3601 // this will cancel mgirate back to default network timer.
3602 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3603 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3604
3605 task_runner->FastForwardBy(next_task_delay);
3606 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
3607
3608 // Verify that the session is still alive.
3609 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3610 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3611
3612 stream.reset();
3613 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
3614 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
3615 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
3616 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
3617}
3618
Zhongyi Shic4823bd2018-04-27 00:49:193619// This test verifies that the connection migrates to the alternate network
Zhongyi Shi22fd5f52018-06-20 17:39:093620// early when path degrading is detected with an ASYNCHRONOUS write before
3621// migration.
3622TEST_P(QuicStreamFactoryTest, MigrateEarlyOnPathDegradingAysnc) {
3623 TestMigrationOnPathDegrading(/*async_write_before_migration*/ true);
3624}
3625
3626// This test verifies that the connection migrates to the alternate network
3627// early when path degrading is detected with a SYNCHRONOUS write before
3628// migration.
3629TEST_P(QuicStreamFactoryTest, MigrateEarlyOnPathDegradingSync) {
3630 TestMigrationOnPathDegrading(/*async_write_before_migration*/ false);
3631}
3632
3633void QuicStreamFactoryTestBase::TestMigrationOnPathDegrading(
3634 bool async_write_before) {
Zhongyi Shic4823bd2018-04-27 00:49:193635 InitializeConnectionMigrationV2Test(
3636 {kDefaultNetworkForTests, kNewNetworkForTests});
3637 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3638 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3639 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3640
3641 // Using a testing task runner so that we can control time.
3642 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3643 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
3644
3645 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3646 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3647
Zhongyi Shi22fd5f52018-06-20 17:39:093648 int packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:593649 MockQuicData quic_data1(version_);
Zhongyi Shic4823bd2018-04-27 00:49:193650 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
Ryan Hamilton0d65a8c2019-06-07 00:46:023651 quic_data1.AddWrite(SYNCHRONOUS,
3652 ConstructInitialSettingsPacket(packet_number++));
Zhongyi Shi22fd5f52018-06-20 17:39:093653 quic_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333654 SYNCHRONOUS,
3655 ConstructGetRequestPacket(packet_number++,
3656 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:023657 true, true));
Zhongyi Shi22fd5f52018-06-20 17:39:093658 if (async_write_before) {
3659 quic_data1.AddWrite(ASYNC, OK);
3660 packet_number++;
3661 }
Zhongyi Shic4823bd2018-04-27 00:49:193662 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3663
3664 // Set up the second socket data provider that is used after migration.
3665 // The response to the earlier request is read on the new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:593666 MockQuicData quic_data2(version_);
Zhongyi Shic4823bd2018-04-27 00:49:193667 // Connectivity probe to be sent on the new path.
Zhongyi Shi22fd5f52018-06-20 17:39:093668 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(
Zhongyi Shi879659422018-08-02 17:58:253669 packet_number++, true));
Zhongyi Shic4823bd2018-04-27 00:49:193670 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3671 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:253672 quic_data2.AddRead(ASYNC,
3673 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shic4823bd2018-04-27 00:49:193674 // Ping packet to send after migration is completed.
Zhongyi Shi22fd5f52018-06-20 17:39:093675 quic_data2.AddWrite(ASYNC, client_maker_.MakeAckAndPingPacket(
3676 packet_number++, false, 1, 1, 1));
Ryan Hamiltona3ee93a72018-08-01 22:03:083677 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:333678 ASYNC,
3679 ConstructOkResponsePacket(
3680 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shic4823bd2018-04-27 00:49:193681 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi22fd5f52018-06-20 17:39:093682 quic_data2.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333683 SYNCHRONOUS,
3684 client_maker_.MakeAckAndRstPacket(
3685 packet_number++, false, GetNthClientInitiatedBidirectionalStreamId(0),
3686 quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true));
Zhongyi Shic4823bd2018-04-27 00:49:193687 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3688
3689 // Create request and QuicHttpStream.
3690 QuicStreamRequest request(factory_.get());
3691 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033692 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:523693 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
3694 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033695 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3696 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shic4823bd2018-04-27 00:49:193697 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3698 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3699 EXPECT_TRUE(stream.get());
3700
3701 // Cause QUIC stream to be created.
3702 HttpRequestInfo request_info;
3703 request_info.method = "GET";
3704 request_info.url = url_;
3705 request_info.traffic_annotation =
3706 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3707 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3708 net_log_, CompletionOnceCallback()));
3709
3710 // Ensure that session is alive and active.
3711 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3712 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3713 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3714
3715 // Send GET request on stream.
3716 HttpResponseInfo response;
3717 HttpRequestHeaders request_headers;
3718 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3719 callback_.callback()));
3720
Zhongyi Shi22fd5f52018-06-20 17:39:093721 if (async_write_before)
3722 session->SendPing();
3723
Zhongyi Shiaba4a832018-04-30 20:29:083724 // Cause the connection to report path degrading to the session.
3725 // Session will start to probe the alternate network.
3726 session->connection()->OnPathDegradingTimeout();
3727
3728 // Next connectivity probe is scheduled to be sent in 2 *
3729 // kDefaultRTTMilliSecs.
3730 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3731 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
3732 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3733 next_task_delay);
3734
3735 // The connection should still be alive, and not marked as going away.
3736 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3737 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3738 EXPECT_EQ(1u, session->GetNumActiveStreams());
3739 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3740
3741 // Resume quic data and a connectivity probe response will be read on the new
3742 // socket.
3743 quic_data2.Resume();
3744
3745 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3746 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3747 EXPECT_EQ(1u, session->GetNumActiveStreams());
3748
3749 // There should be three pending tasks, the nearest one will complete
3750 // migration to the new network.
3751 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
3752 next_task_delay = task_runner->NextPendingTaskDelay();
3753 EXPECT_EQ(base::TimeDelta(), next_task_delay);
3754 task_runner->FastForwardBy(next_task_delay);
3755
3756 // Response headers are received over the new network.
3757 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3758 EXPECT_EQ(200, response.headers->response_code());
3759
3760 // Now there are two pending tasks, the nearest one was to send connectivity
3761 // probe and has been cancelled due to successful migration.
3762 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
3763 next_task_delay = task_runner->NextPendingTaskDelay();
3764 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3765 next_task_delay);
3766 task_runner->FastForwardBy(next_task_delay);
3767
3768 // There's one more task to mgirate back to the default network in 0.4s.
3769 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3770 next_task_delay = task_runner->NextPendingTaskDelay();
3771 base::TimeDelta expected_delay =
3772 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
3773 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
3774 EXPECT_EQ(expected_delay, next_task_delay);
3775
3776 // Deliver a signal that the alternate network now becomes default to session,
3777 // this will cancel mgirate back to default network timer.
3778 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3779 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3780
3781 task_runner->FastForwardBy(next_task_delay);
3782 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
3783
3784 // Verify that the session is still alive.
3785 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3786 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3787
3788 stream.reset();
3789 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
3790 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
3791 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
3792 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
3793}
3794
Renjiea5722ccf2018-08-10 00:18:493795// This test verifies that the session marks itself GOAWAY on path degrading
3796// and it does not receive any new request
3797TEST_P(QuicStreamFactoryTest, GoawayOnPathDegrading) {
Zhongyi Shi967d2f12019-02-08 20:58:533798 test_params_.quic_go_away_on_path_degrading = true;
Renjiea5722ccf2018-08-10 00:18:493799 Initialize();
3800 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3801 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3802 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3803
Ryan Hamiltonabad59e2019-06-06 04:02:593804 MockQuicData quic_data1(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:023805 quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Fan Yang32c5a112018-12-10 20:06:333806 quic_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:023807 SYNCHRONOUS,
3808 ConstructGetRequestPacket(
3809 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Renjiea5722ccf2018-08-10 00:18:493810 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3811 quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:333812 ASYNC,
3813 ConstructOkResponsePacket(
3814 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true));
Renjiea5722ccf2018-08-10 00:18:493815 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
3816 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3817
Ryan Hamilton0d65a8c2019-06-07 00:46:023818 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:593819 MockQuicData quic_data2(version_);
Renjiea5722ccf2018-08-10 00:18:493820 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
Ryan Hamilton0d65a8c2019-06-07 00:46:023821 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Renjiea5722ccf2018-08-10 00:18:493822 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3823
3824 // Creat request and QuicHttpStream.
3825 QuicStreamRequest request(factory_.get());
3826 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033827 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:523828 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
3829 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033830 /*cerf_verify_flags=*/0, url_, net_log_, &net_error_details_,
3831 failed_on_default_network_callback_, callback_.callback()));
Renjiea5722ccf2018-08-10 00:18:493832 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3833 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3834 EXPECT_TRUE(stream.get());
3835
3836 // Cause QUIC stream to be created.
3837 HttpRequestInfo request_info;
3838 request_info.method = "GET";
3839 request_info.url = url_;
3840 request_info.traffic_annotation =
3841 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3842 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3843 net_log_, CompletionOnceCallback()));
3844
3845 // Ensure that session is alive and active.
3846 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3847 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3848 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3849
3850 // Send GET request on stream.
3851 HttpResponseInfo response;
3852 HttpRequestHeaders request_headers;
3853 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3854 callback_.callback()));
3855
3856 // Trigger the connection to report path degrading to the session.
3857 // Session will mark itself GOAWAY.
3858 session->connection()->OnPathDegradingTimeout();
3859
3860 // The connection should still be alive, but marked as going away.
3861 EXPECT_FALSE(HasActiveSession(host_port_pair_));
3862 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3863 EXPECT_EQ(1u, session->GetNumActiveStreams());
3864
3865 // Second request should be sent on a new connection.
3866 QuicStreamRequest request2(factory_.get());
3867 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033868 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:523869 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
3870 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033871 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3872 failed_on_default_network_callback_, callback_.callback()));
Renjiea5722ccf2018-08-10 00:18:493873 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3874 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
3875 EXPECT_TRUE(stream2.get());
3876
3877 // Resume the data, verify old request can read response on the old session
3878 // successfully.
3879 quic_data1.Resume();
3880 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
3881 EXPECT_EQ(200, response.headers->response_code());
3882 EXPECT_EQ(0U, session->GetNumActiveStreams());
3883
3884 // Check an active session exists for the destination.
3885 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3886 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3887 QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
3888 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
3889 EXPECT_NE(session, session2);
3890
3891 stream.reset();
3892 stream2.reset();
3893 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
3894 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
3895 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
3896 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
3897}
3898
Zhongyi Shibb770d92018-06-16 02:07:003899// This test verifies that the connection will not migrate to a bad socket
3900// when path degrading is detected.
3901TEST_P(QuicStreamFactoryTest, DoNotMigrateToBadSocketOnPathDegrading) {
3902 InitializeConnectionMigrationV2Test(
3903 {kDefaultNetworkForTests, kNewNetworkForTests});
3904 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3905 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3906 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3907
3908 // Using a testing task runner so that we can control time.
3909 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3910 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
3911
3912 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3913 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3914
Ryan Hamiltonabad59e2019-06-06 04:02:593915 MockQuicData quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:023916 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
3917 quic_data.AddWrite(
3918 SYNCHRONOUS,
3919 ConstructGetRequestPacket(
3920 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Fan Yang32c5a112018-12-10 20:06:333921 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3922 quic_data.AddRead(ASYNC, ConstructOkResponsePacket(
3923 1, GetNthClientInitiatedBidirectionalStreamId(0),
3924 false, false));
3925 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3926 quic_data.AddWrite(
3927 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
3928 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
3929 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shibb770d92018-06-16 02:07:003930 quic_data.AddSocketDataToFactory(socket_factory_.get());
3931
3932 // Set up second socket that will immediately return disconnected.
3933 // The stream factory will abort probe the alternate network.
3934 MockConnect bad_connect = MockConnect(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
3935 SequencedSocketData socket_data(bad_connect, base::span<MockRead>(),
3936 base::span<MockWrite>());
3937 socket_factory_->AddSocketDataProvider(&socket_data);
3938
3939 // Create request and QuicHttpStream.
3940 QuicStreamRequest request(factory_.get());
3941 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033942 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:523943 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
3944 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033945 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3946 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shibb770d92018-06-16 02:07:003947 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3948 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3949 EXPECT_TRUE(stream.get());
3950
3951 // Cause QUIC stream to be created.
3952 HttpRequestInfo request_info;
3953 request_info.method = "GET";
3954 request_info.url = url_;
3955 request_info.traffic_annotation =
3956 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3957 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3958 net_log_, CompletionOnceCallback()));
3959
3960 // Ensure that session is alive and active.
3961 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3962 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3963 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3964
3965 // Send GET request on stream.
3966 HttpResponseInfo response;
3967 HttpRequestHeaders request_headers;
3968 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3969 callback_.callback()));
3970
3971 // Cause the connection to report path degrading to the session.
3972 // Session will start to probe the alternate network.
3973 session->connection()->OnPathDegradingTimeout();
3974
3975 // The connection should still be alive, and not marked as going away.
3976 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3977 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3978 EXPECT_EQ(1u, session->GetNumActiveStreams());
3979 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3980
3981 // Resume the data, and response header is received over the original network.
3982 quic_data.Resume();
3983 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3984 EXPECT_EQ(200, response.headers->response_code());
3985
3986 // Verify there is no pending task as probing alternate network is halted.
3987 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
3988
3989 // Verify that the session is still alive.
3990 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3991 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3992
3993 stream.reset();
3994 EXPECT_TRUE(quic_data.AllReadDataConsumed());
3995 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
3996}
3997
Zhongyi Shif5cc30392018-05-30 18:25:153998// Regression test for http://crbug.com/847569.
3999// This test verifies that the connection migrates to the alternate network
4000// early when there is no active stream but a draining stream.
Zhongyi Shib3bc982c2018-07-10 19:59:244001// The first packet being written after migration is a synchrnous write, which
4002// will cause a PING packet being sent.
4003TEST_P(QuicStreamFactoryTest, MigrateSessionWithDrainingStreamSync) {
4004 TestMigrateSessionWithDrainingStream(SYNCHRONOUS);
4005}
4006
4007// Regression test for http://crbug.com/847569.
4008// This test verifies that the connection migrates to the alternate network
4009// early when there is no active stream but a draining stream.
4010// The first packet being written after migration is an asynchronous write, no
4011// PING packet will be sent.
4012TEST_P(QuicStreamFactoryTest, MigrateSessionWithDrainingStreamAsync) {
4013 TestMigrateSessionWithDrainingStream(ASYNC);
4014}
4015
4016void QuicStreamFactoryTestBase::TestMigrateSessionWithDrainingStream(
4017 IoMode write_mode_for_queued_packet) {
Zhongyi Shif5cc30392018-05-30 18:25:154018 InitializeConnectionMigrationV2Test(
4019 {kDefaultNetworkForTests, kNewNetworkForTests});
4020 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4021 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4022 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4023
4024 // Using a testing task runner so that we can control time.
4025 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4026 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4027
4028 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4029 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
4030
Zhongyi Shib3bc982c2018-07-10 19:59:244031 int packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:594032 MockQuicData quic_data1(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:024033 quic_data1.AddWrite(SYNCHRONOUS,
4034 ConstructInitialSettingsPacket(packet_number++));
Zhongyi Shib3bc982c2018-07-10 19:59:244035 quic_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334036 SYNCHRONOUS,
4037 ConstructGetRequestPacket(packet_number++,
4038 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:024039 true, true));
Zhongyi Shif5cc30392018-05-30 18:25:154040 // Read an out of order packet with FIN to drain the stream.
4041 quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:334042 ASYNC, ConstructOkResponsePacket(
4043 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
4044 true)); // keep sending version.
Zhongyi Shif5cc30392018-05-30 18:25:154045 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4046 quic_data1.AddSocketDataToFactory(socket_factory_.get());
4047
4048 // Set up the second socket data provider that is used after migration.
Ryan Hamiltonabad59e2019-06-06 04:02:594049 MockQuicData quic_data2(version_);
Zhongyi Shif5cc30392018-05-30 18:25:154050 // Connectivity probe to be sent on the new path.
Zhongyi Shib3bc982c2018-07-10 19:59:244051 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(
Zhongyi Shi879659422018-08-02 17:58:254052 packet_number++, false));
Zhongyi Shif5cc30392018-05-30 18:25:154053 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
4054 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:254055 quic_data2.AddRead(ASYNC,
4056 server_maker_.MakeConnectivityProbingPacket(3, false));
Zhongyi Shif5cc30392018-05-30 18:25:154057 // Ping packet to send after migration is completed.
Zhongyi Shib3bc982c2018-07-10 19:59:244058 quic_data2.AddWrite(
4059 write_mode_for_queued_packet,
4060 client_maker_.MakeAckPacket(packet_number++, 2, 3, 3, 1, true));
4061 if (write_mode_for_queued_packet == SYNCHRONOUS) {
4062 quic_data2.AddWrite(ASYNC,
4063 client_maker_.MakePingPacket(packet_number++, false));
4064 }
Ryan Hamilton0d65a8c2019-06-07 00:46:024065 server_maker_.Reset();
Zhongyi Shif5cc30392018-05-30 18:25:154066 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:334067 ASYNC,
4068 ConstructOkResponsePacket(
4069 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shib3bc982c2018-07-10 19:59:244070 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeAckPacket(
4071 packet_number++, 1, 3, 1, 1, true));
Zhongyi Shif5cc30392018-05-30 18:25:154072 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4073 quic_data2.AddSocketDataToFactory(socket_factory_.get());
4074
4075 // Create request and QuicHttpStream.
4076 QuicStreamRequest request(factory_.get());
4077 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034078 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:524079 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
4080 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:034081 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4082 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shif5cc30392018-05-30 18:25:154083 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4084 std::unique_ptr<HttpStream> stream = CreateStream(&request);
4085 EXPECT_TRUE(stream.get());
4086
4087 // Cause QUIC stream to be created.
4088 HttpRequestInfo request_info;
4089 request_info.method = "GET";
4090 request_info.url = url_;
4091 request_info.traffic_annotation =
4092 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4093 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
4094 net_log_, CompletionOnceCallback()));
4095
4096 // Ensure that session is alive and active.
4097 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
4098 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4099 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4100
4101 // Send GET request on stream.
4102 HttpResponseInfo response;
4103 HttpRequestHeaders request_headers;
4104 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
4105 callback_.callback()));
4106
4107 // Run the message loop to receive the out of order packet which contains a
4108 // FIN and drains the stream.
4109 base::RunLoop().RunUntilIdle();
4110 EXPECT_EQ(0u, session->GetNumActiveStreams());
4111
4112 // Cause the connection to report path degrading to the session.
4113 // Session should still start to probe the alternate network.
4114 session->connection()->OnPathDegradingTimeout();
4115 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4116
4117 // Next connectivity probe is scheduled to be sent in 2 *
4118 // kDefaultRTTMilliSecs.
4119 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4120 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
4121 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
4122 next_task_delay);
4123
4124 // The connection should still be alive, and not marked as going away.
4125 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shif5cc30392018-05-30 18:25:154126
4127 // Resume quic data and a connectivity probe response will be read on the new
4128 // socket.
4129 quic_data2.Resume();
4130
4131 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4132 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:264133 EXPECT_EQ(0u, session->GetNumActiveStreams());
4134 EXPECT_EQ(1u, session->GetNumDrainingStreams());
Zhongyi Shif5cc30392018-05-30 18:25:154135
4136 // There should be three pending tasks, the nearest one will complete
4137 // migration to the new network.
4138 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
4139 next_task_delay = task_runner->NextPendingTaskDelay();
4140 EXPECT_EQ(base::TimeDelta(), next_task_delay);
4141 task_runner->FastForwardBy(next_task_delay);
4142
4143 // Now there are two pending tasks, the nearest one was to send connectivity
4144 // probe and has been cancelled due to successful migration.
4145 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
4146 next_task_delay = task_runner->NextPendingTaskDelay();
4147 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
4148 next_task_delay);
4149 task_runner->FastForwardBy(next_task_delay);
4150
4151 // There's one more task to mgirate back to the default network in 0.4s.
4152 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4153 next_task_delay = task_runner->NextPendingTaskDelay();
4154 base::TimeDelta expected_delay =
4155 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
4156 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
4157 EXPECT_EQ(expected_delay, next_task_delay);
4158
Zhongyi Shib3bc982c2018-07-10 19:59:244159 base::RunLoop().RunUntilIdle();
4160
Zhongyi Shif5cc30392018-05-30 18:25:154161 // Deliver a signal that the alternate network now becomes default to session,
4162 // this will cancel mgirate back to default network timer.
4163 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4164 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
4165
4166 task_runner->FastForwardBy(next_task_delay);
4167 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4168
4169 // Verify that the session is still alive.
4170 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4171 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:264172 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
Zhongyi Shif5cc30392018-05-30 18:25:154173
4174 stream.reset();
4175 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
4176 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
4177 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
4178 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
4179}
4180
Zhongyi Shiaba4a832018-04-30 20:29:084181// Regression test for http://crbug.com/835444.
4182// This test verifies that the connection migrates to the alternate network
4183// when the alternate network is connected after path has been degrading.
4184TEST_P(QuicStreamFactoryTest, MigrateOnNewNetworkConnectAfterPathDegrading) {
4185 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
4186 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4187 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4188 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4189
4190 // Using a testing task runner so that we can control time.
4191 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4192 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4193
4194 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4195 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
4196
Ryan Hamiltonabad59e2019-06-06 04:02:594197 MockQuicData quic_data1(version_);
Zhongyi Shiaba4a832018-04-30 20:29:084198 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
Ryan Hamilton0d65a8c2019-06-07 00:46:024199 quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Fan Yang32c5a112018-12-10 20:06:334200 quic_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:024201 SYNCHRONOUS,
4202 ConstructGetRequestPacket(
4203 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shiaba4a832018-04-30 20:29:084204 quic_data1.AddSocketDataToFactory(socket_factory_.get());
4205
4206 // Set up the second socket data provider that is used after migration.
4207 // The response to the earlier request is read on the new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:594208 MockQuicData quic_data2(version_);
Zhongyi Shiaba4a832018-04-30 20:29:084209 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:254210 quic_data2.AddWrite(SYNCHRONOUS,
4211 client_maker_.MakeConnectivityProbingPacket(3, true));
Zhongyi Shiaba4a832018-04-30 20:29:084212 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
4213 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:254214 quic_data2.AddRead(ASYNC,
4215 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shiaba4a832018-04-30 20:29:084216 // Ping packet to send after migration is completed.
4217 quic_data2.AddWrite(ASYNC,
4218 client_maker_.MakeAckAndPingPacket(4, false, 1, 1, 1));
4219 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:334220 ASYNC,
4221 ConstructOkResponsePacket(
4222 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shiaba4a832018-04-30 20:29:084223 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:334224 quic_data2.AddWrite(
4225 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
4226 5, false, GetNthClientInitiatedBidirectionalStreamId(0),
4227 quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true));
Zhongyi Shiaba4a832018-04-30 20:29:084228 quic_data2.AddSocketDataToFactory(socket_factory_.get());
4229
4230 // Create request and QuicHttpStream.
4231 QuicStreamRequest request(factory_.get());
4232 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034233 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:524234 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
4235 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:034236 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4237 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shiaba4a832018-04-30 20:29:084238 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4239 std::unique_ptr<HttpStream> stream = CreateStream(&request);
4240 EXPECT_TRUE(stream.get());
4241
4242 // Cause QUIC stream to be created.
4243 HttpRequestInfo request_info;
4244 request_info.method = "GET";
4245 request_info.url = url_;
4246 request_info.traffic_annotation =
4247 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4248 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
4249 net_log_, CompletionOnceCallback()));
4250
4251 // Ensure that session is alive and active.
4252 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
4253 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4254 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4255
4256 // Send GET request on stream.
4257 HttpResponseInfo response;
4258 HttpRequestHeaders request_headers;
4259 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
4260 callback_.callback()));
4261
4262 // Cause the connection to report path degrading to the session.
4263 // Due to lack of alternate network, session will not mgirate connection.
4264 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4265 session->connection()->OnPathDegradingTimeout();
4266 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4267
4268 // Deliver a signal that a alternate network is connected now, this should
4269 // cause the connection to start early migration on path degrading.
4270 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4271 ->SetConnectedNetworksList(
4272 {kDefaultNetworkForTests, kNewNetworkForTests});
4273 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4274 ->NotifyNetworkConnected(kNewNetworkForTests);
Zhongyi Shic4823bd2018-04-27 00:49:194275
4276 // Next connectivity probe is scheduled to be sent in 2 *
4277 // kDefaultRTTMilliSecs.
4278 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4279 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
4280 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
4281 next_task_delay);
4282
4283 // The connection should still be alive, and not marked as going away.
4284 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4285 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4286 EXPECT_EQ(1u, session->GetNumActiveStreams());
4287 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
4288
4289 // Resume quic data and a connectivity probe response will be read on the new
4290 // socket.
4291 quic_data2.Resume();
4292
4293 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4294 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4295 EXPECT_EQ(1u, session->GetNumActiveStreams());
4296
4297 // There should be three pending tasks, the nearest one will complete
4298 // migration to the new network.
4299 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
4300 next_task_delay = task_runner->NextPendingTaskDelay();
4301 EXPECT_EQ(base::TimeDelta(), next_task_delay);
4302 task_runner->FastForwardBy(next_task_delay);
4303
4304 // Response headers are received over the new network.
4305 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4306 EXPECT_EQ(200, response.headers->response_code());
4307
4308 // Now there are two pending tasks, the nearest one was to send connectivity
4309 // probe and has been cancelled due to successful migration.
4310 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
4311 next_task_delay = task_runner->NextPendingTaskDelay();
4312 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
4313 next_task_delay);
4314 task_runner->FastForwardBy(next_task_delay);
4315
4316 // There's one more task to mgirate back to the default network in 0.4s.
4317 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4318 next_task_delay = task_runner->NextPendingTaskDelay();
4319 base::TimeDelta expected_delay =
4320 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
4321 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
4322 EXPECT_EQ(expected_delay, next_task_delay);
4323
4324 // Deliver a signal that the alternate network now becomes default to session,
4325 // this will cancel mgirate back to default network timer.
4326 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4327 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
4328
4329 task_runner->FastForwardBy(next_task_delay);
4330 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4331
4332 // Verify that the session is still alive.
4333 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4334 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4335
4336 stream.reset();
4337 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
4338 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
4339 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
4340 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
4341}
4342
Zhongyi Shi28f6e352018-06-20 21:15:434343// This test verifies that multiple sessions are migrated on connection
4344// migration signal.
jrie3d187c2016-09-16 14:29:174345TEST_P(QuicStreamFactoryTest,
Zhongyi Shi28f6e352018-06-20 21:15:434346 MigrateMultipleSessionsToBadSocketsAfterDisconnected) {
4347 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jrie3d187c2016-09-16 14:29:174348
Ryan Hamiltonabad59e2019-06-06 04:02:594349 MockQuicData socket_data1(version_);
jrie3d187c2016-09-16 14:29:174350 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434351 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jrie3d187c2016-09-16 14:29:174352 socket_data1.AddWrite(ASYNC, OK);
Zhongyi Shi5f587cc2017-11-21 23:24:174353 socket_data1.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamilton0d65a8c2019-06-07 00:46:024354 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:594355 MockQuicData socket_data2(version_);
jrie3d187c2016-09-16 14:29:174356 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434357 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jrie3d187c2016-09-16 14:29:174358 socket_data2.AddWrite(ASYNC, OK);
Zhongyi Shi5f587cc2017-11-21 23:24:174359 socket_data2.AddSocketDataToFactory(socket_factory_.get());
jrie3d187c2016-09-16 14:29:174360
4361 HostPortPair server1(kDefaultServerHostName, 443);
4362 HostPortPair server2(kServer2HostName, 443);
4363
4364 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4365 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4366 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4367
Renjiea0cb4a2c2018-09-26 23:37:304368 host_resolver_->set_synchronous_mode(true);
4369 host_resolver_->rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
4370 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.2", "");
jrie3d187c2016-09-16 14:29:174371
4372 // Create request and QuicHttpStream to create session1.
zhongyi98d6a9262017-05-19 02:47:454373 QuicStreamRequest request1(factory_.get());
Matt Menke26e41542019-06-05 01:09:514374 EXPECT_EQ(OK,
4375 request1.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:524376 server1, version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
4377 NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:514378 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4379 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:244380 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
jrie3d187c2016-09-16 14:29:174381 EXPECT_TRUE(stream1.get());
4382
4383 // Create request and QuicHttpStream to create session2.
zhongyi98d6a9262017-05-19 02:47:454384 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:514385 EXPECT_EQ(OK,
4386 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:524387 server2, version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
4388 NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:514389 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
4390 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:244391 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
jrie3d187c2016-09-16 14:29:174392 EXPECT_TRUE(stream2.get());
4393
4394 QuicChromiumClientSession* session1 = GetActiveSession(server1);
4395 QuicChromiumClientSession* session2 = GetActiveSession(server2);
4396 EXPECT_NE(session1, session2);
4397
4398 // Cause QUIC stream to be created and send GET so session1 has an open
4399 // stream.
4400 HttpRequestInfo request_info1;
4401 request_info1.method = "GET";
4402 request_info1.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:394403 request_info1.traffic_annotation =
4404 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274405 EXPECT_EQ(OK,
4406 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394407 net_log_, CompletionOnceCallback()));
jrie3d187c2016-09-16 14:29:174408 HttpResponseInfo response1;
4409 HttpRequestHeaders request_headers1;
4410 EXPECT_EQ(OK, stream1->SendRequest(request_headers1, &response1,
4411 callback_.callback()));
4412
4413 // Cause QUIC stream to be created and send GET so session2 has an open
4414 // stream.
4415 HttpRequestInfo request_info2;
4416 request_info2.method = "GET";
4417 request_info2.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:394418 request_info2.traffic_annotation =
4419 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274420 EXPECT_EQ(OK,
4421 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394422 net_log_, CompletionOnceCallback()));
jrie3d187c2016-09-16 14:29:174423 HttpResponseInfo response2;
4424 HttpRequestHeaders request_headers2;
4425 EXPECT_EQ(OK, stream2->SendRequest(request_headers2, &response2,
4426 callback_.callback()));
4427
4428 // Cause both sessions to be paused due to DISCONNECTED.
4429 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4430 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
4431
4432 // Ensure that both sessions are paused but alive.
4433 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session1));
4434 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
4435
Zhongyi Shi28f6e352018-06-20 21:15:434436 // Add new sockets to use post migration. Those are bad sockets and will cause
4437 // migration to fail.
jrie3d187c2016-09-16 14:29:174438 MockConnect connect_result =
4439 MockConnect(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
Ryan Sleevib8d7ea02018-05-07 20:01:014440 SequencedSocketData socket_data3(connect_result, base::span<MockRead>(),
4441 base::span<MockWrite>());
Zhongyi Shi5f587cc2017-11-21 23:24:174442 socket_factory_->AddSocketDataProvider(&socket_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:014443 SequencedSocketData socket_data4(connect_result, base::span<MockRead>(),
4444 base::span<MockWrite>());
Zhongyi Shi5f587cc2017-11-21 23:24:174445 socket_factory_->AddSocketDataProvider(&socket_data4);
jrie3d187c2016-09-16 14:29:174446
Zhongyi Shi28f6e352018-06-20 21:15:434447 // Connect the new network and cause migration to bad sockets, causing
4448 // sessions to close.
jrie3d187c2016-09-16 14:29:174449 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4450 ->SetConnectedNetworksList({kNewNetworkForTests});
4451 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4452 ->NotifyNetworkConnected(kNewNetworkForTests);
4453
4454 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session1));
4455 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
4456
4457 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
4458 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
4459 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
4460 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
4461}
4462
Zhongyi Shi6ec9b36e2018-06-20 20:32:544463// This test verifies that session attempts connection migration with signals
4464// delivered in the following order (no alternate network is available):
4465// - path degrading is detected: session attempts connection migration but no
4466// alternate network is available, session caches path degrading signal in
4467// connection and stays on the original network.
4468// - original network backs up, request is served in the orignal network,
4469// session is not marked as going away.
4470TEST_P(QuicStreamFactoryTest, MigrateOnPathDegradingWithNoNewNetwork) {
4471 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jrid36ada62016-02-06 02:42:084472 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4473 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4474
Ryan Hamiltonabad59e2019-06-06 04:02:594475 MockQuicData quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:024476 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
4477 quic_data.AddWrite(
4478 SYNCHRONOUS,
4479 ConstructGetRequestPacket(
4480 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi6ec9b36e2018-06-20 20:32:544481 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause for path degrading signal.
4482
4483 // The rest of the data will still flow in the original socket as there is no
4484 // new network after path degrading.
Fan Yang32c5a112018-12-10 20:06:334485 quic_data.AddRead(ASYNC, ConstructOkResponsePacket(
4486 1, GetNthClientInitiatedBidirectionalStreamId(0),
4487 false, false));
Zhongyi Shi6ec9b36e2018-06-20 20:32:544488 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:334489 quic_data.AddWrite(
4490 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
4491 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
4492 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi6ec9b36e2018-06-20 20:32:544493 quic_data.AddSocketDataToFactory(socket_factory_.get());
jrid36ada62016-02-06 02:42:084494
4495 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:454496 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:334497 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034498 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:524499 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
4500 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:034501 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4502 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:014503 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:244504 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jrid36ada62016-02-06 02:42:084505 EXPECT_TRUE(stream.get());
4506
4507 // Cause QUIC stream to be created.
4508 HttpRequestInfo request_info;
Zhongyi Shi6ec9b36e2018-06-20 20:32:544509 request_info.method = "GET";
4510 request_info.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:394511 request_info.traffic_annotation =
4512 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Zhongyi Shi6ec9b36e2018-06-20 20:32:544513 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394514 net_log_, CompletionOnceCallback()));
jrid36ada62016-02-06 02:42:084515
4516 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:504517 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jrid36ada62016-02-06 02:42:084518 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4519 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4520
Zhongyi Shi6ec9b36e2018-06-20 20:32:544521 // Send GET request on stream.
4522 HttpResponseInfo response;
4523 HttpRequestHeaders request_headers;
4524 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
4525 callback_.callback()));
jrid36ada62016-02-06 02:42:084526
Zhongyi Shi6ec9b36e2018-06-20 20:32:544527 // Trigger connection migration on path degrading. Since there are no networks
4528 // to migrate to, the session will remain on the original network, not marked
4529 // as going away.
4530 session->connection()->OnPathDegradingTimeout();
4531 EXPECT_TRUE(session->connection()->IsPathDegrading());
4532
4533 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4534 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4535 EXPECT_EQ(1u, session->GetNumActiveStreams());
4536 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
4537
4538 // Resume so that rest of the data will flow in the original socket.
4539 quic_data.Resume();
jrid36ada62016-02-06 02:42:084540
4541 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4542 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4543 EXPECT_EQ(1u, session->GetNumActiveStreams());
4544
4545 stream.reset();
Zhongyi Shi6ec9b36e2018-06-20 20:32:544546 EXPECT_TRUE(quic_data.AllReadDataConsumed());
4547 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
jrid36ada62016-02-06 02:42:084548}
4549
Zhongyi Shi21e99532018-07-17 22:23:074550// This test verifies that session with non-migratable stream will probe the
4551// alternate network on path degrading, and close the non-migratable streams
4552// when probe is successful.
Zhongyi Shi32fe14d42019-02-28 00:25:364553TEST_P(QuicStreamFactoryTest,
4554 MigrateSessionEarlyNonMigratableStream_DoNotMigrateIdleSessions) {
4555 TestMigrateSessionEarlyNonMigratableStream(false);
4556}
4557
4558TEST_P(QuicStreamFactoryTest,
4559 MigrateSessionEarlyNonMigratableStream_MigrateIdleSessions) {
4560 TestMigrateSessionEarlyNonMigratableStream(true);
4561}
4562
4563void QuicStreamFactoryTestBase::TestMigrateSessionEarlyNonMigratableStream(
4564 bool migrate_idle_sessions) {
4565 test_params_.quic_migrate_idle_sessions = migrate_idle_sessions;
Zhongyi Shi1a054612018-06-14 04:59:084566 InitializeConnectionMigrationV2Test(
jri231c2972016-03-08 19:50:114567 {kDefaultNetworkForTests, kNewNetworkForTests});
4568 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4569 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4570
Ryan Hamiltonabad59e2019-06-06 04:02:594571 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:364572 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434573 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi32fe14d42019-02-28 00:25:364574 if (!migrate_idle_sessions) {
4575 socket_data.AddWrite(
4576 SYNCHRONOUS,
4577 client_maker_.MakeRstAckAndConnectionClosePacket(
4578 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
4579 quic::QUIC_STREAM_CANCELLED,
4580 quic::QuicTime::Delta::FromMilliseconds(0), 1, 1, 1,
4581 quic::QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS,
4582 "net error"));
4583 }
Zhongyi Shi5f587cc2017-11-21 23:24:174584 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri231c2972016-03-08 19:50:114585
Zhongyi Shi21e99532018-07-17 22:23:074586 // Set up the second socket data provider that is used for probing.
Ryan Hamiltonabad59e2019-06-06 04:02:594587 MockQuicData quic_data1(version_);
Zhongyi Shi21e99532018-07-17 22:23:074588 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:254589 quic_data1.AddWrite(SYNCHRONOUS,
4590 client_maker_.MakeConnectivityProbingPacket(2, true));
Zhongyi Shi21e99532018-07-17 22:23:074591 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
4592 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:254593 quic_data1.AddRead(ASYNC,
4594 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shi32fe14d42019-02-28 00:25:364595 if (migrate_idle_sessions) {
4596 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
4597 // A RESET will be sent to the peer to cancel the non-migratable stream.
4598 quic_data1.AddWrite(
4599 SYNCHRONOUS,
4600 client_maker_.MakeRstPacket(
4601 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
4602 quic::QUIC_STREAM_CANCELLED));
4603 // Ping packet to send after migration is completed.
4604 quic_data1.AddWrite(SYNCHRONOUS,
4605 client_maker_.MakeAckAndPingPacket(4, false, 1, 1, 1));
4606 }
Zhongyi Shi21e99532018-07-17 22:23:074607 quic_data1.AddSocketDataToFactory(socket_factory_.get());
4608
jri231c2972016-03-08 19:50:114609 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:454610 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:334611 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034612 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:524613 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
4614 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:034615 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4616 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:014617 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:244618 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri231c2972016-03-08 19:50:114619 EXPECT_TRUE(stream.get());
4620
4621 // Cause QUIC stream to be created, but marked as non-migratable.
4622 HttpRequestInfo request_info;
Zhongyi Shibb28b1f2018-07-18 02:41:264623 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Ramin Halavati683bcaa92018-02-14 08:42:394624 request_info.traffic_annotation =
4625 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274626 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394627 net_log_, CompletionOnceCallback()));
jri231c2972016-03-08 19:50:114628
4629 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:504630 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri231c2972016-03-08 19:50:114631 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4632 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4633
4634 // Trigger connection migration. Since there is a non-migratable stream,
Zhongyi Shic16b4102019-02-12 00:37:404635 // this should cause session to migrate.
jri231c2972016-03-08 19:50:114636 session->OnPathDegrading();
4637
4638 // Run the message loop so that data queued in the new socket is read by the
4639 // packet reader.
4640 base::RunLoop().RunUntilIdle();
4641
jri231c2972016-03-08 19:50:114642 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4643 EXPECT_EQ(1u, session->GetNumActiveStreams());
4644
Zhongyi Shi21e99532018-07-17 22:23:074645 // Resume the data to read the connectivity probing response to declare probe
4646 // as successful. Non-migratable streams will be closed.
4647 quic_data1.Resume();
Zhongyi Shi32fe14d42019-02-28 00:25:364648 if (migrate_idle_sessions)
4649 base::RunLoop().RunUntilIdle();
Zhongyi Shic16b4102019-02-12 00:37:404650
Zhongyi Shi32fe14d42019-02-28 00:25:364651 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(host_port_pair_));
Zhongyi Shi21e99532018-07-17 22:23:074652 EXPECT_EQ(0u, session->GetNumActiveStreams());
jri231c2972016-03-08 19:50:114653
Zhongyi Shi21e99532018-07-17 22:23:074654 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
4655 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
jri231c2972016-03-08 19:50:114656 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4657 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4658}
4659
jri9c541572016-03-29 17:51:484660TEST_P(QuicStreamFactoryTest, MigrateSessionEarlyConnectionMigrationDisabled) {
Zhongyi Shi1a054612018-06-14 04:59:084661 InitializeConnectionMigrationV2Test(
jri9c541572016-03-29 17:51:484662 {kDefaultNetworkForTests, kNewNetworkForTests});
4663 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4664 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4665
Ryan Hamiltonabad59e2019-06-06 04:02:594666 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:364667 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434668 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
4669 socket_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334670 SYNCHRONOUS, client_maker_.MakeRstPacket(
4671 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
4672 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:174673 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9c541572016-03-29 17:51:484674
4675 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:454676 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:334677 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034678 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:524679 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
4680 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:034681 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4682 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:014683 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:244684 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9c541572016-03-29 17:51:484685 EXPECT_TRUE(stream.get());
4686
4687 // Cause QUIC stream to be created.
4688 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:394689 request_info.traffic_annotation =
4690 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274691 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394692 net_log_, CompletionOnceCallback()));
jri9c541572016-03-29 17:51:484693
4694 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:504695 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri9c541572016-03-29 17:51:484696 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4697 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4698
4699 // Set session config to have connection migration disabled.
Ryan Hamilton8d9ee76e2018-05-29 23:52:524700 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
4701 session->config());
jri9c541572016-03-29 17:51:484702 EXPECT_TRUE(session->config()->DisableConnectionMigration());
4703
4704 // Trigger connection migration. Since there is a non-migratable stream,
4705 // this should cause session to be continue without migrating.
4706 session->OnPathDegrading();
4707
4708 // Run the message loop so that data queued in the new socket is read by the
4709 // packet reader.
4710 base::RunLoop().RunUntilIdle();
4711
4712 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4713 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4714 EXPECT_EQ(1u, session->GetNumActiveStreams());
4715
4716 stream.reset();
4717
4718 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4719 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4720}
4721
Zhongyi Shi3c4c9e92018-07-02 23:16:234722// Regression test for http://crbug.com/791886.
4723// This test verifies that the old packet writer which encountered an
4724// asynchronous write error will be blocked during migration on write error. New
4725// packets would not be written until the one with write error is rewritten on
4726// the new network.
4727TEST_P(QuicStreamFactoryTest, MigrateSessionOnAysncWriteError) {
4728 InitializeConnectionMigrationV2Test(
4729 {kDefaultNetworkForTests, kNewNetworkForTests});
4730 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4731 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4732 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4733
4734 // Using a testing task runner so that we can control time.
4735 // base::RunLoop() controls mocked socket writes and reads.
4736 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4737 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4738
Ryan Hamiltonabad59e2019-06-06 04:02:594739 MockQuicData socket_data(version_);
Zhongyi Shi3c4c9e92018-07-02 23:16:234740 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:024741 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi3c4c9e92018-07-02 23:16:234742 socket_data.AddWrite(ASYNC, ERR_ADDRESS_UNREACHABLE);
4743 socket_data.AddSocketDataToFactory(socket_factory_.get());
4744
4745 // Set up second socket data provider that is used after
4746 // migration. The request is rewritten to this new socket, and the
4747 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:594748 MockQuicData socket_data1(version_);
Zhongyi Shi3c4c9e92018-07-02 23:16:234749 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:024750 SYNCHRONOUS,
4751 ConstructGetRequestPacket(
4752 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Ryan Hamilton9f2eac32019-06-27 03:15:544753 client_maker_.set_coalesce_http_frames(true);
Ryan Hamilton0d65a8c2019-06-07 00:46:024754 socket_data1.AddWrite(
4755 SYNCHRONOUS,
4756 ConstructGetRequestPacket(
4757 3, GetNthClientInitiatedBidirectionalStreamId(1),
4758 GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Fan Yang32c5a112018-12-10 20:06:334759 socket_data1.AddRead(
4760 ASYNC,
4761 ConstructOkResponsePacket(
4762 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
4763 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4764 socket_data1.AddWrite(
4765 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
4766 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
4767 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
4768 socket_data1.AddWrite(
4769 SYNCHRONOUS, client_maker_.MakeRstPacket(
4770 5, false, GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:414771 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:184772 /*include_stop_sending_if_v99=*/true));
Zhongyi Shi3c4c9e92018-07-02 23:16:234773
4774 socket_data1.AddSocketDataToFactory(socket_factory_.get());
4775
4776 // Create request #1 and QuicHttpStream.
4777 QuicStreamRequest request1(factory_.get());
4778 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034779 request1.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:524780 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
4781 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:034782 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4783 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi3c4c9e92018-07-02 23:16:234784 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4785 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
4786 EXPECT_TRUE(stream1.get());
4787
4788 HttpRequestInfo request_info1;
4789 request_info1.method = "GET";
4790 request_info1.url = GURL("https://www.example.org/");
4791 request_info1.traffic_annotation =
4792 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4793 EXPECT_EQ(OK,
4794 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
4795 net_log_, CompletionOnceCallback()));
4796
4797 // Request #2 returns synchronously because it pools to existing session.
4798 TestCompletionCallback callback2;
4799 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:514800 EXPECT_EQ(OK,
4801 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:524802 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
4803 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:514804 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4805 failed_on_default_network_callback_, callback2.callback()));
Zhongyi Shi3c4c9e92018-07-02 23:16:234806 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
4807 EXPECT_TRUE(stream2.get());
4808
4809 HttpRequestInfo request_info2;
4810 request_info2.method = "GET";
4811 request_info2.url = GURL("https://www.example.org/");
4812 request_info2.traffic_annotation =
4813 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4814 EXPECT_EQ(OK,
4815 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
4816 net_log_, CompletionOnceCallback()));
4817
4818 // Ensure that session is alive and active.
4819 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
4820 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4821 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4822 EXPECT_EQ(2u, session->GetNumActiveStreams());
4823
4824 // Send GET request on stream1. This should cause an async write error.
4825 HttpResponseInfo response;
4826 HttpRequestHeaders request_headers;
4827 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
4828 callback_.callback()));
4829 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4830
4831 // Run the message loop so that asynchronous write completes and a connection
4832 // migration on write error attempt is posted in QuicStreamFactory's task
4833 // runner.
4834 base::RunLoop().RunUntilIdle();
4835 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4836
4837 // Send GET request on stream. This will cause another write attempt before
4838 // migration on write error is exectued.
4839 HttpResponseInfo response2;
4840 HttpRequestHeaders request_headers2;
4841 EXPECT_EQ(OK, stream2->SendRequest(request_headers2, &response2,
4842 callback2.callback()));
4843
4844 // Run the task runner so that migration on write error is finally executed.
4845 task_runner->RunUntilIdle();
4846
Zhongyi Shia7dd46b2018-07-12 22:59:294847 // Verify the session is still alive and not marked as going away.
Zhongyi Shi3c4c9e92018-07-02 23:16:234848 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:294849 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi3c4c9e92018-07-02 23:16:234850 EXPECT_EQ(2u, session->GetNumActiveStreams());
Zhongyi Shia7dd46b2018-07-12 22:59:294851 // There should be one task posted to migrate back to the default network in
4852 // kMinRetryTimeForDefaultNetworkSecs.
4853 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4854 EXPECT_EQ(base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs),
4855 task_runner->NextPendingTaskDelay());
Zhongyi Shi3c4c9e92018-07-02 23:16:234856
4857 // Verify that response headers on the migrated socket were delivered to the
4858 // stream.
4859 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
4860 EXPECT_EQ(200, response.headers->response_code());
4861
4862 stream1.reset();
4863 stream2.reset();
4864
4865 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4866 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4867 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
4868 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
4869}
4870
Zhongyi Shia7dd46b2018-07-12 22:59:294871// Verify session is not marked as going away after connection migration on
4872// write error and migrate back to default network logic is applied to bring the
4873// migrated session back to the default network. Migration singals delivered
4874// in the following order (alternate network is always availabe):
4875// - session on the default network encountered a write error;
4876// - session successfully migrated to the non-default network;
4877// - session attempts to migrate back to default network post migration;
4878// - migration back to the default network is successful.
4879TEST_P(QuicStreamFactoryTest, MigrateBackToDefaultPostMigrationOnWriteError) {
4880 InitializeConnectionMigrationV2Test(
4881 {kDefaultNetworkForTests, kNewNetworkForTests});
4882 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4883 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4884 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4885
4886 // Using a testing task runner so that we can control time.
4887 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4888 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4889
Ryan Hamiltonabad59e2019-06-06 04:02:594890 MockQuicData socket_data(version_);
Zhongyi Shia7dd46b2018-07-12 22:59:294891 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:024892 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shia7dd46b2018-07-12 22:59:294893 socket_data.AddWrite(ASYNC, ERR_ADDRESS_UNREACHABLE);
4894 socket_data.AddSocketDataToFactory(socket_factory_.get());
4895
4896 // Set up second socket data provider that is used after
4897 // migration. The request is rewritten to this new socket, and the
4898 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:594899 MockQuicData quic_data2(version_);
Fan Yang32c5a112018-12-10 20:06:334900 quic_data2.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:024901 SYNCHRONOUS,
4902 ConstructGetRequestPacket(
4903 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shia7dd46b2018-07-12 22:59:294904 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:334905 ASYNC,
4906 ConstructOkResponsePacket(
4907 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shia7dd46b2018-07-12 22:59:294908 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4909 quic_data2.AddSocketDataToFactory(socket_factory_.get());
4910
4911 // Create request QuicHttpStream.
4912 QuicStreamRequest request1(factory_.get());
4913 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034914 request1.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:524915 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
4916 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:034917 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4918 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shia7dd46b2018-07-12 22:59:294919 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4920 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
4921 EXPECT_TRUE(stream1.get());
4922
4923 HttpRequestInfo request_info1;
4924 request_info1.method = "GET";
4925 request_info1.url = GURL("https://www.example.org/");
4926 request_info1.traffic_annotation =
4927 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4928 EXPECT_EQ(OK,
4929 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
4930 net_log_, CompletionOnceCallback()));
4931
4932 // Ensure that session is alive and active.
4933 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
4934 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4935 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4936 EXPECT_EQ(1u, session->GetNumActiveStreams());
4937
4938 // Send GET request. This should cause an async write error.
4939 HttpResponseInfo response;
4940 HttpRequestHeaders request_headers;
4941 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
4942 callback_.callback()));
4943 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4944
4945 // Run the message loop so that asynchronous write completes and a connection
4946 // migration on write error attempt is posted in QuicStreamFactory's task
4947 // runner.
4948 base::RunLoop().RunUntilIdle();
4949 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4950
4951 // Run the task runner so that migration on write error is finally executed.
4952 task_runner->RunUntilIdle();
4953
4954 // Verify the session is still alive and not marked as going away.
4955 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4956 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4957 EXPECT_EQ(1u, session->GetNumActiveStreams());
4958 // There should be one task posted to migrate back to the default network in
4959 // kMinRetryTimeForDefaultNetworkSecs.
4960 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4961 base::TimeDelta expected_delay =
4962 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs);
4963 EXPECT_EQ(expected_delay, task_runner->NextPendingTaskDelay());
4964
4965 // Verify that response headers on the migrated socket were delivered to the
4966 // stream.
4967 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
4968 EXPECT_EQ(200, response.headers->response_code());
4969
4970 // Set up the third socket data provider for migrate back to default network.
Ryan Hamiltonabad59e2019-06-06 04:02:594971 MockQuicData quic_data3(version_);
Zhongyi Shia7dd46b2018-07-12 22:59:294972 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:254973 quic_data3.AddWrite(SYNCHRONOUS,
4974 client_maker_.MakeConnectivityProbingPacket(3, false));
Zhongyi Shia7dd46b2018-07-12 22:59:294975 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:254976 quic_data3.AddRead(ASYNC,
4977 server_maker_.MakeConnectivityProbingPacket(2, false));
Zhongyi Shia7dd46b2018-07-12 22:59:294978 quic_data3.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4979 quic_data3.AddWrite(ASYNC, client_maker_.MakeAckPacket(4, 1, 2, 1, 1, true));
4980 quic_data3.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334981 SYNCHRONOUS, client_maker_.MakeRstPacket(
4982 5, false, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:414983 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:184984 /*include_stop_sending_if_v99=*/true));
Zhongyi Shia7dd46b2018-07-12 22:59:294985 quic_data3.AddSocketDataToFactory(socket_factory_.get());
4986
4987 // Fast forward to fire the migrate back timer and verify the session
4988 // successfully migrates back to the default network.
4989 task_runner->FastForwardBy(expected_delay);
4990
4991 // Verify the session is still alive and not marked as going away.
4992 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4993 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4994 EXPECT_EQ(1u, session->GetNumActiveStreams());
4995
4996 // There should be one task posted to one will resend a connectivity probe and
4997 // the other will retry migrate back, both are cancelled.
4998 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
4999 task_runner->FastForwardBy(
5000 base::TimeDelta::FromSeconds(2 * kMinRetryTimeForDefaultNetworkSecs));
5001 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
5002
5003 stream1.reset();
5004 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5005 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5006 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
5007 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
5008 EXPECT_TRUE(quic_data3.AllReadDataConsumed());
5009 EXPECT_TRUE(quic_data3.AllWriteDataConsumed());
5010}
5011
Zhongyi Shic1449372018-08-09 09:58:585012// This test verifies that the connection will not attempt connection migration
5013// (send connectivity probes on alternate path) when path degrading is detected
5014// and handshake is not confirmed.
5015TEST_P(QuicStreamFactoryTest,
5016 NoMigrationOnPathDegradingBeforeHandshakeConfirmed) {
5017 InitializeConnectionMigrationV2Test(
5018 {kDefaultNetworkForTests, kNewNetworkForTests});
5019
5020 // Using a testing task runner.
5021 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
5022 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
5023
5024 // Use cold start mode to send crypto message for handshake.
5025 crypto_client_stream_factory_.set_handshake_mode(
5026 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
5027
Ryan Hamiltonabad59e2019-06-06 04:02:595028 MockQuicData socket_data(version_);
Zhongyi Shic1449372018-08-09 09:58:585029 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5030 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
5031 socket_data.AddSocketDataToFactory(socket_factory_.get());
5032
5033 // Create request and QuicHttpStream.
5034 QuicStreamRequest request(factory_.get());
5035 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035036 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:525037 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
5038 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035039 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5040 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shic1449372018-08-09 09:58:585041
5042 base::RunLoop().RunUntilIdle();
5043
5044 // Ensure that session is alive but not active.
5045 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5046 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5047 QuicChromiumClientSession* session = GetPendingSession(host_port_pair_);
5048 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5049 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
5050
5051 // Cause the connection to report path degrading to the session.
5052 // Session will ignore the signal as handshake is not completed.
5053 session->connection()->OnPathDegradingTimeout();
5054 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
5055
5056 EXPECT_FALSE(HasActiveSession(host_port_pair_));
Zhongyi Shi8de43832018-08-15 23:40:005057 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
Zhongyi Shic1449372018-08-09 09:58:585058 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5059 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5060}
5061
Zhongyi Shi634c1882018-08-16 04:05:595062// This test verifies that if a connection is closed with
5063// QUIC_NETWORK_IDLE_TIMEOUT before handshake is completed and there is no
5064// alternate network, no new connection will be created.
5065TEST_P(QuicStreamFactoryTest, NoAlternateNetworkBeforeHandshakeOnIdleTimeout) {
5066 TestNoAlternateNetworkBeforeHandshake(quic::QUIC_NETWORK_IDLE_TIMEOUT);
5067}
5068
5069// This test verifies that if a connection is closed with QUIC_HANDSHAKE_TIMEOUT
5070// and there is no alternate network, no new connection will be created.
5071TEST_P(QuicStreamFactoryTest, NoAlternateNetworkOnHandshakeTimeout) {
5072 TestNoAlternateNetworkBeforeHandshake(quic::QUIC_HANDSHAKE_TIMEOUT);
5073}
5074
5075void QuicStreamFactoryTestBase::TestNoAlternateNetworkBeforeHandshake(
5076 quic::QuicErrorCode quic_error) {
5077 DCHECK(quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT ||
5078 quic_error == quic::QUIC_HANDSHAKE_TIMEOUT);
5079 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
5080
5081 // Using a testing task runner.
5082 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
5083 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
5084
5085 // Use cold start mode to send crypto message for handshake.
5086 crypto_client_stream_factory_.set_handshake_mode(
5087 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
5088
Ryan Hamiltonabad59e2019-06-06 04:02:595089 MockQuicData socket_data(version_);
Zhongyi Shi634c1882018-08-16 04:05:595090 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5091 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
5092 socket_data.AddSocketDataToFactory(socket_factory_.get());
5093
5094 // Create request.
5095 QuicStreamRequest request(factory_.get());
5096 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035097 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:525098 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
5099 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035100 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5101 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi634c1882018-08-16 04:05:595102
5103 base::RunLoop().RunUntilIdle();
5104
5105 // Ensure that session is alive but not active.
5106 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5107 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5108 QuicChromiumClientSession* session = GetPendingSession(host_port_pair_);
5109 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5110 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
5111
5112 // Cause the connection to report path degrading to the session.
5113 // Session will ignore the signal as handshake is not completed.
5114 session->connection()->OnPathDegradingTimeout();
5115 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
5116 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5117 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5118
5119 // Cause the connection to close due to |quic_error| before handshake.
Victor Vasiliev076657c2019-03-12 02:46:435120 std::string error_details;
Zhongyi Shi634c1882018-08-16 04:05:595121 if (quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT) {
5122 error_details = "No recent network activity.";
5123 } else {
5124 error_details = "Handshake timeout expired.";
5125 }
5126 session->connection()->CloseConnection(
5127 quic_error, error_details, quic::ConnectionCloseBehavior::SILENT_CLOSE);
5128
5129 // A task will be posted to clean up the session in the factory.
5130 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
5131 task_runner->FastForwardUntilNoTasksRemain();
5132
5133 // No new session should be created as there is no alternate network.
5134 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5135 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
5136 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5137 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5138}
5139
Zhongyi Shi8de43832018-08-15 23:40:005140TEST_P(QuicStreamFactoryTest, NewConnectionBeforeHandshakeAfterIdleTimeout) {
5141 TestNewConnectionOnAlternateNetworkBeforeHandshake(
5142 quic::QUIC_NETWORK_IDLE_TIMEOUT);
5143}
5144
5145TEST_P(QuicStreamFactoryTest, NewConnectionAfterHandshakeTimeout) {
5146 TestNewConnectionOnAlternateNetworkBeforeHandshake(
5147 quic::QUIC_HANDSHAKE_TIMEOUT);
5148}
5149
Zhongyi Shif3fcbbe62018-08-16 22:52:085150// Sets up a test to verify that a new connection will be created on the
5151// alternate network after the initial connection fails before handshake with
5152// signals delivered in the following order (alternate network is available):
5153// - the default network is not able to complete crypto handshake;
5154// - the original connection is closed with |quic_error|;
5155// - a new connection is created on the alternate network and is able to finish
5156// crypto handshake;
5157// - the new session on the alternate network attempts to migrate back to the
5158// default network by sending probes;
5159// - default network being disconnected is delivered: session will stop probing
5160// the original network.
5161// - alternate network is made by default.
Zhongyi Shi8de43832018-08-15 23:40:005162void QuicStreamFactoryTestBase::
5163 TestNewConnectionOnAlternateNetworkBeforeHandshake(
5164 quic::QuicErrorCode quic_error) {
5165 DCHECK(quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT ||
5166 quic_error == quic::QUIC_HANDSHAKE_TIMEOUT);
Zhongyi Shi967d2f12019-02-08 20:58:535167 test_params_.quic_retry_on_alternate_network_before_handshake = true;
Zhongyi Shi8de43832018-08-15 23:40:005168 InitializeConnectionMigrationV2Test(
5169 {kDefaultNetworkForTests, kNewNetworkForTests});
5170
5171 // Using a testing task runner.
5172 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
5173 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
5174
5175 // Use cold start mode to send crypto message for handshake.
5176 crypto_client_stream_factory_.set_handshake_mode(
5177 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
5178
5179 // Socket data for connection on the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:595180 MockQuicData socket_data(version_);
Zhongyi Shi8de43832018-08-15 23:40:005181 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5182 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
5183 socket_data.AddSocketDataToFactory(socket_factory_.get());
5184
5185 // Socket data for connection on the alternate network.
Ryan Hamiltonabad59e2019-06-06 04:02:595186 MockQuicData socket_data2(version_);
Zhongyi Shi8de43832018-08-15 23:40:005187 socket_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5188 socket_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
5189 // Change the encryption level after handshake is confirmed.
5190 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamilton0d65a8c2019-06-07 00:46:025191 socket_data2.AddWrite(ASYNC, ConstructInitialSettingsPacket(2));
Zhongyi Shi8de43832018-08-15 23:40:005192 socket_data2.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335193 ASYNC, ConstructGetRequestPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:025194 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi8de43832018-08-15 23:40:005195 socket_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:335196 ASYNC,
5197 ConstructOkResponsePacket(
5198 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shi8de43832018-08-15 23:40:005199 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:335200 socket_data2.AddWrite(
5201 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
5202 5, false, GetNthClientInitiatedBidirectionalStreamId(0),
5203 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi8de43832018-08-15 23:40:005204 socket_data2.AddSocketDataToFactory(socket_factory_.get());
5205
Zhongyi Shif3fcbbe62018-08-16 22:52:085206 // Socket data for probing on the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:595207 MockQuicData probing_data(version_);
Zhongyi Shif3fcbbe62018-08-16 22:52:085208 probing_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
5209 probing_data.AddWrite(SYNCHRONOUS,
5210 client_maker_.MakeConnectivityProbingPacket(4, false));
5211 probing_data.AddSocketDataToFactory(socket_factory_.get());
5212
Zhongyi Shi8de43832018-08-15 23:40:005213 // Create request and QuicHttpStream.
5214 QuicStreamRequest request(factory_.get());
5215 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035216 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:525217 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
5218 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035219 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5220 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi8de43832018-08-15 23:40:005221
5222 base::RunLoop().RunUntilIdle();
5223
5224 // Ensure that session is alive but not active.
5225 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5226 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5227 QuicChromiumClientSession* session = GetPendingSession(host_port_pair_);
5228 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5229 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
Zhongyi Shia6b68d112018-09-24 07:49:035230 EXPECT_FALSE(failed_on_default_network_);
Zhongyi Shi8de43832018-08-15 23:40:005231
Victor Vasiliev076657c2019-03-12 02:46:435232 std::string error_details;
Zhongyi Shi8de43832018-08-15 23:40:005233 if (quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT) {
5234 error_details = "No recent network activity.";
5235 } else {
5236 error_details = "Handshake timeout expired.";
5237 }
5238 session->connection()->CloseConnection(
5239 quic_error, error_details, quic::ConnectionCloseBehavior::SILENT_CLOSE);
5240
5241 // A task will be posted to clean up the session in the factory.
5242 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
5243 task_runner->FastForwardUntilNoTasksRemain();
5244
5245 // Verify a new session is created on the alternate network.
5246 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5247 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5248 QuicChromiumClientSession* session2 = GetPendingSession(host_port_pair_);
5249 EXPECT_NE(session, session2);
Zhongyi Shia6b68d112018-09-24 07:49:035250 EXPECT_TRUE(failed_on_default_network_);
Zhongyi Shi8de43832018-08-15 23:40:005251
5252 // Confirm the handshake on the alternate network.
5253 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5254 quic::QuicSession::HANDSHAKE_CONFIRMED);
5255 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5256 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5257 // Resume the data now so that data can be sent and read.
5258 socket_data2.Resume();
5259
5260 // Create the stream.
5261 std::unique_ptr<HttpStream> stream = CreateStream(&request);
5262 EXPECT_TRUE(stream.get());
5263 HttpRequestInfo request_info;
5264 request_info.method = "GET";
5265 request_info.url = GURL("https://www.example.org/");
5266 request_info.traffic_annotation =
5267 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5268 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
5269 net_log_, CompletionOnceCallback()));
5270 // Send the request.
5271 HttpResponseInfo response;
5272 HttpRequestHeaders request_headers;
5273 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5274 callback_.callback()));
5275 // Run the message loop to finish asynchronous mock write.
5276 base::RunLoop().RunUntilIdle();
5277 // Read the response.
5278 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
5279 EXPECT_EQ(200, response.headers->response_code());
5280
Zhongyi Shif3fcbbe62018-08-16 22:52:085281 // There should be a new task posted to migrate back to the default network.
5282 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
5283 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
5284 EXPECT_EQ(base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs),
5285 next_task_delay);
5286 task_runner->FastForwardBy(next_task_delay);
5287
5288 // There should be two tasks posted. One will retry probing and the other
5289 // will retry migrate back.
5290 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
5291 next_task_delay = task_runner->NextPendingTaskDelay();
5292 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
5293 next_task_delay);
5294
5295 // Deliver the signal that the default network is disconnected.
5296 scoped_mock_network_change_notifier_->mock_network_change_notifier()
5297 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
5298 // Verify no connectivity probes will be sent as probing will be cancelled.
5299 task_runner->FastForwardUntilNoTasksRemain();
5300 // Deliver the signal that the alternate network is made default.
5301 scoped_mock_network_change_notifier_->mock_network_change_notifier()
5302 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
5303 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
5304
Zhongyi Shi8de43832018-08-15 23:40:005305 stream.reset();
5306 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5307 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5308 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
5309 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
5310}
5311
Zhongyi Shi247d6322018-07-24 07:03:355312// Test that connection will be closed with PACKET_WRITE_ERROR if a write error
5313// is triggered before handshake is confirmed and connection migration is turned
5314// on.
5315TEST_P(QuicStreamFactoryTest, MigrationOnWriteErrorBeforeHandshakeConfirmed) {
Zhongyi Shi967d2f12019-02-08 20:58:535316 DCHECK(!test_params_.quic_retry_on_alternate_network_before_handshake);
Zhongyi Shi247d6322018-07-24 07:03:355317 InitializeConnectionMigrationV2Test(
5318 {kDefaultNetworkForTests, kNewNetworkForTests});
5319
5320 // Use unmocked crypto stream to do crypto connect.
5321 crypto_client_stream_factory_.set_handshake_mode(
Zhongyi Shi879659422018-08-02 17:58:255322 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
Zhongyi Shi247d6322018-07-24 07:03:355323
Ryan Hamiltonabad59e2019-06-06 04:02:595324 MockQuicData socket_data(version_);
Zhongyi Shi247d6322018-07-24 07:03:355325 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5326 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
5327 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
5328 socket_data.AddSocketDataToFactory(socket_factory_.get());
5329
5330 // Create request, should fail after the write of the CHLO fails.
5331 QuicStreamRequest request(factory_.get());
5332 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035333 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:525334 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
5335 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035336 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5337 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi247d6322018-07-24 07:03:355338 EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED, callback_.WaitForResult());
5339 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5340 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
5341
5342 // Verify new requests can be sent normally.
5343 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:275344 MockCryptoClientStream::COLD_START);
Zhongyi Shi247d6322018-07-24 07:03:355345 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5346 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
Ryan Hamilton0d65a8c2019-06-07 00:46:025347 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:595348 MockQuicData socket_data2(version_);
Zhongyi Shi247d6322018-07-24 07:03:355349 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5350 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
5351 socket_data2.AddSocketDataToFactory(socket_factory_.get());
5352
5353 QuicStreamRequest request2(factory_.get());
5354 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035355 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:525356 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
5357 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035358 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5359 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi247d6322018-07-24 07:03:355360 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5361 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5362 // Run the message loop to complete host resolution.
5363 base::RunLoop().RunUntilIdle();
5364
5365 // Complete handshake. QuicStreamFactory::Job should complete and succeed.
5366 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5367 quic::QuicSession::HANDSHAKE_CONFIRMED);
5368 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5369 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5370 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
5371
5372 // Create QuicHttpStream.
5373 std::unique_ptr<HttpStream> stream = CreateStream(&request2);
5374 EXPECT_TRUE(stream.get());
5375 stream.reset();
5376 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5377 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5378 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
5379 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
5380}
5381
Zhongyi Shif2524bf2019-01-27 07:44:035382// Test that if the original connection is closed with QUIC_PACKET_WRITE_ERROR
5383// before handshake is confirmed and new connection before handshake is turned
5384// on, a new connection will be retried on the alternate network.
5385TEST_P(QuicStreamFactoryTest,
5386 RetryConnectionOnWriteErrorBeforeHandshakeConfirmed) {
Zhongyi Shi967d2f12019-02-08 20:58:535387 test_params_.quic_retry_on_alternate_network_before_handshake = true;
Zhongyi Shif2524bf2019-01-27 07:44:035388 InitializeConnectionMigrationV2Test(
5389 {kDefaultNetworkForTests, kNewNetworkForTests});
5390
5391 // Use unmocked crypto stream to do crypto connect.
5392 crypto_client_stream_factory_.set_handshake_mode(
5393 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
5394
5395 // Socket data for connection on the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:595396 MockQuicData socket_data(version_);
Zhongyi Shif2524bf2019-01-27 07:44:035397 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5398 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
5399 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
5400 socket_data.AddSocketDataToFactory(socket_factory_.get());
5401
5402 // Socket data for connection on the alternate network.
Ryan Hamiltonabad59e2019-06-06 04:02:595403 MockQuicData socket_data2(version_);
Zhongyi Shif2524bf2019-01-27 07:44:035404 socket_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5405 socket_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
5406 // Change the encryption level after handshake is confirmed.
5407 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamilton0d65a8c2019-06-07 00:46:025408 socket_data2.AddWrite(ASYNC, ConstructInitialSettingsPacket(2));
Zhongyi Shif2524bf2019-01-27 07:44:035409 socket_data2.AddWrite(
5410 ASYNC, ConstructGetRequestPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:025411 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shif2524bf2019-01-27 07:44:035412 socket_data2.AddRead(
5413 ASYNC,
5414 ConstructOkResponsePacket(
5415 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
5416 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5417 socket_data2.AddWrite(
5418 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
5419 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
5420 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
5421 socket_data2.AddSocketDataToFactory(socket_factory_.get());
5422
5423 // Create request, should fail after the write of the CHLO fails.
5424 QuicStreamRequest request(factory_.get());
5425 EXPECT_EQ(ERR_IO_PENDING,
5426 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:525427 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
5428 SocketTag(), NetworkIsolationKey(),
Zhongyi Shif2524bf2019-01-27 07:44:035429 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5430 failed_on_default_network_callback_, callback_.callback()));
5431 // Ensure that the session is alive but not active.
5432 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5433 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5434 base::RunLoop().RunUntilIdle();
5435 QuicChromiumClientSession* session = GetPendingSession(host_port_pair_);
5436 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5437
5438 // Confirm the handshake on the alternate network.
5439 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5440 quic::QuicSession::HANDSHAKE_CONFIRMED);
5441 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5442 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5443
5444 // Resume the data now so that data can be sent and read.
5445 socket_data2.Resume();
5446
5447 // Create the stream.
5448 std::unique_ptr<HttpStream> stream = CreateStream(&request);
5449 EXPECT_TRUE(stream.get());
5450 HttpRequestInfo request_info;
5451 request_info.method = "GET";
5452 request_info.url = GURL("https://www.example.org/");
5453 request_info.traffic_annotation =
5454 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5455 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
5456 net_log_, CompletionOnceCallback()));
5457 // Send the request.
5458 HttpResponseInfo response;
5459 HttpRequestHeaders request_headers;
5460 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5461 callback_.callback()));
5462 // Run the message loop to finish asynchronous mock write.
5463 base::RunLoop().RunUntilIdle();
5464 // Read the response.
5465 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
5466 EXPECT_EQ(200, response.headers->response_code());
5467
5468 stream.reset();
5469 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5470 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5471 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
5472 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
5473}
5474
jri9f303712016-09-13 01:10:225475void QuicStreamFactoryTestBase::TestMigrationOnWriteError(
5476 IoMode write_error_mode) {
Zhongyi Shi1a054612018-06-14 04:59:085477 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:225478 {kDefaultNetworkForTests, kNewNetworkForTests});
5479 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5480 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5481 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5482
Zhongyi Shi3c4c9e92018-07-02 23:16:235483 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
5484
Ryan Hamiltonabad59e2019-06-06 04:02:595485 MockQuicData socket_data(version_);
jri9f303712016-09-13 01:10:225486 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:025487 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jri9f303712016-09-13 01:10:225488 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:175489 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:225490
5491 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:455492 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:335493 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035494 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:525495 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
5496 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035497 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5498 failed_on_default_network_callback_, callback_.callback()));
jri9f303712016-09-13 01:10:225499 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:245500 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:225501 EXPECT_TRUE(stream.get());
5502
5503 // Cause QUIC stream to be created.
5504 HttpRequestInfo request_info;
5505 request_info.method = "GET";
5506 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:395507 request_info.traffic_annotation =
5508 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:275509 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:395510 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:225511
5512 // Ensure that session is alive and active.
5513 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5514 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5515 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5516
5517 // Set up second socket data provider that is used after
5518 // migration. The request is rewritten to this new socket, and the
5519 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:595520 MockQuicData socket_data1(version_);
Fan Yang32c5a112018-12-10 20:06:335521 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:025522 SYNCHRONOUS,
5523 ConstructGetRequestPacket(
5524 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi32f2fd02018-04-16 18:23:435525 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:335526 ASYNC,
5527 ConstructOkResponsePacket(
5528 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
jri9f303712016-09-13 01:10:225529 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:335530 socket_data1.AddWrite(
5531 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
5532 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
5533 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:175534 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:225535
5536 // Send GET request on stream. This should cause a write error, which triggers
5537 // a connection migration attempt.
5538 HttpResponseInfo response;
5539 HttpRequestHeaders request_headers;
5540 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5541 callback_.callback()));
5542
5543 // Run the message loop so that the migration attempt is executed and
5544 // data queued in the new socket is read by the packet reader.
5545 base::RunLoop().RunUntilIdle();
5546
Zhongyi Shia7dd46b2018-07-12 22:59:295547 // Verify that session is alive and not marked as going awya.
jri9f303712016-09-13 01:10:225548 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:295549 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri9f303712016-09-13 01:10:225550 EXPECT_EQ(1u, session->GetNumActiveStreams());
5551
5552 // Verify that response headers on the migrated socket were delivered to the
5553 // stream.
5554 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
5555 EXPECT_EQ(200, response.headers->response_code());
5556
5557 stream.reset();
5558
5559 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5560 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5561 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
5562 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
5563}
5564
5565TEST_P(QuicStreamFactoryTest, MigrateSessionOnWriteErrorSynchronous) {
5566 TestMigrationOnWriteError(SYNCHRONOUS);
5567}
5568
5569TEST_P(QuicStreamFactoryTest, MigrateSessionOnWriteErrorAsync) {
5570 TestMigrationOnWriteError(ASYNC);
5571}
5572
5573void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorNoNewNetwork(
5574 IoMode write_error_mode) {
Zhongyi Shi1a054612018-06-14 04:59:085575 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri9f303712016-09-13 01:10:225576 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5577 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5578
jri5b785512016-09-13 04:29:115579 // Use the test task runner, to force the migration alarm timeout later.
5580 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
5581
Ryan Hamiltonabad59e2019-06-06 04:02:595582 MockQuicData socket_data(version_);
jri9f303712016-09-13 01:10:225583 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:435584 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jri9f303712016-09-13 01:10:225585 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:175586 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:225587
5588 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:455589 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:335590 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035591 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:525592 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
5593 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035594 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5595 failed_on_default_network_callback_, callback_.callback()));
jri9f303712016-09-13 01:10:225596 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:245597 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:225598 EXPECT_TRUE(stream.get());
5599
5600 // Cause QUIC stream to be created.
5601 HttpRequestInfo request_info;
5602 request_info.method = "GET";
5603 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:395604 request_info.traffic_annotation =
5605 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:275606 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:395607 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:225608
5609 // Ensure that session is alive and active.
5610 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5611 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5612 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5613
jri5b785512016-09-13 04:29:115614 // Send GET request on stream. This causes a write error, which triggers
5615 // a connection migration attempt. Since there are no networks
5616 // to migrate to, this causes the session to wait for a new network.
jri9f303712016-09-13 01:10:225617 HttpResponseInfo response;
5618 HttpRequestHeaders request_headers;
5619 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5620 callback_.callback()));
jri5b785512016-09-13 04:29:115621
5622 // Complete any pending writes. Pending async MockQuicData writes
5623 // are run on the message loop, not on the test runner.
jri9f303712016-09-13 01:10:225624 base::RunLoop().RunUntilIdle();
jri5b785512016-09-13 04:29:115625
5626 // Write error causes migration task to be posted. Spin the loop.
5627 if (write_error_mode == ASYNC)
5628 runner_->RunNextTask();
5629
5630 // Migration has not yet failed. The session should be alive and active.
5631 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5632 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5633 EXPECT_EQ(1u, session->GetNumActiveStreams());
5634 EXPECT_TRUE(session->connection()->writer()->IsWriteBlocked());
5635
5636 // The migration will not fail until the migration alarm timeout.
5637 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5638 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5639 EXPECT_EQ(1u, session->GetNumActiveStreams());
5640 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
5641
5642 // Force migration alarm timeout to run.
5643 RunTestLoopUntilIdle();
5644
5645 // The connection should be closed. A request for response headers
5646 // should fail.
jri9f303712016-09-13 01:10:225647 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5648 EXPECT_FALSE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:115649 EXPECT_EQ(ERR_NETWORK_CHANGED, callback_.WaitForResult());
5650 EXPECT_EQ(ERR_NETWORK_CHANGED,
5651 stream->ReadResponseHeaders(callback_.callback()));
jri9f303712016-09-13 01:10:225652
Zhongyi Shi59aaf072019-01-17 03:32:135653 NetErrorDetails error_details;
5654 stream->PopulateNetErrorDetails(&error_details);
5655 EXPECT_EQ(error_details.quic_connection_error,
5656 quic::QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK);
5657
jri9f303712016-09-13 01:10:225658 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5659 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5660}
5661
5662TEST_P(QuicStreamFactoryTest,
5663 MigrateSessionOnWriteErrorNoNewNetworkSynchronous) {
5664 TestMigrationOnWriteErrorNoNewNetwork(SYNCHRONOUS);
5665}
5666
5667TEST_P(QuicStreamFactoryTest, MigrateSessionOnWriteErrorNoNewNetworkAsync) {
5668 TestMigrationOnWriteErrorNoNewNetwork(ASYNC);
5669}
5670
Zhongyi Shi0439ecc72018-07-11 04:41:265671TEST_P(QuicStreamFactoryTest,
5672 MigrateSessionOnWriteErrorWithMultipleRequestsSync) {
5673 TestMigrationOnWriteErrorWithMultipleRequests(SYNCHRONOUS);
5674}
5675
5676TEST_P(QuicStreamFactoryTest,
5677 MigrateSessionOnWriteErrorWithMultipleRequestsAsync) {
5678 TestMigrationOnWriteErrorWithMultipleRequests(ASYNC);
5679}
5680
5681// Sets up a test which verifies that connection migration on write error can
5682// eventually succeed and rewrite the packet on the new network with *multiple*
5683// migratable streams.
5684void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorWithMultipleRequests(
5685 IoMode write_error_mode) {
5686 InitializeConnectionMigrationV2Test(
5687 {kDefaultNetworkForTests, kNewNetworkForTests});
5688 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5689 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5690 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5691
Ryan Hamiltonabad59e2019-06-06 04:02:595692 MockQuicData socket_data(version_);
Zhongyi Shi0439ecc72018-07-11 04:41:265693 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:025694 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi0439ecc72018-07-11 04:41:265695 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
5696 socket_data.AddSocketDataToFactory(socket_factory_.get());
5697
5698 // Set up second socket data provider that is used after
5699 // migration. The request is rewritten to this new socket, and the
5700 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:595701 MockQuicData socket_data1(version_);
Zhongyi Shi0439ecc72018-07-11 04:41:265702 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:025703 SYNCHRONOUS,
5704 ConstructGetRequestPacket(
5705 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Fan Yang32c5a112018-12-10 20:06:335706 socket_data1.AddRead(
5707 ASYNC,
5708 ConstructOkResponsePacket(
5709 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
5710 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5711 socket_data1.AddWrite(
5712 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
5713 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
5714 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
5715 socket_data1.AddWrite(
5716 SYNCHRONOUS, client_maker_.MakeRstPacket(
5717 4, false, GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:415718 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:185719 /*include_stop_sending_if_v99=*/true));
Zhongyi Shi0439ecc72018-07-11 04:41:265720
5721 socket_data1.AddSocketDataToFactory(socket_factory_.get());
5722
5723 // Create request #1 and QuicHttpStream.
5724 QuicStreamRequest request1(factory_.get());
5725 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035726 request1.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:525727 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
5728 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035729 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5730 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi0439ecc72018-07-11 04:41:265731 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5732 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
5733 EXPECT_TRUE(stream1.get());
5734
5735 HttpRequestInfo request_info1;
5736 request_info1.method = "GET";
5737 request_info1.url = GURL("https://www.example.org/");
5738 request_info1.traffic_annotation =
5739 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5740 EXPECT_EQ(OK,
5741 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
5742 net_log_, CompletionOnceCallback()));
5743
5744 // Second request returns synchronously because it pools to existing session.
5745 TestCompletionCallback callback2;
5746 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:515747 EXPECT_EQ(OK,
5748 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:525749 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
5750 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:515751 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5752 failed_on_default_network_callback_, callback2.callback()));
Zhongyi Shi0439ecc72018-07-11 04:41:265753 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
5754 EXPECT_TRUE(stream2.get());
5755 HttpRequestInfo request_info2;
5756 request_info2.method = "GET";
5757 request_info2.url = GURL("https://www.example.org/");
5758 request_info2.traffic_annotation =
5759 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5760 EXPECT_EQ(OK,
5761 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
5762 net_log_, CompletionOnceCallback()));
5763
5764 // Ensure that session is alive and active.
5765 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5766 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5767 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5768 EXPECT_EQ(2u, session->GetNumActiveStreams());
5769
5770 // Send GET request on stream. This should cause a write error, which triggers
5771 // a connection migration attempt.
5772 HttpResponseInfo response;
5773 HttpRequestHeaders request_headers;
5774 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
5775 callback_.callback()));
5776
5777 // Run the message loop so that the migration attempt is executed and
5778 // data queued in the new socket is read by the packet reader.
5779 base::RunLoop().RunUntilIdle();
5780
Zhongyi Shia7dd46b2018-07-12 22:59:295781 // Verify session is still alive and not marked as going away.
Zhongyi Shi0439ecc72018-07-11 04:41:265782 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:295783 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:265784 EXPECT_EQ(2u, session->GetNumActiveStreams());
5785
5786 // Verify that response headers on the migrated socket were delivered to the
5787 // stream.
5788 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
5789 EXPECT_EQ(200, response.headers->response_code());
5790
5791 stream1.reset();
5792 stream2.reset();
5793
5794 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5795 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5796 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
5797 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
5798}
5799
5800TEST_P(QuicStreamFactoryTest, MigrateOnWriteErrorWithMixedRequestsSync) {
5801 TestMigrationOnWriteErrorMixedStreams(SYNCHRONOUS);
5802}
5803
5804TEST_P(QuicStreamFactoryTest, MigrateOnWriteErrorWithMixedRequestsAsync) {
5805 TestMigrationOnWriteErrorMixedStreams(ASYNC);
5806}
5807
5808// Sets up a test that verifies connection migration manages to migrate to
5809// alternate network after encountering a SYNC/ASYNC write error based on
5810// |write_error_mode| on the original network.
5811// Note there are mixed types of unfinished requests before migration: one
5812// migratable and one non-migratable. The *migratable* one triggers write
5813// error.
5814void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorMixedStreams(
5815 IoMode write_error_mode) {
5816 InitializeConnectionMigrationV2Test(
5817 {kDefaultNetworkForTests, kNewNetworkForTests});
5818 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5819 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5820 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5821
5822 int packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595823 MockQuicData socket_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:025824
Zhongyi Shi0439ecc72018-07-11 04:41:265825 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:025826 socket_data.AddWrite(SYNCHRONOUS,
5827 ConstructInitialSettingsPacket(packet_number++));
Zhongyi Shi0439ecc72018-07-11 04:41:265828 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
5829 socket_data.AddSocketDataToFactory(socket_factory_.get());
5830
5831 // Set up second socket data provider that is used after
5832 // migration. The request is rewritten to this new socket, and the
5833 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:595834 MockQuicData socket_data1(version_);
Zhongyi Shi0439ecc72018-07-11 04:41:265835 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335836 SYNCHRONOUS,
5837 ConstructGetRequestPacket(packet_number++,
5838 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:025839 true, true));
Zhongyi Shi0439ecc72018-07-11 04:41:265840 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335841 SYNCHRONOUS,
5842 client_maker_.MakeRstPacket(packet_number++, true,
5843 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:415844 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:185845 /*include_stop_sending_if_v99=*/true));
Zhongyi Shi0439ecc72018-07-11 04:41:265846 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:335847 ASYNC,
5848 ConstructOkResponsePacket(
5849 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shi0439ecc72018-07-11 04:41:265850 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5851 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335852 SYNCHRONOUS,
5853 client_maker_.MakeAckAndRstPacket(
5854 packet_number++, false, GetNthClientInitiatedBidirectionalStreamId(0),
5855 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi0439ecc72018-07-11 04:41:265856 socket_data1.AddSocketDataToFactory(socket_factory_.get());
5857
5858 // Create request #1 and QuicHttpStream.
5859 QuicStreamRequest request1(factory_.get());
5860 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035861 request1.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:525862 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
5863 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035864 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5865 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi0439ecc72018-07-11 04:41:265866 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5867 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
5868 EXPECT_TRUE(stream1.get());
5869
5870 HttpRequestInfo request_info1;
5871 request_info1.method = "GET";
5872 request_info1.url = GURL("https://www.example.org/");
5873 request_info1.traffic_annotation =
5874 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5875 EXPECT_EQ(OK,
5876 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
5877 net_log_, CompletionOnceCallback()));
5878
5879 // Second request returns synchronously because it pools to existing session.
5880 TestCompletionCallback callback2;
5881 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:515882 EXPECT_EQ(OK,
5883 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:525884 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
5885 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:515886 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5887 failed_on_default_network_callback_, callback2.callback()));
Zhongyi Shi0439ecc72018-07-11 04:41:265888 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
5889 EXPECT_TRUE(stream2.get());
5890
5891 HttpRequestInfo request_info2;
5892 request_info2.method = "GET";
Zhongyi Shibb28b1f2018-07-18 02:41:265893 request_info2.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Zhongyi Shi0439ecc72018-07-11 04:41:265894 request_info2.url = GURL("https://www.example.org/");
5895 request_info2.traffic_annotation =
5896 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5897 EXPECT_EQ(OK,
5898 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
5899 net_log_, CompletionOnceCallback()));
5900
5901 // Ensure that session is alive and active.
5902 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5903 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5904 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5905 EXPECT_EQ(2u, session->GetNumActiveStreams());
5906
5907 // Send GET request on stream 1. This should cause a write error, which
5908 // triggers a connection migration attempt.
5909 HttpResponseInfo response;
5910 HttpRequestHeaders request_headers;
5911 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
5912 callback_.callback()));
5913
5914 // Run the message loop so that the migration attempt is executed and
5915 // data queued in the new socket is read by the packet reader.
5916 base::RunLoop().RunUntilIdle();
5917
Zhongyi Shia7dd46b2018-07-12 22:59:295918 // Verify that the session is still alive and not marked as going away.
5919 // Non-migratable stream should be closed due to migration.
Zhongyi Shi0439ecc72018-07-11 04:41:265920 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:295921 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:265922 EXPECT_EQ(1u, session->GetNumActiveStreams());
5923
5924 // Verify that response headers on the migrated socket were delivered to the
5925 // stream.
5926 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
5927 EXPECT_EQ(200, response.headers->response_code());
5928
5929 stream1.reset();
5930
5931 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5932 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5933 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
5934 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
5935}
5936
5937TEST_P(QuicStreamFactoryTest, MigrateOnWriteErrorWithMixedRequests2Sync) {
5938 TestMigrationOnWriteErrorMixedStreams2(SYNCHRONOUS);
5939}
5940
5941TEST_P(QuicStreamFactoryTest, MigrateOnWriteErrorWithMixedRequests2Async) {
5942 TestMigrationOnWriteErrorMixedStreams2(ASYNC);
5943}
5944
5945// The one triggers write error is a non-migratable stream.
5946// Sets up a test that verifies connection migration manages to migrate to
5947// alternate network after encountering a SYNC/ASYNC write error based on
5948// |write_error_mode| on the original network.
5949// Note there are mixed types of unfinished requests before migration: one
5950// migratable and one non-migratable. The *non-migratable* one triggers write
5951// error.
5952void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorMixedStreams2(
5953 IoMode write_error_mode) {
5954 InitializeConnectionMigrationV2Test(
5955 {kDefaultNetworkForTests, kNewNetworkForTests});
5956 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5957 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5958 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5959
5960 int packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595961 MockQuicData socket_data(version_);
Zhongyi Shi0439ecc72018-07-11 04:41:265962 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:025963 socket_data.AddWrite(SYNCHRONOUS,
5964 ConstructInitialSettingsPacket(packet_number++));
Zhongyi Shi0439ecc72018-07-11 04:41:265965 socket_data.AddWrite(write_error_mode,
5966 ERR_ADDRESS_UNREACHABLE); // Write error.
5967 socket_data.AddSocketDataToFactory(socket_factory_.get());
5968
5969 // Set up second socket data provider that is used after
5970 // migration. The request is rewritten to this new socket, and the
5971 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:595972 MockQuicData socket_data1(version_);
Zhongyi Shi0439ecc72018-07-11 04:41:265973 // The packet triggered writer error will be sent anyway even if the stream
5974 // will be cancelled later.
5975 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335976 SYNCHRONOUS,
5977 ConstructGetRequestPacket(packet_number++,
5978 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamilton0d65a8c2019-06-07 00:46:025979 true, true));
Zhongyi Shi0439ecc72018-07-11 04:41:265980 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335981 SYNCHRONOUS,
5982 client_maker_.MakeRstPacket(packet_number++, true,
5983 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:415984 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:185985 /*include_stop_sending_if_v99=*/true));
Zhongyi Shi0439ecc72018-07-11 04:41:265986 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335987 SYNCHRONOUS,
5988 ConstructGetRequestPacket(packet_number++,
5989 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:025990 true, true));
Zhongyi Shi0439ecc72018-07-11 04:41:265991 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:335992 ASYNC,
5993 ConstructOkResponsePacket(
5994 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shi0439ecc72018-07-11 04:41:265995 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5996 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335997 SYNCHRONOUS,
5998 client_maker_.MakeAckAndRstPacket(
5999 packet_number++, false, GetNthClientInitiatedBidirectionalStreamId(0),
6000 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi0439ecc72018-07-11 04:41:266001 socket_data1.AddSocketDataToFactory(socket_factory_.get());
6002
6003 // Create request #1 and QuicHttpStream.
6004 QuicStreamRequest request1(factory_.get());
6005 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036006 request1.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:526007 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
6008 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036009 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6010 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi0439ecc72018-07-11 04:41:266011 EXPECT_THAT(callback_.WaitForResult(), IsOk());
6012 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
6013 EXPECT_TRUE(stream1.get());
6014
6015 HttpRequestInfo request_info1;
6016 request_info1.method = "GET";
6017 request_info1.url = GURL("https://www.example.org/");
6018 request_info1.traffic_annotation =
6019 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6020 EXPECT_EQ(OK,
6021 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
6022 net_log_, CompletionOnceCallback()));
6023
6024 // Second request returns synchronously because it pools to existing session.
6025 TestCompletionCallback callback2;
6026 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:516027 EXPECT_EQ(OK,
6028 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:526029 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
6030 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:516031 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6032 failed_on_default_network_callback_, callback2.callback()));
Zhongyi Shi0439ecc72018-07-11 04:41:266033 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
6034 EXPECT_TRUE(stream2.get());
6035
6036 HttpRequestInfo request_info2;
6037 request_info2.method = "GET";
Zhongyi Shibb28b1f2018-07-18 02:41:266038 request_info2.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Zhongyi Shi0439ecc72018-07-11 04:41:266039 request_info2.url = GURL("https://www.example.org/");
6040 request_info2.traffic_annotation =
6041 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6042 EXPECT_EQ(OK,
6043 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
6044 net_log_, CompletionOnceCallback()));
6045
6046 // Ensure that session is alive and active.
6047 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6048 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6049 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6050 EXPECT_EQ(2u, session->GetNumActiveStreams());
6051
6052 // Send GET request on stream 2 which is non-migratable. This should cause a
6053 // write error, which triggers a connection migration attempt.
6054 HttpResponseInfo response2;
6055 HttpRequestHeaders request_headers2;
6056 EXPECT_EQ(OK, stream2->SendRequest(request_headers2, &response2,
6057 callback2.callback()));
6058
6059 // Run the message loop so that the migration attempt is executed and
Zhongyi Shia7dd46b2018-07-12 22:59:296060 // data queued in the new socket is read by the packet reader. Session is
6061 // still alive and not marked as going away, non-migratable stream will be
6062 // closed.
Zhongyi Shi0439ecc72018-07-11 04:41:266063 base::RunLoop().RunUntilIdle();
6064 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:296065 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:266066 EXPECT_EQ(1u, session->GetNumActiveStreams());
6067
6068 // Send GET request on stream 1.
6069 HttpResponseInfo response;
6070 HttpRequestHeaders request_headers;
6071 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
6072 callback_.callback()));
6073
6074 base::RunLoop().RunUntilIdle();
6075
6076 // Verify that response headers on the migrated socket were delivered to the
6077 // stream.
6078 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
6079 EXPECT_EQ(200, response.headers->response_code());
6080
6081 stream1.reset();
6082
6083 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6084 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6085 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6086 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6087}
6088
Zhongyi Shic16b4102019-02-12 00:37:406089// This test verifies that when a connection encounters a packet write error, it
6090// will cancel non-migratable streams, and migrate to the alternate network.
jri9f303712016-09-13 01:10:226091void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorNonMigratableStream(
Zhongyi Shi32fe14d42019-02-28 00:25:366092 IoMode write_error_mode,
6093 bool migrate_idle_sessions) {
Zhongyi Shic16b4102019-02-12 00:37:406094 DVLOG(1) << "Write error mode: "
jri9f303712016-09-13 01:10:226095 << ((write_error_mode == SYNCHRONOUS) ? "SYNCHRONOUS" : "ASYNC");
Zhongyi Shi32fe14d42019-02-28 00:25:366096 DVLOG(1) << "Migrate idle sessions: " << migrate_idle_sessions;
6097 test_params_.quic_migrate_idle_sessions = migrate_idle_sessions;
Zhongyi Shi1a054612018-06-14 04:59:086098 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:226099 {kDefaultNetworkForTests, kNewNetworkForTests});
6100 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6101 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6102
Ryan Hamiltonabad59e2019-06-06 04:02:596103 MockQuicData failed_socket_data(version_);
6104 MockQuicData socket_data(version_);
Zhongyi Shi32fe14d42019-02-28 00:25:366105 if (migrate_idle_sessions) {
Zhongyi Shi32fe14d42019-02-28 00:25:366106 // The socket data provider for the original socket before migration.
6107 failed_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:026108 failed_socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi32fe14d42019-02-28 00:25:366109 failed_socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
6110 failed_socket_data.AddSocketDataToFactory(socket_factory_.get());
6111
6112 // Set up second socket data provider that is used after migration.
6113 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
6114 // Although the write error occurs when writing a packet for the
6115 // non-migratable stream and the stream will be cancelled during migration,
6116 // the packet will still be retransimitted at the connection level.
6117 socket_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:026118 SYNCHRONOUS,
6119 ConstructGetRequestPacket(
6120 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi32fe14d42019-02-28 00:25:366121 // A RESET will be sent to the peer to cancel the non-migratable stream.
6122 socket_data.AddWrite(
6123 SYNCHRONOUS, client_maker_.MakeRstPacket(
6124 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
6125 quic::QUIC_STREAM_CANCELLED));
6126 socket_data.AddSocketDataToFactory(socket_factory_.get());
6127 } else {
6128 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6129 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
6130 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
6131 socket_data.AddSocketDataToFactory(socket_factory_.get());
6132 }
jri9f303712016-09-13 01:10:226133
6134 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456135 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336136 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036137 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:526138 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
6139 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036140 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6141 failed_on_default_network_callback_, callback_.callback()));
jri9f303712016-09-13 01:10:226142 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246143 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:226144 EXPECT_TRUE(stream.get());
6145
6146 // Cause QUIC stream to be created, but marked as non-migratable.
6147 HttpRequestInfo request_info;
Zhongyi Shibb28b1f2018-07-18 02:41:266148 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
jri9f303712016-09-13 01:10:226149 request_info.method = "GET";
6150 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396151 request_info.traffic_annotation =
6152 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276153 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396154 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:226155
6156 // Ensure that session is alive and active.
6157 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6158 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6159 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6160
6161 // Send GET request on stream. This should cause a write error, which triggers
6162 // a connection migration attempt.
6163 HttpResponseInfo response;
6164 HttpRequestHeaders request_headers;
6165 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6166 callback_.callback()));
6167
6168 // Run message loop to execute migration attempt.
6169 base::RunLoop().RunUntilIdle();
6170
Zhongyi Shi32fe14d42019-02-28 00:25:366171 // Migration closes the non-migratable stream and:
6172 // if migrate idle session is enabled, it migrates to the alternate network
6173 // successfully; otherwise the connection is closed.
6174 EXPECT_EQ(migrate_idle_sessions,
6175 QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6176 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(host_port_pair_));
jri9f303712016-09-13 01:10:226177
Zhongyi Shi32fe14d42019-02-28 00:25:366178 if (migrate_idle_sessions) {
6179 EXPECT_TRUE(failed_socket_data.AllReadDataConsumed());
6180 EXPECT_TRUE(failed_socket_data.AllWriteDataConsumed());
6181 }
jri9f303712016-09-13 01:10:226182 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6183 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6184}
6185
Zhongyi Shi32fe14d42019-02-28 00:25:366186TEST_P(
6187 QuicStreamFactoryTest,
6188 MigrateSessionOnWriteErrorNonMigratableStreamSync_DoNotMigrateIdleSessions) {
6189 TestMigrationOnWriteErrorNonMigratableStream(SYNCHRONOUS, false);
6190}
6191
6192TEST_P(
6193 QuicStreamFactoryTest,
6194 MigrateSessionOnWriteErrorNonMigratableStreamAsync_DoNotMigrateIdleSessions) {
6195 TestMigrationOnWriteErrorNonMigratableStream(ASYNC, false);
jri9f303712016-09-13 01:10:226196}
6197
6198TEST_P(QuicStreamFactoryTest,
Zhongyi Shi32fe14d42019-02-28 00:25:366199 MigrateSessionOnWriteErrorNonMigratableStreamSync_MigrateIdleSessions) {
6200 TestMigrationOnWriteErrorNonMigratableStream(SYNCHRONOUS, true);
6201}
6202
6203TEST_P(QuicStreamFactoryTest,
6204 MigrateSessionOnWriteErrorNonMigratableStreamAsync_MigrateIdleSessions) {
6205 TestMigrationOnWriteErrorNonMigratableStream(ASYNC, true);
jri9f303712016-09-13 01:10:226206}
6207
6208void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorMigrationDisabled(
6209 IoMode write_error_mode) {
Zhongyi Shi1a054612018-06-14 04:59:086210 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:226211 {kDefaultNetworkForTests, kNewNetworkForTests});
6212 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6213 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6214
Ryan Hamiltonabad59e2019-06-06 04:02:596215 MockQuicData socket_data(version_);
jri9f303712016-09-13 01:10:226216 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436217 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jri9f303712016-09-13 01:10:226218 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:176219 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:226220
6221 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456222 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336223 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036224 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:526225 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
6226 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036227 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6228 failed_on_default_network_callback_, callback_.callback()));
jri9f303712016-09-13 01:10:226229 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246230 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:226231 EXPECT_TRUE(stream.get());
6232
6233 // Cause QUIC stream to be created.
6234 HttpRequestInfo request_info;
6235 request_info.method = "GET";
6236 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396237 request_info.traffic_annotation =
6238 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276239 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396240 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:226241
6242 // Ensure that session is alive and active.
6243 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6244 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6245 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6246
6247 // Set session config to have connection migration disabled.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526248 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
6249 session->config());
jri9f303712016-09-13 01:10:226250 EXPECT_TRUE(session->config()->DisableConnectionMigration());
6251
6252 // Send GET request on stream. This should cause a write error, which triggers
6253 // a connection migration attempt.
6254 HttpResponseInfo response;
6255 HttpRequestHeaders request_headers;
6256 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6257 callback_.callback()));
6258 // Run message loop to execute migration attempt.
6259 base::RunLoop().RunUntilIdle();
6260 // Migration fails, and session is closed and deleted.
6261 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6262 EXPECT_FALSE(HasActiveSession(host_port_pair_));
6263 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6264 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6265}
6266
6267TEST_P(QuicStreamFactoryTest,
6268 MigrateSessionOnWriteErrorMigrationDisabledSynchronous) {
6269 TestMigrationOnWriteErrorMigrationDisabled(SYNCHRONOUS);
6270}
6271
6272TEST_P(QuicStreamFactoryTest,
6273 MigrateSessionOnWriteErrorMigrationDisabledAsync) {
6274 TestMigrationOnWriteErrorMigrationDisabled(ASYNC);
6275}
6276
Zhongyi Shi7f1d9212018-06-22 23:24:366277// Sets up a test which verifies that connection migration on write error can
6278// eventually succeed and rewrite the packet on the new network with singals
6279// delivered in the following order (alternate network is always availabe):
6280// - original network encounters a SYNC/ASYNC write error based on
6281// |write_error_mode_on_old_network|, the packet failed to be written is
6282// cached, session migrates immediately to the alternate network.
6283// - an immediate SYNC/ASYNC write error based on
6284// |write_error_mode_on_new_network| is encountered after migration to the
6285// alternate network, session migrates immediately to the original network.
6286// - an immediate SYNC/ASYNC write error based on
6287// |write_error_mode_on_old_network| is encountered after migration to the
6288// original network, session migrates immediately to the alternate network.
6289// - finally, session successfully sends the packet and reads the response on
6290// the alternate network.
6291// TODO(zhongyi): once https://crbug.com/855666 is fixed, this test should be
6292// modified to test that session is closed early if hopping between networks
6293// with consecutive write errors is detected.
jri9f303712016-09-13 01:10:226294void QuicStreamFactoryTestBase::TestMigrationOnMultipleWriteErrors(
Zhongyi Shi7f1d9212018-06-22 23:24:366295 IoMode write_error_mode_on_old_network,
6296 IoMode write_error_mode_on_new_network) {
6297 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:226298 {kDefaultNetworkForTests, kNewNetworkForTests});
6299 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6300 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6301 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6302
Zhongyi Shi7f1d9212018-06-22 23:24:366303 // Set up the socket data used by the original network, which encounters a
6304 // write erorr.
Ryan Hamiltonabad59e2019-06-06 04:02:596305 MockQuicData socket_data1(version_);
Zhongyi Shi7f1d9212018-06-22 23:24:366306 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:026307 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi7f1d9212018-06-22 23:24:366308 socket_data1.AddWrite(write_error_mode_on_old_network,
6309 ERR_ADDRESS_UNREACHABLE); // Write Error
6310 socket_data1.AddSocketDataToFactory(socket_factory_.get());
6311
6312 // Set up the socket data used by the alternate network, which also
6313 // encounters a write error.
Ryan Hamiltonabad59e2019-06-06 04:02:596314 MockQuicData failed_quic_data2(version_);
Zhongyi Shi7f1d9212018-06-22 23:24:366315 failed_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6316 failed_quic_data2.AddWrite(write_error_mode_on_new_network, ERR_FAILED);
6317 failed_quic_data2.AddSocketDataToFactory(socket_factory_.get());
6318
6319 // Set up the third socket data used by original network, which encounters a
6320 // write error again.
Ryan Hamiltonabad59e2019-06-06 04:02:596321 MockQuicData failed_quic_data1(version_);
Zhongyi Shi7f1d9212018-06-22 23:24:366322 failed_quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6323 failed_quic_data1.AddWrite(write_error_mode_on_old_network, ERR_FAILED);
6324 failed_quic_data1.AddSocketDataToFactory(socket_factory_.get());
6325
6326 // Set up the last socket data used by the alternate network, which will
6327 // finish migration successfully. The request is rewritten to this new socket,
6328 // and the response to the request is read on this socket.
Ryan Hamiltonabad59e2019-06-06 04:02:596329 MockQuicData socket_data2(version_);
Fan Yang32c5a112018-12-10 20:06:336330 socket_data2.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:026331 SYNCHRONOUS,
6332 ConstructGetRequestPacket(
6333 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi7f1d9212018-06-22 23:24:366334 socket_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:336335 ASYNC,
6336 ConstructOkResponsePacket(
6337 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shi7f1d9212018-06-22 23:24:366338 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:336339 socket_data2.AddWrite(
6340 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
6341 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
6342 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi7f1d9212018-06-22 23:24:366343 socket_data2.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:226344
6345 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456346 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336347 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036348 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:526349 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
6350 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036351 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6352 failed_on_default_network_callback_, callback_.callback()));
jri9f303712016-09-13 01:10:226353 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246354 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:226355 EXPECT_TRUE(stream.get());
6356
6357 // Cause QUIC stream to be created.
6358 HttpRequestInfo request_info;
6359 request_info.method = "GET";
6360 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396361 request_info.traffic_annotation =
6362 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276363 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396364 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:226365
6366 // Ensure that session is alive and active.
6367 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6368 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6369 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6370
Zhongyi Shi7f1d9212018-06-22 23:24:366371 // Send GET request on stream.
6372 // This should encounter a write error on network 1,
6373 // then migrate to network 2, which encounters another write error,
6374 // and migrate again to network 1, which encoutners one more write error.
6375 // Finally the session migrates to network 2 successfully.
jri9f303712016-09-13 01:10:226376 HttpResponseInfo response;
6377 HttpRequestHeaders request_headers;
6378 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6379 callback_.callback()));
jri9f303712016-09-13 01:10:226380
jri9f303712016-09-13 01:10:226381 base::RunLoop().RunUntilIdle();
Zhongyi Shi7f1d9212018-06-22 23:24:366382 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6383 EXPECT_EQ(1u, session->GetNumActiveStreams());
jri9f303712016-09-13 01:10:226384
Zhongyi Shi7f1d9212018-06-22 23:24:366385 // Verify that response headers on the migrated socket were delivered to the
6386 // stream.
6387 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6388 EXPECT_EQ(200, response.headers->response_code());
jri9f303712016-09-13 01:10:226389
6390 stream.reset();
Zhongyi Shi7f1d9212018-06-22 23:24:366391 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6392 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6393 EXPECT_TRUE(failed_quic_data2.AllReadDataConsumed());
6394 EXPECT_TRUE(failed_quic_data2.AllWriteDataConsumed());
6395 EXPECT_TRUE(failed_quic_data1.AllReadDataConsumed());
6396 EXPECT_TRUE(failed_quic_data1.AllWriteDataConsumed());
6397 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
6398 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
jri9f303712016-09-13 01:10:226399}
6400
6401TEST_P(QuicStreamFactoryTest, MigrateSessionOnMultipleWriteErrorsSyncSync) {
Zhongyi Shi7f1d9212018-06-22 23:24:366402 TestMigrationOnMultipleWriteErrors(
6403 /*write_error_mode_on_old_network*/ SYNCHRONOUS,
6404 /*write_error_mode_on_new_network*/ SYNCHRONOUS);
jri9f303712016-09-13 01:10:226405}
6406
6407TEST_P(QuicStreamFactoryTest, MigrateSessionOnMultipleWriteErrorsSyncAsync) {
Zhongyi Shi7f1d9212018-06-22 23:24:366408 TestMigrationOnMultipleWriteErrors(
6409 /*write_error_mode_on_old_network*/ SYNCHRONOUS,
6410 /*write_error_mode_on_new_network*/ ASYNC);
jri9f303712016-09-13 01:10:226411}
6412
6413TEST_P(QuicStreamFactoryTest, MigrateSessionOnMultipleWriteErrorsAsyncSync) {
Zhongyi Shi7f1d9212018-06-22 23:24:366414 TestMigrationOnMultipleWriteErrors(
6415 /*write_error_mode_on_old_network*/ ASYNC,
6416 /*write_error_mode_on_new_network*/ SYNCHRONOUS);
jri9f303712016-09-13 01:10:226417}
6418
6419TEST_P(QuicStreamFactoryTest, MigrateSessionOnMultipleWriteErrorsAsyncAsync) {
Zhongyi Shi7f1d9212018-06-22 23:24:366420 TestMigrationOnMultipleWriteErrors(
6421 /*write_error_mode_on_old_network*/ ASYNC,
6422 /*write_error_mode_on_new_network*/ ASYNC);
jri9f303712016-09-13 01:10:226423}
6424
Zhongyi Shi6abe33812018-07-24 19:43:116425// Verifies that a connection is closed when connection migration is triggered
6426// on network being disconnected and the handshake is not confirmed.
6427TEST_P(QuicStreamFactoryTest, NoMigrationBeforeHandshakeOnNetworkDisconnected) {
6428 InitializeConnectionMigrationV2Test(
6429 {kDefaultNetworkForTests, kNewNetworkForTests});
6430
Zhongyi Shi879659422018-08-02 17:58:256431 // Use cold start mode to do crypto connect, and send CHLO packet on wire.
Zhongyi Shi6abe33812018-07-24 19:43:116432 crypto_client_stream_factory_.set_handshake_mode(
Zhongyi Shi879659422018-08-02 17:58:256433 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
Zhongyi Shi6abe33812018-07-24 19:43:116434
Ryan Hamiltonabad59e2019-06-06 04:02:596435 MockQuicData socket_data(version_);
Zhongyi Shi879659422018-08-02 17:58:256436 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5068bb02018-08-03 02:44:096437 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
Zhongyi Shi6abe33812018-07-24 19:43:116438 socket_data.AddSocketDataToFactory(socket_factory_.get());
6439
6440 // Create request and QuicHttpStream.
6441 QuicStreamRequest request(factory_.get());
6442 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036443 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:526444 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
6445 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036446 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6447 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi6abe33812018-07-24 19:43:116448 // Deliver the network notification, which should cause the connection to be
6449 // closed.
6450 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6451 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
6452 EXPECT_EQ(ERR_NETWORK_CHANGED, callback_.WaitForResult());
Zhongyi Shi4293b142018-07-25 00:33:576453
Zhongyi Shi6abe33812018-07-24 19:43:116454 EXPECT_FALSE(HasActiveSession(host_port_pair_));
6455 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
Zhongyi Shi4293b142018-07-25 00:33:576456 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6457 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
Zhongyi Shi6abe33812018-07-24 19:43:116458}
6459
Zhongyi Shib24001c02018-06-18 20:01:526460// Sets up the connection migration test where network change notification is
6461// queued BEFORE connection migration attempt on write error is posted.
6462void QuicStreamFactoryTestBase::
6463 TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
6464 bool disconnected) {
6465 InitializeConnectionMigrationV2Test(
jried79618b2016-07-02 03:18:526466 {kDefaultNetworkForTests, kNewNetworkForTests});
6467 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6468 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6469 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6470
Ryan Hamiltonabad59e2019-06-06 04:02:596471 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:366472 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:026473 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
rcha00569732016-08-27 11:09:366474 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:176475 socket_data.AddSocketDataToFactory(socket_factory_.get());
jried79618b2016-07-02 03:18:526476
6477 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456478 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336479 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036480 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:526481 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
6482 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036483 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6484 failed_on_default_network_callback_, callback_.callback()));
jried79618b2016-07-02 03:18:526485 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246486 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jried79618b2016-07-02 03:18:526487 EXPECT_TRUE(stream.get());
6488
6489 // Cause QUIC stream to be created.
6490 HttpRequestInfo request_info;
6491 request_info.method = "GET";
6492 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396493 request_info.traffic_annotation =
6494 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276495 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396496 net_log_, CompletionOnceCallback()));
jried79618b2016-07-02 03:18:526497
6498 // Ensure that session is alive and active.
6499 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6500 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6501 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6502
6503 // Set up second socket data provider that is used after
6504 // migration. The request is rewritten to this new socket, and the
6505 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:596506 MockQuicData socket_data1(version_);
Fan Yang32c5a112018-12-10 20:06:336507 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:026508 SYNCHRONOUS,
6509 ConstructGetRequestPacket(
6510 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi32f2fd02018-04-16 18:23:436511 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:336512 ASYNC,
6513 ConstructOkResponsePacket(
6514 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
rcha00569732016-08-27 11:09:366515 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:336516 socket_data1.AddWrite(
6517 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
6518 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
6519 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:176520 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jried79618b2016-07-02 03:18:526521
jri9f303712016-09-13 01:10:226522 // First queue a network change notification in the message loop.
6523 if (disconnected) {
6524 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6525 ->QueueNetworkDisconnected(kDefaultNetworkForTests);
6526 } else {
6527 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6528 ->QueueNetworkMadeDefault(kNewNetworkForTests);
6529 }
6530 // Send GET request on stream. This should cause a write error,
6531 // which triggers a connection migration attempt. This will queue a
6532 // migration attempt behind the notification in the message loop.
jried79618b2016-07-02 03:18:526533 HttpResponseInfo response;
6534 HttpRequestHeaders request_headers;
6535 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6536 callback_.callback()));
6537
jried79618b2016-07-02 03:18:526538 base::RunLoop().RunUntilIdle();
Zhongyi Shia7dd46b2018-07-12 22:59:296539 // Verify the session is still alive and not marked as going away post
6540 // migration.
jried79618b2016-07-02 03:18:526541 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:296542 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jried79618b2016-07-02 03:18:526543 EXPECT_EQ(1u, session->GetNumActiveStreams());
6544
6545 // Verify that response headers on the migrated socket were delivered to the
6546 // stream.
6547 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6548 EXPECT_EQ(200, response.headers->response_code());
6549
6550 stream.reset();
6551
6552 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6553 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6554 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6555 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6556}
6557
Zhongyi Shib24001c02018-06-18 20:01:526558// This test verifies that session attempts connection migration successfully
6559// with signals delivered in the following order (alternate network is always
6560// available):
6561// - a notification that default network is disconnected is queued.
6562// - write error is triggered: session posts a task to attempt connection
6563// migration, |migration_pending_| set to true.
6564// - default network disconnected is delivered: session immediately migrates to
6565// the alternate network, |migration_pending_| set to false.
Zhongyi Shif3d6cddb2018-07-11 03:30:026566// - connection migration on write error attempt aborts: writer encountered
6567// error is no longer in active use.
jri9f303712016-09-13 01:10:226568TEST_P(QuicStreamFactoryTest,
Zhongyi Shib24001c02018-06-18 20:01:526569 MigrateOnNetworkDisconnectedWithWriteErrorQueuedLater) {
6570 TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
6571 /*disconnected=*/true);
jri9f303712016-09-13 01:10:226572}
6573
Zhongyi Shib24001c02018-06-18 20:01:526574// This test verifies that session attempts connection migration successfully
6575// with signals delivered in the following order (alternate network is always
6576// available):
6577// - a notification that alternate network is made default is queued.
6578// - write error is triggered: session posts a task to attempt connection
6579// migration, block future migrations.
6580// - new default notification is delivered: migrate back timer spins and task is
6581// posted to migrate to the new default network.
6582// - connection migration on write error attempt proceeds successfully: session
6583// is
6584// marked as going away, future migrations unblocked.
6585// - migrate back to default network task executed: session is already on the
6586// default network, no-op.
jri9f303712016-09-13 01:10:226587TEST_P(QuicStreamFactoryTest,
Zhongyi Shib24001c02018-06-18 20:01:526588 MigrateOnWriteErrorWithNetworkMadeDefaultQueuedEarlier) {
6589 TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
6590 /*disconnected=*/false);
jri9f303712016-09-13 01:10:226591}
6592
Zhongyi Shi1e2bc742018-06-16 02:06:076593// Sets up the connection migration test where network change notification is
6594// queued AFTER connection migration attempt on write error is posted.
6595void QuicStreamFactoryTestBase::
6596 TestMigrationOnWriteErrorWithNotificationQueuedLater(bool disconnected) {
Zhongyi Shi1a054612018-06-14 04:59:086597 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:226598 {kDefaultNetworkForTests, kNewNetworkForTests});
jried79618b2016-07-02 03:18:526599 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6600 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri9f303712016-09-13 01:10:226601 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jried79618b2016-07-02 03:18:526602
Ryan Hamiltonabad59e2019-06-06 04:02:596603 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:366604 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:026605 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
rcha00569732016-08-27 11:09:366606 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:176607 socket_data.AddSocketDataToFactory(socket_factory_.get());
jried79618b2016-07-02 03:18:526608
6609 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456610 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336611 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036612 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:526613 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
6614 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036615 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6616 failed_on_default_network_callback_, callback_.callback()));
jried79618b2016-07-02 03:18:526617 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246618 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jried79618b2016-07-02 03:18:526619 EXPECT_TRUE(stream.get());
6620
6621 // Cause QUIC stream to be created.
6622 HttpRequestInfo request_info;
6623 request_info.method = "GET";
6624 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396625 request_info.traffic_annotation =
6626 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276627 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396628 net_log_, CompletionOnceCallback()));
jried79618b2016-07-02 03:18:526629
6630 // Ensure that session is alive and active.
6631 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6632 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6633 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6634
jri9f303712016-09-13 01:10:226635 // Set up second socket data provider that is used after
6636 // migration. The request is rewritten to this new socket, and the
6637 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:596638 MockQuicData socket_data1(version_);
Fan Yang32c5a112018-12-10 20:06:336639 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:026640 SYNCHRONOUS,
6641 ConstructGetRequestPacket(
6642 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi32f2fd02018-04-16 18:23:436643 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:336644 ASYNC,
6645 ConstructOkResponsePacket(
6646 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
jri9f303712016-09-13 01:10:226647 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:336648 socket_data1.AddWrite(
6649 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
6650 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
6651 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:176652 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:226653
6654 // Send GET request on stream. This should cause a write error,
6655 // which triggers a connection migration attempt. This will queue a
6656 // migration attempt in the message loop.
jried79618b2016-07-02 03:18:526657 HttpResponseInfo response;
6658 HttpRequestHeaders request_headers;
jri9f303712016-09-13 01:10:226659 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6660 callback_.callback()));
jried79618b2016-07-02 03:18:526661
jri9f303712016-09-13 01:10:226662 // Now queue a network change notification in the message loop behind
6663 // the migration attempt.
6664 if (disconnected) {
6665 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6666 ->QueueNetworkDisconnected(kDefaultNetworkForTests);
6667 } else {
6668 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6669 ->QueueNetworkMadeDefault(kNewNetworkForTests);
6670 }
6671
6672 base::RunLoop().RunUntilIdle();
Zhongyi Shia7dd46b2018-07-12 22:59:296673 // Verify session is still alive and not marked as going away.
jri9f303712016-09-13 01:10:226674 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:296675 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri9f303712016-09-13 01:10:226676 EXPECT_EQ(1u, session->GetNumActiveStreams());
6677
6678 // Verify that response headers on the migrated socket were delivered to the
6679 // stream.
6680 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6681 EXPECT_EQ(200, response.headers->response_code());
6682
6683 stream.reset();
jried79618b2016-07-02 03:18:526684
6685 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6686 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
jri9f303712016-09-13 01:10:226687 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6688 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
jried79618b2016-07-02 03:18:526689}
6690
Zhongyi Shi1e2bc742018-06-16 02:06:076691// This test verifies that session attempts connection migration successfully
6692// with signals delivered in the following order (alternate network is always
6693// available):
6694// - write error is triggered: session posts a task to complete connection
6695// migration.
6696// - a notification that alternate network is made default is queued.
6697// - connection migration attempt proceeds successfully, session is marked as
6698// going away.
6699// - new default notification is delivered after connection migration has been
6700// completed.
jri9f303712016-09-13 01:10:226701TEST_P(QuicStreamFactoryTest,
Zhongyi Shi1e2bc742018-06-16 02:06:076702 MigrateOnWriteErrorWithNetworkMadeDefaultQueuedLater) {
6703 TestMigrationOnWriteErrorWithNotificationQueuedLater(/*disconnected=*/false);
jried79618b2016-07-02 03:18:526704}
6705
Zhongyi Shi1e2bc742018-06-16 02:06:076706// This test verifies that session attempts connection migration successfully
6707// with signals delivered in the following order (alternate network is always
6708// available):
6709// - write error is triggered: session posts a task to complete connection
6710// migration.
6711// - a notification that default network is diconnected is queued.
6712// - connection migration attempt proceeds successfully, session is marked as
6713// going away.
6714// - disconnect notification is delivered after connection migration has been
6715// completed.
jri9f303712016-09-13 01:10:226716TEST_P(QuicStreamFactoryTest,
Zhongyi Shi1e2bc742018-06-16 02:06:076717 MigrateOnWriteErrorWithNetworkDisconnectedQueuedLater) {
6718 TestMigrationOnWriteErrorWithNotificationQueuedLater(/*disconnected=*/true);
jried79618b2016-07-02 03:18:526719}
6720
Zhongyi Shia3810c52018-06-15 23:07:196721// This tests connection migration on write error with signals delivered in the
6722// following order:
6723// - a synchronous/asynchronous write error is triggered base on
Zhongyi Shif3d6cddb2018-07-11 03:30:026724// |write_error_mode|: connection migration attempt is posted.
6725// - old default network disconnects, migration waits for a new network.
Zhongyi Shia3810c52018-06-15 23:07:196726// - after a pause, new network is connected: session will migrate to new
6727// network immediately.
Zhongyi Shif3d6cddb2018-07-11 03:30:026728// - migration on writer error is exectued and aborts as writer passed in is no
6729// longer active in use.
Zhongyi Shia3810c52018-06-15 23:07:196730// - new network is made default.
jri5b785512016-09-13 04:29:116731void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorPauseBeforeConnected(
6732 IoMode write_error_mode) {
Zhongyi Shia3810c52018-06-15 23:07:196733 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri5b785512016-09-13 04:29:116734 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6735 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6736 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6737
Zhongyi Shia3810c52018-06-15 23:07:196738 // Use the test task runner.
6739 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
6740
Ryan Hamiltonabad59e2019-06-06 04:02:596741 MockQuicData socket_data(version_);
Zhongyi Shia3810c52018-06-15 23:07:196742 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
Ryan Hamilton0d65a8c2019-06-07 00:46:026743 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shia3810c52018-06-15 23:07:196744 socket_data.AddWrite(write_error_mode, ERR_FAILED);
Zhongyi Shi5f587cc2017-11-21 23:24:176745 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri5b785512016-09-13 04:29:116746
6747 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456748 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336749 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036750 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:526751 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
6752 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036753 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6754 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shia3810c52018-06-15 23:07:196755 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:246756 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri5b785512016-09-13 04:29:116757 EXPECT_TRUE(stream.get());
6758
6759 // Cause QUIC stream to be created.
6760 HttpRequestInfo request_info;
6761 request_info.method = "GET";
Zhongyi Shia3810c52018-06-15 23:07:196762 request_info.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:396763 request_info.traffic_annotation =
6764 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276765 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396766 net_log_, CompletionOnceCallback()));
jri5b785512016-09-13 04:29:116767
6768 // Ensure that session is alive and active.
6769 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6770 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6771 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6772
Zhongyi Shia3810c52018-06-15 23:07:196773 // Send GET request on stream.
jri5b785512016-09-13 04:29:116774 HttpResponseInfo response;
6775 HttpRequestHeaders request_headers;
6776 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6777 callback_.callback()));
6778
Zhongyi Shia3810c52018-06-15 23:07:196779 // The connection should still be alive, not marked as going away.
jri5b785512016-09-13 04:29:116780 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6781 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6782 EXPECT_EQ(1u, session->GetNumActiveStreams());
6783 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
6784
Zhongyi Shia3810c52018-06-15 23:07:196785 // Set up second socket data provider that is used after migration.
6786 // The response to the earlier request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:596787 MockQuicData socket_data1(version_);
Fan Yang32c5a112018-12-10 20:06:336788 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:026789 SYNCHRONOUS,
6790 ConstructGetRequestPacket(
6791 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi32f2fd02018-04-16 18:23:436792 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:336793 ASYNC,
6794 ConstructOkResponsePacket(
6795 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
jri5b785512016-09-13 04:29:116796 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:336797 socket_data1.AddWrite(
6798 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
6799 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
6800 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:176801 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri5b785512016-09-13 04:29:116802
Zhongyi Shia3810c52018-06-15 23:07:196803 // On a DISCONNECTED notification, nothing happens.
6804 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6805 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
6806 // Add a new network and notify the stream factory of a new connected network.
6807 // This causes a PING packet to be sent over the new network.
jri5b785512016-09-13 04:29:116808 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6809 ->SetConnectedNetworksList({kNewNetworkForTests});
6810 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6811 ->NotifyNetworkConnected(kNewNetworkForTests);
6812
Zhongyi Shia3810c52018-06-15 23:07:196813 // Ensure that the session is still alive.
jri5b785512016-09-13 04:29:116814 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia3810c52018-06-15 23:07:196815 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:116816 EXPECT_EQ(1u, session->GetNumActiveStreams());
6817
Zhongyi Shia3810c52018-06-15 23:07:196818 // Run the message loop migration for write error can finish.
6819 runner_->RunUntilIdle();
6820
6821 // Response headers are received over the new network.
jri5b785512016-09-13 04:29:116822 EXPECT_THAT(callback_.WaitForResult(), IsOk());
6823 EXPECT_EQ(200, response.headers->response_code());
6824
Zhongyi Shia3810c52018-06-15 23:07:196825 // Check that the session is still alive.
6826 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
jri5b785512016-09-13 04:29:116827 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shia3810c52018-06-15 23:07:196828
6829 // There should be no posted tasks not executed, no way to migrate back to
6830 // default network.
6831 EXPECT_TRUE(runner_->GetPostedTasks().empty());
6832
6833 // Receive signal to mark new network as default.
6834 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6835 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri5b785512016-09-13 04:29:116836
6837 stream.reset();
jri5b785512016-09-13 04:29:116838 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6839 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6840 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6841 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
jri5b785512016-09-13 04:29:116842}
6843
6844TEST_P(QuicStreamFactoryTest,
Zhongyi Shia3810c52018-06-15 23:07:196845 MigrateSessionOnSyncWriteErrorPauseBeforeConnected) {
jri5b785512016-09-13 04:29:116846 TestMigrationOnWriteErrorPauseBeforeConnected(SYNCHRONOUS);
6847}
6848
6849TEST_P(QuicStreamFactoryTest,
Zhongyi Shia3810c52018-06-15 23:07:196850 MigrateSessionOnAsyncWriteErrorPauseBeforeConnected) {
jri5b785512016-09-13 04:29:116851 TestMigrationOnWriteErrorPauseBeforeConnected(ASYNC);
6852}
6853
Zhongyi Shif3d6cddb2018-07-11 03:30:026854// This test verifies that when session successfully migrate to the alternate
6855// network, packet write error on the old writer will be ignored and will not
6856// trigger connection migration on write error.
6857TEST_P(QuicStreamFactoryTest, IgnoreWriteErrorFromOldWriterAfterMigration) {
6858 InitializeConnectionMigrationV2Test(
6859 {kDefaultNetworkForTests, kNewNetworkForTests});
6860 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6861 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6862 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6863
6864 // Using a testing task runner so that we can verify whether the migrate on
6865 // write error task is posted.
6866 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
6867 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
6868
Ryan Hamiltonabad59e2019-06-06 04:02:596869 MockQuicData socket_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:026870 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shif3d6cddb2018-07-11 03:30:026871 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
Ryan Hamilton9f2eac32019-06-27 03:15:546872 socket_data.AddWrite(
6873 ASYNC, ERR_ADDRESS_UNREACHABLE,
6874 ConstructGetRequestPacket(
6875 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shif3d6cddb2018-07-11 03:30:026876 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6877 socket_data.AddSocketDataToFactory(socket_factory_.get());
6878
6879 // Create request and QuicHttpStream.
6880 QuicStreamRequest request(factory_.get());
6881 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036882 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:526883 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
6884 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036885 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6886 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shif3d6cddb2018-07-11 03:30:026887 EXPECT_EQ(OK, callback_.WaitForResult());
6888 std::unique_ptr<HttpStream> stream = CreateStream(&request);
6889 EXPECT_TRUE(stream.get());
6890
6891 // Cause QUIC stream to be created.
6892 HttpRequestInfo request_info;
6893 request_info.method = "GET";
6894 request_info.url = GURL("https://www.example.org/");
6895 request_info.traffic_annotation =
6896 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6897 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
6898 net_log_, CompletionOnceCallback()));
6899
6900 // Ensure that session is alive and active.
6901 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6902 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6903 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6904
6905 // Set up second socket data provider that is used after
6906 // migration. The response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:596907 MockQuicData socket_data1(version_);
Zhongyi Shif3d6cddb2018-07-11 03:30:026908 socket_data1.AddWrite(
6909 SYNCHRONOUS, client_maker_.MakePingPacket(3, /*include_version=*/true));
6910 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:336911 ASYNC,
6912 ConstructOkResponsePacket(
6913 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shif3d6cddb2018-07-11 03:30:026914 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:336915 socket_data1.AddWrite(
6916 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
6917 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
6918 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shif3d6cddb2018-07-11 03:30:026919 socket_data1.AddSocketDataToFactory(socket_factory_.get());
6920
6921 // Send GET request on stream.
6922 HttpResponseInfo response;
6923 HttpRequestHeaders request_headers;
6924 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6925 callback_.callback()));
6926
6927 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
6928 // Now notify network is disconnected, cause the migration to complete
6929 // immediately.
6930 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6931 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
6932 // There will be two pending task, one will complete migration with no delay
6933 // and the other will attempt to migrate back to the default network with
6934 // delay.
6935 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
6936
6937 // Complete migration.
6938 task_runner->RunUntilIdle();
6939 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
6940
6941 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6942 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6943 EXPECT_EQ(1u, session->GetNumActiveStreams());
6944
6945 // Verify that response headers on the migrated socket were delivered to the
6946 // stream.
6947 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6948 EXPECT_EQ(200, response.headers->response_code());
6949
6950 // Resume the old socket data, a write error will be delivered to the old
6951 // packet writer. Verify no additional task is posted.
6952 socket_data.Resume();
6953 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
6954
6955 stream.reset();
6956 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6957 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6958 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6959}
6960
6961// This test verifies that when session successfully migrate to the alternate
6962// network, packet read error on the old reader will be ignored and will not
6963// close the connection.
6964TEST_P(QuicStreamFactoryTest, IgnoreReadErrorFromOldReaderAfterMigration) {
6965 InitializeConnectionMigrationV2Test(
6966 {kDefaultNetworkForTests, kNewNetworkForTests});
6967 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6968 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6969 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6970
6971 // Using a testing task runner.
6972 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
6973 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
6974
Ryan Hamiltonabad59e2019-06-06 04:02:596975 MockQuicData socket_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:026976 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shif3d6cddb2018-07-11 03:30:026977 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
6978 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE);
6979 socket_data.AddSocketDataToFactory(socket_factory_.get());
6980
6981 // Create request and QuicHttpStream.
6982 QuicStreamRequest request(factory_.get());
6983 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036984 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:526985 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
6986 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036987 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6988 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shif3d6cddb2018-07-11 03:30:026989 EXPECT_EQ(OK, callback_.WaitForResult());
6990 std::unique_ptr<HttpStream> stream = CreateStream(&request);
6991 EXPECT_TRUE(stream.get());
6992
6993 // Cause QUIC stream to be created.
6994 HttpRequestInfo request_info;
6995 request_info.method = "GET";
6996 request_info.url = GURL("https://www.example.org/");
6997 request_info.traffic_annotation =
6998 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6999 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7000 net_log_, CompletionOnceCallback()));
7001
7002 // Ensure that session is alive and active.
7003 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7004 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7005 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7006
7007 // Set up second socket data provider that is used after
7008 // migration. The request is written to this new socket, and the
7009 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:597010 MockQuicData socket_data1(version_);
Zhongyi Shif3d6cddb2018-07-11 03:30:027011 socket_data1.AddWrite(
7012 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
Fan Yang32c5a112018-12-10 20:06:337013 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027014 SYNCHRONOUS,
7015 ConstructGetRequestPacket(
7016 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shif3d6cddb2018-07-11 03:30:027017 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337018 ASYNC,
7019 ConstructOkResponsePacket(
7020 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shif3d6cddb2018-07-11 03:30:027021 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:337022 socket_data1.AddWrite(
7023 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
7024 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
7025 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shif3d6cddb2018-07-11 03:30:027026 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7027
7028 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
7029 // Now notify network is disconnected, cause the migration to complete
7030 // immediately.
7031 scoped_mock_network_change_notifier_->mock_network_change_notifier()
7032 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
7033 // There will be two pending task, one will complete migration with no delay
7034 // and the other will attempt to migrate back to the default network with
7035 // delay.
7036 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
7037
7038 // Complete migration.
7039 task_runner->RunUntilIdle();
7040 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
7041
7042 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7043 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7044 EXPECT_EQ(1u, session->GetNumActiveStreams());
7045
7046 // Send GET request on stream.
7047 HttpResponseInfo response;
7048 HttpRequestHeaders request_headers;
7049 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7050 callback_.callback()));
7051
7052 // Verify that response headers on the migrated socket were delivered to the
7053 // stream.
7054 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
7055 EXPECT_EQ(OK, callback_.WaitForResult());
7056 EXPECT_EQ(200, response.headers->response_code());
7057
7058 // Resume the old socket data, a read error will be delivered to the old
7059 // packet reader. Verify that the session is not affected.
7060 socket_data.Resume();
7061 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
7062 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7063 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7064 EXPECT_EQ(1u, session->GetNumActiveStreams());
7065
7066 stream.reset();
7067 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7068 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7069 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7070 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7071}
7072
7073// This test verifies that after migration on network is executed, packet
7074// read error on the old reader will be ignored and will not close the
7075// connection.
7076TEST_P(QuicStreamFactoryTest, IgnoreReadErrorOnOldReaderDuringMigration) {
7077 InitializeConnectionMigrationV2Test(
7078 {kDefaultNetworkForTests, kNewNetworkForTests});
7079 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7080 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7081 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7082
7083 // Using a testing task runner.
7084 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7085 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7086
Ryan Hamiltonabad59e2019-06-06 04:02:597087 MockQuicData socket_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027088 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shif3d6cddb2018-07-11 03:30:027089 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
7090 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE);
7091 socket_data.AddSocketDataToFactory(socket_factory_.get());
7092
7093 // Create request and QuicHttpStream.
7094 QuicStreamRequest request(factory_.get());
7095 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:037096 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:527097 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
7098 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:037099 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7100 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shif3d6cddb2018-07-11 03:30:027101 EXPECT_EQ(OK, callback_.WaitForResult());
7102 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7103 EXPECT_TRUE(stream.get());
7104
7105 // Cause QUIC stream to be created.
7106 HttpRequestInfo request_info;
7107 request_info.method = "GET";
7108 request_info.url = GURL("https://www.example.org/");
7109 request_info.traffic_annotation =
7110 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7111 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7112 net_log_, CompletionOnceCallback()));
7113
7114 // Ensure that session is alive and active.
7115 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7116 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7117 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7118
7119 // Set up second socket data provider that is used after
7120 // migration. The request is written to this new socket, and the
7121 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:597122 MockQuicData socket_data1(version_);
Zhongyi Shif3d6cddb2018-07-11 03:30:027123 socket_data1.AddWrite(
7124 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
Fan Yang32c5a112018-12-10 20:06:337125 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027126 SYNCHRONOUS,
7127 ConstructGetRequestPacket(
7128 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shif3d6cddb2018-07-11 03:30:027129 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337130 ASYNC,
7131 ConstructOkResponsePacket(
7132 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shif3d6cddb2018-07-11 03:30:027133 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:337134 socket_data1.AddWrite(
7135 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
7136 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
7137 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shif3d6cddb2018-07-11 03:30:027138 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7139
7140 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
7141 // Now notify network is disconnected, cause the migration to complete
7142 // immediately.
7143 scoped_mock_network_change_notifier_->mock_network_change_notifier()
7144 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
7145 // There will be two pending task, one will complete migration with no delay
7146 // and the other will attempt to migrate back to the default network with
7147 // delay.
7148 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
7149
7150 // Resume the old socket data, a read error will be delivered to the old
7151 // packet reader. Verify that the session is not affected.
7152 socket_data.Resume();
7153 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
7154 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7155 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7156 EXPECT_EQ(1u, session->GetNumActiveStreams());
7157
7158 // Complete migration.
7159 task_runner->RunUntilIdle();
7160 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
7161
7162 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7163 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7164 EXPECT_EQ(1u, session->GetNumActiveStreams());
7165
7166 // Send GET request on stream.
7167 HttpResponseInfo response;
7168 HttpRequestHeaders request_headers;
7169 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7170 callback_.callback()));
7171
7172 // Verify that response headers on the migrated socket were delivered to the
7173 // stream.
7174 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
7175 EXPECT_EQ(OK, callback_.WaitForResult());
7176 EXPECT_EQ(200, response.headers->response_code());
7177
7178 stream.reset();
Zhongyi Shi99d0cdd2019-05-21 01:18:427179 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7180 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7181 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7182}
7183
7184// This test verifies that when connection migration on path degrading is
7185// enabled, and no custom retransmittable on wire timeout is specified, the
7186// default value is used.
7187TEST_P(QuicStreamFactoryTest, DefaultRetransmittableOnWireTimeoutForMigration) {
7188 InitializeConnectionMigrationV2Test(
7189 {kDefaultNetworkForTests, kNewNetworkForTests});
7190 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7191 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7192 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7193
7194 // Using a testing task runner.
7195 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7196 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7197 QuicStreamFactoryPeer::SetAlarmFactory(
7198 factory_.get(),
7199 std::make_unique<QuicChromiumAlarmFactory>(task_runner.get(), &clock_));
7200
Ryan Hamiltonabad59e2019-06-06 04:02:597201 MockQuicData socket_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027202 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi99d0cdd2019-05-21 01:18:427203 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
7204 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE);
7205 socket_data.AddSocketDataToFactory(socket_factory_.get());
7206
7207 // Set up second socket data provider that is used after
7208 // migration. The request is written to this new socket, and the
7209 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:597210 MockQuicData socket_data1(version_);
Zhongyi Shi99d0cdd2019-05-21 01:18:427211 // The PING packet sent post migration.
7212 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(2, true));
7213 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027214 SYNCHRONOUS,
7215 ConstructGetRequestPacket(
7216 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi99d0cdd2019-05-21 01:18:427217 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7218 // Read two packets so that client will send ACK immedaitely.
Ryan Hamilton9f2eac32019-06-27 03:15:547219 socket_data1.AddRead(
7220 ASYNC,
7221 ConstructOkResponsePacket(
7222 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
7223 socket_data1.AddRead(
7224 ASYNC, server_maker_.MakeDataPacket(
7225 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7226 base::StringPiece("Hello World")));
7227
Zhongyi Shi99d0cdd2019-05-21 01:18:427228 // Read an ACK from server which acks all client data.
7229 socket_data1.AddRead(SYNCHRONOUS,
7230 server_maker_.MakeAckPacket(3, 3, 1, 1, false));
7231 socket_data1.AddWrite(ASYNC, client_maker_.MakeAckPacket(4, 2, 1, 1, false));
7232 // The PING packet sent for retransmittable on wire.
7233 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(5, false));
7234 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7235 std::string header = ConstructDataHeader(6);
7236 socket_data1.AddRead(
7237 ASYNC, ConstructServerDataPacket(
7238 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177239 header + "hello!"));
Zhongyi Shi99d0cdd2019-05-21 01:18:427240 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read.
7241 socket_data1.AddWrite(
7242 SYNCHRONOUS, client_maker_.MakeRstPacket(
7243 6, false, GetNthClientInitiatedBidirectionalStreamId(0),
7244 quic::QUIC_STREAM_CANCELLED));
7245 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7246
7247 // Create request and QuicHttpStream.
7248 QuicStreamRequest request(factory_.get());
7249 EXPECT_EQ(ERR_IO_PENDING,
7250 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:527251 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
7252 SocketTag(), NetworkIsolationKey(),
Zhongyi Shi99d0cdd2019-05-21 01:18:427253 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7254 failed_on_default_network_callback_, callback_.callback()));
7255 EXPECT_EQ(OK, callback_.WaitForResult());
7256 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7257 EXPECT_TRUE(stream.get());
7258
7259 // Cause QUIC stream to be created.
7260 HttpRequestInfo request_info;
7261 request_info.method = "GET";
7262 request_info.url = GURL("https://www.example.org/");
7263 request_info.traffic_annotation =
7264 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7265 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7266 net_log_, CompletionOnceCallback()));
7267
7268 // Ensure that session is alive and active.
7269 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7270 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7271
7272 // Now notify network is disconnected, cause the migration to complete
7273 // immediately.
7274 scoped_mock_network_change_notifier_->mock_network_change_notifier()
7275 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
7276
7277 // Complete migration.
7278 task_runner->RunUntilIdle();
7279 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7280 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7281 EXPECT_EQ(1u, session->GetNumActiveStreams());
7282
7283 // Send GET request on stream.
7284 HttpResponseInfo response;
7285 HttpRequestHeaders request_headers;
7286 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7287 callback_.callback()));
7288 socket_data1.Resume();
7289 // Spin up the message loop to read incoming data from server till the ACK.
7290 base::RunLoop().RunUntilIdle();
7291
7292 // Ack delay time.
7293 int delay = task_runner->NextPendingTaskDelay().InMilliseconds();
7294 EXPECT_GT(kDefaultRetransmittableOnWireTimeoutMillisecs, delay);
7295 // Fire the ack alarm, since ack has been sent, no ack will be sent.
7296 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7297 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7298
7299 // Fire the ping alarm with retransmittable-on-wire timeout, send PING.
7300 delay = kDefaultRetransmittableOnWireTimeoutMillisecs - delay;
7301 EXPECT_EQ(base::TimeDelta::FromMilliseconds(delay),
7302 task_runner->NextPendingTaskDelay());
7303 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7304 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7305
7306 socket_data1.Resume();
7307
7308 // Verify that response headers on the migrated socket were delivered to the
7309 // stream.
7310 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
7311 EXPECT_EQ(200, response.headers->response_code());
7312
7313 // Resume the old socket data, a read error will be delivered to the old
7314 // packet reader. Verify that the session is not affected.
7315 socket_data.Resume();
7316 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7317 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7318 EXPECT_EQ(1u, session->GetNumActiveStreams());
7319
7320 stream.reset();
Zhongyi Shif3d6cddb2018-07-11 03:30:027321 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7322 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7323 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7324 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7325}
7326
Zhongyi Shi99d0cdd2019-05-21 01:18:427327// This test verifies that when connection migration on path degrading is
7328// enabled, and a custom retransmittable on wire timeout is specified, the
7329// custom value is used.
7330TEST_P(QuicStreamFactoryTest, CustomRetransmittableOnWireTimeoutForMigration) {
7331 int custom_timeout_value = 200;
7332 test_params_.quic_retransmittable_on_wire_timeout_milliseconds =
7333 custom_timeout_value;
7334 InitializeConnectionMigrationV2Test(
7335 {kDefaultNetworkForTests, kNewNetworkForTests});
7336 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7337 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7338 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7339
7340 // Using a testing task runner.
7341 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7342 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7343 QuicStreamFactoryPeer::SetAlarmFactory(
7344 factory_.get(),
7345 std::make_unique<QuicChromiumAlarmFactory>(task_runner.get(), &clock_));
7346
Ryan Hamiltonabad59e2019-06-06 04:02:597347 MockQuicData socket_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027348 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi99d0cdd2019-05-21 01:18:427349 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
7350 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE);
7351 socket_data.AddSocketDataToFactory(socket_factory_.get());
7352
7353 // Set up second socket data provider that is used after
7354 // migration. The request is written to this new socket, and the
7355 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:597356 MockQuicData socket_data1(version_);
Zhongyi Shi99d0cdd2019-05-21 01:18:427357 // The PING packet sent post migration.
7358 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(2, true));
7359 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027360 SYNCHRONOUS,
7361 ConstructGetRequestPacket(
7362 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi99d0cdd2019-05-21 01:18:427363 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7364 // Read two packets so that client will send ACK immedaitely.
Ryan Hamilton9f2eac32019-06-27 03:15:547365 socket_data1.AddRead(
7366 ASYNC,
7367 ConstructOkResponsePacket(
7368 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
7369 socket_data1.AddRead(
7370 ASYNC, server_maker_.MakeDataPacket(
7371 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7372 base::StringPiece("Hello World")));
Zhongyi Shi99d0cdd2019-05-21 01:18:427373 // Read an ACK from server which acks all client data.
7374 socket_data1.AddRead(SYNCHRONOUS,
7375 server_maker_.MakeAckPacket(3, 3, 1, 1, false));
7376 socket_data1.AddWrite(ASYNC, client_maker_.MakeAckPacket(4, 2, 1, 1, false));
7377 // The PING packet sent for retransmittable on wire.
7378 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(5, false));
7379 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7380 std::string header = ConstructDataHeader(6);
7381 socket_data1.AddRead(
7382 ASYNC, ConstructServerDataPacket(
7383 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177384 header + "hello!"));
Zhongyi Shi99d0cdd2019-05-21 01:18:427385 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read.
7386 socket_data1.AddWrite(
7387 SYNCHRONOUS, client_maker_.MakeRstPacket(
7388 6, false, GetNthClientInitiatedBidirectionalStreamId(0),
7389 quic::QUIC_STREAM_CANCELLED));
7390 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7391
7392 // Create request and QuicHttpStream.
7393 QuicStreamRequest request(factory_.get());
7394 EXPECT_EQ(ERR_IO_PENDING,
7395 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:527396 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
7397 SocketTag(), NetworkIsolationKey(),
Zhongyi Shi99d0cdd2019-05-21 01:18:427398 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7399 failed_on_default_network_callback_, callback_.callback()));
7400 EXPECT_EQ(OK, callback_.WaitForResult());
7401 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7402 EXPECT_TRUE(stream.get());
7403
7404 // Cause QUIC stream to be created.
7405 HttpRequestInfo request_info;
7406 request_info.method = "GET";
7407 request_info.url = GURL("https://www.example.org/");
7408 request_info.traffic_annotation =
7409 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7410 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7411 net_log_, CompletionOnceCallback()));
7412
7413 // Ensure that session is alive and active.
7414 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7415 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7416
7417 // Now notify network is disconnected, cause the migration to complete
7418 // immediately.
7419 scoped_mock_network_change_notifier_->mock_network_change_notifier()
7420 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
7421
7422 // Complete migration.
7423 task_runner->RunUntilIdle();
7424 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7425 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7426 EXPECT_EQ(1u, session->GetNumActiveStreams());
7427
7428 // Send GET request on stream.
7429 HttpResponseInfo response;
7430 HttpRequestHeaders request_headers;
7431 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7432 callback_.callback()));
7433 socket_data1.Resume();
7434 // Spin up the message loop to read incoming data from server till the ACK.
7435 base::RunLoop().RunUntilIdle();
7436
7437 // Ack delay time.
7438 int delay = task_runner->NextPendingTaskDelay().InMilliseconds();
7439 EXPECT_GT(custom_timeout_value, delay);
7440 // Fire the ack alarm, since ack has been sent, no ack will be sent.
7441 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7442 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7443
7444 // Fire the ping alarm with retransmittable-on-wire timeout, send PING.
7445 delay = custom_timeout_value - delay;
7446 EXPECT_EQ(base::TimeDelta::FromMilliseconds(delay),
7447 task_runner->NextPendingTaskDelay());
7448 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7449 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7450
7451 socket_data1.Resume();
7452
7453 // Verify that response headers on the migrated socket were delivered to the
7454 // stream.
7455 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
7456 EXPECT_EQ(200, response.headers->response_code());
7457
7458 // Resume the old socket data, a read error will be delivered to the old
7459 // packet reader. Verify that the session is not affected.
7460 socket_data.Resume();
7461 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7462 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7463 EXPECT_EQ(1u, session->GetNumActiveStreams());
7464
7465 stream.reset();
7466 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7467 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7468 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7469 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7470}
7471
7472// This test verifies that when no migration is enabled, but a custom value for
7473// retransmittable-on-wire timeout is specified, the ping alarm is set up to
7474// send retransmittable pings with the custom value.
7475TEST_P(QuicStreamFactoryTest, CustomRetransmittableOnWireTimeout) {
7476 int custom_timeout_value = 200;
7477 test_params_.quic_retransmittable_on_wire_timeout_milliseconds =
7478 custom_timeout_value;
7479 Initialize();
7480 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7481 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7482 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7483
7484 // Using a testing task runner.
7485 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7486 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7487 QuicStreamFactoryPeer::SetAlarmFactory(
7488 factory_.get(),
7489 std::make_unique<QuicChromiumAlarmFactory>(task_runner.get(), &clock_));
7490
Ryan Hamiltonabad59e2019-06-06 04:02:597491 MockQuicData socket_data1(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027492 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi99d0cdd2019-05-21 01:18:427493 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027494 SYNCHRONOUS,
7495 ConstructGetRequestPacket(
7496 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi99d0cdd2019-05-21 01:18:427497 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7498 // Read two packets so that client will send ACK immedaitely.
Ryan Hamilton9f2eac32019-06-27 03:15:547499 socket_data1.AddRead(
7500 ASYNC,
7501 ConstructOkResponsePacket(
7502 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
7503 socket_data1.AddRead(
7504 ASYNC, server_maker_.MakeDataPacket(
7505 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7506 base::StringPiece("Hello World")));
Zhongyi Shi99d0cdd2019-05-21 01:18:427507 // Read an ACK from server which acks all client data.
7508 socket_data1.AddRead(SYNCHRONOUS,
7509 server_maker_.MakeAckPacket(3, 2, 1, 1, false));
7510 socket_data1.AddWrite(ASYNC, client_maker_.MakeAckPacket(3, 2, 1, 1, false));
7511 // The PING packet sent for retransmittable on wire.
7512 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(4, false));
7513 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7514 std::string header = ConstructDataHeader(6);
7515 socket_data1.AddRead(
7516 ASYNC, ConstructServerDataPacket(
7517 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177518 header + "hello!"));
Zhongyi Shi99d0cdd2019-05-21 01:18:427519 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read.
7520 socket_data1.AddWrite(
7521 SYNCHRONOUS, client_maker_.MakeRstPacket(
7522 5, false, GetNthClientInitiatedBidirectionalStreamId(0),
7523 quic::QUIC_STREAM_CANCELLED));
7524 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7525
7526 // Create request and QuicHttpStream.
7527 QuicStreamRequest request(factory_.get());
7528 EXPECT_EQ(ERR_IO_PENDING,
7529 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:527530 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
7531 SocketTag(), NetworkIsolationKey(),
Zhongyi Shi99d0cdd2019-05-21 01:18:427532 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7533 failed_on_default_network_callback_, callback_.callback()));
7534 EXPECT_EQ(OK, callback_.WaitForResult());
7535 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7536 EXPECT_TRUE(stream.get());
7537
7538 // Cause QUIC stream to be created.
7539 HttpRequestInfo request_info;
7540 request_info.method = "GET";
7541 request_info.url = GURL("https://www.example.org/");
7542 request_info.traffic_annotation =
7543 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7544 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7545 net_log_, CompletionOnceCallback()));
7546
7547 // Ensure that session is alive and active.
7548 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7549 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7550
7551 // Complete migration.
7552 task_runner->RunUntilIdle();
7553 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7554 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7555 EXPECT_EQ(1u, session->GetNumActiveStreams());
7556
7557 // Send GET request on stream.
7558 HttpResponseInfo response;
7559 HttpRequestHeaders request_headers;
7560 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7561 callback_.callback()));
7562 socket_data1.Resume();
7563 // Spin up the message loop to read incoming data from server till the ACK.
7564 base::RunLoop().RunUntilIdle();
7565
7566 // Ack delay time.
7567 int delay = task_runner->NextPendingTaskDelay().InMilliseconds();
7568 EXPECT_GT(custom_timeout_value, delay);
7569 // Fire the ack alarm, since ack has been sent, no ack will be sent.
7570 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7571 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7572
7573 // Fire the ping alarm with retransmittable-on-wire timeout, send PING.
7574 delay = custom_timeout_value - delay;
7575 EXPECT_EQ(base::TimeDelta::FromMilliseconds(delay),
7576 task_runner->NextPendingTaskDelay());
7577 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7578 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7579
7580 socket_data1.Resume();
7581
7582 // Verify that response headers on the migrated socket were delivered to the
7583 // stream.
7584 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
7585 EXPECT_EQ(200, response.headers->response_code());
7586
7587 // Resume the old socket data, a read error will be delivered to the old
7588 // packet reader. Verify that the session is not affected.
7589 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7590 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7591 EXPECT_EQ(1u, session->GetNumActiveStreams());
7592
7593 stream.reset();
7594 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7595 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7596}
7597
7598// This test verifies that when no migration is enabled, and no custom value
7599// for retransmittable-on-wire timeout is specified, the ping alarm will not
7600// send any retransmittable pings.
7601TEST_P(QuicStreamFactoryTest, NoRetransmittableOnWireTimeout) {
7602 Initialize();
7603 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7604 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7605 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7606
7607 // Using a testing task runner.
7608 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7609 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7610 QuicStreamFactoryPeer::SetAlarmFactory(
7611 factory_.get(),
7612 std::make_unique<QuicChromiumAlarmFactory>(task_runner.get(), &clock_));
7613
Ryan Hamiltonabad59e2019-06-06 04:02:597614 MockQuicData socket_data1(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027615 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi99d0cdd2019-05-21 01:18:427616 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027617 SYNCHRONOUS,
7618 ConstructGetRequestPacket(
7619 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi99d0cdd2019-05-21 01:18:427620 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7621 // Read two packets so that client will send ACK immedaitely.
Ryan Hamilton9f2eac32019-06-27 03:15:547622 socket_data1.AddRead(
7623 ASYNC,
7624 ConstructOkResponsePacket(
7625 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
7626 socket_data1.AddRead(
7627 ASYNC, server_maker_.MakeDataPacket(
7628 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7629 base::StringPiece("Hello World")));
Zhongyi Shi99d0cdd2019-05-21 01:18:427630 // Read an ACK from server which acks all client data.
7631 socket_data1.AddRead(SYNCHRONOUS,
7632 server_maker_.MakeAckPacket(3, 2, 1, 1, false));
7633 socket_data1.AddWrite(ASYNC, client_maker_.MakeAckPacket(3, 2, 1, 1, false));
7634 std::string header = ConstructDataHeader(6);
7635 socket_data1.AddRead(
7636 ASYNC, ConstructServerDataPacket(
7637 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177638 header + "hello!"));
Zhongyi Shi99d0cdd2019-05-21 01:18:427639 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read.
7640 socket_data1.AddWrite(
7641 SYNCHRONOUS, client_maker_.MakeRstPacket(
7642 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
7643 quic::QUIC_STREAM_CANCELLED));
7644 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7645
7646 // Create request and QuicHttpStream.
7647 QuicStreamRequest request(factory_.get());
7648 EXPECT_EQ(ERR_IO_PENDING,
7649 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:527650 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
7651 SocketTag(), NetworkIsolationKey(),
Zhongyi Shi99d0cdd2019-05-21 01:18:427652 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7653 failed_on_default_network_callback_, callback_.callback()));
7654 EXPECT_EQ(OK, callback_.WaitForResult());
7655 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7656 EXPECT_TRUE(stream.get());
7657
7658 // Cause QUIC stream to be created.
7659 HttpRequestInfo request_info;
7660 request_info.method = "GET";
7661 request_info.url = GURL("https://www.example.org/");
7662 request_info.traffic_annotation =
7663 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7664 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7665 net_log_, CompletionOnceCallback()));
7666
7667 // Ensure that session is alive and active.
7668 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7669 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7670
7671 // Complete migration.
7672 task_runner->RunUntilIdle();
7673 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7674 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7675 EXPECT_EQ(1u, session->GetNumActiveStreams());
7676
7677 // Send GET request on stream.
7678 HttpResponseInfo response;
7679 HttpRequestHeaders request_headers;
7680 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7681 callback_.callback()));
7682 socket_data1.Resume();
7683 // Spin up the message loop to read incoming data from server till the ACK.
7684 base::RunLoop().RunUntilIdle();
7685
7686 // Ack delay time.
7687 int delay = task_runner->NextPendingTaskDelay().InMilliseconds();
7688 EXPECT_GT(kDefaultRetransmittableOnWireTimeoutMillisecs, delay);
7689 // Fire the ack alarm, since ack has been sent, no ack will be sent.
7690 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7691 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7692
7693 // Verify that the ping alarm is not set with any default value.
7694 int wrong_delay = kDefaultRetransmittableOnWireTimeoutMillisecs - delay;
7695 delay = task_runner->NextPendingTaskDelay().InMilliseconds();
7696 EXPECT_NE(wrong_delay, delay);
7697 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7698 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7699
7700 // Verify that response headers on the migrated socket were delivered to the
7701 // stream.
7702 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
7703 EXPECT_EQ(200, response.headers->response_code());
7704
7705 // Resume the old socket data, a read error will be delivered to the old
7706 // packet reader. Verify that the session is not affected.
7707 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7708 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7709 EXPECT_EQ(1u, session->GetNumActiveStreams());
7710
7711 stream.reset();
7712 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7713 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7714}
7715
7716// This test verifies that when only migration on network change is enabled, and
7717// a custom value for retransmittable-on-wire is specified, the ping alarm will
7718// send retransmittable pings to the peer with custom value.
7719TEST_P(QuicStreamFactoryTest,
7720 CustomeRetransmittableOnWireTimeoutWithMigrationOnNetworkChangeOnly) {
7721 int custom_timeout_value = 200;
7722 test_params_.quic_retransmittable_on_wire_timeout_milliseconds =
7723 custom_timeout_value;
7724 test_params_.quic_migrate_sessions_on_network_change_v2 = true;
7725 Initialize();
7726 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7727 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7728 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7729
7730 // Using a testing task runner.
7731 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7732 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7733 QuicStreamFactoryPeer::SetAlarmFactory(
7734 factory_.get(),
7735 std::make_unique<QuicChromiumAlarmFactory>(task_runner.get(), &clock_));
7736
Ryan Hamiltonabad59e2019-06-06 04:02:597737 MockQuicData socket_data1(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027738 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi99d0cdd2019-05-21 01:18:427739 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027740 SYNCHRONOUS,
7741 ConstructGetRequestPacket(
7742 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi99d0cdd2019-05-21 01:18:427743 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7744 // Read two packets so that client will send ACK immedaitely.
Ryan Hamilton9f2eac32019-06-27 03:15:547745 socket_data1.AddRead(
7746 ASYNC,
7747 ConstructOkResponsePacket(
7748 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
7749 socket_data1.AddRead(
7750 ASYNC, server_maker_.MakeDataPacket(
7751 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7752 base::StringPiece("Hello World")));
Zhongyi Shi99d0cdd2019-05-21 01:18:427753 // Read an ACK from server which acks all client data.
7754 socket_data1.AddRead(SYNCHRONOUS,
7755 server_maker_.MakeAckPacket(3, 2, 1, 1, false));
7756 socket_data1.AddWrite(ASYNC, client_maker_.MakeAckPacket(3, 2, 1, 1, false));
7757 // The PING packet sent for retransmittable on wire.
7758 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(4, false));
7759 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7760 std::string header = ConstructDataHeader(6);
7761 socket_data1.AddRead(
7762 ASYNC, ConstructServerDataPacket(
7763 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177764 header + "hello!"));
Zhongyi Shi99d0cdd2019-05-21 01:18:427765 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read.
7766 socket_data1.AddWrite(
7767 SYNCHRONOUS, client_maker_.MakeRstPacket(
7768 5, false, GetNthClientInitiatedBidirectionalStreamId(0),
7769 quic::QUIC_STREAM_CANCELLED));
7770 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7771
7772 // Create request and QuicHttpStream.
7773 QuicStreamRequest request(factory_.get());
7774 EXPECT_EQ(ERR_IO_PENDING,
7775 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:527776 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
7777 SocketTag(), NetworkIsolationKey(),
Zhongyi Shi99d0cdd2019-05-21 01:18:427778 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7779 failed_on_default_network_callback_, callback_.callback()));
7780 EXPECT_EQ(OK, callback_.WaitForResult());
7781 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7782 EXPECT_TRUE(stream.get());
7783
7784 // Cause QUIC stream to be created.
7785 HttpRequestInfo request_info;
7786 request_info.method = "GET";
7787 request_info.url = GURL("https://www.example.org/");
7788 request_info.traffic_annotation =
7789 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7790 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7791 net_log_, CompletionOnceCallback()));
7792
7793 // Ensure that session is alive and active.
7794 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7795 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7796
7797 // Complete migration.
7798 task_runner->RunUntilIdle();
7799 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7800 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7801 EXPECT_EQ(1u, session->GetNumActiveStreams());
7802
7803 // Send GET request on stream.
7804 HttpResponseInfo response;
7805 HttpRequestHeaders request_headers;
7806 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7807 callback_.callback()));
7808 socket_data1.Resume();
7809 // Spin up the message loop to read incoming data from server till the ACK.
7810 base::RunLoop().RunUntilIdle();
7811
7812 // Ack delay time.
7813 int delay = task_runner->NextPendingTaskDelay().InMilliseconds();
7814 EXPECT_GT(custom_timeout_value, delay);
7815 // Fire the ack alarm, since ack has been sent, no ack will be sent.
7816 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7817 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7818
7819 // Fire the ping alarm with retransmittable-on-wire timeout, send PING.
7820 delay = custom_timeout_value - delay;
7821 EXPECT_EQ(base::TimeDelta::FromMilliseconds(delay),
7822 task_runner->NextPendingTaskDelay());
7823 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7824 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7825
7826 socket_data1.Resume();
7827
7828 // Verify that response headers on the migrated socket were delivered to the
7829 // stream.
7830 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
7831 EXPECT_EQ(200, response.headers->response_code());
7832
7833 // Resume the old socket data, a read error will be delivered to the old
7834 // packet reader. Verify that the session is not affected.
7835 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7836 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7837 EXPECT_EQ(1u, session->GetNumActiveStreams());
7838
7839 stream.reset();
7840 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7841 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7842}
7843
7844// This test verifies that when only migration on network change is enabled, and
7845// no custom value for retransmittable-on-wire is specified, the ping alarm will
7846// NOT send retransmittable pings to the peer with custom value.
7847TEST_P(QuicStreamFactoryTest,
7848 NoRetransmittableOnWireTimeoutWithMigrationOnNetworkChangeOnly) {
7849 test_params_.quic_migrate_sessions_on_network_change_v2 = true;
7850 Initialize();
7851 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7852 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7853 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7854
7855 // Using a testing task runner.
7856 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7857 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7858 QuicStreamFactoryPeer::SetAlarmFactory(
7859 factory_.get(),
7860 std::make_unique<QuicChromiumAlarmFactory>(task_runner.get(), &clock_));
7861
Ryan Hamiltonabad59e2019-06-06 04:02:597862 MockQuicData socket_data1(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027863 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi99d0cdd2019-05-21 01:18:427864 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027865 SYNCHRONOUS,
7866 ConstructGetRequestPacket(
7867 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi99d0cdd2019-05-21 01:18:427868 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7869 // Read two packets so that client will send ACK immedaitely.
Ryan Hamilton9f2eac32019-06-27 03:15:547870 socket_data1.AddRead(
7871 ASYNC,
7872 ConstructOkResponsePacket(
7873 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
7874 socket_data1.AddRead(
7875 ASYNC, server_maker_.MakeDataPacket(
7876 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7877 base::StringPiece("Hello World")));
Zhongyi Shi99d0cdd2019-05-21 01:18:427878 // Read an ACK from server which acks all client data.
7879 socket_data1.AddRead(SYNCHRONOUS,
7880 server_maker_.MakeAckPacket(3, 2, 1, 1, false));
7881 socket_data1.AddWrite(ASYNC, client_maker_.MakeAckPacket(3, 2, 1, 1, false));
7882 std::string header = ConstructDataHeader(6);
7883 socket_data1.AddRead(
7884 ASYNC, ConstructServerDataPacket(
7885 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177886 header + "hello!"));
Zhongyi Shi99d0cdd2019-05-21 01:18:427887 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read.
7888 socket_data1.AddWrite(
7889 SYNCHRONOUS, client_maker_.MakeRstPacket(
7890 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
7891 quic::QUIC_STREAM_CANCELLED));
7892 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7893
7894 // Create request and QuicHttpStream.
7895 QuicStreamRequest request(factory_.get());
7896 EXPECT_EQ(ERR_IO_PENDING,
7897 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:527898 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
7899 SocketTag(), NetworkIsolationKey(),
Zhongyi Shi99d0cdd2019-05-21 01:18:427900 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7901 failed_on_default_network_callback_, callback_.callback()));
7902 EXPECT_EQ(OK, callback_.WaitForResult());
7903 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7904 EXPECT_TRUE(stream.get());
7905
7906 // Cause QUIC stream to be created.
7907 HttpRequestInfo request_info;
7908 request_info.method = "GET";
7909 request_info.url = GURL("https://www.example.org/");
7910 request_info.traffic_annotation =
7911 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7912 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7913 net_log_, CompletionOnceCallback()));
7914
7915 // Ensure that session is alive and active.
7916 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7917 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7918
7919 // Complete migration.
7920 task_runner->RunUntilIdle();
7921 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7922 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7923 EXPECT_EQ(1u, session->GetNumActiveStreams());
7924
7925 // Send GET request on stream.
7926 HttpResponseInfo response;
7927 HttpRequestHeaders request_headers;
7928 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7929 callback_.callback()));
7930 socket_data1.Resume();
7931 // Spin up the message loop to read incoming data from server till the ACK.
7932 base::RunLoop().RunUntilIdle();
7933
7934 // Ack delay time.
7935 int delay = task_runner->NextPendingTaskDelay().InMilliseconds();
7936 EXPECT_GT(kDefaultRetransmittableOnWireTimeoutMillisecs, delay);
7937 // Fire the ack alarm, since ack has been sent, no ack will be sent.
7938 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7939 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7940
7941 // Verify ping alarm is not set with default value.
7942 int wrong_delay = kDefaultRetransmittableOnWireTimeoutMillisecs - delay;
7943 delay = task_runner->NextPendingTaskDelay().InMilliseconds();
7944 EXPECT_NE(wrong_delay, delay);
7945 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7946 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7947
7948 // Verify that response headers on the migrated socket were delivered to the
7949 // stream.
7950 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
7951 EXPECT_EQ(200, response.headers->response_code());
7952
7953 // Resume the old socket data, a read error will be delivered to the old
7954 // packet reader. Verify that the session is not affected.
7955 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7956 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7957 EXPECT_EQ(1u, session->GetNumActiveStreams());
7958
7959 stream.reset();
7960 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7961 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7962}
7963
Zhongyi Shif3d6cddb2018-07-11 03:30:027964// This test verifies that after migration on write error is posted, packet
7965// read error on the old reader will be ignored and will not close the
7966// connection.
7967TEST_P(QuicStreamFactoryTest,
7968 IgnoreReadErrorOnOldReaderDuringPendingMigrationOnWriteError) {
7969 InitializeConnectionMigrationV2Test(
7970 {kDefaultNetworkForTests, kNewNetworkForTests});
7971 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7972 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7973 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7974
7975 // Using a testing task runner.
7976 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7977 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7978
Ryan Hamiltonabad59e2019-06-06 04:02:597979 MockQuicData socket_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027980 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shif3d6cddb2018-07-11 03:30:027981 socket_data.AddWrite(ASYNC, ERR_FAILED); // Write error.
7982 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE); // Read error.
7983 socket_data.AddSocketDataToFactory(socket_factory_.get());
7984
7985 // Create request and QuicHttpStream.
7986 QuicStreamRequest request(factory_.get());
7987 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:037988 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:527989 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
7990 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:037991 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7992 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shif3d6cddb2018-07-11 03:30:027993 EXPECT_EQ(OK, callback_.WaitForResult());
7994 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7995 EXPECT_TRUE(stream.get());
7996
7997 // Cause QUIC stream to be created.
7998 HttpRequestInfo request_info;
7999 request_info.method = "GET";
8000 request_info.url = GURL("https://www.example.org/");
8001 request_info.traffic_annotation =
8002 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8003 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
8004 net_log_, CompletionOnceCallback()));
8005
8006 // Ensure that session is alive and active.
8007 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
8008 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8009 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8010
8011 // Set up second socket data provider that is used after
8012 // migration. The request is written to this new socket, and the
8013 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:598014 MockQuicData socket_data1(version_);
Fan Yang32c5a112018-12-10 20:06:338015 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:028016 SYNCHRONOUS,
8017 ConstructGetRequestPacket(
8018 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Ryan Hamilton9f2eac32019-06-27 03:15:548019 client_maker_.set_coalesce_http_frames(true);
Zhongyi Shif3d6cddb2018-07-11 03:30:028020 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:338021 ASYNC,
8022 ConstructOkResponsePacket(
8023 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shif3d6cddb2018-07-11 03:30:028024
8025 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
8026 socket_data1.AddRead(ASYNC, ERR_FAILED); // Read error to close connection.
8027 socket_data1.AddSocketDataToFactory(socket_factory_.get());
8028
8029 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
8030 // Send GET request on stream.
8031 HttpResponseInfo response;
8032 HttpRequestHeaders request_headers;
8033 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
8034 callback_.callback()));
8035 // Run the message loop to complete asynchronous write and read with errors.
8036 base::RunLoop().RunUntilIdle();
8037 // There will be one pending task to complete migration on write error.
8038 // Verify session is not closed with read error.
8039 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
8040 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8041 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8042 EXPECT_EQ(1u, session->GetNumActiveStreams());
8043
8044 // Complete migration.
8045 task_runner->RunUntilIdle();
Zhongyi Shia7dd46b2018-07-12 22:59:298046 // There will be one more task posted attempting to migrate back to the
8047 // default network.
8048 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
Zhongyi Shif3d6cddb2018-07-11 03:30:028049 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:298050 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shif3d6cddb2018-07-11 03:30:028051 EXPECT_EQ(1u, session->GetNumActiveStreams());
8052
8053 // Verify that response headers on the migrated socket were delivered to the
8054 // stream.
8055 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
8056 EXPECT_EQ(200, response.headers->response_code());
8057
8058 // Resume to consume the read error on new socket, which will close
8059 // the connection.
8060 socket_data1.Resume();
8061
8062 EXPECT_TRUE(socket_data.AllReadDataConsumed());
8063 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
8064 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
8065 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
8066}
8067
Zhongyi Shi4ac9e1f2018-06-21 05:21:478068// Migrate on asynchronous write error, old network disconnects after alternate
8069// network connects.
8070TEST_P(QuicStreamFactoryTest,
8071 MigrateSessionOnWriteErrorWithDisconnectAfterConnectAysnc) {
8072 TestMigrationOnWriteErrorWithMultipleNotifications(
8073 ASYNC, /*disconnect_before_connect*/ false);
8074}
8075
8076// Migrate on synchronous write error, old network disconnects after alternate
8077// network connects.
8078TEST_P(QuicStreamFactoryTest,
8079 MigrateSessionOnWriteErrorWithDisconnectAfterConnectSync) {
8080 TestMigrationOnWriteErrorWithMultipleNotifications(
8081 SYNCHRONOUS, /*disconnect_before_connect*/ false);
8082}
8083
8084// Migrate on asynchronous write error, old network disconnects before alternate
8085// network connects.
8086TEST_P(QuicStreamFactoryTest,
8087 MigrateSessionOnWriteErrorWithDisconnectBeforeConnectAysnc) {
8088 TestMigrationOnWriteErrorWithMultipleNotifications(
8089 ASYNC, /*disconnect_before_connect*/ true);
8090}
8091
8092// Migrate on synchronous write error, old network disconnects before alternate
8093// network connects.
8094TEST_P(QuicStreamFactoryTest,
8095 MigrateSessionOnWriteErrorWithDisconnectBeforeConnectSync) {
8096 TestMigrationOnWriteErrorWithMultipleNotifications(
8097 SYNCHRONOUS, /*disconnect_before_connect*/ true);
8098}
8099
8100// Setps up test which verifies that session successfully migrate to alternate
8101// network with signals delivered in the following order:
8102// *NOTE* Signal (A) and (B) can reverse order based on
8103// |disconnect_before_connect|.
8104// - (No alternate network is connected) session connects to
8105// kDefaultNetworkForTests.
8106// - An async/sync write error is encountered based on |write_error_mode|:
8107// session posted task to migrate session on write error.
8108// - Posted task is executed, miration moves to pending state due to lack of
8109// alternate network.
8110// - (A) An alternate network is connected, pending migration completes.
8111// - (B) Old default network disconnects, no migration will be attempted as
Zhongyi Shi329f5cbd2018-06-22 23:51:188112// session has already migrate to the alternate network.
Zhongyi Shi4ac9e1f2018-06-21 05:21:478113// - The alternate network is made default.
jri5b785512016-09-13 04:29:118114void QuicStreamFactoryTestBase::
Zhongyi Shi4ac9e1f2018-06-21 05:21:478115 TestMigrationOnWriteErrorWithMultipleNotifications(
jri5b785512016-09-13 04:29:118116 IoMode write_error_mode,
Zhongyi Shi4ac9e1f2018-06-21 05:21:478117 bool disconnect_before_connect) {
Zhongyi Shi329f5cbd2018-06-22 23:51:188118 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri5b785512016-09-13 04:29:118119 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8120 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8121 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8122
Ryan Hamiltonabad59e2019-06-06 04:02:598123 MockQuicData socket_data(version_);
jri5b785512016-09-13 04:29:118124 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:028125 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi4ac9e1f2018-06-21 05:21:478126 socket_data.AddWrite(write_error_mode, ERR_FAILED); // Write error.
Zhongyi Shi5f587cc2017-11-21 23:24:178127 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri5b785512016-09-13 04:29:118128
8129 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:458130 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338131 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:038132 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:528133 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
8134 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:038135 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8136 failed_on_default_network_callback_, callback_.callback()));
jri5b785512016-09-13 04:29:118137 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:248138 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri5b785512016-09-13 04:29:118139 EXPECT_TRUE(stream.get());
8140
8141 // Cause QUIC stream to be created.
8142 HttpRequestInfo request_info;
8143 request_info.method = "GET";
8144 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:398145 request_info.traffic_annotation =
8146 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:278147 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:398148 net_log_, CompletionOnceCallback()));
jri5b785512016-09-13 04:29:118149
8150 // Ensure that session is alive and active.
8151 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
8152 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8153 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8154
8155 // Send GET request on stream. This should cause a write error, which triggers
8156 // a connection migration attempt.
8157 HttpResponseInfo response;
8158 HttpRequestHeaders request_headers;
8159 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
8160 callback_.callback()));
Zhongyi Shi4ac9e1f2018-06-21 05:21:478161 // Run the message loop so that posted task to migrate to socket will be
8162 // executed. A new task will be posted to wait for a new network.
jri5b785512016-09-13 04:29:118163 base::RunLoop().RunUntilIdle();
8164
8165 // In this particular code path, the network will not yet be marked
8166 // as going away and the session will still be alive.
8167 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8168 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8169 EXPECT_EQ(1u, session->GetNumActiveStreams());
8170 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
8171
8172 // Set up second socket data provider that is used after
8173 // migration. The request is rewritten to this new socket, and the
8174 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:598175 MockQuicData socket_data1(version_);
Fan Yang32c5a112018-12-10 20:06:338176 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:028177 SYNCHRONOUS,
8178 ConstructGetRequestPacket(
8179 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Ryan Hamilton9f2eac32019-06-27 03:15:548180 client_maker_.set_coalesce_http_frames(true);
Zhongyi Shi32f2fd02018-04-16 18:23:438181 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:338182 ASYNC,
8183 ConstructOkResponsePacket(
8184 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
jri5b785512016-09-13 04:29:118185 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:338186 socket_data1.AddWrite(
8187 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
8188 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
8189 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:178190 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri5b785512016-09-13 04:29:118191
8192 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8193 ->SetConnectedNetworksList(
8194 {kDefaultNetworkForTests, kNewNetworkForTests});
Zhongyi Shi4ac9e1f2018-06-21 05:21:478195 if (disconnect_before_connect) {
8196 // Now deliver a DISCONNECT notification.
jri5b785512016-09-13 04:29:118197 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8198 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
Zhongyi Shi4ac9e1f2018-06-21 05:21:478199
8200 // Now deliver a CONNECTED notification and completes migration.
jri5b785512016-09-13 04:29:118201 scoped_mock_network_change_notifier_->mock_network_change_notifier()
Zhongyi Shi4ac9e1f2018-06-21 05:21:478202 ->NotifyNetworkConnected(kNewNetworkForTests);
8203 } else {
8204 // Now deliver a CONNECTED notification and completes migration.
8205 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8206 ->NotifyNetworkConnected(kNewNetworkForTests);
8207
8208 // Now deliver a DISCONNECT notification.
8209 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8210 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
jri5b785512016-09-13 04:29:118211 }
jri5b785512016-09-13 04:29:118212 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shi329f5cbd2018-06-22 23:51:188213 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:118214 EXPECT_EQ(1u, session->GetNumActiveStreams());
8215
8216 // This is the callback for the response headers that returned
8217 // pending previously, because no result was available. Check that
8218 // the result is now available due to the successful migration.
8219 EXPECT_THAT(callback_.WaitForResult(), IsOk());
8220 EXPECT_EQ(200, response.headers->response_code());
8221
Zhongyi Shi4ac9e1f2018-06-21 05:21:478222 // Deliver a MADEDEFAULT notification.
jri5b785512016-09-13 04:29:118223 scoped_mock_network_change_notifier_->mock_network_change_notifier()
Zhongyi Shi4ac9e1f2018-06-21 05:21:478224 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri5b785512016-09-13 04:29:118225
zhongyi98d6a9262017-05-19 02:47:458226 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:518227 EXPECT_EQ(OK,
8228 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:528229 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
8230 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:518231 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8232 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:248233 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
jri5b785512016-09-13 04:29:118234 EXPECT_TRUE(stream2.get());
8235
8236 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi329f5cbd2018-06-22 23:51:188237 EXPECT_EQ(session, GetActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:118238
8239 stream.reset();
8240 stream2.reset();
8241
8242 EXPECT_TRUE(socket_data.AllReadDataConsumed());
8243 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
8244 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
8245 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
jri5b785512016-09-13 04:29:118246}
8247
Zhongyi Shic16b4102019-02-12 00:37:408248// This test verifies after session migrates off the default network, it keeps
8249// retrying migrate back to the default network until successfully gets on the
8250// default network or the idle migration period threshold is exceeded.
8251// The default threshold is 30s.
8252TEST_P(QuicStreamFactoryTest, DefaultIdleMigrationPeriod) {
Zhongyi Shi32fe14d42019-02-28 00:25:368253 test_params_.quic_migrate_idle_sessions = true;
Zhongyi Shic16b4102019-02-12 00:37:408254 InitializeConnectionMigrationV2Test(
8255 {kDefaultNetworkForTests, kNewNetworkForTests});
8256 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8257 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8258
8259 // Using a testing task runner and a test tick tock.
8260 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
8261 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
8262 QuicStreamFactoryPeer::SetTickClock(factory_.get(),
8263 task_runner->GetMockTickClock());
8264
Ryan Hamiltonabad59e2019-06-06 04:02:598265 MockQuicData default_socket_data(version_);
Zhongyi Shic16b4102019-02-12 00:37:408266 default_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
8267 default_socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
8268 default_socket_data.AddSocketDataToFactory(socket_factory_.get());
8269
8270 // Set up second socket data provider that is used after migration.
Ryan Hamiltonabad59e2019-06-06 04:02:598271 MockQuicData alternate_socket_data(version_);
Zhongyi Shic16b4102019-02-12 00:37:408272 alternate_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8273 // Ping packet to send after migration.
8274 alternate_socket_data.AddWrite(
8275 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
8276 alternate_socket_data.AddSocketDataToFactory(socket_factory_.get());
8277
8278 // Set up probing socket for migrating back to the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:598279 MockQuicData quic_data(version_); // retry count: 0.
Zhongyi Shic16b4102019-02-12 00:37:408280 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8281 quic_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8282 quic_data.AddSocketDataToFactory(socket_factory_.get());
8283
Ryan Hamiltonabad59e2019-06-06 04:02:598284 MockQuicData quic_data1(version_); // retry count: 1
Zhongyi Shic16b4102019-02-12 00:37:408285 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8286 quic_data1.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8287 quic_data1.AddSocketDataToFactory(socket_factory_.get());
8288
Ryan Hamilton0d65a8c2019-06-07 00:46:028289 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:598290 MockQuicData quic_data2(version_); // retry count: 2
Zhongyi Shic16b4102019-02-12 00:37:408291 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8292 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8293 quic_data2.AddSocketDataToFactory(socket_factory_.get());
8294
Ryan Hamilton0d65a8c2019-06-07 00:46:028295 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:598296 MockQuicData quic_data3(version_); // retry count: 3
Zhongyi Shic16b4102019-02-12 00:37:408297 quic_data3.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8298 quic_data3.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8299 quic_data3.AddSocketDataToFactory(socket_factory_.get());
8300
Ryan Hamilton0d65a8c2019-06-07 00:46:028301 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:598302 MockQuicData quic_data4(version_); // retry count: 4
Zhongyi Shic16b4102019-02-12 00:37:408303 quic_data4.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8304 quic_data4.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8305 quic_data4.AddSocketDataToFactory(socket_factory_.get());
8306
Ryan Hamilton0d65a8c2019-06-07 00:46:028307 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:598308 MockQuicData quic_data5(version_); // retry count: 5
Zhongyi Shic16b4102019-02-12 00:37:408309 quic_data5.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8310 quic_data5.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8311 quic_data5.AddSocketDataToFactory(socket_factory_.get());
8312
8313 // Create request and QuicHttpStream.
8314 QuicStreamRequest request(factory_.get());
8315 EXPECT_EQ(ERR_IO_PENDING,
8316 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:528317 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
8318 SocketTag(), NetworkIsolationKey(),
Zhongyi Shic16b4102019-02-12 00:37:408319 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8320 failed_on_default_network_callback_, callback_.callback()));
8321 EXPECT_THAT(callback_.WaitForResult(), IsOk());
8322 std::unique_ptr<HttpStream> stream = CreateStream(&request);
8323 EXPECT_TRUE(stream.get());
8324
8325 // Ensure that session is active.
8326 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8327
8328 // Trigger connection migration. Since there are no active streams,
8329 // the session will be closed.
8330 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8331 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
8332
8333 // The nearest task will complete migration.
8334 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
8335 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
8336 task_runner->FastForwardBy(base::TimeDelta());
8337
8338 // The migrate back timer will fire. Due to default network
8339 // being disconnected, no attempt will be exercised to migrate back.
8340 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
8341 EXPECT_EQ(base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs),
8342 task_runner->NextPendingTaskDelay());
8343 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
8344 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
8345
8346 // Deliver the signal that the old default network now backs up.
8347 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8348 ->NotifyNetworkMadeDefault(kDefaultNetworkForTests);
8349
8350 // A task is posted to migrate back to the default network immediately.
8351 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
8352 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
8353 task_runner->FastForwardBy(base::TimeDelta());
8354
8355 // Retry migrate back in 1, 2, 4, 8, 16s.
8356 // Session will be closed due to idle migration timeout.
8357 for (int i = 0; i < 5; i++) {
8358 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8359 // A task is posted to migrate back to the default network in 2^i seconds.
8360 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
8361 EXPECT_EQ(base::TimeDelta::FromSeconds(UINT64_C(1) << i),
8362 task_runner->NextPendingTaskDelay());
8363 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
8364 }
8365
8366 EXPECT_TRUE(default_socket_data.AllReadDataConsumed());
8367 EXPECT_TRUE(default_socket_data.AllWriteDataConsumed());
8368 EXPECT_TRUE(alternate_socket_data.AllReadDataConsumed());
8369 EXPECT_TRUE(alternate_socket_data.AllWriteDataConsumed());
8370}
8371
8372TEST_P(QuicStreamFactoryTest, CustomIdleMigrationPeriod) {
8373 // The customized threshold is 15s.
Zhongyi Shi32fe14d42019-02-28 00:25:368374 test_params_.quic_migrate_idle_sessions = true;
Zhongyi Shic16b4102019-02-12 00:37:408375 test_params_.quic_idle_session_migration_period =
8376 base::TimeDelta::FromSeconds(15);
8377 InitializeConnectionMigrationV2Test(
8378 {kDefaultNetworkForTests, kNewNetworkForTests});
8379 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8380 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8381
8382 // Using a testing task runner and a test tick tock.
8383 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
8384 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
8385 QuicStreamFactoryPeer::SetTickClock(factory_.get(),
8386 task_runner->GetMockTickClock());
8387
Ryan Hamiltonabad59e2019-06-06 04:02:598388 MockQuicData default_socket_data(version_);
Zhongyi Shic16b4102019-02-12 00:37:408389 default_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
8390 default_socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
8391 default_socket_data.AddSocketDataToFactory(socket_factory_.get());
8392
8393 // Set up second socket data provider that is used after migration.
Ryan Hamiltonabad59e2019-06-06 04:02:598394 MockQuicData alternate_socket_data(version_);
Zhongyi Shic16b4102019-02-12 00:37:408395 alternate_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8396 // Ping packet to send after migration.
8397 alternate_socket_data.AddWrite(
8398 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
8399 alternate_socket_data.AddSocketDataToFactory(socket_factory_.get());
8400
8401 // Set up probing socket for migrating back to the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:598402 MockQuicData quic_data(version_); // retry count: 0.
Zhongyi Shic16b4102019-02-12 00:37:408403 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8404 quic_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8405 quic_data.AddSocketDataToFactory(socket_factory_.get());
8406
Ryan Hamilton0d65a8c2019-06-07 00:46:028407 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:598408 MockQuicData quic_data1(version_); // retry count: 1
Zhongyi Shic16b4102019-02-12 00:37:408409 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8410 quic_data1.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8411 quic_data1.AddSocketDataToFactory(socket_factory_.get());
8412
Ryan Hamilton0d65a8c2019-06-07 00:46:028413 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:598414 MockQuicData quic_data2(version_); // retry count: 2
Zhongyi Shic16b4102019-02-12 00:37:408415 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8416 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8417 quic_data2.AddSocketDataToFactory(socket_factory_.get());
8418
Ryan Hamilton0d65a8c2019-06-07 00:46:028419 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:598420 MockQuicData quic_data3(version_); // retry count: 3
Zhongyi Shic16b4102019-02-12 00:37:408421 quic_data3.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8422 quic_data3.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8423 quic_data3.AddSocketDataToFactory(socket_factory_.get());
8424
Ryan Hamilton0d65a8c2019-06-07 00:46:028425 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:598426 MockQuicData quic_data4(version_); // retry count: 4
Zhongyi Shic16b4102019-02-12 00:37:408427 quic_data4.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8428 quic_data4.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8429 quic_data4.AddSocketDataToFactory(socket_factory_.get());
8430
8431 // Create request and QuicHttpStream.
8432 QuicStreamRequest request(factory_.get());
8433 EXPECT_EQ(ERR_IO_PENDING,
8434 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:528435 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
8436 SocketTag(), NetworkIsolationKey(),
Zhongyi Shic16b4102019-02-12 00:37:408437 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8438 failed_on_default_network_callback_, callback_.callback()));
8439 EXPECT_THAT(callback_.WaitForResult(), IsOk());
8440 std::unique_ptr<HttpStream> stream = CreateStream(&request);
8441 EXPECT_TRUE(stream.get());
8442
8443 // Ensure that session is active.
8444 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8445
8446 // Trigger connection migration. Since there are no active streams,
8447 // the session will be closed.
8448 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8449 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
8450
8451 // The nearest task will complete migration.
8452 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
8453 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
8454 task_runner->FastForwardBy(base::TimeDelta());
8455
8456 // The migrate back timer will fire. Due to default network
8457 // being disconnected, no attempt will be exercised to migrate back.
8458 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
8459 EXPECT_EQ(base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs),
8460 task_runner->NextPendingTaskDelay());
8461 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
8462 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
8463
8464 // Deliver the signal that the old default network now backs up.
8465 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8466 ->NotifyNetworkMadeDefault(kDefaultNetworkForTests);
8467
8468 // A task is posted to migrate back to the default network immediately.
8469 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
8470 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
8471 task_runner->FastForwardBy(base::TimeDelta());
8472
8473 // Retry migrate back in 1, 2, 4, 8s.
8474 // Session will be closed due to idle migration timeout.
8475 for (int i = 0; i < 4; i++) {
8476 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8477 // A task is posted to migrate back to the default network in 2^i seconds.
8478 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
8479 EXPECT_EQ(base::TimeDelta::FromSeconds(UINT64_C(1) << i),
8480 task_runner->NextPendingTaskDelay());
8481 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
8482 }
8483
8484 EXPECT_TRUE(default_socket_data.AllReadDataConsumed());
8485 EXPECT_TRUE(default_socket_data.AllWriteDataConsumed());
8486 EXPECT_TRUE(alternate_socket_data.AllReadDataConsumed());
8487 EXPECT_TRUE(alternate_socket_data.AllWriteDataConsumed());
8488}
8489
jri217455a12016-07-13 20:15:098490TEST_P(QuicStreamFactoryTest, ServerMigration) {
Zhongyi Shi967d2f12019-02-08 20:58:538491 test_params_.quic_allow_server_migration = true;
jri217455a12016-07-13 20:15:098492 Initialize();
8493
8494 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8495 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8496 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8497
Ryan Hamiltonabad59e2019-06-06 04:02:598498 MockQuicData socket_data1(version_);
rcha00569732016-08-27 11:09:368499 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:028500 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
rch5cb522462017-04-25 20:18:368501 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:028502 SYNCHRONOUS,
8503 ConstructGetRequestPacket(
8504 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi5f587cc2017-11-21 23:24:178505 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri217455a12016-07-13 20:15:098506
8507 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:458508 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338509 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:038510 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:528511 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
8512 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:038513 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8514 failed_on_default_network_callback_, callback_.callback()));
jri217455a12016-07-13 20:15:098515 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:248516 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri217455a12016-07-13 20:15:098517 EXPECT_TRUE(stream.get());
8518
8519 // Cause QUIC stream to be created.
8520 HttpRequestInfo request_info;
8521 request_info.method = "GET";
8522 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:398523 request_info.traffic_annotation =
8524 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:278525 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:398526 net_log_, CompletionOnceCallback()));
jri217455a12016-07-13 20:15:098527
8528 // Ensure that session is alive and active.
8529 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
8530 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8531 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8532
8533 // Send GET request on stream.
8534 HttpResponseInfo response;
8535 HttpRequestHeaders request_headers;
8536 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
8537 callback_.callback()));
8538
8539 IPEndPoint ip;
8540 session->GetDefaultSocket()->GetPeerAddress(&ip);
8541 DVLOG(1) << "Socket connected to: " << ip.address().ToString() << " "
8542 << ip.port();
8543
8544 // Set up second socket data provider that is used after
8545 // migration. The request is rewritten to this new socket, and the
8546 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:598547 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:368548 socket_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438549 SYNCHRONOUS, client_maker_.MakePingPacket(3, /*include_version=*/true));
8550 socket_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:338551 ASYNC,
8552 ConstructOkResponsePacket(
8553 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
rcha00569732016-08-27 11:09:368554 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:338555 socket_data2.AddWrite(
8556 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
8557 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
8558 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:178559 socket_data2.AddSocketDataToFactory(socket_factory_.get());
jri217455a12016-07-13 20:15:098560
8561 const uint8_t kTestIpAddress[] = {1, 2, 3, 4};
8562 const uint16_t kTestPort = 123;
Zhongyi Shif124a582017-11-02 00:15:048563 session->Migrate(NetworkChangeNotifier::kInvalidNetworkHandle,
8564 IPEndPoint(IPAddress(kTestIpAddress), kTestPort), true,
8565 net_log_);
jri217455a12016-07-13 20:15:098566
8567 session->GetDefaultSocket()->GetPeerAddress(&ip);
8568 DVLOG(1) << "Socket migrated to: " << ip.address().ToString() << " "
8569 << ip.port();
8570
8571 // The session should be alive and active.
8572 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8573 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8574 EXPECT_EQ(1u, session->GetNumActiveStreams());
8575
8576 // Run the message loop so that data queued in the new socket is read by the
8577 // packet reader.
8578 base::RunLoop().RunUntilIdle();
8579
8580 // Verify that response headers on the migrated socket were delivered to the
8581 // stream.
8582 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
8583 EXPECT_EQ(200, response.headers->response_code());
8584
8585 stream.reset();
8586
8587 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
8588 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
8589 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
8590 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
8591}
8592
jri053fdbd2016-08-19 02:33:058593TEST_P(QuicStreamFactoryTest, ServerMigrationIPv4ToIPv4) {
8594 // Add alternate IPv4 server address to config.
8595 IPEndPoint alt_address = IPEndPoint(IPAddress(1, 2, 3, 4), 123);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528596 quic::QuicConfig config;
Victor Vasiliev4f6fb892019-05-31 16:58:318597 config.SetAlternateServerAddressToSend(ToQuicSocketAddress(alt_address));
jri053fdbd2016-08-19 02:33:058598 VerifyServerMigration(config, alt_address);
8599}
8600
8601TEST_P(QuicStreamFactoryTest, ServerMigrationIPv6ToIPv6) {
8602 // Add a resolver rule to make initial connection to an IPv6 address.
Renjiea0cb4a2c2018-09-26 23:37:308603 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
8604 "fe80::aebc:32ff:febb:1e33", "");
jri053fdbd2016-08-19 02:33:058605 // Add alternate IPv6 server address to config.
8606 IPEndPoint alt_address = IPEndPoint(
8607 IPAddress(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), 123);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528608 quic::QuicConfig config;
Victor Vasiliev4f6fb892019-05-31 16:58:318609 config.SetAlternateServerAddressToSend(ToQuicSocketAddress(alt_address));
jri053fdbd2016-08-19 02:33:058610 VerifyServerMigration(config, alt_address);
8611}
8612
8613TEST_P(QuicStreamFactoryTest, ServerMigrationIPv6ToIPv4) {
8614 // Add a resolver rule to make initial connection to an IPv6 address.
Renjiea0cb4a2c2018-09-26 23:37:308615 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
8616 "fe80::aebc:32ff:febb:1e33", "");
jri053fdbd2016-08-19 02:33:058617 // Add alternate IPv4 server address to config.
8618 IPEndPoint alt_address = IPEndPoint(IPAddress(1, 2, 3, 4), 123);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528619 quic::QuicConfig config;
Victor Vasiliev4f6fb892019-05-31 16:58:318620 config.SetAlternateServerAddressToSend(ToQuicSocketAddress(alt_address));
jri053fdbd2016-08-19 02:33:058621 IPEndPoint expected_address(
8622 ConvertIPv4ToIPv4MappedIPv6(alt_address.address()), alt_address.port());
8623 VerifyServerMigration(config, expected_address);
8624}
8625
8626TEST_P(QuicStreamFactoryTest, ServerMigrationIPv4ToIPv6Fails) {
Zhongyi Shi967d2f12019-02-08 20:58:538627 test_params_.quic_allow_server_migration = true;
jri053fdbd2016-08-19 02:33:058628 Initialize();
8629
8630 // Add a resolver rule to make initial connection to an IPv4 address.
Renjiea0cb4a2c2018-09-26 23:37:308631 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), "1.2.3.4",
8632 "");
jri053fdbd2016-08-19 02:33:058633 // Add alternate IPv6 server address to config.
8634 IPEndPoint alt_address = IPEndPoint(
8635 IPAddress(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), 123);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528636 quic::QuicConfig config;
Victor Vasiliev4f6fb892019-05-31 16:58:318637 config.SetAlternateServerAddressToSend(ToQuicSocketAddress(alt_address));
jri053fdbd2016-08-19 02:33:058638
8639 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8640 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8641 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8642
8643 crypto_client_stream_factory_.SetConfig(config);
8644
8645 // Set up only socket data provider.
Ryan Hamiltonabad59e2019-06-06 04:02:598646 MockQuicData socket_data1(version_);
rcha00569732016-08-27 11:09:368647 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:438648 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
8649 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338650 SYNCHRONOUS, client_maker_.MakeRstPacket(
8651 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
8652 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:178653 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri053fdbd2016-08-19 02:33:058654
8655 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:458656 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338657 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:038658 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:528659 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
8660 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:038661 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8662 failed_on_default_network_callback_, callback_.callback()));
jri053fdbd2016-08-19 02:33:058663 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:248664 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri053fdbd2016-08-19 02:33:058665 EXPECT_TRUE(stream.get());
8666
8667 // Cause QUIC stream to be created.
8668 HttpRequestInfo request_info;
8669 request_info.method = "GET";
8670 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:398671 request_info.traffic_annotation =
8672 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:278673 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:398674 net_log_, CompletionOnceCallback()));
jri053fdbd2016-08-19 02:33:058675
8676 // Ensure that session is alive and active.
8677 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
8678 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8679 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8680
8681 IPEndPoint actual_address;
8682 session->GetDefaultSocket()->GetPeerAddress(&actual_address);
8683 // No migration should have happened.
8684 IPEndPoint expected_address =
8685 IPEndPoint(IPAddress(1, 2, 3, 4), kDefaultServerPort);
8686 EXPECT_EQ(actual_address, expected_address);
8687 DVLOG(1) << "Socket connected to: " << actual_address.address().ToString()
8688 << " " << actual_address.port();
8689 DVLOG(1) << "Expected address: " << expected_address.address().ToString()
8690 << " " << expected_address.port();
8691
8692 stream.reset();
8693 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
8694 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
8695}
8696
rsleevi17784692016-10-12 01:36:208697TEST_P(QuicStreamFactoryTest, OnCertDBChanged) {
jri7046038f2015-10-22 00:29:268698 Initialize();
rch6faa4d42016-01-05 20:48:438699 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8700 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8701 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8702
Ryan Hamiltonabad59e2019-06-06 04:02:598703 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:368704 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:438705 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:178706 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]d7d1e50b2013-11-25 22:08:098707
Ryan Hamilton0d65a8c2019-06-07 00:46:028708 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:598709 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:368710 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:028711 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:178712 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]d7d1e50b2013-11-25 22:08:098713
zhongyi98d6a9262017-05-19 02:47:458714 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338715 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:038716 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:528717 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
8718 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:038719 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8720 failed_on_default_network_callback_, callback_.callback()));
[email protected]d7d1e50b2013-11-25 22:08:098721
robpercival214763f2016-07-01 23:27:018722 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:248723 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Charles 'Buck' Krasic71763c9f2018-02-16 02:37:288724 EXPECT_TRUE(stream);
8725 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
[email protected]d7d1e50b2013-11-25 22:08:098726
8727 // Change the CA cert and verify that stream saw the event.
mattmfd05a1f2017-02-18 06:18:448728 factory_->OnCertDBChanged();
Charles 'Buck' Krasic71763c9f2018-02-16 02:37:288729
jri7046038f2015-10-22 00:29:268730 EXPECT_FALSE(factory_->require_confirmation());
Charles 'Buck' Krasic71763c9f2018-02-16 02:37:288731 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8732 EXPECT_FALSE(HasActiveSession(host_port_pair_));
[email protected]d7d1e50b2013-11-25 22:08:098733
8734 // Now attempting to request a stream to the same origin should create
8735 // a new session.
8736
zhongyi98d6a9262017-05-19 02:47:458737 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338738 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:038739 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:528740 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
8741 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:038742 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8743 failed_on_default_network_callback_, callback_.callback()));
[email protected]d7d1e50b2013-11-25 22:08:098744
robpercival214763f2016-07-01 23:27:018745 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Charles 'Buck' Krasic71763c9f2018-02-16 02:37:288746 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
8747 EXPECT_TRUE(stream2);
8748 QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
8749 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8750 EXPECT_NE(session, session2);
8751 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8752 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
8753
8754 stream2.reset();
8755 stream.reset();
[email protected]d7d1e50b2013-11-25 22:08:098756
rch37de576c2015-05-17 20:28:178757 EXPECT_TRUE(socket_data.AllReadDataConsumed());
8758 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
8759 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
8760 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]d7d1e50b2013-11-25 22:08:098761}
8762
[email protected]1e960032013-12-20 19:00:208763TEST_P(QuicStreamFactoryTest, SharedCryptoConfig) {
jri7046038f2015-10-22 00:29:268764 Initialize();
rch6faa4d42016-01-05 20:48:438765
rch872e00e2016-12-02 02:48:188766 std::vector<string> cannoncial_suffixes;
[email protected]6e12d702013-11-13 00:17:178767 cannoncial_suffixes.push_back(string(".c.youtube.com"));
8768 cannoncial_suffixes.push_back(string(".googlevideo.com"));
[email protected]c49ff182013-09-28 08:33:268769
[email protected]6e12d702013-11-13 00:17:178770 for (unsigned i = 0; i < cannoncial_suffixes.size(); ++i) {
8771 string r1_host_name("r1");
8772 string r2_host_name("r2");
8773 r1_host_name.append(cannoncial_suffixes[i]);
8774 r2_host_name.append(cannoncial_suffixes[i]);
[email protected]b70fdb792013-10-25 19:04:148775
[email protected]bf4ea2f2014-03-10 22:57:538776 HostPortPair host_port_pair1(r1_host_name, 80);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528777 quic::QuicCryptoClientConfig* crypto_config =
jri7046038f2015-10-22 00:29:268778 QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
Ryan Hamilton4f0b26e2018-06-27 23:52:328779 quic::QuicServerId server_id1(host_port_pair1.host(),
8780 host_port_pair1.port(), privacy_mode_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528781 quic::QuicCryptoClientConfig::CachedState* cached1 =
[email protected]257f24f2014-04-01 09:15:378782 crypto_config->LookupOrCreate(server_id1);
[email protected]6e12d702013-11-13 00:17:178783 EXPECT_FALSE(cached1->proof_valid());
8784 EXPECT_TRUE(cached1->source_address_token().empty());
8785
8786 // Mutate the cached1 to have different data.
8787 // TODO(rtenneti): mutate other members of CachedState.
8788 cached1->set_source_address_token(r1_host_name);
8789 cached1->SetProofValid();
8790
[email protected]bf4ea2f2014-03-10 22:57:538791 HostPortPair host_port_pair2(r2_host_name, 80);
Ryan Hamilton4f0b26e2018-06-27 23:52:328792 quic::QuicServerId server_id2(host_port_pair2.host(),
8793 host_port_pair2.port(), privacy_mode_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528794 quic::QuicCryptoClientConfig::CachedState* cached2 =
[email protected]257f24f2014-04-01 09:15:378795 crypto_config->LookupOrCreate(server_id2);
[email protected]6e12d702013-11-13 00:17:178796 EXPECT_EQ(cached1->source_address_token(), cached2->source_address_token());
8797 EXPECT_TRUE(cached2->proof_valid());
8798 }
[email protected]b70fdb792013-10-25 19:04:148799}
8800
[email protected]1e960032013-12-20 19:00:208801TEST_P(QuicStreamFactoryTest, CryptoConfigWhenProofIsInvalid) {
jri7046038f2015-10-22 00:29:268802 Initialize();
rch872e00e2016-12-02 02:48:188803 std::vector<string> cannoncial_suffixes;
[email protected]6e12d702013-11-13 00:17:178804 cannoncial_suffixes.push_back(string(".c.youtube.com"));
8805 cannoncial_suffixes.push_back(string(".googlevideo.com"));
[email protected]b70fdb792013-10-25 19:04:148806
[email protected]6e12d702013-11-13 00:17:178807 for (unsigned i = 0; i < cannoncial_suffixes.size(); ++i) {
8808 string r3_host_name("r3");
8809 string r4_host_name("r4");
8810 r3_host_name.append(cannoncial_suffixes[i]);
8811 r4_host_name.append(cannoncial_suffixes[i]);
[email protected]b70fdb792013-10-25 19:04:148812
[email protected]bf4ea2f2014-03-10 22:57:538813 HostPortPair host_port_pair1(r3_host_name, 80);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528814 quic::QuicCryptoClientConfig* crypto_config =
jri7046038f2015-10-22 00:29:268815 QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
Ryan Hamilton4f0b26e2018-06-27 23:52:328816 quic::QuicServerId server_id1(host_port_pair1.host(),
8817 host_port_pair1.port(), privacy_mode_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528818 quic::QuicCryptoClientConfig::CachedState* cached1 =
[email protected]257f24f2014-04-01 09:15:378819 crypto_config->LookupOrCreate(server_id1);
[email protected]6e12d702013-11-13 00:17:178820 EXPECT_FALSE(cached1->proof_valid());
8821 EXPECT_TRUE(cached1->source_address_token().empty());
8822
8823 // Mutate the cached1 to have different data.
8824 // TODO(rtenneti): mutate other members of CachedState.
8825 cached1->set_source_address_token(r3_host_name);
8826 cached1->SetProofInvalid();
8827
[email protected]bf4ea2f2014-03-10 22:57:538828 HostPortPair host_port_pair2(r4_host_name, 80);
Ryan Hamilton4f0b26e2018-06-27 23:52:328829 quic::QuicServerId server_id2(host_port_pair2.host(),
8830 host_port_pair2.port(), privacy_mode_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528831 quic::QuicCryptoClientConfig::CachedState* cached2 =
[email protected]257f24f2014-04-01 09:15:378832 crypto_config->LookupOrCreate(server_id2);
[email protected]6e12d702013-11-13 00:17:178833 EXPECT_NE(cached1->source_address_token(), cached2->source_address_token());
8834 EXPECT_TRUE(cached2->source_address_token().empty());
8835 EXPECT_FALSE(cached2->proof_valid());
8836 }
[email protected]c49ff182013-09-28 08:33:268837}
8838
rtenneti34dffe752015-02-24 23:27:328839TEST_P(QuicStreamFactoryTest, EnableNotLoadFromDiskCache) {
jri7046038f2015-10-22 00:29:268840 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:208841 factory_->set_require_confirmation(false);
rch6faa4d42016-01-05 20:48:438842 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8843 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8844
jri7046038f2015-10-22 00:29:268845 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
rtenneti34dffe752015-02-24 23:27:328846
Ryan Hamiltonabad59e2019-06-06 04:02:598847 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:368848 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:178849 socket_data.AddSocketDataToFactory(socket_factory_.get());
rtenneti34dffe752015-02-24 23:27:328850
8851 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:278852 MockCryptoClientStream::ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:308853 host_resolver_->set_synchronous_mode(true);
8854 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
8855 "192.168.0.1", "");
rtenneti34dffe752015-02-24 23:27:328856
zhongyi98d6a9262017-05-19 02:47:458857 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:518858 EXPECT_EQ(OK,
8859 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:528860 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
8861 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:518862 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8863 failed_on_default_network_callback_, callback_.callback()));
rtenneti34dffe752015-02-24 23:27:328864
8865 // If we are waiting for disk cache, we would have posted a task. Verify that
8866 // the CancelWaitForDataReady task hasn't been posted.
8867 ASSERT_EQ(0u, runner_->GetPostedTasks().size());
8868
Yixin Wang7891a39d2017-11-08 20:59:248869 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rtenneti34dffe752015-02-24 23:27:328870 EXPECT_TRUE(stream.get());
rch37de576c2015-05-17 20:28:178871 EXPECT_TRUE(socket_data.AllReadDataConsumed());
8872 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
rtenneti34dffe752015-02-24 23:27:328873}
8874
dmurph44ca4f42016-09-09 20:39:098875TEST_P(QuicStreamFactoryTest, ReducePingTimeoutOnConnectionTimeOutOpenStreams) {
Zhongyi Shi967d2f12019-02-08 20:58:538876 test_params_.quic_reduced_ping_timeout_seconds = 10;
dmurph44ca4f42016-09-09 20:39:098877 Initialize();
8878 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8879 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8880 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8881
8882 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
zhongyidd1439f62016-09-02 02:02:268883
Ryan Hamiltonabad59e2019-06-06 04:02:598884 MockQuicData socket_data(version_);
zhongyidd1439f62016-09-02 02:02:268885 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:438886 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:178887 socket_data.AddSocketDataToFactory(socket_factory_.get());
zhongyidd1439f62016-09-02 02:02:268888
Ryan Hamilton0d65a8c2019-06-07 00:46:028889 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:598890 MockQuicData socket_data2(version_);
zhongyidd1439f62016-09-02 02:02:268891 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:028892 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:178893 socket_data2.AddSocketDataToFactory(socket_factory_.get());
zhongyidd1439f62016-09-02 02:02:268894
8895 HostPortPair server2(kServer2HostName, kDefaultServerPort);
8896
8897 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:278898 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Renjiea0cb4a2c2018-09-26 23:37:308899 host_resolver_->set_synchronous_mode(true);
8900 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
8901 "192.168.0.1", "");
8902 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
zhongyidd1439f62016-09-02 02:02:268903
8904 // Quic should use default PING timeout when no previous connection times out
8905 // with open stream.
Ryan Hamilton8d9ee76e2018-05-29 23:52:528906 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(quic::kPingTimeoutSecs),
zhongyidd1439f62016-09-02 02:02:268907 QuicStreamFactoryPeer::GetPingTimeout(factory_.get()));
zhongyi98d6a9262017-05-19 02:47:458908 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:518909 EXPECT_EQ(OK,
8910 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:528911 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
8912 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:518913 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8914 failed_on_default_network_callback_, callback_.callback()));
zhongyidd1439f62016-09-02 02:02:268915
8916 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528917 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(quic::kPingTimeoutSecs),
zhongyidd1439f62016-09-02 02:02:268918 session->connection()->ping_timeout());
8919
Yixin Wang7891a39d2017-11-08 20:59:248920 std::unique_ptr<HttpStream> stream = CreateStream(&request);
zhongyidd1439f62016-09-02 02:02:268921 EXPECT_TRUE(stream.get());
8922 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:398923 request_info.traffic_annotation =
8924 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:278925 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:398926 net_log_, CompletionOnceCallback()));
zhongyidd1439f62016-09-02 02:02:268927
8928 DVLOG(1)
8929 << "Created 1st session and initialized a stream. Now trigger timeout";
Ryan Hamilton8d9ee76e2018-05-29 23:52:528930 session->connection()->CloseConnection(
8931 quic::QUIC_NETWORK_IDLE_TIMEOUT, "test",
8932 quic::ConnectionCloseBehavior::SILENT_CLOSE);
zhongyidd1439f62016-09-02 02:02:268933 // Need to spin the loop now to ensure that
8934 // QuicStreamFactory::OnSessionClosed() runs.
8935 base::RunLoop run_loop;
8936 run_loop.RunUntilIdle();
8937
zhongyidd1439f62016-09-02 02:02:268938 // The first connection times out with open stream, QUIC should reduce initial
8939 // PING time for subsequent connections.
Ryan Hamilton8d9ee76e2018-05-29 23:52:528940 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(10),
zhongyidd1439f62016-09-02 02:02:268941 QuicStreamFactoryPeer::GetPingTimeout(factory_.get()));
8942
8943 // Test two-in-a-row timeouts with open streams.
8944 DVLOG(1) << "Create 2nd session and timeout with open stream";
8945 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:458946 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:518947 EXPECT_EQ(OK,
8948 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:528949 server2, version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
8950 NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:518951 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
8952 failed_on_default_network_callback_, callback2.callback()));
zhongyidd1439f62016-09-02 02:02:268953 QuicChromiumClientSession* session2 = GetActiveSession(server2);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528954 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(10),
zhongyidd1439f62016-09-02 02:02:268955 session2->connection()->ping_timeout());
8956
Yixin Wang7891a39d2017-11-08 20:59:248957 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
zhongyidd1439f62016-09-02 02:02:268958 EXPECT_TRUE(stream2.get());
Steven Valdezb4ff0412018-01-18 22:39:278959 EXPECT_EQ(OK,
8960 stream2->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:398961 net_log_, CompletionOnceCallback()));
zhongyidd1439f62016-09-02 02:02:268962 session2->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:528963 quic::QUIC_NETWORK_IDLE_TIMEOUT, "test",
8964 quic::ConnectionCloseBehavior::SILENT_CLOSE);
zhongyidd1439f62016-09-02 02:02:268965 // Need to spin the loop now to ensure that
8966 // QuicStreamFactory::OnSessionClosed() runs.
8967 base::RunLoop run_loop2;
8968 run_loop2.RunUntilIdle();
zhongyidd1439f62016-09-02 02:02:268969
8970 EXPECT_TRUE(socket_data.AllReadDataConsumed());
8971 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
8972 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
8973 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
8974}
8975
tbansal3b966952016-10-25 23:25:148976// Verifies that the QUIC stream factory is initialized correctly.
rtenneticd2aaa15b2015-10-10 20:29:338977TEST_P(QuicStreamFactoryTest, MaybeInitialize) {
tbansal9b1cdf32017-05-10 17:28:398978 VerifyInitialization();
rtenneti8a80a6dc2015-09-21 19:51:138979}
8980
rtennetid073dd22016-08-04 01:58:338981TEST_P(QuicStreamFactoryTest, StartCertVerifyJob) {
8982 Initialize();
8983
Ryan Hamiltonabad59e2019-06-06 04:02:598984 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:368985 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:438986 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:178987 socket_data.AddSocketDataToFactory(socket_factory_.get());
rtennetid073dd22016-08-04 01:58:338988
8989 // Save current state of |race_cert_verification|.
8990 bool race_cert_verification =
8991 QuicStreamFactoryPeer::GetRaceCertVerification(factory_.get());
8992
8993 // Load server config.
8994 HostPortPair host_port_pair(kDefaultServerHostName, kDefaultServerPort);
Ryan Hamilton4f0b26e2018-06-27 23:52:328995 quic::QuicServerId quic_server_id(host_port_pair_.host(),
8996 host_port_pair_.port(),
8997 privacy_mode_ == PRIVACY_MODE_ENABLED);
rtennetid073dd22016-08-04 01:58:338998 QuicStreamFactoryPeer::CacheDummyServerConfig(factory_.get(), quic_server_id);
8999
9000 QuicStreamFactoryPeer::SetRaceCertVerification(factory_.get(), true);
9001 EXPECT_FALSE(HasActiveCertVerifierJob(quic_server_id));
9002
9003 // Start CertVerifyJob.
Ryan Hamilton8d9ee76e2018-05-29 23:52:529004 quic::QuicAsyncStatus status = QuicStreamFactoryPeer::StartCertVerifyJob(
rtennetid073dd22016-08-04 01:58:339005 factory_.get(), quic_server_id, /*cert_verify_flags=*/0, net_log_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:529006 if (status == quic::QUIC_PENDING) {
rtennetid073dd22016-08-04 01:58:339007 // Verify CertVerifierJob has started.
9008 EXPECT_TRUE(HasActiveCertVerifierJob(quic_server_id));
9009
9010 while (HasActiveCertVerifierJob(quic_server_id)) {
9011 base::RunLoop().RunUntilIdle();
9012 }
9013 }
9014 // Verify CertVerifierJob has finished.
9015 EXPECT_FALSE(HasActiveCertVerifierJob(quic_server_id));
9016
9017 // Start a QUIC request.
zhongyi98d6a9262017-05-19 02:47:459018 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339019 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039020 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529021 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
9022 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039023 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9024 failed_on_default_network_callback_, callback_.callback()));
rtennetid073dd22016-08-04 01:58:339025
9026 EXPECT_EQ(OK, callback_.WaitForResult());
9027
Yixin Wang7891a39d2017-11-08 20:59:249028 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rtennetid073dd22016-08-04 01:58:339029 EXPECT_TRUE(stream.get());
9030
9031 // Restore |race_cert_verification|.
9032 QuicStreamFactoryPeer::SetRaceCertVerification(factory_.get(),
9033 race_cert_verification);
9034
9035 EXPECT_TRUE(socket_data.AllReadDataConsumed());
9036 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
9037
9038 // Verify there are no outstanding CertVerifierJobs after request has
9039 // finished.
9040 EXPECT_FALSE(HasActiveCertVerifierJob(quic_server_id));
9041}
9042
rtenneti1cd3b162015-09-29 02:58:289043TEST_P(QuicStreamFactoryTest, YieldAfterPackets) {
jri7046038f2015-10-22 00:29:269044 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:209045 factory_->set_require_confirmation(false);
rch6faa4d42016-01-05 20:48:439046 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9047 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:269048 QuicStreamFactoryPeer::SetYieldAfterPackets(factory_.get(), 0);
rtenneti1cd3b162015-09-29 02:58:289049
Ryan Hamiltonabad59e2019-06-06 04:02:599050 MockQuicData socket_data(version_);
Fan Yangac867502019-01-28 21:10:239051 socket_data.AddRead(SYNCHRONOUS, ConstructClientConnectionClosePacket(1));
rcha00569732016-08-27 11:09:369052 socket_data.AddRead(ASYNC, OK);
Zhongyi Shi5f587cc2017-11-21 23:24:179053 socket_data.AddSocketDataToFactory(socket_factory_.get());
rtenneti1cd3b162015-09-29 02:58:289054
9055 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:279056 MockCryptoClientStream::ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:309057 host_resolver_->set_synchronous_mode(true);
9058 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
9059 "192.168.0.1", "");
rtenneti1cd3b162015-09-29 02:58:289060
rcha02807b42016-01-29 21:56:159061 // Set up the TaskObserver to verify QuicChromiumPacketReader::StartReading
9062 // posts a task.
rtenneti1cd3b162015-09-29 02:58:289063 // TODO(rtenneti): Change SpdySessionTestTaskObserver to NetTestTaskObserver??
rcha02807b42016-01-29 21:56:159064 SpdySessionTestTaskObserver observer("quic_chromium_packet_reader.cc",
9065 "StartReading");
rtenneti1cd3b162015-09-29 02:58:289066
zhongyi98d6a9262017-05-19 02:47:459067 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:519068 EXPECT_EQ(OK,
9069 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529070 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
9071 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:519072 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9073 failed_on_default_network_callback_, callback_.callback()));
rtenneti1cd3b162015-09-29 02:58:289074
rcha02807b42016-01-29 21:56:159075 // Call run_loop so that QuicChromiumPacketReader::OnReadComplete() gets
9076 // called.
rtenneti1cd3b162015-09-29 02:58:289077 base::RunLoop run_loop;
9078 run_loop.RunUntilIdle();
9079
9080 // Verify task that the observer's executed_count is 1, which indicates
rcha02807b42016-01-29 21:56:159081 // QuicChromiumPacketReader::StartReading() has posted only one task and
9082 // yielded the read.
rtenneti1cd3b162015-09-29 02:58:289083 EXPECT_EQ(1u, observer.executed_count());
9084
Yixin Wang7891a39d2017-11-08 20:59:249085 std::unique_ptr<HttpStream> stream = CreateStream(&request);
xunjieli2608f9b2016-03-14 13:39:239086 EXPECT_FALSE(stream.get()); // Session is already closed.
rtenneti1cd3b162015-09-29 02:58:289087 EXPECT_TRUE(socket_data.AllReadDataConsumed());
9088 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
9089}
9090
9091TEST_P(QuicStreamFactoryTest, YieldAfterDuration) {
jri7046038f2015-10-22 00:29:269092 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:209093 factory_->set_require_confirmation(false);
rch6faa4d42016-01-05 20:48:439094 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9095 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rtenneti1cd3b162015-09-29 02:58:289096 QuicStreamFactoryPeer::SetYieldAfterDuration(
Ryan Hamilton8d9ee76e2018-05-29 23:52:529097 factory_.get(), quic::QuicTime::Delta::FromMilliseconds(-1));
rtenneti1cd3b162015-09-29 02:58:289098
Ryan Hamiltonabad59e2019-06-06 04:02:599099 MockQuicData socket_data(version_);
Fan Yangac867502019-01-28 21:10:239100 socket_data.AddRead(SYNCHRONOUS, ConstructClientConnectionClosePacket(1));
rcha00569732016-08-27 11:09:369101 socket_data.AddRead(ASYNC, OK);
Zhongyi Shi5f587cc2017-11-21 23:24:179102 socket_data.AddSocketDataToFactory(socket_factory_.get());
rtenneti1cd3b162015-09-29 02:58:289103
9104 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:279105 MockCryptoClientStream::ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:309106 host_resolver_->set_synchronous_mode(true);
9107 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
9108 "192.168.0.1", "");
rtenneti1cd3b162015-09-29 02:58:289109
rcha02807b42016-01-29 21:56:159110 // Set up the TaskObserver to verify QuicChromiumPacketReader::StartReading
9111 // posts a task.
rtenneti1cd3b162015-09-29 02:58:289112 // TODO(rtenneti): Change SpdySessionTestTaskObserver to NetTestTaskObserver??
rcha02807b42016-01-29 21:56:159113 SpdySessionTestTaskObserver observer("quic_chromium_packet_reader.cc",
9114 "StartReading");
rtenneti1cd3b162015-09-29 02:58:289115
zhongyi98d6a9262017-05-19 02:47:459116 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:519117 EXPECT_EQ(OK,
9118 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529119 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
9120 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:519121 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9122 failed_on_default_network_callback_, callback_.callback()));
rtenneti1cd3b162015-09-29 02:58:289123
rcha02807b42016-01-29 21:56:159124 // Call run_loop so that QuicChromiumPacketReader::OnReadComplete() gets
9125 // called.
rtenneti1cd3b162015-09-29 02:58:289126 base::RunLoop run_loop;
9127 run_loop.RunUntilIdle();
9128
9129 // Verify task that the observer's executed_count is 1, which indicates
rcha02807b42016-01-29 21:56:159130 // QuicChromiumPacketReader::StartReading() has posted only one task and
9131 // yielded the read.
rtenneti1cd3b162015-09-29 02:58:289132 EXPECT_EQ(1u, observer.executed_count());
9133
Yixin Wang7891a39d2017-11-08 20:59:249134 std::unique_ptr<HttpStream> stream = CreateStream(&request);
xunjieli2608f9b2016-03-14 13:39:239135 EXPECT_FALSE(stream.get()); // Session is already closed.
rtenneti1cd3b162015-09-29 02:58:289136 EXPECT_TRUE(socket_data.AllReadDataConsumed());
9137 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
9138}
9139
ckrasic3865ee0f2016-02-29 22:04:569140TEST_P(QuicStreamFactoryTest, ServerPushSessionAffinity) {
9141 Initialize();
9142 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9143 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9144
Ryan Hamiltonabad59e2019-06-06 04:02:599145 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:369146 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:439147 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:179148 socket_data.AddSocketDataToFactory(socket_factory_.get());
ckrasic3865ee0f2016-02-29 22:04:569149
zhongyi98d6a9262017-05-19 02:47:459150 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339151 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039152 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529153 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
9154 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039155 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9156 failed_on_default_network_callback_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:569157
robpercival214763f2016-07-01 23:27:019158 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:249159 std::unique_ptr<HttpStream> stream = CreateStream(&request);
ckrasic3865ee0f2016-02-29 22:04:569160 EXPECT_TRUE(stream.get());
9161
9162 EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumPushStreamsCreated(factory_.get()));
9163
bnc5fdc07162016-05-23 17:36:039164 string url = "https://www.example.org/";
ckrasic3865ee0f2016-02-29 22:04:569165
bnc912a04b2016-04-20 14:19:509166 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
ckrasic3865ee0f2016-02-29 22:04:569167
Ryan Hamilton8d9ee76e2018-05-29 23:52:529168 quic::QuicClientPromisedInfo promised(
Fan Yang32c5a112018-12-10 20:06:339169 session, GetNthServerInitiatedUnidirectionalStreamId(0), kDefaultUrl);
ckrasic3865ee0f2016-02-29 22:04:569170 (*QuicStreamFactoryPeer::GetPushPromiseIndex(factory_.get())
bnc3d9035b32016-06-30 18:18:489171 ->promised_by_url())[kDefaultUrl] = &promised;
ckrasic3865ee0f2016-02-29 22:04:569172
zhongyi98d6a9262017-05-19 02:47:459173 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:519174 EXPECT_EQ(OK,
9175 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529176 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
9177 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:519178 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9179 failed_on_default_network_callback_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:569180
9181 EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumPushStreamsCreated(factory_.get()));
9182}
9183
9184TEST_P(QuicStreamFactoryTest, ServerPushPrivacyModeMismatch) {
9185 Initialize();
9186 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9187 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9188 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9189
Ryan Hamiltonabad59e2019-06-06 04:02:599190 MockQuicData socket_data1(version_);
rcha00569732016-08-27 11:09:369191 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:439192 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
9193 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:339194 SYNCHRONOUS, client_maker_.MakeRstPacket(
9195 2, true, GetNthServerInitiatedUnidirectionalStreamId(0),
9196 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:179197 socket_data1.AddSocketDataToFactory(socket_factory_.get());
ckrasic3865ee0f2016-02-29 22:04:569198
Ryan Hamilton0d65a8c2019-06-07 00:46:029199 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:599200 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:369201 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:439202 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:179203 socket_data2.AddSocketDataToFactory(socket_factory_.get());
ckrasic3865ee0f2016-02-29 22:04:569204
zhongyi98d6a9262017-05-19 02:47:459205 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339206 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039207 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529208 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
9209 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039210 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9211 failed_on_default_network_callback_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:569212
robpercival214763f2016-07-01 23:27:019213 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:249214 std::unique_ptr<HttpStream> stream = CreateStream(&request);
ckrasic3865ee0f2016-02-29 22:04:569215 EXPECT_TRUE(stream.get());
9216
9217 EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumPushStreamsCreated(factory_.get()));
9218
bnc5fdc07162016-05-23 17:36:039219 string url = "https://www.example.org/";
bnc912a04b2016-04-20 14:19:509220 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
ckrasic3865ee0f2016-02-29 22:04:569221
Ryan Hamilton8d9ee76e2018-05-29 23:52:529222 quic::QuicClientPromisedInfo promised(
Fan Yang32c5a112018-12-10 20:06:339223 session, GetNthServerInitiatedUnidirectionalStreamId(0), kDefaultUrl);
ckrasic3865ee0f2016-02-29 22:04:569224
Ryan Hamilton8d9ee76e2018-05-29 23:52:529225 quic::QuicClientPushPromiseIndex* index =
ckrasic3865ee0f2016-02-29 22:04:569226 QuicStreamFactoryPeer::GetPushPromiseIndex(factory_.get());
9227
bnc3d9035b32016-06-30 18:18:489228 (*index->promised_by_url())[kDefaultUrl] = &promised;
9229 EXPECT_EQ(index->GetPromised(kDefaultUrl), &promised);
ckrasic3865ee0f2016-02-29 22:04:569230
9231 // Doing the request should not use the push stream, but rather
9232 // cancel it because the privacy modes do not match.
zhongyi98d6a9262017-05-19 02:47:459233 QuicStreamRequest request2(factory_.get());
Ryan Hamilton9ef8c102019-06-28 03:58:529234 EXPECT_EQ(ERR_IO_PENDING,
9235 request2.Request(
9236 host_port_pair_, version_, PRIVACY_MODE_ENABLED,
9237 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
9238 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9239 failed_on_default_network_callback_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:569240
9241 EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumPushStreamsCreated(factory_.get()));
bnc3d9035b32016-06-30 18:18:489242 EXPECT_EQ(index->GetPromised(kDefaultUrl), nullptr);
ckrasic3865ee0f2016-02-29 22:04:569243
robpercival214763f2016-07-01 23:27:019244 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:249245 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
ckrasic3865ee0f2016-02-29 22:04:569246 EXPECT_TRUE(stream2.get());
9247
9248 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
9249 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
9250 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
9251 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
9252}
9253
Ryan Hamilton8d9ee76e2018-05-29 23:52:529254// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:459255// even if destination is different.
9256TEST_P(QuicStreamFactoryTest, PoolByOrigin) {
9257 Initialize();
9258
9259 HostPortPair destination1("first.example.com", 443);
9260 HostPortPair destination2("second.example.com", 443);
9261
9262 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9263 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9264
Ryan Hamiltonabad59e2019-06-06 04:02:599265 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:369266 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:439267 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:179268 socket_data.AddSocketDataToFactory(socket_factory_.get());
bnc359ed2a2016-04-29 20:43:459269
zhongyi98d6a9262017-05-19 02:47:459270 QuicStreamRequest request1(factory_.get());
Nick Harper23290b82019-05-02 00:02:569271 EXPECT_EQ(ERR_IO_PENDING,
9272 request1.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529273 destination1, version_, privacy_mode_, DEFAULT_PRIORITY,
9274 SocketTag(), NetworkIsolationKey(),
Nick Harper23290b82019-05-02 00:02:569275 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9276 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:019277 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:249278 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
bnc359ed2a2016-04-29 20:43:459279 EXPECT_TRUE(stream1.get());
9280 EXPECT_TRUE(HasActiveSession(host_port_pair_));
9281
9282 // Second request returns synchronously because it pools to existing session.
9283 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:459284 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:519285 EXPECT_EQ(OK,
9286 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529287 destination2, version_, privacy_mode_, DEFAULT_PRIORITY,
9288 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:519289 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9290 failed_on_default_network_callback_, callback2.callback()));
Yixin Wang7891a39d2017-11-08 20:59:249291 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
bnc359ed2a2016-04-29 20:43:459292 EXPECT_TRUE(stream2.get());
9293
rchf0b18c8a2017-05-05 19:31:579294 QuicChromiumClientSession::Handle* session1 =
9295 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
9296 QuicChromiumClientSession::Handle* session2 =
9297 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
9298 EXPECT_TRUE(session1->SharesSameSession(*session2));
Ryan Hamilton4f0b26e2018-06-27 23:52:329299 EXPECT_EQ(quic::QuicServerId(host_port_pair_.host(), host_port_pair_.port(),
9300 privacy_mode_ == PRIVACY_MODE_ENABLED),
bnc359ed2a2016-04-29 20:43:459301 session1->server_id());
9302
9303 EXPECT_TRUE(socket_data.AllReadDataConsumed());
9304 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
9305}
9306
9307class QuicStreamFactoryWithDestinationTest
9308 : public QuicStreamFactoryTestBase,
9309 public ::testing::TestWithParam<PoolingTestParams> {
9310 protected:
9311 QuicStreamFactoryWithDestinationTest()
Yixin Wang079ad542018-01-11 04:06:059312 : QuicStreamFactoryTestBase(
9313 GetParam().version,
9314 GetParam().client_headers_include_h2_stream_dependency),
bnc359ed2a2016-04-29 20:43:459315 destination_type_(GetParam().destination_type),
9316 hanging_read_(SYNCHRONOUS, ERR_IO_PENDING, 0) {}
9317
9318 HostPortPair GetDestination() {
9319 switch (destination_type_) {
9320 case SAME_AS_FIRST:
9321 return origin1_;
9322 case SAME_AS_SECOND:
9323 return origin2_;
9324 case DIFFERENT:
9325 return HostPortPair(kDifferentHostname, 443);
9326 default:
9327 NOTREACHED();
9328 return HostPortPair();
9329 }
9330 }
9331
9332 void AddHangingSocketData() {
9333 std::unique_ptr<SequencedSocketData> sequenced_socket_data(
Ryan Sleevib8d7ea02018-05-07 20:01:019334 new SequencedSocketData(base::make_span(&hanging_read_, 1),
9335 base::span<MockWrite>()));
Zhongyi Shi5f587cc2017-11-21 23:24:179336 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
bnc359ed2a2016-04-29 20:43:459337 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
9338 }
9339
9340 bool AllDataConsumed() {
9341 for (const auto& socket_data_ptr : sequenced_socket_data_vector_) {
9342 if (!socket_data_ptr->AllReadDataConsumed() ||
9343 !socket_data_ptr->AllWriteDataConsumed()) {
9344 return false;
9345 }
9346 }
9347 return true;
9348 }
9349
9350 DestinationType destination_type_;
9351 HostPortPair origin1_;
9352 HostPortPair origin2_;
9353 MockRead hanging_read_;
rch872e00e2016-12-02 02:48:189354 std::vector<std::unique_ptr<SequencedSocketData>>
9355 sequenced_socket_data_vector_;
bnc359ed2a2016-04-29 20:43:459356};
9357
Victor Costane635086f2019-01-27 05:20:309358INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
9359 QuicStreamFactoryWithDestinationTest,
9360 ::testing::ValuesIn(GetPoolingTestParams()));
bnc359ed2a2016-04-29 20:43:459361
9362// A single QUIC request fails because the certificate does not match the origin
9363// hostname, regardless of whether it matches the alternative service hostname.
9364TEST_P(QuicStreamFactoryWithDestinationTest, InvalidCertificate) {
9365 if (destination_type_ == DIFFERENT)
9366 return;
9367
9368 Initialize();
9369
9370 GURL url("https://mail.example.com/");
9371 origin1_ = HostPortPair::FromURL(url);
9372
9373 // Not used for requests, but this provides a test case where the certificate
9374 // is valid for the hostname of the alternative service.
9375 origin2_ = HostPortPair("mail.example.org", 433);
9376
9377 HostPortPair destination = GetDestination();
9378
9379 scoped_refptr<X509Certificate> cert(
9380 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:249381 ASSERT_FALSE(cert->VerifyNameMatch(origin1_.host()));
9382 ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host()));
bnc359ed2a2016-04-29 20:43:459383
9384 ProofVerifyDetailsChromium verify_details;
9385 verify_details.cert_verify_result.verified_cert = cert;
9386 verify_details.cert_verify_result.is_issued_by_known_root = true;
9387 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9388
9389 AddHangingSocketData();
9390
zhongyi98d6a9262017-05-19 02:47:459391 QuicStreamRequest request(factory_.get());
Nick Harper23290b82019-05-02 00:02:569392 EXPECT_EQ(ERR_IO_PENDING,
9393 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529394 destination, version_, privacy_mode_, DEFAULT_PRIORITY,
9395 SocketTag(), NetworkIsolationKey(),
Nick Harper23290b82019-05-02 00:02:569396 /*cert_verify_flags=*/0, url, net_log_, &net_error_details_,
9397 failed_on_default_network_callback_, callback_.callback()));
bnc359ed2a2016-04-29 20:43:459398
robpercival214763f2016-07-01 23:27:019399 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_QUIC_HANDSHAKE_FAILED));
bnc359ed2a2016-04-29 20:43:459400
9401 EXPECT_TRUE(AllDataConsumed());
9402}
9403
9404// QuicStreamRequest is pooled based on |destination| if certificate matches.
9405TEST_P(QuicStreamFactoryWithDestinationTest, SharedCertificate) {
9406 Initialize();
9407
9408 GURL url1("https://www.example.org/");
9409 GURL url2("https://mail.example.org/");
9410 origin1_ = HostPortPair::FromURL(url1);
9411 origin2_ = HostPortPair::FromURL(url2);
9412
9413 HostPortPair destination = GetDestination();
9414
9415 scoped_refptr<X509Certificate> cert(
9416 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:249417 ASSERT_TRUE(cert->VerifyNameMatch(origin1_.host()));
9418 ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host()));
9419 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:459420
9421 ProofVerifyDetailsChromium verify_details;
9422 verify_details.cert_verify_result.verified_cert = cert;
9423 verify_details.cert_verify_result.is_issued_by_known_root = true;
9424 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9425
fayang3bcb8b502016-12-07 21:44:379426 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:529427 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Ryan Hamilton0d65a8c2019-06-07 00:46:029428 client_maker_.MakeInitialSettingsPacket(1));
bnceb9aa7112017-01-05 01:03:469429 MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(),
9430 settings_packet->length(), 1)};
fayang3bcb8b502016-12-07 21:44:379431 std::unique_ptr<SequencedSocketData> sequenced_socket_data(
Ryan Sleevib8d7ea02018-05-07 20:01:019432 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:179433 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
fayang3bcb8b502016-12-07 21:44:379434 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
bnc359ed2a2016-04-29 20:43:459435
zhongyi98d6a9262017-05-19 02:47:459436 QuicStreamRequest request1(factory_.get());
Nick Harper23290b82019-05-02 00:02:569437 EXPECT_EQ(ERR_IO_PENDING,
9438 request1.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529439 destination, version_, privacy_mode_, DEFAULT_PRIORITY,
9440 SocketTag(), NetworkIsolationKey(),
Nick Harper23290b82019-05-02 00:02:569441 /*cert_verify_flags=*/0, url1, net_log_, &net_error_details_,
9442 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:019443 EXPECT_THAT(callback_.WaitForResult(), IsOk());
fayang3bcb8b502016-12-07 21:44:379444
Yixin Wang7891a39d2017-11-08 20:59:249445 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
bnc359ed2a2016-04-29 20:43:459446 EXPECT_TRUE(stream1.get());
9447 EXPECT_TRUE(HasActiveSession(origin1_));
9448
9449 // Second request returns synchronously because it pools to existing session.
9450 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:459451 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:519452 EXPECT_EQ(OK,
9453 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529454 destination, version_, privacy_mode_, DEFAULT_PRIORITY,
9455 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:519456 /*cert_verify_flags=*/0, url2, net_log_, &net_error_details_,
9457 failed_on_default_network_callback_, callback2.callback()));
Yixin Wang7891a39d2017-11-08 20:59:249458 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
bnc359ed2a2016-04-29 20:43:459459 EXPECT_TRUE(stream2.get());
9460
rchf0b18c8a2017-05-05 19:31:579461 QuicChromiumClientSession::Handle* session1 =
9462 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
9463 QuicChromiumClientSession::Handle* session2 =
9464 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
9465 EXPECT_TRUE(session1->SharesSameSession(*session2));
bnc359ed2a2016-04-29 20:43:459466
Ryan Hamilton4f0b26e2018-06-27 23:52:329467 EXPECT_EQ(quic::QuicServerId(origin1_.host(), origin1_.port(),
9468 privacy_mode_ == PRIVACY_MODE_ENABLED),
9469 session1->server_id());
bnc359ed2a2016-04-29 20:43:459470
9471 EXPECT_TRUE(AllDataConsumed());
9472}
9473
bnc47eba7d2016-07-01 00:43:389474// QuicStreamRequest is not pooled if PrivacyMode differs.
9475TEST_P(QuicStreamFactoryWithDestinationTest, DifferentPrivacyMode) {
9476 Initialize();
9477
9478 GURL url1("https://www.example.org/");
9479 GURL url2("https://mail.example.org/");
9480 origin1_ = HostPortPair::FromURL(url1);
9481 origin2_ = HostPortPair::FromURL(url2);
9482
9483 HostPortPair destination = GetDestination();
9484
9485 scoped_refptr<X509Certificate> cert(
9486 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:249487 ASSERT_TRUE(cert->VerifyNameMatch(origin1_.host()));
9488 ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host()));
9489 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc47eba7d2016-07-01 00:43:389490
9491 ProofVerifyDetailsChromium verify_details1;
9492 verify_details1.cert_verify_result.verified_cert = cert;
9493 verify_details1.cert_verify_result.is_issued_by_known_root = true;
9494 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
9495
9496 ProofVerifyDetailsChromium verify_details2;
9497 verify_details2.cert_verify_result.verified_cert = cert;
9498 verify_details2.cert_verify_result.is_issued_by_known_root = true;
9499 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
9500
fayang3bcb8b502016-12-07 21:44:379501 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:529502 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Ryan Hamilton0d65a8c2019-06-07 00:46:029503 client_maker_.MakeInitialSettingsPacket(1));
bnceb9aa7112017-01-05 01:03:469504 MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(),
9505 settings_packet->length(), 1)};
fayang3bcb8b502016-12-07 21:44:379506 std::unique_ptr<SequencedSocketData> sequenced_socket_data(
Ryan Sleevib8d7ea02018-05-07 20:01:019507 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:179508 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
fayang3bcb8b502016-12-07 21:44:379509 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
9510 std::unique_ptr<SequencedSocketData> sequenced_socket_data1(
Ryan Sleevib8d7ea02018-05-07 20:01:019511 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:179512 socket_factory_->AddSocketDataProvider(sequenced_socket_data1.get());
fayang3bcb8b502016-12-07 21:44:379513 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data1));
bnc47eba7d2016-07-01 00:43:389514
zhongyi98d6a9262017-05-19 02:47:459515 QuicStreamRequest request1(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339516 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039517 request1.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529518 destination, version_, PRIVACY_MODE_DISABLED, DEFAULT_PRIORITY,
9519 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039520 /*cert_verify_flags=*/0, url1, net_log_, &net_error_details_,
9521 failed_on_default_network_callback_, callback_.callback()));
bnc47eba7d2016-07-01 00:43:389522 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:249523 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
bnc47eba7d2016-07-01 00:43:389524 EXPECT_TRUE(stream1.get());
9525 EXPECT_TRUE(HasActiveSession(origin1_));
9526
9527 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:459528 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339529 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039530 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529531 destination, version_, PRIVACY_MODE_ENABLED, DEFAULT_PRIORITY,
9532 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039533 /*cert_verify_flags=*/0, url2, net_log_, &net_error_details_,
9534 failed_on_default_network_callback_, callback2.callback()));
bnc47eba7d2016-07-01 00:43:389535 EXPECT_EQ(OK, callback2.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:249536 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
bnc47eba7d2016-07-01 00:43:389537 EXPECT_TRUE(stream2.get());
9538
9539 // |request2| does not pool to the first session, because PrivacyMode does not
9540 // match. Instead, another session is opened to the same destination, but
Ryan Hamilton8d9ee76e2018-05-29 23:52:529541 // with a different quic::QuicServerId.
rchf0b18c8a2017-05-05 19:31:579542 QuicChromiumClientSession::Handle* session1 =
9543 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
9544 QuicChromiumClientSession::Handle* session2 =
9545 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
9546 EXPECT_FALSE(session1->SharesSameSession(*session2));
bnc47eba7d2016-07-01 00:43:389547
Ryan Hamilton4f0b26e2018-06-27 23:52:329548 EXPECT_EQ(quic::QuicServerId(origin1_.host(), origin1_.port(), false),
bnc47eba7d2016-07-01 00:43:389549 session1->server_id());
Ryan Hamilton4f0b26e2018-06-27 23:52:329550 EXPECT_EQ(quic::QuicServerId(origin2_.host(), origin2_.port(), true),
bnc47eba7d2016-07-01 00:43:389551 session2->server_id());
9552
9553 EXPECT_TRUE(AllDataConsumed());
9554}
9555
bnc359ed2a2016-04-29 20:43:459556// QuicStreamRequest is not pooled if certificate does not match its origin.
9557TEST_P(QuicStreamFactoryWithDestinationTest, DisjointCertificate) {
9558 Initialize();
9559
9560 GURL url1("https://news.example.org/");
9561 GURL url2("https://mail.example.com/");
9562 origin1_ = HostPortPair::FromURL(url1);
9563 origin2_ = HostPortPair::FromURL(url2);
9564
9565 HostPortPair destination = GetDestination();
9566
9567 scoped_refptr<X509Certificate> cert1(
9568 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:249569 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_.host()));
9570 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_.host()));
9571 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:459572
9573 ProofVerifyDetailsChromium verify_details1;
9574 verify_details1.cert_verify_result.verified_cert = cert1;
9575 verify_details1.cert_verify_result.is_issued_by_known_root = true;
9576 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
9577
9578 scoped_refptr<X509Certificate> cert2(
9579 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:249580 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_.host()));
9581 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:459582
9583 ProofVerifyDetailsChromium verify_details2;
9584 verify_details2.cert_verify_result.verified_cert = cert2;
9585 verify_details2.cert_verify_result.is_issued_by_known_root = true;
9586 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
9587
fayang3bcb8b502016-12-07 21:44:379588 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:529589 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Ryan Hamilton0d65a8c2019-06-07 00:46:029590 client_maker_.MakeInitialSettingsPacket(1));
bnceb9aa7112017-01-05 01:03:469591 MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(),
9592 settings_packet->length(), 1)};
fayang3bcb8b502016-12-07 21:44:379593 std::unique_ptr<SequencedSocketData> sequenced_socket_data(
Ryan Sleevib8d7ea02018-05-07 20:01:019594 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:179595 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
fayang3bcb8b502016-12-07 21:44:379596 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
9597 std::unique_ptr<SequencedSocketData> sequenced_socket_data1(
Ryan Sleevib8d7ea02018-05-07 20:01:019598 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:179599 socket_factory_->AddSocketDataProvider(sequenced_socket_data1.get());
fayang3bcb8b502016-12-07 21:44:379600 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data1));
bnc359ed2a2016-04-29 20:43:459601
zhongyi98d6a9262017-05-19 02:47:459602 QuicStreamRequest request1(factory_.get());
Nick Harper23290b82019-05-02 00:02:569603 EXPECT_EQ(ERR_IO_PENDING,
9604 request1.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529605 destination, version_, privacy_mode_, DEFAULT_PRIORITY,
9606 SocketTag(), NetworkIsolationKey(),
Nick Harper23290b82019-05-02 00:02:569607 /*cert_verify_flags=*/0, url1, net_log_, &net_error_details_,
9608 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:019609 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:249610 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
bnc359ed2a2016-04-29 20:43:459611 EXPECT_TRUE(stream1.get());
9612 EXPECT_TRUE(HasActiveSession(origin1_));
9613
9614 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:459615 QuicStreamRequest request2(factory_.get());
Nick Harper23290b82019-05-02 00:02:569616 EXPECT_EQ(ERR_IO_PENDING,
9617 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529618 destination, version_, privacy_mode_, DEFAULT_PRIORITY,
9619 SocketTag(), NetworkIsolationKey(),
Nick Harper23290b82019-05-02 00:02:569620 /*cert_verify_flags=*/0, url2, net_log_, &net_error_details_,
9621 failed_on_default_network_callback_, callback2.callback()));
robpercival214763f2016-07-01 23:27:019622 EXPECT_THAT(callback2.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:249623 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
bnc359ed2a2016-04-29 20:43:459624 EXPECT_TRUE(stream2.get());
9625
9626 // |request2| does not pool to the first session, because the certificate does
9627 // not match. Instead, another session is opened to the same destination, but
Ryan Hamilton8d9ee76e2018-05-29 23:52:529628 // with a different quic::QuicServerId.
rchf0b18c8a2017-05-05 19:31:579629 QuicChromiumClientSession::Handle* session1 =
9630 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
9631 QuicChromiumClientSession::Handle* session2 =
9632 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
9633 EXPECT_FALSE(session1->SharesSameSession(*session2));
bnc359ed2a2016-04-29 20:43:459634
Ryan Hamilton4f0b26e2018-06-27 23:52:329635 EXPECT_EQ(quic::QuicServerId(origin1_.host(), origin1_.port(),
9636 privacy_mode_ == PRIVACY_MODE_ENABLED),
9637 session1->server_id());
9638 EXPECT_EQ(quic::QuicServerId(origin2_.host(), origin2_.port(),
9639 privacy_mode_ == PRIVACY_MODE_ENABLED),
9640 session2->server_id());
bnc359ed2a2016-04-29 20:43:459641
9642 EXPECT_TRUE(AllDataConsumed());
9643}
9644
msramek992625ec2016-08-04 18:33:589645// This test verifies that QuicStreamFactory::ClearCachedStatesInCryptoConfig
9646// correctly transform an origin filter to a ServerIdFilter. Whether the
9647// deletion itself works correctly is tested in QuicCryptoClientConfigTest.
9648TEST_P(QuicStreamFactoryTest, ClearCachedStatesInCryptoConfig) {
9649 Initialize();
Ryan Hamilton8d9ee76e2018-05-29 23:52:529650 quic::QuicCryptoClientConfig* crypto_config =
msramek992625ec2016-08-04 18:33:589651 QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
9652
9653 struct TestCase {
9654 TestCase(const std::string& host,
9655 int port,
9656 PrivacyMode privacy_mode,
Ryan Hamilton8d9ee76e2018-05-29 23:52:529657 quic::QuicCryptoClientConfig* crypto_config)
msramek992625ec2016-08-04 18:33:589658 : server_id(host, port, privacy_mode),
9659 state(crypto_config->LookupOrCreate(server_id)) {
rch872e00e2016-12-02 02:48:189660 std::vector<string> certs(1);
msramek992625ec2016-08-04 18:33:589661 certs[0] = "cert";
9662 state->SetProof(certs, "cert_sct", "chlo_hash", "signature");
9663 state->set_source_address_token("TOKEN");
9664 state->SetProofValid();
9665
9666 EXPECT_FALSE(state->certs().empty());
9667 }
9668
Ryan Hamilton8d9ee76e2018-05-29 23:52:529669 quic::QuicServerId server_id;
9670 quic::QuicCryptoClientConfig::CachedState* state;
msramek992625ec2016-08-04 18:33:589671 } test_cases[] = {
9672 TestCase("www.google.com", 443, privacy_mode_, crypto_config),
9673 TestCase("www.example.com", 443, privacy_mode_, crypto_config),
9674 TestCase("www.example.com", 4433, privacy_mode_, crypto_config)};
9675
9676 // Clear cached states for the origin https://www.example.com:4433.
9677 GURL origin("https://www.example.com:4433");
csharrisonebeca8e2016-10-18 02:35:369678 factory_->ClearCachedStatesInCryptoConfig(base::Bind(
9679 static_cast<bool (*)(const GURL&, const GURL&)>(::operator==), origin));
msramek992625ec2016-08-04 18:33:589680 EXPECT_FALSE(test_cases[0].state->certs().empty());
9681 EXPECT_FALSE(test_cases[1].state->certs().empty());
9682 EXPECT_TRUE(test_cases[2].state->certs().empty());
9683
9684 // Clear all cached states.
9685 factory_->ClearCachedStatesInCryptoConfig(
9686 base::Callback<bool(const GURL&)>());
9687 EXPECT_TRUE(test_cases[0].state->certs().empty());
9688 EXPECT_TRUE(test_cases[1].state->certs().empty());
9689 EXPECT_TRUE(test_cases[2].state->certs().empty());
9690}
9691
Yixin Wang46a425f2017-08-10 23:02:209692// Passes connection options and client connection options to QuicStreamFactory,
Ryan Hamilton8d9ee76e2018-05-29 23:52:529693// then checks that its internal quic::QuicConfig is correct.
Yixin Wang46a425f2017-08-10 23:02:209694TEST_P(QuicStreamFactoryTest, ConfigConnectionOptions) {
Zhongyi Shi967d2f12019-02-08 20:58:539695 test_params_.quic_connection_options.push_back(quic::kTIME);
9696 test_params_.quic_connection_options.push_back(quic::kTBBR);
9697 test_params_.quic_connection_options.push_back(quic::kREJ);
Yixin Wang46a425f2017-08-10 23:02:209698
Zhongyi Shi967d2f12019-02-08 20:58:539699 test_params_.quic_client_connection_options.push_back(quic::kTBBR);
9700 test_params_.quic_client_connection_options.push_back(quic::k1RTT);
Yixin Wang46a425f2017-08-10 23:02:209701
9702 Initialize();
9703
Ryan Hamilton8d9ee76e2018-05-29 23:52:529704 const quic::QuicConfig* config =
9705 QuicStreamFactoryPeer::GetConfig(factory_.get());
Zhongyi Shi967d2f12019-02-08 20:58:539706 EXPECT_EQ(test_params_.quic_connection_options,
9707 config->SendConnectionOptions());
Yixin Wang46a425f2017-08-10 23:02:209708 EXPECT_TRUE(config->HasClientRequestedIndependentOption(
Ryan Hamilton8d9ee76e2018-05-29 23:52:529709 quic::kTBBR, quic::Perspective::IS_CLIENT));
Yixin Wang46a425f2017-08-10 23:02:209710 EXPECT_TRUE(config->HasClientRequestedIndependentOption(
Ryan Hamilton8d9ee76e2018-05-29 23:52:529711 quic::k1RTT, quic::Perspective::IS_CLIENT));
Yixin Wang46a425f2017-08-10 23:02:209712}
9713
Yixin Wang247ea642017-11-15 01:15:509714// Verifies that the host resolver uses the request priority passed to
9715// QuicStreamRequest::Request().
9716TEST_P(QuicStreamFactoryTest, HostResolverUsesRequestPriority) {
9717 Initialize();
9718 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9719 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9720
Ryan Hamiltonabad59e2019-06-06 04:02:599721 MockQuicData socket_data(version_);
Yixin Wang247ea642017-11-15 01:15:509722 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:439723 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:179724 socket_data.AddSocketDataToFactory(socket_factory_.get());
Yixin Wang247ea642017-11-15 01:15:509725
9726 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339727 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039728 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529729 host_port_pair_, version_, privacy_mode_, MAXIMUM_PRIORITY,
9730 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039731 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9732 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang247ea642017-11-15 01:15:509733
9734 EXPECT_THAT(callback_.WaitForResult(), IsOk());
9735 std::unique_ptr<HttpStream> stream = CreateStream(&request);
9736 EXPECT_TRUE(stream.get());
9737
Renjiea0cb4a2c2018-09-26 23:37:309738 EXPECT_EQ(MAXIMUM_PRIORITY, host_resolver_->last_request_priority());
Yixin Wang247ea642017-11-15 01:15:509739
9740 EXPECT_TRUE(socket_data.AllReadDataConsumed());
9741 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
9742}
9743
Lily Chenf11e1292018-11-29 16:42:099744TEST_P(QuicStreamFactoryTest, HostResolverRequestReprioritizedOnSetPriority) {
9745 Initialize();
9746 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9747 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9748
Ryan Hamiltonabad59e2019-06-06 04:02:599749 MockQuicData socket_data(version_);
Lily Chenf11e1292018-11-29 16:42:099750 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9751 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
9752 socket_data.AddSocketDataToFactory(socket_factory_.get());
9753
9754 QuicStreamRequest request(factory_.get());
9755 EXPECT_EQ(ERR_IO_PENDING,
9756 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529757 host_port_pair_, version_, privacy_mode_, MAXIMUM_PRIORITY,
9758 SocketTag(), NetworkIsolationKey(),
Lily Chenf11e1292018-11-29 16:42:099759 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9760 failed_on_default_network_callback_, callback_.callback()));
9761
9762 EXPECT_EQ(MAXIMUM_PRIORITY, host_resolver_->last_request_priority());
9763 EXPECT_EQ(MAXIMUM_PRIORITY, host_resolver_->request_priority(1));
9764
9765 QuicStreamRequest request2(factory_.get());
9766 EXPECT_EQ(ERR_IO_PENDING,
9767 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529768 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
9769 SocketTag(), NetworkIsolationKey(),
Lily Chenf11e1292018-11-29 16:42:099770 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
9771 failed_on_default_network_callback_, callback_.callback()));
9772 EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_->last_request_priority());
9773 EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_->request_priority(2));
9774
9775 request.SetPriority(LOWEST);
9776 EXPECT_EQ(LOWEST, host_resolver_->request_priority(1));
9777 EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_->request_priority(2));
9778}
9779
Zhongyi Shi967d2f12019-02-08 20:58:539780// Passes |quic_max_time_before_crypto_handshake_seconds| and
9781// |quic_max_idle_time_before_crypto_handshake_seconds| to QuicStreamFactory,
Ryan Hamilton8d9ee76e2018-05-29 23:52:529782// checks that its internal quic::QuicConfig is correct.
Yixin Wang469da562017-11-15 21:34:589783TEST_P(QuicStreamFactoryTest, ConfigMaxTimeBeforeCryptoHandshake) {
Zhongyi Shi967d2f12019-02-08 20:58:539784 test_params_.quic_max_time_before_crypto_handshake_seconds = 11;
9785 test_params_.quic_max_idle_time_before_crypto_handshake_seconds = 13;
Yixin Wang469da562017-11-15 21:34:589786 Initialize();
9787
Ryan Hamilton8d9ee76e2018-05-29 23:52:529788 const quic::QuicConfig* config =
9789 QuicStreamFactoryPeer::GetConfig(factory_.get());
9790 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(11),
Yixin Wang469da562017-11-15 21:34:589791 config->max_time_before_crypto_handshake());
Ryan Hamilton8d9ee76e2018-05-29 23:52:529792 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(13),
Yixin Wang469da562017-11-15 21:34:589793 config->max_idle_time_before_crypto_handshake());
9794}
9795
Yixin Wang7c5d11a82017-12-21 02:40:009796// Verify ResultAfterHostResolutionCallback behavior when host resolution
9797// succeeds asynchronously, then crypto handshake fails synchronously.
9798TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackAsyncSync) {
9799 Initialize();
9800 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9801 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9802
Renjiea0cb4a2c2018-09-26 23:37:309803 host_resolver_->set_ondemand_mode(true);
Yixin Wang7c5d11a82017-12-21 02:40:009804
Ryan Hamiltonabad59e2019-06-06 04:02:599805 MockQuicData socket_data(version_);
Yixin Wang7c5d11a82017-12-21 02:40:009806 socket_data.AddRead(SYNCHRONOUS, ERR_FAILED);
9807 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
9808 socket_data.AddSocketDataToFactory(socket_factory_.get());
9809
9810 QuicStreamRequest request(factory_.get());
9811 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039812 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529813 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
9814 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039815 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9816 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:009817
9818 TestCompletionCallback host_resolution_callback;
9819 EXPECT_TRUE(
9820 request.WaitForHostResolution(host_resolution_callback.callback()));
9821
9822 // |host_resolver_| has not finished host resolution at this point, so
9823 // |host_resolution_callback| should not have a result.
9824 base::RunLoop().RunUntilIdle();
9825 EXPECT_FALSE(host_resolution_callback.have_result());
9826
9827 // Allow |host_resolver_| to finish host resolution.
9828 // Since the request fails immediately after host resolution (getting
9829 // ERR_FAILED from socket reads/writes), |host_resolution_callback| should be
9830 // called with ERR_QUIC_PROTOCOL_ERROR since that's the next result in
9831 // forming the connection.
Renjiea0cb4a2c2018-09-26 23:37:309832 host_resolver_->ResolveAllPending();
Yixin Wang7c5d11a82017-12-21 02:40:009833 base::RunLoop().RunUntilIdle();
9834 EXPECT_TRUE(host_resolution_callback.have_result());
9835 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, host_resolution_callback.WaitForResult());
9836
9837 // Calling WaitForHostResolution() a second time should return
9838 // false since host resolution has finished already.
9839 EXPECT_FALSE(
9840 request.WaitForHostResolution(host_resolution_callback.callback()));
9841
9842 EXPECT_TRUE(callback_.have_result());
9843 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
9844}
9845
9846// Verify ResultAfterHostResolutionCallback behavior when host resolution
9847// succeeds asynchronously, then crypto handshake fails asynchronously.
9848TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackAsyncAsync) {
9849 Initialize();
9850 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9851 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9852
Renjiea0cb4a2c2018-09-26 23:37:309853 host_resolver_->set_ondemand_mode(true);
Yixin Wang7c5d11a82017-12-21 02:40:009854 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:279855 MockCryptoClientStream::ZERO_RTT);
Yixin Wang7c5d11a82017-12-21 02:40:009856 factory_->set_require_confirmation(true);
9857
Ryan Hamiltonabad59e2019-06-06 04:02:599858 MockQuicData socket_data(version_);
Yixin Wang7c5d11a82017-12-21 02:40:009859 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
9860 socket_data.AddRead(ASYNC, ERR_FAILED);
9861 socket_data.AddWrite(ASYNC, ERR_FAILED);
9862 socket_data.AddSocketDataToFactory(socket_factory_.get());
9863
9864 QuicStreamRequest request(factory_.get());
9865 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039866 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529867 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
9868 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039869 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9870 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:009871
9872 TestCompletionCallback host_resolution_callback;
9873 EXPECT_TRUE(
9874 request.WaitForHostResolution(host_resolution_callback.callback()));
9875
9876 // |host_resolver_| has not finished host resolution at this point, so
9877 // |host_resolution_callback| should not have a result.
9878 base::RunLoop().RunUntilIdle();
9879 EXPECT_FALSE(host_resolution_callback.have_result());
9880
9881 // Allow |host_resolver_| to finish host resolution. Since crypto handshake
9882 // will hang after host resolution, |host_resolution_callback| should run with
9883 // ERR_IO_PENDING since that's the next result in forming the connection.
Renjiea0cb4a2c2018-09-26 23:37:309884 host_resolver_->ResolveAllPending();
Yixin Wang7c5d11a82017-12-21 02:40:009885 base::RunLoop().RunUntilIdle();
9886 EXPECT_TRUE(host_resolution_callback.have_result());
9887 EXPECT_EQ(ERR_IO_PENDING, host_resolution_callback.WaitForResult());
9888
9889 // Calling WaitForHostResolution() a second time should return
9890 // false since host resolution has finished already.
9891 EXPECT_FALSE(
9892 request.WaitForHostResolution(host_resolution_callback.callback()));
9893
9894 EXPECT_FALSE(callback_.have_result());
9895 socket_data.GetSequencedSocketData()->Resume();
9896 base::RunLoop().RunUntilIdle();
9897 EXPECT_TRUE(callback_.have_result());
9898 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
9899}
9900
9901// Verify ResultAfterHostResolutionCallback behavior when host resolution
9902// succeeds synchronously, then crypto handshake fails synchronously.
9903TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackSyncSync) {
9904 Initialize();
9905 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9906 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9907
Renjiea0cb4a2c2018-09-26 23:37:309908 host_resolver_->set_synchronous_mode(true);
Yixin Wang7c5d11a82017-12-21 02:40:009909
Ryan Hamiltonabad59e2019-06-06 04:02:599910 MockQuicData socket_data(version_);
Yixin Wang7c5d11a82017-12-21 02:40:009911 socket_data.AddRead(SYNCHRONOUS, ERR_FAILED);
9912 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
9913 socket_data.AddSocketDataToFactory(socket_factory_.get());
9914
9915 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339916 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR,
Zhongyi Shia6b68d112018-09-24 07:49:039917 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529918 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
9919 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039920 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9921 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:009922
9923 // WaitForHostResolution() should return false since host
9924 // resolution has finished already.
9925 TestCompletionCallback host_resolution_callback;
9926 EXPECT_FALSE(
9927 request.WaitForHostResolution(host_resolution_callback.callback()));
9928 base::RunLoop().RunUntilIdle();
9929 EXPECT_FALSE(host_resolution_callback.have_result());
9930 EXPECT_FALSE(callback_.have_result());
9931}
9932
9933// Verify ResultAfterHostResolutionCallback behavior when host resolution
9934// succeeds synchronously, then crypto handshake fails asynchronously.
9935TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackSyncAsync) {
9936 Initialize();
9937 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9938 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9939
9940 // Host resolution will succeed synchronously, but Request() as a whole
9941 // will fail asynchronously.
Renjiea0cb4a2c2018-09-26 23:37:309942 host_resolver_->set_synchronous_mode(true);
Yixin Wang7c5d11a82017-12-21 02:40:009943 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:279944 MockCryptoClientStream::ZERO_RTT);
Yixin Wang7c5d11a82017-12-21 02:40:009945 factory_->set_require_confirmation(true);
9946
Ryan Hamiltonabad59e2019-06-06 04:02:599947 MockQuicData socket_data(version_);
Yixin Wang7c5d11a82017-12-21 02:40:009948 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
9949 socket_data.AddRead(ASYNC, ERR_FAILED);
9950 socket_data.AddWrite(ASYNC, ERR_FAILED);
9951 socket_data.AddSocketDataToFactory(socket_factory_.get());
9952
9953 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339954 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039955 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529956 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
9957 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039958 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9959 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:009960
9961 // WaitForHostResolution() should return false since host
9962 // resolution has finished already.
9963 TestCompletionCallback host_resolution_callback;
9964 EXPECT_FALSE(
9965 request.WaitForHostResolution(host_resolution_callback.callback()));
9966 base::RunLoop().RunUntilIdle();
9967 EXPECT_FALSE(host_resolution_callback.have_result());
9968
9969 EXPECT_FALSE(callback_.have_result());
9970 socket_data.GetSequencedSocketData()->Resume();
9971 base::RunLoop().RunUntilIdle();
9972 EXPECT_TRUE(callback_.have_result());
9973 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
9974}
9975
9976// Verify ResultAfterHostResolutionCallback behavior when host resolution fails
9977// synchronously.
9978TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackFailSync) {
9979 Initialize();
9980 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9981 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9982
9983 // Host resolution will fail synchronously.
Renjiea0cb4a2c2018-09-26 23:37:309984 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
9985 host_resolver_->set_synchronous_mode(true);
Yixin Wang7c5d11a82017-12-21 02:40:009986
9987 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339988 EXPECT_EQ(ERR_NAME_NOT_RESOLVED,
Zhongyi Shia6b68d112018-09-24 07:49:039989 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529990 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
9991 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039992 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9993 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:009994
9995 // WaitForHostResolution() should return false since host
9996 // resolution has failed already.
9997 TestCompletionCallback host_resolution_callback;
9998 EXPECT_FALSE(
9999 request.WaitForHostResolution(host_resolution_callback.callback()));
10000 base::RunLoop().RunUntilIdle();
10001 EXPECT_FALSE(host_resolution_callback.have_result());
10002}
10003
10004// Verify ResultAfterHostResolutionCallback behavior when host resolution fails
10005// asynchronously.
10006TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackFailAsync) {
10007 Initialize();
10008 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10009 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10010
Renjiea0cb4a2c2018-09-26 23:37:3010011 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
Yixin Wang7c5d11a82017-12-21 02:40:0010012
10013 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:3310014 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:0310015 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210016 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10017 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:0310018 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10019 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:0010020
10021 TestCompletionCallback host_resolution_callback;
10022 EXPECT_TRUE(
10023 request.WaitForHostResolution(host_resolution_callback.callback()));
10024
10025 // Allow |host_resolver_| to fail host resolution. |host_resolution_callback|
10026 // Should run with ERR_NAME_NOT_RESOLVED since that's the error host
10027 // resolution failed with.
10028 base::RunLoop().RunUntilIdle();
10029 EXPECT_TRUE(host_resolution_callback.have_result());
10030 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, host_resolution_callback.WaitForResult());
10031
10032 EXPECT_TRUE(callback_.have_result());
10033 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, callback_.WaitForResult());
10034}
10035
Renjiea0cb4a2c2018-09-26 23:37:3010036// With dns race experiment turned on, and DNS resolve succeeds synchronously,
10037// the final connection is established through the resolved DNS. No racing
10038// connection.
10039TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceAndHostResolutionSync) {
Zhongyi Shi967d2f12019-02-08 20:58:5310040 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010041 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10042 Initialize();
10043 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10044 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10045
10046 // Set an address in resolver for synchronous return.
10047 host_resolver_->set_synchronous_mode(true);
10048 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10049 kNonCachedIPAddress, "");
10050
10051 // Set up a different address in stale resolver cache.
10052 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10053 HostCache::Entry entry(OK,
10054 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10055 HostCache::Entry::SOURCE_DNS);
10056 base::TimeDelta zero;
10057 HostCache* cache = host_resolver_->GetHostCache();
10058 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10059 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810060 cache->Invalidate();
Renjie8d2d8d91b2018-09-29 00:29:0310061
Ryan Hamiltonabad59e2019-06-06 04:02:5910062 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010063 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10064 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10065 quic_data.AddSocketDataToFactory(socket_factory_.get());
10066
10067 QuicStreamRequest request(factory_.get());
10068 EXPECT_THAT(request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210069 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10070 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010071 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10072 failed_on_default_network_callback_, callback_.callback()),
10073 IsOk());
10074 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10075 EXPECT_TRUE(stream.get());
10076 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Victor Vasilievbee79ea2019-05-15 01:25:4810077 EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress);
Renjiea0cb4a2c2018-09-26 23:37:3010078
10079 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10080 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10081}
10082
10083// With dns race experiment on, DNS resolve returns async, no matching cache in
10084// host resolver, connection should be successful and through resolved DNS. No
10085// racing connection.
10086TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceAndHostResolutionAsync) {
Renjiea0cb4a2c2018-09-26 23:37:3010087 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10088 Initialize();
10089 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10090 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10091
10092 // Set an address in resolver for asynchronous return.
10093 host_resolver_->set_ondemand_mode(true);
10094 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10095 kNonCachedIPAddress, "");
10096
Ryan Hamiltonabad59e2019-06-06 04:02:5910097 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010098 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10099 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10100 quic_data.AddSocketDataToFactory(socket_factory_.get());
10101
10102 QuicStreamRequest request(factory_.get());
10103 EXPECT_EQ(ERR_IO_PENDING,
10104 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210105 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10106 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010107 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10108 failed_on_default_network_callback_, callback_.callback()));
10109 TestCompletionCallback host_resolution_callback;
10110 EXPECT_TRUE(
10111 request.WaitForHostResolution(host_resolution_callback.callback()));
10112 base::RunLoop().RunUntilIdle();
10113 EXPECT_FALSE(host_resolution_callback.have_result());
10114
10115 // Cause the host resolution to return.
10116 host_resolver_->ResolveAllPending();
10117 EXPECT_THAT(host_resolution_callback.WaitForResult(), IsOk());
10118 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10119
10120 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10121 EXPECT_TRUE(stream.get());
10122 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
10123
Victor Vasilievbee79ea2019-05-15 01:25:4810124 EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress);
Renjiea0cb4a2c2018-09-26 23:37:3010125
10126 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10127 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10128}
10129
10130// With dns race experiment on, DNS resolve returns async, stale dns used,
10131// connects synchrounously, and then the resolved DNS matches.
10132TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveAsyncStaleMatch) {
Zhongyi Shi967d2f12019-02-08 20:58:5310133 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010134 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10135 Initialize();
10136 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10137 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10138
10139 // Set an address in resolver for asynchronous return.
10140 host_resolver_->set_ondemand_mode(true);
10141 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10142 kCachedIPAddress.ToString(), "");
10143
10144 // Set up the same address in the stale resolver cache.
10145 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10146 HostCache::Entry entry(OK,
10147 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10148 HostCache::Entry::SOURCE_DNS);
10149 base::TimeDelta zero;
10150 HostCache* cache = host_resolver_->GetHostCache();
10151 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10152 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810153 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010154
Ryan Hamiltonabad59e2019-06-06 04:02:5910155 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010156 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10157 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10158 quic_data.AddSocketDataToFactory(socket_factory_.get());
10159
10160 QuicStreamRequest request(factory_.get());
10161 EXPECT_EQ(ERR_IO_PENDING,
10162 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210163 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10164 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010165 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10166 failed_on_default_network_callback_, callback_.callback()));
10167
10168 // Check that the racing job is running.
10169 EXPECT_TRUE(HasLiveSession(host_port_pair_));
10170 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10171
10172 // Resolve dns and return.
10173 host_resolver_->ResolveAllPending();
10174 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10175 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10176 EXPECT_TRUE(stream.get());
10177
10178 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
10179
Victor Vasilievbee79ea2019-05-15 01:25:4810180 EXPECT_EQ(session->peer_address().host().ToString(),
10181 kCachedIPAddress.ToString());
Renjiea0cb4a2c2018-09-26 23:37:3010182
10183 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10184 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10185}
10186
10187// With dns race experiment on, dns resolve async, stale dns used, connect
10188// async, and then the result matches.
10189TEST_P(QuicStreamFactoryTest,
10190 ResultAfterDNSRaceHostResolveAsyncConnectAsyncStaleMatch) {
Zhongyi Shi967d2f12019-02-08 20:58:5310191 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010192 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10193 Initialize();
10194 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10195 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10196
10197 // Set an address in resolver for asynchronous return.
10198 host_resolver_->set_ondemand_mode(true);
10199 factory_->set_require_confirmation(true);
10200 crypto_client_stream_factory_.set_handshake_mode(
10201 MockCryptoClientStream::ZERO_RTT);
10202 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10203 kCachedIPAddress.ToString(), "");
10204
10205 // Set up the same address in the stale resolver cache.
10206 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10207 HostCache::Entry entry(OK,
10208 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10209 HostCache::Entry::SOURCE_DNS);
10210 base::TimeDelta zero;
10211 HostCache* cache = host_resolver_->GetHostCache();
10212 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10213 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810214 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010215
Ryan Hamiltonabad59e2019-06-06 04:02:5910216 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010217 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10218 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10219 quic_data.AddSocketDataToFactory(socket_factory_.get());
10220
10221 QuicStreamRequest request(factory_.get());
10222 EXPECT_EQ(ERR_IO_PENDING,
10223 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210224 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10225 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010226 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10227 failed_on_default_network_callback_, callback_.callback()));
10228
10229 // Send Crypto handshake so connect will call back.
10230 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
10231 quic::QuicSession::HANDSHAKE_CONFIRMED);
10232 base::RunLoop().RunUntilIdle();
10233
10234 // Check that the racing job is running.
10235 EXPECT_TRUE(HasLiveSession(host_port_pair_));
10236 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10237
10238 // Resolve dns and call back, make sure job finishes.
10239 host_resolver_->ResolveAllPending();
10240 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10241
10242 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10243 EXPECT_TRUE(stream.get());
10244
10245 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
10246
Victor Vasilievbee79ea2019-05-15 01:25:4810247 EXPECT_EQ(session->peer_address().host().ToString(),
10248 kCachedIPAddress.ToString());
Renjiea0cb4a2c2018-09-26 23:37:3010249
10250 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10251 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10252}
10253
10254// With dns race experiment on, dns resolve async, stale dns used, dns resolve
10255// return, then connection finishes and matches with the result.
10256TEST_P(QuicStreamFactoryTest,
10257 ResultAfterDNSRaceHostResolveAsyncStaleMatchConnectAsync) {
Zhongyi Shi967d2f12019-02-08 20:58:5310258 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010259 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10260 Initialize();
10261 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10262 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10263
10264 // Set an address in resolver for asynchronous return.
10265 host_resolver_->set_ondemand_mode(true);
10266 factory_->set_require_confirmation(true);
10267 crypto_client_stream_factory_.set_handshake_mode(
10268 MockCryptoClientStream::ZERO_RTT);
10269 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10270 kCachedIPAddress.ToString(), "");
10271
10272 // Set up the same address in the stale resolver cache.
10273 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10274 HostCache::Entry entry(OK,
10275 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10276 HostCache::Entry::SOURCE_DNS);
10277 base::TimeDelta zero;
10278 HostCache* cache = host_resolver_->GetHostCache();
10279 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10280 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810281 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010282
Ryan Hamiltonabad59e2019-06-06 04:02:5910283 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010284 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10285 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10286 quic_data.AddSocketDataToFactory(socket_factory_.get());
10287
10288 QuicStreamRequest request(factory_.get());
10289 EXPECT_EQ(ERR_IO_PENDING,
10290 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210291 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10292 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010293 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10294 failed_on_default_network_callback_, callback_.callback()));
10295
10296 // Finish dns async, check we still need to wait for stale connection async.
10297 host_resolver_->ResolveAllPending();
10298 base::RunLoop().RunUntilIdle();
10299 EXPECT_FALSE(callback_.have_result());
10300
10301 // Finish stale connection async, and the stale connection should pass dns
10302 // validation.
10303 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
10304 quic::QuicSession::HANDSHAKE_CONFIRMED);
10305 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10306 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10307 EXPECT_TRUE(stream.get());
10308
10309 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Victor Vasilievbee79ea2019-05-15 01:25:4810310 EXPECT_EQ(session->peer_address().host().ToString(),
10311 kCachedIPAddress.ToString());
Renjiea0cb4a2c2018-09-26 23:37:3010312
10313 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10314 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10315}
10316
10317// With dns race experiment on, dns resolve async, stale used and connects
10318// sync, but dns no match
10319TEST_P(QuicStreamFactoryTest,
10320 ResultAfterDNSRaceHostResolveAsyncStaleSyncNoMatch) {
Zhongyi Shi967d2f12019-02-08 20:58:5310321 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010322 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10323 Initialize();
10324 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10325 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10326
10327 // Set an address in resolver for asynchronous return.
10328 host_resolver_->set_ondemand_mode(true);
10329 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10330 kNonCachedIPAddress, "");
10331
10332 // Set up a different address in the stale resolver cache.
10333 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10334 HostCache::Entry entry(OK,
10335 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10336 HostCache::Entry::SOURCE_DNS);
10337 base::TimeDelta zero;
10338 HostCache* cache = host_resolver_->GetHostCache();
10339 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10340 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810341 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010342
10343 // Socket for the stale connection which will invoke connection closure.
Ryan Hamiltonabad59e2019-06-06 04:02:5910344 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010345 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10346 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10347 quic_data.AddWrite(
Renjief5fcb172019-02-05 01:59:3310348 SYNCHRONOUS,
10349 client_maker_.MakeConnectionClosePacket(
10350 2, true, quic::QUIC_STALE_CONNECTION_CANCELLED, "net error"));
Renjiea0cb4a2c2018-09-26 23:37:3010351 quic_data.AddSocketDataToFactory(socket_factory_.get());
10352
10353 // Socket for the new connection.
Ryan Hamilton0d65a8c2019-06-07 00:46:0210354 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:5910355 MockQuicData quic_data2(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010356 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10357 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10358 quic_data2.AddSocketDataToFactory(socket_factory_.get());
10359
10360 QuicStreamRequest request(factory_.get());
10361 EXPECT_EQ(ERR_IO_PENDING,
10362 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210363 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10364 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010365 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10366 failed_on_default_network_callback_, callback_.callback()));
10367
10368 // Check the stale connection is running.
10369 EXPECT_TRUE(HasLiveSession(host_port_pair_));
10370 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10371
10372 // Finish dns resolution and check the job has finished.
10373 host_resolver_->ResolveAllPending();
10374 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10375
10376 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10377 EXPECT_TRUE(stream.get());
10378
10379 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
10380
Victor Vasilievbee79ea2019-05-15 01:25:4810381 EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress);
Renjiea0cb4a2c2018-09-26 23:37:3010382
10383 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10384 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10385 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
10386 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
10387}
10388
10389// With dns race experiment on, dns resolve async, stale used and connects
10390// async, finishes before dns, but no match
10391TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleAsyncResolveAsyncNoMatch) {
Zhongyi Shi967d2f12019-02-08 20:58:5310392 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010393 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10394 Initialize();
10395 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10396 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10397
10398 // Set an address in resolver for asynchronous return.
10399 host_resolver_->set_ondemand_mode(true);
10400 factory_->set_require_confirmation(true);
10401 crypto_client_stream_factory_.set_handshake_mode(
10402 MockCryptoClientStream::ZERO_RTT);
10403 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10404 kNonCachedIPAddress, "");
10405
10406 // Set up a different address in the stale resolvercache.
10407 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10408 HostCache::Entry entry(OK,
10409 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10410 HostCache::Entry::SOURCE_DNS);
10411 base::TimeDelta zero;
10412 HostCache* cache = host_resolver_->GetHostCache();
10413 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10414 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810415 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010416
Ryan Hamiltonabad59e2019-06-06 04:02:5910417 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010418 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10419 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10420 quic_data.AddWrite(
Renjief5fcb172019-02-05 01:59:3310421 SYNCHRONOUS,
10422 client_maker_.MakeConnectionClosePacket(
10423 2, true, quic::QUIC_STALE_CONNECTION_CANCELLED, "net error"));
Renjiea0cb4a2c2018-09-26 23:37:3010424 quic_data.AddSocketDataToFactory(socket_factory_.get());
10425
Ryan Hamilton0d65a8c2019-06-07 00:46:0210426 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:5910427 MockQuicData quic_data2(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010428 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10429 quic_data2.AddSocketDataToFactory(socket_factory_.get());
10430
10431 QuicStreamRequest request(factory_.get());
10432 EXPECT_EQ(ERR_IO_PENDING,
10433 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210434 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10435 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010436 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10437 failed_on_default_network_callback_, callback_.callback()));
10438
10439 // Finish the stale connection.
10440 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
10441 quic::QuicSession::HANDSHAKE_CONFIRMED);
10442 base::RunLoop().RunUntilIdle();
10443 EXPECT_TRUE(HasLiveSession(host_port_pair_));
10444 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10445
10446 // Finish host resolution and check the job is done.
10447 host_resolver_->ResolveAllPending();
10448 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10449
10450 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10451 EXPECT_TRUE(stream.get());
10452
10453 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Victor Vasilievbee79ea2019-05-15 01:25:4810454 EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress);
Renjiea0cb4a2c2018-09-26 23:37:3010455
10456 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10457 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10458 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
10459 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
10460}
10461
10462// With dns race experiment on, dns resolve async, stale used and connects
10463// async, dns finishes first, but no match
10464TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceResolveAsyncStaleAsyncNoMatch) {
Zhongyi Shi967d2f12019-02-08 20:58:5310465 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010466 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10467 Initialize();
10468 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10469 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10470
10471 // Set an address in resolver for asynchronous return.
10472 host_resolver_->set_ondemand_mode(true);
10473 factory_->set_require_confirmation(true);
10474 crypto_client_stream_factory_.set_handshake_mode(
10475 MockCryptoClientStream::ZERO_RTT);
10476 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10477 kNonCachedIPAddress, "");
10478
10479 // Set up a different address in the stale resolver cache.
10480 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10481 HostCache::Entry entry(OK,
10482 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10483 HostCache::Entry::SOURCE_DNS);
10484 base::TimeDelta zero;
10485 HostCache* cache = host_resolver_->GetHostCache();
10486 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10487 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810488 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010489
Ryan Hamiltonabad59e2019-06-06 04:02:5910490 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010491 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Michael Warres167db3e2019-03-01 21:38:0310492 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:3010493 quic_data.AddWrite(
Renjief5fcb172019-02-05 01:59:3310494 SYNCHRONOUS,
10495 client_maker_.MakeConnectionClosePacket(
10496 1, true, quic::QUIC_STALE_CONNECTION_CANCELLED, "net error"));
Renjiea0cb4a2c2018-09-26 23:37:3010497 quic_data.AddSocketDataToFactory(socket_factory_.get());
10498
Ryan Hamilton0d65a8c2019-06-07 00:46:0210499 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:5910500 MockQuicData quic_data2(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010501 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie8d2d8d91b2018-09-29 00:29:0310502 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
10503 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Renjiea0cb4a2c2018-09-26 23:37:3010504 quic_data2.AddSocketDataToFactory(socket_factory_.get());
10505
10506 QuicStreamRequest request(factory_.get());
10507 EXPECT_EQ(ERR_IO_PENDING,
10508 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210509 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10510 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010511 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10512 failed_on_default_network_callback_, callback_.callback()));
10513 // Finish dns resolution, but need to wait for stale connection.
10514 host_resolver_->ResolveAllPending();
Renjie8d2d8d91b2018-09-29 00:29:0310515 base::RunLoop().RunUntilIdle();
Renjiea0cb4a2c2018-09-26 23:37:3010516 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
10517 quic::QuicSession::HANDSHAKE_CONFIRMED);
10518 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10519
10520 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10521 EXPECT_TRUE(stream.get());
10522
10523 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Victor Vasilievbee79ea2019-05-15 01:25:4810524 EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress);
Renjiea0cb4a2c2018-09-26 23:37:3010525
10526 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10527 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10528 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
10529 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
10530}
10531
10532// With dns race experiment on, dns resolve returns error sync, same behavior
10533// as experiment is not on
10534TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveError) {
Zhongyi Shi967d2f12019-02-08 20:58:5310535 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010536 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10537 Initialize();
10538 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10539 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10540
10541 // Set synchronous failure in resolver.
10542 host_resolver_->set_synchronous_mode(true);
10543 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
10544
Ryan Hamiltonabad59e2019-06-06 04:02:5910545 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010546 quic_data.AddSocketDataToFactory(socket_factory_.get());
10547 QuicStreamRequest request(factory_.get());
10548
10549 EXPECT_EQ(ERR_NAME_NOT_RESOLVED,
10550 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210551 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10552 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010553 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10554 failed_on_default_network_callback_, callback_.callback()));
10555}
10556
10557// With dns race experiment on, no cache available, dns resolve returns error
10558// async
10559TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveAsyncError) {
Zhongyi Shi967d2f12019-02-08 20:58:5310560 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010561 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10562 Initialize();
10563 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10564 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10565
10566 // Set asynchronous failure in resolver.
10567 host_resolver_->set_ondemand_mode(true);
10568 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
10569
Ryan Hamiltonabad59e2019-06-06 04:02:5910570 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010571 quic_data.AddSocketDataToFactory(socket_factory_.get());
10572 QuicStreamRequest request(factory_.get());
10573
10574 EXPECT_EQ(ERR_IO_PENDING,
10575 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210576 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10577 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010578 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10579 failed_on_default_network_callback_, callback_.callback()));
10580
10581 // Resolve and expect result that shows the resolution error.
10582 host_resolver_->ResolveAllPending();
10583 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
10584}
10585
10586// With dns race experiment on, dns resolve async, staled used and connects
10587// sync, dns returns error and no connection is established.
10588TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleSyncHostResolveError) {
Zhongyi Shi967d2f12019-02-08 20:58:5310589 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010590 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10591 Initialize();
10592 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10593 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10594
10595 // Set asynchronous failure in resolver.
10596 host_resolver_->set_ondemand_mode(true);
10597 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
10598
10599 // Set up an address in the stale cache.
10600 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10601 HostCache::Entry entry(OK,
10602 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10603 HostCache::Entry::SOURCE_DNS);
10604 base::TimeDelta zero;
10605 HostCache* cache = host_resolver_->GetHostCache();
10606 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10607 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810608 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010609
10610 // Socket for the stale connection which is supposed to disconnect.
Ryan Hamiltonabad59e2019-06-06 04:02:5910611 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010612 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10613 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10614 quic_data.AddWrite(
Renjief5fcb172019-02-05 01:59:3310615 SYNCHRONOUS,
10616 client_maker_.MakeConnectionClosePacket(
10617 2, true, quic::QUIC_STALE_CONNECTION_CANCELLED, "net error"));
Renjiea0cb4a2c2018-09-26 23:37:3010618 quic_data.AddSocketDataToFactory(socket_factory_.get());
10619
10620 QuicStreamRequest request(factory_.get());
10621 EXPECT_EQ(ERR_IO_PENDING,
10622 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210623 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10624 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010625 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10626 failed_on_default_network_callback_, callback_.callback()));
10627
10628 // Check that the stale connection is running.
10629 EXPECT_TRUE(HasLiveSession(host_port_pair_));
10630 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10631
10632 // Finish host resolution.
10633 host_resolver_->ResolveAllPending();
10634 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
10635
Renjiea0cb4a2c2018-09-26 23:37:3010636 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10637 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10638}
10639
10640// With dns race experiment on, dns resolve async, stale used and connection
Renjie99ec24b2019-04-26 17:44:3410641// return error, then dns matches.
10642// This serves as a regression test for crbug.com/956374.
Renjiea0cb4a2c2018-09-26 23:37:3010643TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleErrorDNSMatches) {
Zhongyi Shi967d2f12019-02-08 20:58:5310644 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010645 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10646 Initialize();
10647 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10648 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10649
10650 // Set an address in host resolver for asynchronous return.
10651 host_resolver_->set_ondemand_mode(true);
10652 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10653 kCachedIPAddress.ToString(), "");
10654
10655 // Set up the same address in the stale resolver cache.
10656 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10657 HostCache::Entry entry(OK,
10658 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10659 HostCache::Entry::SOURCE_DNS);
10660 base::TimeDelta zero;
10661 HostCache* cache = host_resolver_->GetHostCache();
10662 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10663 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810664 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010665
10666 // Simulate synchronous connect failure.
Ryan Hamiltonabad59e2019-06-06 04:02:5910667 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010668 quic_data.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
10669 quic_data.AddSocketDataToFactory(socket_factory_.get());
10670
Ryan Hamilton0d65a8c2019-06-07 00:46:0210671 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:5910672 MockQuicData quic_data2(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010673 quic_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
10674 quic_data2.AddSocketDataToFactory(socket_factory_.get());
10675
10676 QuicStreamRequest request(factory_.get());
10677 EXPECT_EQ(ERR_IO_PENDING,
10678 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210679 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10680 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010681 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10682 failed_on_default_network_callback_, callback_.callback()));
10683 EXPECT_FALSE(HasLiveSession(host_port_pair_));
10684 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10685
10686 host_resolver_->ResolveAllPending();
10687 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_ADDRESS_IN_USE));
10688}
10689
10690// With dns race experiment on, dns resolve async, stale used and connection
10691// returns error, dns no match, new connection is established
10692TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleErrorDNSNoMatch) {
Zhongyi Shi967d2f12019-02-08 20:58:5310693 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010694 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10695 Initialize();
10696 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10697 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10698
10699 // Set an address in host resolver.
10700 host_resolver_->set_ondemand_mode(true);
10701 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10702 kNonCachedIPAddress, "");
10703
10704 // Set up a different address in stale resolver cache.
10705 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10706 HostCache::Entry entry(OK,
10707 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10708 HostCache::Entry::SOURCE_DNS);
10709 base::TimeDelta zero;
10710 HostCache* cache = host_resolver_->GetHostCache();
10711 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10712 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810713 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010714
10715 // Add failure for the stale connection.
Ryan Hamiltonabad59e2019-06-06 04:02:5910716 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010717 quic_data.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
10718 quic_data.AddSocketDataToFactory(socket_factory_.get());
10719
Ryan Hamilton0d65a8c2019-06-07 00:46:0210720 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:5910721 MockQuicData quic_data2(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010722 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10723 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10724 quic_data2.AddSocketDataToFactory(socket_factory_.get());
10725
10726 QuicStreamRequest request(factory_.get());
10727 EXPECT_EQ(ERR_IO_PENDING,
10728 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210729 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10730 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010731 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10732 failed_on_default_network_callback_, callback_.callback()));
10733
10734 // Check that the stale connection fails.
10735 EXPECT_FALSE(HasLiveSession(host_port_pair_));
10736 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10737
10738 // Finish host resolution and check the job finishes ok.
10739 host_resolver_->ResolveAllPending();
10740 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10741
10742 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10743 EXPECT_TRUE(stream.get());
10744
10745 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
10746
Victor Vasilievbee79ea2019-05-15 01:25:4810747 EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress);
Renjiea0cb4a2c2018-09-26 23:37:3010748
10749 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
10750 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
10751}
10752
10753// With dns race experiment on, dns resolve async, stale used and connection
10754// returns error, dns no match, new connection error
10755TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleErrorDNSNoMatchError) {
Zhongyi Shi967d2f12019-02-08 20:58:5310756 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010757 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10758 Initialize();
10759 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10760 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10761
10762 // Set an address in host resolver asynchronously.
10763 host_resolver_->set_ondemand_mode(true);
10764 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10765 kNonCachedIPAddress, "");
10766
10767 // Set up a different address in the stale cache.
10768 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10769 HostCache::Entry entry(OK,
10770 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10771 HostCache::Entry::SOURCE_DNS);
10772 base::TimeDelta zero;
10773 HostCache* cache = host_resolver_->GetHostCache();
10774 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10775 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810776 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010777
10778 // Add failure for stale connection.
Ryan Hamiltonabad59e2019-06-06 04:02:5910779 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010780 quic_data.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
10781 quic_data.AddSocketDataToFactory(socket_factory_.get());
10782
10783 // Add failure for resolved dns connection.
Ryan Hamilton0d65a8c2019-06-07 00:46:0210784 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:5910785 MockQuicData quic_data2(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010786 quic_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
10787 quic_data2.AddSocketDataToFactory(socket_factory_.get());
10788
10789 QuicStreamRequest request(factory_.get());
10790 EXPECT_EQ(ERR_IO_PENDING,
10791 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210792 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10793 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010794 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10795 failed_on_default_network_callback_, callback_.callback()));
10796
10797 // Check the stale connection fails.
10798 EXPECT_FALSE(HasLiveSession(host_port_pair_));
10799 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10800
10801 // Check the resolved dns connection fails.
10802 host_resolver_->ResolveAllPending();
10803 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_ADDRESS_IN_USE));
10804}
10805
10806// With dns race experiment on, dns resolve async and stale connect async, dns
10807// resolve returns error and then preconnect finishes
10808TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceResolveAsyncErrorStaleAsync) {
Zhongyi Shi967d2f12019-02-08 20:58:5310809 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010810 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10811 Initialize();
10812 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10813 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10814
10815 // Add asynchronous failure in host resolver.
10816 host_resolver_->set_ondemand_mode(true);
10817 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
10818 factory_->set_require_confirmation(true);
10819 crypto_client_stream_factory_.set_handshake_mode(
10820 MockCryptoClientStream::ZERO_RTT);
10821
10822 // Set up an address in stale resolver cache.
10823 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10824 HostCache::Entry entry(OK,
10825 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10826 HostCache::Entry::SOURCE_DNS);
10827 base::TimeDelta zero;
10828 HostCache* cache = host_resolver_->GetHostCache();
10829 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10830 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810831 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010832
10833 // Socket data for stale connection which is supposed to disconnect.
Ryan Hamiltonabad59e2019-06-06 04:02:5910834 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010835 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Michael Warres167db3e2019-03-01 21:38:0310836 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:3010837 quic_data.AddWrite(
Renjief5fcb172019-02-05 01:59:3310838 SYNCHRONOUS,
10839 client_maker_.MakeConnectionClosePacket(
10840 1, true, quic::QUIC_STALE_CONNECTION_CANCELLED, "net error"));
Renjiea0cb4a2c2018-09-26 23:37:3010841 quic_data.AddSocketDataToFactory(socket_factory_.get());
10842
10843 QuicStreamRequest request(factory_.get());
10844 EXPECT_EQ(ERR_IO_PENDING,
10845 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210846 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10847 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010848 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10849 failed_on_default_network_callback_, callback_.callback()));
10850
10851 // host resolution returned but stale connection hasn't finished yet.
10852 host_resolver_->ResolveAllPending();
10853 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
10854
10855 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10856 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10857}
10858
10859// With dns race experiment on, dns resolve async and stale connect async, dns
Renjiea0cb4a2c2018-09-26 23:37:3010860// resolve returns error and then preconnect fails.
10861TEST_P(QuicStreamFactoryTest,
10862 ResultAfterDNSRaceResolveAsyncErrorStaleAsyncError) {
Zhongyi Shi967d2f12019-02-08 20:58:5310863 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010864 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10865 Initialize();
10866 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10867 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10868
10869 // Add asynchronous failure to host resolver.
10870 host_resolver_->set_ondemand_mode(true);
10871 factory_->set_require_confirmation(true);
10872 crypto_client_stream_factory_.set_handshake_mode(
10873 MockCryptoClientStream::ZERO_RTT);
10874 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
10875
10876 // Set up an address in stale resolver cache.
10877 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10878 HostCache::Entry entry(OK,
10879 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10880 HostCache::Entry::SOURCE_DNS);
10881 base::TimeDelta zero;
10882 HostCache* cache = host_resolver_->GetHostCache();
10883 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10884 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810885 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010886
Ryan Hamiltonabad59e2019-06-06 04:02:5910887 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010888 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Michael Warres167db3e2019-03-01 21:38:0310889 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:3010890 quic_data.AddWrite(
Renjief5fcb172019-02-05 01:59:3310891 SYNCHRONOUS,
10892 client_maker_.MakeConnectionClosePacket(
10893 1, true, quic::QUIC_STALE_CONNECTION_CANCELLED, "net error"));
Renjiea0cb4a2c2018-09-26 23:37:3010894 quic_data.AddSocketDataToFactory(socket_factory_.get());
10895
10896 QuicStreamRequest request(factory_.get());
10897 EXPECT_EQ(ERR_IO_PENDING,
10898 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210899 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10900 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010901 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10902 failed_on_default_network_callback_, callback_.callback()));
10903
10904 // Host Resolution returns failure but stale connection hasn't finished.
10905 host_resolver_->ResolveAllPending();
10906
10907 // Check that the final error is on resolution failure.
10908 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
10909
10910 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10911}
10912
10913// With dns race experiment on, test that host resolution callback behaves
10914// normal as experiment is not on
10915TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveAsync) {
Zhongyi Shi967d2f12019-02-08 20:58:5310916 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010917 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10918 Initialize();
10919 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10920 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10921
10922 host_resolver_->set_ondemand_mode(true);
10923 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10924 kNonCachedIPAddress, "");
10925
Ryan Hamiltonabad59e2019-06-06 04:02:5910926 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010927 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10928 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10929 quic_data.AddSocketDataToFactory(socket_factory_.get());
10930
10931 QuicStreamRequest request(factory_.get());
10932 EXPECT_EQ(ERR_IO_PENDING,
10933 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210934 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10935 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010936 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10937 failed_on_default_network_callback_, callback_.callback()));
10938
10939 // Check that expect_on_host_resolution_ is properlly set.
10940 TestCompletionCallback host_resolution_callback;
10941 EXPECT_TRUE(
10942 request.WaitForHostResolution(host_resolution_callback.callback()));
10943 base::RunLoop().RunUntilIdle();
10944 EXPECT_FALSE(host_resolution_callback.have_result());
10945
10946 host_resolver_->ResolveAllPending();
10947 EXPECT_THAT(host_resolution_callback.WaitForResult(), IsOk());
10948
10949 // Check that expect_on_host_resolution_ is flipped back.
10950 EXPECT_FALSE(
10951 request.WaitForHostResolution(host_resolution_callback.callback()));
10952
10953 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10954 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10955}
10956
Renjiea0522f062019-04-29 18:52:2110957TEST_P(QuicStreamFactoryTest, ConfigInitialRttForHandshake) {
10958 int kInitialRtt = 400;
10959 test_params_.quic_initial_rtt_for_handshake_milliseconds = kInitialRtt;
10960 crypto_client_stream_factory_.set_handshake_mode(
10961 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
10962 Initialize();
10963 factory_->set_require_confirmation(true);
10964 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10965 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10966
10967 // Using a testing task runner so that we can control time.
10968 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
10969
10970 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
10971 QuicStreamFactoryPeer::SetAlarmFactory(
10972 factory_.get(),
10973 std::make_unique<QuicChromiumAlarmFactory>(task_runner.get(), &clock_));
10974
Ryan Hamiltonabad59e2019-06-06 04:02:5910975 MockQuicData socket_data(version_);
Renjiea0522f062019-04-29 18:52:2110976 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10977 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
10978 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(2));
10979 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamilton0d65a8c2019-06-07 00:46:0210980 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(3));
10981
Renjiea0522f062019-04-29 18:52:2110982 socket_data.AddSocketDataToFactory(socket_factory_.get());
10983
10984 QuicStreamRequest request(factory_.get());
10985 EXPECT_EQ(ERR_IO_PENDING,
10986 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210987 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10988 SocketTag(), NetworkIsolationKey(),
Renjiea0522f062019-04-29 18:52:2110989 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10990 failed_on_default_network_callback_, callback_.callback()));
10991 base::RunLoop().RunUntilIdle();
10992
10993 EXPECT_FALSE(HasActiveSession(host_port_pair_));
10994 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10995
10996 // The pending task is scheduled for handshake timeout retransmission,
10997 // which is 2 * 400ms for v99 and 1.5 * 400ms for others.
Nick Harper23290b82019-05-02 00:02:5610998 int handshake_timeout = version_.transport_version == quic::QUIC_VERSION_99
10999 ? 2 * kInitialRtt
11000 : 1.5 * kInitialRtt;
Renjiea0522f062019-04-29 18:52:2111001 EXPECT_EQ(base::TimeDelta::FromMilliseconds(handshake_timeout),
11002 task_runner->NextPendingTaskDelay());
11003
11004 // The alarm factory dependes on |clock_|, so clock is advanced to trigger
11005 // retransmission alarm.
11006 clock_.AdvanceTime(
11007 quic::QuicTime::Delta::FromMilliseconds(handshake_timeout));
11008 task_runner->FastForwardBy(
11009 base::TimeDelta::FromMilliseconds(handshake_timeout));
11010
11011 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
11012 quic::QuicSession::HANDSHAKE_CONFIRMED);
11013
11014 EXPECT_THAT(callback_.WaitForResult(), IsOk());
11015
11016 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
11017 EXPECT_EQ(400000u, session->config()->GetInitialRoundTripTimeUsToSend());
11018 EXPECT_TRUE(socket_data.AllReadDataConsumed());
11019 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
11020}
11021
Paul Jensen8e3c5d32018-02-19 17:06:3311022// Test that QuicStreamRequests with similar and different tags results in
11023// reused and unique QUIC streams using appropriately tagged sockets.
11024TEST_P(QuicStreamFactoryTest, Tag) {
11025 MockTaggingClientSocketFactory* socket_factory =
11026 new MockTaggingClientSocketFactory();
11027 socket_factory_.reset(socket_factory);
11028 Initialize();
11029 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
11030 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
11031
11032 // Prepare to establish two QUIC sessions.
Ryan Hamiltonabad59e2019-06-06 04:02:5911033 MockQuicData socket_data(version_);
Paul Jensen8e3c5d32018-02-19 17:06:3311034 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:4311035 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Paul Jensen8e3c5d32018-02-19 17:06:3311036 socket_data.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamilton0d65a8c2019-06-07 00:46:0211037 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:5911038 MockQuicData socket_data2(version_);
Paul Jensen8e3c5d32018-02-19 17:06:3311039 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:4311040 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Paul Jensen8e3c5d32018-02-19 17:06:3311041 socket_data2.AddSocketDataToFactory(socket_factory_.get());
11042
11043#if defined(OS_ANDROID)
11044 SocketTag tag1(SocketTag::UNSET_UID, 0x12345678);
11045 SocketTag tag2(getuid(), 0x87654321);
11046#else
11047 // On non-Android platforms we can only use the default constructor.
11048 SocketTag tag1, tag2;
11049#endif
11050
11051 // Request a stream with |tag1|.
11052 QuicStreamRequest request1(factory_.get());
Zhongyi Shia6b68d112018-09-24 07:49:0311053 int rv = request1.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5211054 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY, tag1,
11055 NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:0311056 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
11057 failed_on_default_network_callback_, callback_.callback());
Paul Jensen8e3c5d32018-02-19 17:06:3311058 EXPECT_THAT(callback_.GetResult(rv), IsOk());
11059 EXPECT_EQ(socket_factory->GetLastProducedUDPSocket()->tag(), tag1);
11060 EXPECT_TRUE(socket_factory->GetLastProducedUDPSocket()
11061 ->tagged_before_data_transferred());
11062 std::unique_ptr<QuicChromiumClientSession::Handle> stream1 =
11063 request1.ReleaseSessionHandle();
11064 EXPECT_TRUE(stream1);
11065 EXPECT_TRUE(stream1->IsConnected());
11066
11067 // Request a stream with |tag1| and verify underlying session is reused.
11068 QuicStreamRequest request2(factory_.get());
Zhongyi Shia6b68d112018-09-24 07:49:0311069 rv = request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5211070 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY, tag1,
11071 NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:0311072 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
11073 failed_on_default_network_callback_, callback_.callback());
Paul Jensen8e3c5d32018-02-19 17:06:3311074 EXPECT_THAT(callback_.GetResult(rv), IsOk());
11075 std::unique_ptr<QuicChromiumClientSession::Handle> stream2 =
11076 request2.ReleaseSessionHandle();
11077 EXPECT_TRUE(stream2);
11078 EXPECT_TRUE(stream2->IsConnected());
11079 EXPECT_TRUE(stream2->SharesSameSession(*stream1));
11080
11081 // Request a stream with |tag2| and verify a new session is created.
11082 QuicStreamRequest request3(factory_.get());
Zhongyi Shia6b68d112018-09-24 07:49:0311083 rv = request3.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5211084 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY, tag2,
11085 NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:0311086 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
11087 failed_on_default_network_callback_, callback_.callback());
Paul Jensen8e3c5d32018-02-19 17:06:3311088 EXPECT_THAT(callback_.GetResult(rv), IsOk());
11089 EXPECT_EQ(socket_factory->GetLastProducedUDPSocket()->tag(), tag2);
11090 EXPECT_TRUE(socket_factory->GetLastProducedUDPSocket()
11091 ->tagged_before_data_transferred());
11092 std::unique_ptr<QuicChromiumClientSession::Handle> stream3 =
11093 request3.ReleaseSessionHandle();
11094 EXPECT_TRUE(stream3);
11095 EXPECT_TRUE(stream3->IsConnected());
11096#if defined(OS_ANDROID)
11097 EXPECT_FALSE(stream3->SharesSameSession(*stream1));
11098#else
11099 // Same tag should reuse session.
11100 EXPECT_TRUE(stream3->SharesSameSession(*stream1));
11101#endif
11102}
11103
[email protected]e13201d82012-12-12 05:00:3211104} // namespace test
[email protected]e13201d82012-12-12 05:00:3211105} // namespace net