blob: 388e8249c0ce0f03b7ad9eaee687ccc74bf97c01 [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))),
Nick Harper72ade192019-07-17 03:30:42266 failed_on_default_network_(false) {
267 test_params_.quic_params.headers_include_h2_stream_dependency =
Zhongyi Shi967d2f12019-02-08 20:58:53268 client_headers_include_h2_stream_dependency;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52269 clock_.AdvanceTime(quic::QuicTime::Delta::FromSeconds(1));
bnc359ed2a2016-04-29 20:43:45270 }
271
jri7046038f2015-10-22 00:29:26272 void Initialize() {
bnc359ed2a2016-04-29 20:43:45273 DCHECK(!factory_);
jri7046038f2015-10-22 00:29:26274 factory_.reset(new QuicStreamFactory(
Renjiea0cb4a2c2018-09-26 23:37:30275 net_log_.net_log(), host_resolver_.get(), ssl_config_service_.get(),
Zhongyi Shi5f587cc2017-11-21 23:24:17276 socket_factory_.get(), &http_server_properties_, cert_verifier_.get(),
Nick Harperecf319d2018-10-16 07:58:54277 &ct_policy_enforcer_, &transport_security_state_,
278 cert_transparency_verifier_.get(),
jri7046038f2015-10-22 00:29:26279 /*SocketPerformanceWatcherFactory*/ nullptr,
rchbf4c26d2017-04-16 23:17:55280 &crypto_client_stream_factory_, &random_generator_, &clock_,
Nick Harper72ade192019-07-17 03:30:42281 test_params_.quic_params));
[email protected]e13201d82012-12-12 05:00:32282 }
283
Zhongyi Shi5f587cc2017-11-21 23:24:17284 void InitializeConnectionMigrationV2Test(
285 NetworkChangeNotifier::NetworkList connected_networks) {
286 scoped_mock_network_change_notifier_.reset(
287 new ScopedMockNetworkChangeNotifier());
288 MockNetworkChangeNotifier* mock_ncn =
289 scoped_mock_network_change_notifier_->mock_network_change_notifier();
290 mock_ncn->ForceNetworkHandlesSupported();
291 mock_ncn->SetConnectedNetworksList(connected_networks);
Nick Harper72ade192019-07-17 03:30:42292 test_params_.quic_params.migrate_sessions_on_network_change_v2 = true;
293 test_params_.quic_params.migrate_sessions_early_v2 = true;
Zhongyi Shi5f587cc2017-11-21 23:24:17294 socket_factory_.reset(new TestConnectionMigrationSocketFactory);
295 Initialize();
296 }
297
Yixin Wang7891a39d2017-11-08 20:59:24298 std::unique_ptr<HttpStream> CreateStream(QuicStreamRequest* request) {
299 std::unique_ptr<QuicChromiumClientSession::Handle> session =
300 request->ReleaseSessionHandle();
301 if (!session || !session->IsConnected())
302 return nullptr;
303
304 return std::make_unique<QuicHttpStream>(std::move(session));
305 }
306
bnccb7ff3c2015-05-21 20:51:55307 bool HasActiveSession(const HostPortPair& host_port_pair) {
Ryan Hamilton4f0b26e2018-06-27 23:52:32308 quic::QuicServerId server_id(host_port_pair.host(), host_port_pair.port(),
309 false);
bnc5fdc07162016-05-23 17:36:03310 return QuicStreamFactoryPeer::HasActiveSession(factory_.get(), server_id);
bnccb7ff3c2015-05-21 20:51:55311 }
312
Renjiea0cb4a2c2018-09-26 23:37:30313 bool HasLiveSession(const HostPortPair& host_port_pair) {
314 quic::QuicServerId server_id(host_port_pair.host(), host_port_pair.port(),
315 false);
316 return QuicStreamFactoryPeer::HasLiveSession(factory_.get(), host_port_pair,
317 server_id);
318 }
319
zhongyi363c91c2017-03-23 23:16:08320 bool HasActiveJob(const HostPortPair& host_port_pair,
321 const PrivacyMode privacy_mode) {
Ryan Hamilton4f0b26e2018-06-27 23:52:32322 quic::QuicServerId server_id(host_port_pair.host(), host_port_pair.port(),
323 privacy_mode == PRIVACY_MODE_ENABLED);
zhongyi363c91c2017-03-23 23:16:08324 return QuicStreamFactoryPeer::HasActiveJob(factory_.get(), server_id);
325 }
326
Ryan Hamilton8d9ee76e2018-05-29 23:52:52327 bool HasActiveCertVerifierJob(const quic::QuicServerId& server_id) {
rtennetid073dd22016-08-04 01:58:33328 return QuicStreamFactoryPeer::HasActiveCertVerifierJob(factory_.get(),
329 server_id);
330 }
331
Zhongyi Shic1449372018-08-09 09:58:58332 // Get the pending, not activated session, if there is only one session alive.
333 QuicChromiumClientSession* GetPendingSession(
334 const HostPortPair& host_port_pair) {
335 quic::QuicServerId server_id(host_port_pair.host(), host_port_pair.port(),
336 false);
337 return QuicStreamFactoryPeer::GetPendingSession(factory_.get(), server_id,
338 host_port_pair);
339 }
340
bnc912a04b2016-04-20 14:19:50341 QuicChromiumClientSession* GetActiveSession(
342 const HostPortPair& host_port_pair) {
Ryan Hamilton4f0b26e2018-06-27 23:52:32343 quic::QuicServerId server_id(host_port_pair.host(), host_port_pair.port(),
344 false);
bnc5fdc07162016-05-23 17:36:03345 return QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server_id);
bnc912a04b2016-04-20 14:19:50346 }
347
[email protected]bf4ea2f2014-03-10 22:57:53348 int GetSourcePortForNewSession(const HostPortPair& destination) {
[email protected]d8e2abf82014-03-06 10:30:10349 return GetSourcePortForNewSessionInner(destination, false);
350 }
351
rjshaded5ced072015-12-18 19:26:02352 int GetSourcePortForNewSessionAndGoAway(const HostPortPair& destination) {
[email protected]d8e2abf82014-03-06 10:30:10353 return GetSourcePortForNewSessionInner(destination, true);
354 }
355
[email protected]bf4ea2f2014-03-10 22:57:53356 int GetSourcePortForNewSessionInner(const HostPortPair& destination,
[email protected]d8e2abf82014-03-06 10:30:10357 bool goaway_received) {
[email protected]3c772402013-12-18 21:38:11358 // Should only be called if there is no active session for this destination.
bnccb7ff3c2015-05-21 20:51:55359 EXPECT_FALSE(HasActiveSession(destination));
Zhongyi Shi5f587cc2017-11-21 23:24:17360 size_t socket_count = socket_factory_->udp_client_socket_ports().size();
[email protected]3c772402013-12-18 21:38:11361
Ryan Hamiltonabad59e2019-06-06 04:02:59362 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:36363 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:43364 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:17365 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]3c772402013-12-18 21:38:11366
zhongyi98d6a9262017-05-19 02:47:45367 QuicStreamRequest request(factory_.get());
ckrasic3865ee0f2016-02-29 22:04:56368 GURL url("https://" + destination.host() + "/");
Nick Harper23290b82019-05-02 00:02:56369 EXPECT_EQ(ERR_IO_PENDING,
370 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:52371 destination, version_, privacy_mode_, DEFAULT_PRIORITY,
372 SocketTag(), NetworkIsolationKey(),
Nick Harper23290b82019-05-02 00:02:56373 /*cert_verify_flags=*/0, url, net_log_, &net_error_details_,
374 failed_on_default_network_callback_, callback_.callback()));
[email protected]3c772402013-12-18 21:38:11375
robpercival214763f2016-07-01 23:27:01376 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:24377 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]3c772402013-12-18 21:38:11378 EXPECT_TRUE(stream.get());
379 stream.reset();
380
bnc912a04b2016-04-20 14:19:50381 QuicChromiumClientSession* session = GetActiveSession(destination);
[email protected]3c772402013-12-18 21:38:11382
Zhongyi Shi5f587cc2017-11-21 23:24:17383 if (socket_count + 1 != socket_factory_->udp_client_socket_ports().size()) {
mmenke651bae7f2015-12-18 21:26:45384 ADD_FAILURE();
[email protected]3c772402013-12-18 21:38:11385 return 0;
386 }
387
[email protected]d8e2abf82014-03-06 10:30:10388 if (goaway_received) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:52389 quic::QuicGoAwayFrame goaway(quic::kInvalidControlFrameId,
390 quic::QUIC_NO_ERROR, 1, "");
rtenneti9bd5d4b2015-08-21 05:44:52391 session->connection()->OnGoAwayFrame(goaway);
[email protected]d8e2abf82014-03-06 10:30:10392 }
[email protected]3c772402013-12-18 21:38:11393
jri7046038f2015-10-22 00:29:26394 factory_->OnSessionClosed(session);
bnccb7ff3c2015-05-21 20:51:55395 EXPECT_FALSE(HasActiveSession(destination));
rch37de576c2015-05-17 20:28:17396 EXPECT_TRUE(socket_data.AllReadDataConsumed());
397 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
Zhongyi Shi5f587cc2017-11-21 23:24:17398 return socket_factory_->udp_client_socket_ports()[socket_count];
[email protected]3c772402013-12-18 21:38:11399 }
400
Ryan Hamilton8d9ee76e2018-05-29 23:52:52401 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23402 ConstructClientConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03403 return client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52404 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
rtenneti1cd3b162015-09-29 02:58:28405 }
406
Ryan Hamilton8d9ee76e2018-05-29 23:52:52407 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
Fan Yangac867502019-01-28 21:10:23408 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52409 quic::QuicRstStreamErrorCode error_code) {
Fan Yang32c5a112018-12-10 20:06:33410 quic::QuicStreamId stream_id =
411 GetNthClientInitiatedBidirectionalStreamId(0);
fayang3bcb8b502016-12-07 21:44:37412 return client_maker_.MakeRstPacket(packet_number, true, stream_id,
Jana Iyengarba355772017-09-21 22:03:21413 error_code);
fayang3bcb8b502016-12-07 21:44:37414 }
415
bncf8bf0722015-05-19 20:04:13416 static ProofVerifyDetailsChromium DefaultProofVerifyDetails() {
rch6faa4d42016-01-05 20:48:43417 // Load a certificate that is valid for *.example.org
bncf8bf0722015-05-19 20:04:13418 scoped_refptr<X509Certificate> test_cert(
rch6faa4d42016-01-05 20:48:43419 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bncf8bf0722015-05-19 20:04:13420 EXPECT_TRUE(test_cert.get());
421 ProofVerifyDetailsChromium verify_details;
422 verify_details.cert_verify_result.verified_cert = test_cert;
423 verify_details.cert_verify_result.is_issued_by_known_root = true;
424 return verify_details;
425 }
426
jri8c44d692015-10-23 23:53:41427 void NotifyIPAddressChanged() {
428 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
jri7e636642016-01-14 06:57:08429 // Spin the message loop so the notification is delivered.
fdoray92e35a72016-06-10 15:54:55430 base::RunLoop().RunUntilIdle();
jri8c44d692015-10-23 23:53:41431 }
432
Ryan Hamilton8d9ee76e2018-05-29 23:52:52433 std::unique_ptr<quic::QuicEncryptedPacket> ConstructGetRequestPacket(
Fan Yangac867502019-01-28 21:10:23434 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52435 quic::QuicStreamId stream_id,
jri7e636642016-01-14 06:57:08436 bool should_include_version,
437 bool fin) {
Ryan Hamilton0239aac2018-05-19 00:03:13438 spdy::SpdyHeaderBlock headers =
alyssar2adf3ac2016-05-03 17:12:58439 client_maker_.GetRequestHeaders("GET", "https", "/");
Ryan Hamilton0239aac2018-05-19 00:03:13440 spdy::SpdyPriority priority =
jri7e636642016-01-14 06:57:08441 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
442 size_t spdy_headers_frame_len;
alyssar2adf3ac2016-05-03 17:12:58443 return client_maker_.MakeRequestHeadersPacket(
jri7e636642016-01-14 06:57:08444 packet_number, stream_id, should_include_version, fin, priority,
Yixin Wang7a3f1b8d2018-01-17 21:40:48445 std::move(headers), 0, &spdy_headers_frame_len);
jri7e636642016-01-14 06:57:08446 }
447
Ryan Hamilton8d9ee76e2018-05-29 23:52:52448 std::unique_ptr<quic::QuicEncryptedPacket> ConstructGetRequestPacket(
Fan Yangac867502019-01-28 21:10:23449 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52450 quic::QuicStreamId stream_id,
Zhongyi Shi3c4c9e92018-07-02 23:16:23451 quic::QuicStreamId parent_stream_id,
fayang3bcb8b502016-12-07 21:44:37452 bool should_include_version,
Ryan Hamilton0d65a8c2019-06-07 00:46:02453 bool fin) {
Ryan Hamilton0239aac2018-05-19 00:03:13454 spdy::SpdyHeaderBlock headers =
fayang3bcb8b502016-12-07 21:44:37455 client_maker_.GetRequestHeaders("GET", "https", "/");
Ryan Hamilton0239aac2018-05-19 00:03:13456 spdy::SpdyPriority priority =
fayang3bcb8b502016-12-07 21:44:37457 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
458 size_t spdy_headers_frame_len;
459 return client_maker_.MakeRequestHeadersPacket(
460 packet_number, stream_id, should_include_version, fin, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02461 std::move(headers), parent_stream_id, &spdy_headers_frame_len);
fayang3bcb8b502016-12-07 21:44:37462 }
463
Ryan Hamilton8d9ee76e2018-05-29 23:52:52464 std::unique_ptr<quic::QuicEncryptedPacket> ConstructOkResponsePacket(
Fan Yangac867502019-01-28 21:10:23465 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52466 quic::QuicStreamId stream_id,
jri7e636642016-01-14 06:57:08467 bool should_include_version,
468 bool fin) {
Ryan Hamilton0239aac2018-05-19 00:03:13469 spdy::SpdyHeaderBlock headers = server_maker_.GetResponseHeaders("200 OK");
jri7e636642016-01-14 06:57:08470 size_t spdy_headers_frame_len;
alyssar2adf3ac2016-05-03 17:12:58471 return server_maker_.MakeResponseHeadersPacket(
bnc086b39e12016-06-24 13:05:26472 packet_number, stream_id, should_include_version, fin,
473 std::move(headers), &spdy_headers_frame_len);
jri7e636642016-01-14 06:57:08474 }
475
Ryan Hamilton8d9ee76e2018-05-29 23:52:52476 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket() {
Ryan Hamilton0d65a8c2019-06-07 00:46:02477 return client_maker_.MakeInitialSettingsPacket(1);
rch5cb522462017-04-25 20:18:36478 }
479
Ryan Hamilton8d9ee76e2018-05-29 23:52:52480 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:02481 uint64_t packet_number) {
482 return client_maker_.MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:37483 }
484
jri053fdbd2016-08-19 02:33:05485 // Helper method for server migration tests.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52486 void VerifyServerMigration(const quic::QuicConfig& config,
bnc6a0348c2017-05-22 18:56:19487 IPEndPoint expected_address) {
Nick Harper72ade192019-07-17 03:30:42488 test_params_.quic_params.allow_server_migration = true;
jri053fdbd2016-08-19 02:33:05489 Initialize();
490
491 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
492 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri053fdbd2016-08-19 02:33:05493 crypto_client_stream_factory_.SetConfig(config);
494
495 // Set up first socket data provider.
Ryan Hamiltonabad59e2019-06-06 04:02:59496 MockQuicData socket_data1(version_);
rcha00569732016-08-27 11:09:36497 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:17498 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri053fdbd2016-08-19 02:33:05499
Ryan Hamilton9f2eac32019-06-27 03:15:54500 client_maker_.set_coalesce_http_frames(true);
rcha00569732016-08-27 11:09:36501 // Set up second socket data provider that is used after
502 // migration.
Ryan Hamiltonabad59e2019-06-06 04:02:59503 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:36504 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:43505 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
fayang3bcb8b502016-12-07 21:44:37506 socket_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:43507 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
508 socket_data2.AddWrite(
Fan Yang32c5a112018-12-10 20:06:33509 SYNCHRONOUS, client_maker_.MakeRstPacket(
510 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
511 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:17512 socket_data2.AddSocketDataToFactory(socket_factory_.get());
jri053fdbd2016-08-19 02:33:05513
514 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:45515 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:33516 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:03517 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:52518 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
519 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:03520 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
521 failed_on_default_network_callback_, callback_.callback()));
jri053fdbd2016-08-19 02:33:05522 EXPECT_EQ(OK, callback_.WaitForResult());
bnceb9aa7112017-01-05 01:03:46523
524 // Run QuicChromiumClientSession::WriteToNewSocket()
525 // posted by QuicChromiumClientSession::MigrateToSocket().
526 base::RunLoop().RunUntilIdle();
527
Yixin Wang7891a39d2017-11-08 20:59:24528 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri053fdbd2016-08-19 02:33:05529 EXPECT_TRUE(stream.get());
530
531 // Cause QUIC stream to be created.
532 HttpRequestInfo request_info;
533 request_info.method = "GET";
534 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:39535 request_info.traffic_annotation =
536 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:27537 EXPECT_EQ(OK,
538 stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:39539 net_log_, CompletionOnceCallback()));
jri053fdbd2016-08-19 02:33:05540 // Ensure that session is alive and active.
541 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
542 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
543 EXPECT_TRUE(HasActiveSession(host_port_pair_));
544
545 IPEndPoint actual_address;
546 session->GetDefaultSocket()->GetPeerAddress(&actual_address);
547 EXPECT_EQ(actual_address, expected_address);
548 DVLOG(1) << "Socket connected to: " << actual_address.address().ToString()
549 << " " << actual_address.port();
550 DVLOG(1) << "Expected address: " << expected_address.address().ToString()
551 << " " << expected_address.port();
552
553 stream.reset();
554 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
555 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
556 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
557 }
558
tbansal3b966952016-10-25 23:25:14559 // Verifies that the QUIC stream factory is initialized correctly.
tbansal9b1cdf32017-05-10 17:28:39560 void VerifyInitialization() {
Nick Harper72ade192019-07-17 03:30:42561 test_params_.quic_params.max_server_configs_stored_in_properties = 1;
562 test_params_.quic_params.idle_connection_timeout_seconds = 500;
tbansal3b966952016-10-25 23:25:14563 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:20564 factory_->set_require_confirmation(false);
tbansal3b966952016-10-25 23:25:14565 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
566 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rch431dd4452017-04-19 15:22:35567 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
568 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:27569 MockCryptoClientStream::ZERO_RTT);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52570 const quic::QuicConfig* config =
571 QuicStreamFactoryPeer::GetConfig(factory_.get());
ckrasic32b17dcd2016-10-31 06:15:35572 EXPECT_EQ(500, config->IdleNetworkTimeout().ToSeconds());
tbansal3b966952016-10-25 23:25:14573
574 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
575
bnc3472afd2016-11-17 15:27:21576 const AlternativeService alternative_service1(
577 kProtoQUIC, host_port_pair_.host(), host_port_pair_.port());
tbansal3b966952016-10-25 23:25:14578 AlternativeServiceInfoVector alternative_service_info_vector;
579 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
580 alternative_service_info_vector.push_back(
zhongyie537a002017-06-27 16:48:21581 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
582 alternative_service1, expiration, {version_}));
tbansal3b966952016-10-25 23:25:14583 http_server_properties_.SetAlternativeServices(
584 url::SchemeHostPort(url_), alternative_service_info_vector);
585
586 HostPortPair host_port_pair2(kServer2HostName, kDefaultServerPort);
587 url::SchemeHostPort server2("https", kServer2HostName, kDefaultServerPort);
bnc3472afd2016-11-17 15:27:21588 const AlternativeService alternative_service2(
589 kProtoQUIC, host_port_pair2.host(), host_port_pair2.port());
tbansal3b966952016-10-25 23:25:14590 AlternativeServiceInfoVector alternative_service_info_vector2;
591 alternative_service_info_vector2.push_back(
zhongyie537a002017-06-27 16:48:21592 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
593 alternative_service2, expiration, {version_}));
tbansal9b1cdf32017-05-10 17:28:39594
595 http_server_properties_.SetAlternativeServices(
596 server2, alternative_service_info_vector2);
597 // Verify that the properties of both QUIC servers are stored in the
598 // HTTP properties map.
599 EXPECT_EQ(2U, http_server_properties_.alternative_service_map().size());
tbansal3b966952016-10-25 23:25:14600
601 http_server_properties_.SetMaxServerConfigsStoredInProperties(
Yixin Wang4a227aa22017-11-30 21:33:01602 kDefaultMaxQuicServerEntries);
tbansal3b966952016-10-25 23:25:14603
Ryan Hamilton8d9ee76e2018-05-29 23:52:52604 quic::QuicServerId quic_server_id(kDefaultServerHostName, 443,
605 PRIVACY_MODE_DISABLED);
rch431dd4452017-04-19 15:22:35606 std::unique_ptr<QuicServerInfo> quic_server_info =
Jeremy Roman0579ed62017-08-29 15:56:19607 std::make_unique<PropertiesBasedQuicServerInfo>(
rch431dd4452017-04-19 15:22:35608 quic_server_id, &http_server_properties_);
tbansal3b966952016-10-25 23:25:14609
610 // Update quic_server_info's server_config and persist it.
611 QuicServerInfo::State* state = quic_server_info->mutable_state();
612 // Minimum SCFG that passes config validation checks.
613 const char scfg[] = {// SCFG
614 0x53, 0x43, 0x46, 0x47,
615 // num entries
616 0x01, 0x00,
617 // padding
618 0x00, 0x00,
619 // EXPY
620 0x45, 0x58, 0x50, 0x59,
621 // EXPY end offset
622 0x08, 0x00, 0x00, 0x00,
623 // Value
624 '1', '2', '3', '4', '5', '6', '7', '8'};
625
626 // Create temporary strings becasue Persist() clears string data in |state|.
627 string server_config(reinterpret_cast<const char*>(&scfg), sizeof(scfg));
628 string source_address_token("test_source_address_token");
629 string cert_sct("test_cert_sct");
630 string chlo_hash("test_chlo_hash");
631 string signature("test_signature");
632 string test_cert("test_cert");
rch872e00e2016-12-02 02:48:18633 std::vector<string> certs;
tbansal3b966952016-10-25 23:25:14634 certs.push_back(test_cert);
635 state->server_config = server_config;
636 state->source_address_token = source_address_token;
637 state->cert_sct = cert_sct;
638 state->chlo_hash = chlo_hash;
639 state->server_config_sig = signature;
640 state->certs = certs;
641
642 quic_server_info->Persist();
643
Ryan Hamilton8d9ee76e2018-05-29 23:52:52644 quic::QuicServerId quic_server_id2(kServer2HostName, 443,
645 PRIVACY_MODE_DISABLED);
rch431dd4452017-04-19 15:22:35646 std::unique_ptr<QuicServerInfo> quic_server_info2 =
Jeremy Roman0579ed62017-08-29 15:56:19647 std::make_unique<PropertiesBasedQuicServerInfo>(
rch431dd4452017-04-19 15:22:35648 quic_server_id2, &http_server_properties_);
tbansal3b966952016-10-25 23:25:14649 // Update quic_server_info2's server_config and persist it.
650 QuicServerInfo::State* state2 = quic_server_info2->mutable_state();
651
652 // Minimum SCFG that passes config validation checks.
653 const char scfg2[] = {// SCFG
654 0x53, 0x43, 0x46, 0x47,
655 // num entries
656 0x01, 0x00,
657 // padding
658 0x00, 0x00,
659 // EXPY
660 0x45, 0x58, 0x50, 0x59,
661 // EXPY end offset
662 0x08, 0x00, 0x00, 0x00,
663 // Value
664 '8', '7', '3', '4', '5', '6', '2', '1'};
665
666 // Create temporary strings becasue Persist() clears string data in
667 // |state2|.
668 string server_config2(reinterpret_cast<const char*>(&scfg2), sizeof(scfg2));
669 string source_address_token2("test_source_address_token2");
670 string cert_sct2("test_cert_sct2");
671 string chlo_hash2("test_chlo_hash2");
672 string signature2("test_signature2");
673 string test_cert2("test_cert2");
rch872e00e2016-12-02 02:48:18674 std::vector<string> certs2;
tbansal3b966952016-10-25 23:25:14675 certs2.push_back(test_cert2);
676 state2->server_config = server_config2;
677 state2->source_address_token = source_address_token2;
678 state2->cert_sct = cert_sct2;
679 state2->chlo_hash = chlo_hash2;
680 state2->server_config_sig = signature2;
681 state2->certs = certs2;
682
683 quic_server_info2->Persist();
684
tbansal3b966952016-10-25 23:25:14685 // Verify the MRU order is maintained.
686 const QuicServerInfoMap& quic_server_info_map =
687 http_server_properties_.quic_server_info_map();
688 EXPECT_EQ(2u, quic_server_info_map.size());
jdoerrie22a91d8b92018-10-05 08:43:26689 auto quic_server_info_map_it = quic_server_info_map.begin();
tbansal3b966952016-10-25 23:25:14690 EXPECT_EQ(quic_server_info_map_it->first, quic_server_id2);
691 ++quic_server_info_map_it;
692 EXPECT_EQ(quic_server_info_map_it->first, quic_server_id);
693
Renjiea0cb4a2c2018-09-26 23:37:30694 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
695 "192.168.0.1", "");
rch431dd4452017-04-19 15:22:35696
697 // Create a session and verify that the cached state is loaded.
Ryan Hamiltonabad59e2019-06-06 04:02:59698 MockQuicData socket_data(version_);
rch431dd4452017-04-19 15:22:35699 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:17700 socket_data.AddSocketDataToFactory(socket_factory_.get());
rch431dd4452017-04-19 15:22:35701
zhongyi98d6a9262017-05-19 02:47:45702 QuicStreamRequest request(factory_.get());
Yixin Wang247ea642017-11-15 01:15:50703 EXPECT_EQ(ERR_IO_PENDING,
Ryan Hamilton4f0b26e2018-06-27 23:52:32704 request.Request(
705 HostPortPair(quic_server_id.host(), quic_server_id.port()),
Ryan Hamilton9ef8c102019-06-28 03:58:52706 version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
707 NetworkIsolationKey(),
Ryan Hamilton4f0b26e2018-06-27 23:52:32708 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
Zhongyi Shia6b68d112018-09-24 07:49:03709 failed_on_default_network_callback_, callback_.callback()));
rch431dd4452017-04-19 15:22:35710 EXPECT_THAT(callback_.WaitForResult(), IsOk());
711
tbansal3b966952016-10-25 23:25:14712 EXPECT_FALSE(QuicStreamFactoryPeer::CryptoConfigCacheIsEmpty(
713 factory_.get(), quic_server_id));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52714 quic::QuicCryptoClientConfig* crypto_config =
tbansal3b966952016-10-25 23:25:14715 QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
Ryan Hamilton8d9ee76e2018-05-29 23:52:52716 quic::QuicCryptoClientConfig::CachedState* cached =
tbansal3b966952016-10-25 23:25:14717 crypto_config->LookupOrCreate(quic_server_id);
718 EXPECT_FALSE(cached->server_config().empty());
719 EXPECT_TRUE(cached->GetServerConfig());
720 EXPECT_EQ(server_config, cached->server_config());
721 EXPECT_EQ(source_address_token, cached->source_address_token());
722 EXPECT_EQ(cert_sct, cached->cert_sct());
723 EXPECT_EQ(chlo_hash, cached->chlo_hash());
724 EXPECT_EQ(signature, cached->signature());
725 ASSERT_EQ(1U, cached->certs().size());
726 EXPECT_EQ(test_cert, cached->certs()[0]);
727
rch431dd4452017-04-19 15:22:35728 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
729
730 // Create a session and verify that the cached state is loaded.
Ryan Hamiltonabad59e2019-06-06 04:02:59731 MockQuicData socket_data2(version_);
rch431dd4452017-04-19 15:22:35732 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:17733 socket_data2.AddSocketDataToFactory(socket_factory_.get());
rch431dd4452017-04-19 15:22:35734
Renjiea0cb4a2c2018-09-26 23:37:30735 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
736 "192.168.0.2", "");
rch431dd4452017-04-19 15:22:35737
zhongyi98d6a9262017-05-19 02:47:45738 QuicStreamRequest request2(factory_.get());
rch431dd4452017-04-19 15:22:35739 EXPECT_EQ(ERR_IO_PENDING,
Ryan Hamilton4f0b26e2018-06-27 23:52:32740 request2.Request(
741 HostPortPair(quic_server_id2.host(), quic_server_id2.port()),
Ryan Hamilton9ef8c102019-06-28 03:58:52742 version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
743 NetworkIsolationKey(),
Ryan Hamilton4f0b26e2018-06-27 23:52:32744 /*cert_verify_flags=*/0, GURL("https://mail.example.org/"),
Zhongyi Shia6b68d112018-09-24 07:49:03745 net_log_, &net_error_details_,
746 failed_on_default_network_callback_, callback_.callback()));
rch431dd4452017-04-19 15:22:35747 EXPECT_THAT(callback_.WaitForResult(), IsOk());
748
tbansal3b966952016-10-25 23:25:14749 EXPECT_FALSE(QuicStreamFactoryPeer::CryptoConfigCacheIsEmpty(
750 factory_.get(), quic_server_id2));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52751 quic::QuicCryptoClientConfig::CachedState* cached2 =
tbansal3b966952016-10-25 23:25:14752 crypto_config->LookupOrCreate(quic_server_id2);
753 EXPECT_FALSE(cached2->server_config().empty());
754 EXPECT_TRUE(cached2->GetServerConfig());
755 EXPECT_EQ(server_config2, cached2->server_config());
756 EXPECT_EQ(source_address_token2, cached2->source_address_token());
757 EXPECT_EQ(cert_sct2, cached2->cert_sct());
758 EXPECT_EQ(chlo_hash2, cached2->chlo_hash());
759 EXPECT_EQ(signature2, cached2->signature());
760 ASSERT_EQ(1U, cached->certs().size());
761 EXPECT_EQ(test_cert2, cached2->certs()[0]);
762 }
763
jri5b785512016-09-13 04:29:11764 void RunTestLoopUntilIdle() {
765 while (!runner_->GetPostedTasks().empty())
766 runner_->RunNextTask();
767 }
768
Fan Yang32c5a112018-12-10 20:06:33769 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56770 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
771 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36772 }
773
Zhongyi Shi99d0cdd2019-05-21 01:18:42774 std::string ConstructDataHeader(size_t body_len) {
775 if (version_.transport_version != quic::QUIC_VERSION_99) {
776 return "";
777 }
778 quic::HttpEncoder encoder;
779 std::unique_ptr<char[]> buffer;
780 auto header_length = encoder.SerializeDataFrameHeader(body_len, &buffer);
781 return std::string(buffer.get(), header_length);
782 }
783
784 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
785 uint64_t packet_number,
786 quic::QuicStreamId stream_id,
787 bool should_include_version,
788 bool fin,
Zhongyi Shi99d0cdd2019-05-21 01:18:42789 quic::QuicStringPiece data) {
Ryan Hamilton7505eb92019-06-08 00:22:17790 return server_maker_.MakeDataPacket(packet_number, stream_id,
791 should_include_version, fin, data);
Zhongyi Shi99d0cdd2019-05-21 01:18:42792 }
793
Fan Yang32c5a112018-12-10 20:06:33794 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56795 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
796 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36797 }
798
Zhongyi Shia6b68d112018-09-24 07:49:03799 void OnFailedOnDefaultNetwork(int rv) { failed_on_default_network_ = true; }
800
jri9f303712016-09-13 01:10:22801 // Helper methods for tests of connection migration on write error.
Zhongyi Shi32fe14d42019-02-28 00:25:36802 void TestMigrationOnWriteErrorNonMigratableStream(IoMode write_error_mode,
803 bool migrate_idle_sessions);
Zhongyi Shi0439ecc72018-07-11 04:41:26804 // Migratable stream triggers write error.
805 void TestMigrationOnWriteErrorMixedStreams(IoMode write_error_mode);
806 // Non-migratable stream triggers write error.
807 void TestMigrationOnWriteErrorMixedStreams2(IoMode write_error_mode);
jri9f303712016-09-13 01:10:22808 void TestMigrationOnWriteErrorMigrationDisabled(IoMode write_error_mode);
809 void TestMigrationOnWriteError(IoMode write_error_mode);
Zhongyi Shi0439ecc72018-07-11 04:41:26810 void TestMigrationOnWriteErrorWithMultipleRequests(IoMode write_error_mode);
jri9f303712016-09-13 01:10:22811 void TestMigrationOnWriteErrorNoNewNetwork(IoMode write_error_mode);
Zhongyi Shi7f1d9212018-06-22 23:24:36812 void TestMigrationOnMultipleWriteErrors(
813 IoMode write_error_mode_on_old_network,
814 IoMode write_error_mode_on_new_network);
Zhongyi Shib24001c02018-06-18 20:01:52815 void TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
816 bool disconnected);
Zhongyi Shi1e2bc742018-06-16 02:06:07817 void TestMigrationOnWriteErrorWithNotificationQueuedLater(bool disconnected);
Zhongyi Shi9f316b262018-06-18 22:01:16818 void TestMigrationOnNetworkDisconnected(bool async_write_before);
Zhongyi Shia0644e32018-06-21 05:19:52819 void TestMigrationOnNetworkMadeDefault(IoMode write_mode);
Zhongyi Shi22fd5f52018-06-20 17:39:09820 void TestMigrationOnPathDegrading(bool async_write_before);
Zhongyi Shib3bc982c2018-07-10 19:59:24821 void TestMigrateSessionWithDrainingStream(
822 IoMode write_mode_for_queued_packet);
jri5b785512016-09-13 04:29:11823 void TestMigrationOnWriteErrorPauseBeforeConnected(IoMode write_error_mode);
Zhongyi Shi4ac9e1f2018-06-21 05:21:47824 void TestMigrationOnWriteErrorWithMultipleNotifications(
jri5b785512016-09-13 04:29:11825 IoMode write_error_mode,
Zhongyi Shi4ac9e1f2018-06-21 05:21:47826 bool disconnect_before_connect);
Zhongyi Shi634c1882018-08-16 04:05:59827 void TestNoAlternateNetworkBeforeHandshake(quic::QuicErrorCode error);
Zhongyi Shi8de43832018-08-15 23:40:00828 void TestNewConnectionOnAlternateNetworkBeforeHandshake(
829 quic::QuicErrorCode error);
Zhongyi Shi32fe14d42019-02-28 00:25:36830 void TestOnNetworkMadeDefaultNonMigratableStream(bool migrate_idle_sessions);
831 void TestMigrateSessionEarlyNonMigratableStream(bool migrate_idle_sessions);
832 void TestOnNetworkDisconnectedNoOpenStreams(bool migrate_idle_sessions);
833 void TestOnNetworkMadeDefaultNoOpenStreams(bool migrate_idle_sessions);
834 void TestOnNetworkDisconnectedNonMigratableStream(bool migrate_idle_sessions);
jri9f303712016-09-13 01:10:22835
Jana Iyengarf6b13d82017-09-04 02:09:10836 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Renjiea0cb4a2c2018-09-26 23:37:30837 std::unique_ptr<MockHostResolverBase> host_resolver_;
Ryan Sleevib8449e02018-07-15 04:31:07838 std::unique_ptr<SSLConfigService> ssl_config_service_;
Zhongyi Shi5f587cc2017-11-21 23:24:17839 std::unique_ptr<MockClientSocketFactory> socket_factory_;
[email protected]e8ff26842013-03-22 21:02:05840 MockCryptoClientStreamFactory crypto_client_stream_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52841 quic::test::MockRandom random_generator_;
842 quic::MockClock clock_;
rtenneti38f5cd52014-10-28 20:28:28843 scoped_refptr<TestTaskRunner> runner_;
Nick Harper23290b82019-05-02 00:02:56844 const quic::ParsedQuicVersion version_;
alyssar2adf3ac2016-05-03 17:12:58845 QuicTestPacketMaker client_maker_;
846 QuicTestPacketMaker server_maker_;
rtenneticcab42b2015-10-09 06:38:16847 HttpServerPropertiesImpl http_server_properties_;
danakjad1777e2016-04-16 00:56:42848 std::unique_ptr<CertVerifier> cert_verifier_;
[email protected]080b77932014-08-04 01:22:46849 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42850 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:23851 DefaultCTPolicyEnforcer ct_policy_enforcer_;
danakjad1777e2016-04-16 00:56:42852 std::unique_ptr<ScopedMockNetworkChangeNotifier>
jri7e636642016-01-14 06:57:08853 scoped_mock_network_change_notifier_;
danakjad1777e2016-04-16 00:56:42854 std::unique_ptr<QuicStreamFactory> factory_;
[email protected]bf4ea2f2014-03-10 22:57:53855 HostPortPair host_port_pair_;
ckrasic3865ee0f2016-02-29 22:04:56856 GURL url_;
857 GURL url2_;
858 GURL url3_;
859 GURL url4_;
860
[email protected]9dd3ff0f2014-03-26 09:51:28861 PrivacyMode privacy_mode_;
tfarina42834112016-09-22 13:38:20862 NetLogWithSource net_log_;
[email protected]e13201d82012-12-12 05:00:32863 TestCompletionCallback callback_;
Zhongyi Shia6b68d112018-09-24 07:49:03864 const CompletionRepeatingCallback failed_on_default_network_callback_;
865 bool failed_on_default_network_;
Ryan Hamilton75f197262017-08-17 14:00:07866 NetErrorDetails net_error_details_;
jri7046038f2015-10-22 00:29:26867
868 // Variables to configure QuicStreamFactory.
Zhongyi Shi967d2f12019-02-08 20:58:53869 HttpNetworkSession::Params test_params_;
[email protected]e13201d82012-12-12 05:00:32870};
871
bnc359ed2a2016-04-29 20:43:45872class QuicStreamFactoryTest : public QuicStreamFactoryTestBase,
873 public ::testing::TestWithParam<TestParams> {
874 protected:
Yixin Wang079ad542018-01-11 04:06:05875 QuicStreamFactoryTest()
876 : QuicStreamFactoryTestBase(
877 GetParam().version,
878 GetParam().client_headers_include_h2_stream_dependency) {}
bnc359ed2a2016-04-29 20:43:45879};
880
Victor Costane635086f2019-01-27 05:20:30881INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
882 QuicStreamFactoryTest,
883 ::testing::ValuesIn(GetTestParams()));
[email protected]1e960032013-12-20 19:00:20884
[email protected]1e960032013-12-20 19:00:20885TEST_P(QuicStreamFactoryTest, Create) {
jri7046038f2015-10-22 00:29:26886 Initialize();
rch6faa4d42016-01-05 20:48:43887 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
888 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:26889
Ryan Hamiltonabad59e2019-06-06 04:02:59890 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:36891 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:43892 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:17893 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]e13201d82012-12-12 05:00:32894
zhongyi98d6a9262017-05-19 02:47:45895 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:33896 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:03897 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:52898 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
899 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:03900 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
901 failed_on_default_network_callback_, callback_.callback()));
[email protected]e13201d82012-12-12 05:00:32902
robpercival214763f2016-07-01 23:27:01903 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:24904 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0edce6a2013-05-08 18:02:40905 EXPECT_TRUE(stream.get());
[email protected]e13201d82012-12-12 05:00:32906
Renjiea0cb4a2c2018-09-26 23:37:30907 EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_->last_request_priority());
Yixin Wang247ea642017-11-15 01:15:50908
zhongyi98d6a9262017-05-19 02:47:45909 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:51910 EXPECT_EQ(OK,
911 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:52912 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
913 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:51914 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
915 failed_on_default_network_callback_, callback_.callback()));
rch68a80eb2017-04-25 05:24:24916 // Will reset stream 3.
Yixin Wang7891a39d2017-11-08 20:59:24917 stream = CreateStream(&request2);
rch68a80eb2017-04-25 05:24:24918
919 EXPECT_TRUE(stream.get());
920
921 // TODO(rtenneti): We should probably have a tests that HTTP and HTTPS result
922 // in streams on different sessions.
zhongyi98d6a9262017-05-19 02:47:45923 QuicStreamRequest request3(factory_.get());
Matt Menke26e41542019-06-05 01:09:51924 EXPECT_EQ(OK,
925 request3.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:52926 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
927 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:51928 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
929 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:24930 stream = CreateStream(&request3); // Will reset stream 5.
Ryan Hamiltona12722b2017-08-12 02:23:20931 stream.reset(); // Will reset stream 7.
[email protected]e13201d82012-12-12 05:00:32932
rch37de576c2015-05-17 20:28:17933 EXPECT_TRUE(socket_data.AllReadDataConsumed());
934 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]e13201d82012-12-12 05:00:32935}
936
[email protected]8bd2b812014-03-26 04:01:17937TEST_P(QuicStreamFactoryTest, CreateZeroRtt) {
jri7046038f2015-10-22 00:29:26938 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:20939 factory_->set_require_confirmation(false);
rch6faa4d42016-01-05 20:48:43940 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
941 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:26942
Ryan Hamiltonabad59e2019-06-06 04:02:59943 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:36944 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:17945 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]8bd2b812014-03-26 04:01:17946
947 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:27948 MockCryptoClientStream::ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:30949 host_resolver_->set_synchronous_mode(true);
950 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
951 "192.168.0.1", "");
[email protected]8bd2b812014-03-26 04:01:17952
zhongyi98d6a9262017-05-19 02:47:45953 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:51954 EXPECT_EQ(OK,
955 request.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()));
[email protected]8bd2b812014-03-26 04:01:17960
Yixin Wang7891a39d2017-11-08 20:59:24961 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]8bd2b812014-03-26 04:01:17962 EXPECT_TRUE(stream.get());
rch37de576c2015-05-17 20:28:17963 EXPECT_TRUE(socket_data.AllReadDataConsumed());
964 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]8bd2b812014-03-26 04:01:17965}
966
rchd6163f32017-01-30 23:50:38967TEST_P(QuicStreamFactoryTest, DefaultInitialRtt) {
968 Initialize();
969 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
970 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
971
Ryan Hamiltonabad59e2019-06-06 04:02:59972 MockQuicData socket_data(version_);
rchd6163f32017-01-30 23:50:38973 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:43974 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:17975 socket_data.AddSocketDataToFactory(socket_factory_.get());
rchd6163f32017-01-30 23:50:38976
zhongyi98d6a9262017-05-19 02:47:45977 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:33978 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:03979 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:52980 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
981 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:03982 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
983 failed_on_default_network_callback_, callback_.callback()));
rchd6163f32017-01-30 23:50:38984
985 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:24986 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rchd6163f32017-01-30 23:50:38987 EXPECT_TRUE(stream.get());
988
989 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Ryan Hamiltona12722b2017-08-12 02:23:20990 EXPECT_TRUE(session->require_confirmation());
rchd6163f32017-01-30 23:50:38991 EXPECT_EQ(100000u, session->connection()->GetStats().srtt_us);
992 ASSERT_FALSE(session->config()->HasInitialRoundTripTimeUsToSend());
993}
994
Helen Li0e823912017-09-25 19:48:30995TEST_P(QuicStreamFactoryTest, FactoryDestroyedWhenJobPending) {
996 Initialize();
997 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
998 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
999
Ryan Hamiltonabad59e2019-06-06 04:02:591000 MockQuicData socket_data(version_);
Helen Li0e823912017-09-25 19:48:301001 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431002 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171003 socket_data.AddSocketDataToFactory(socket_factory_.get());
Helen Li0e823912017-09-25 19:48:301004
1005 auto request = std::make_unique<QuicStreamRequest>(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331006 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031007 request->Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521008 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1009 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031010 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1011 failed_on_default_network_callback_, callback_.callback()));
Helen Li0e823912017-09-25 19:48:301012 request.reset();
1013 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
1014 // Tearing down a QuicStreamFactory with a pending Job should not cause any
1015 // crash. crbug.com/768343.
1016 factory_.reset();
1017}
1018
Ryan Hamiltona12722b2017-08-12 02:23:201019TEST_P(QuicStreamFactoryTest, RequireConfirmation) {
1020 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271021 MockCryptoClientStream::ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:301022 host_resolver_->set_synchronous_mode(true);
1023 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
1024 "192.168.0.1", "");
Ryan Hamiltona12722b2017-08-12 02:23:201025 Initialize();
1026 factory_->set_require_confirmation(true);
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_);
Ryan Hamiltona12722b2017-08-12 02:23:201031 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());
Ryan Hamiltona12722b2017-08-12 02:23:201034
1035 QuicStreamRequest request(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()));
Ryan Hamiltona12722b2017-08-12 02:23:201042
Ryan Hamilton8e32a2b2017-08-28 20:06:521043 IPAddress last_address;
1044 EXPECT_FALSE(http_server_properties_.GetSupportsQuic(&last_address));
1045
Ryan Hamiltona12722b2017-08-12 02:23:201046 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521047 quic::QuicSession::HANDSHAKE_CONFIRMED);
Ryan Hamiltona12722b2017-08-12 02:23:201048
Ryan Hamilton8e32a2b2017-08-28 20:06:521049 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
1050
Ryan Hamiltona12722b2017-08-12 02:23:201051 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241052 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Ryan Hamiltona12722b2017-08-12 02:23:201053 EXPECT_TRUE(stream.get());
1054
1055 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1056 EXPECT_TRUE(session->require_confirmation());
1057}
1058
1059TEST_P(QuicStreamFactoryTest, DontRequireConfirmationFromSameIP) {
1060 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271061 MockCryptoClientStream::ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:301062 host_resolver_->set_synchronous_mode(true);
1063 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
1064 "192.168.0.1", "");
Ryan Hamiltona12722b2017-08-12 02:23:201065 Initialize();
1066 factory_->set_require_confirmation(true);
1067 http_server_properties_.SetSupportsQuic(IPAddress(192, 0, 2, 33));
1068
1069 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1070 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1071
Ryan Hamiltonabad59e2019-06-06 04:02:591072 MockQuicData socket_data(version_);
Ryan Hamiltona12722b2017-08-12 02:23:201073 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431074 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171075 socket_data.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamiltona12722b2017-08-12 02:23:201076
1077 QuicStreamRequest request(factory_.get());
Zhongyi Shia6b68d112018-09-24 07:49:031078 EXPECT_THAT(request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521079 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1080 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031081 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1082 failed_on_default_network_callback_, callback_.callback()),
Paul Jensen8e3c5d32018-02-19 17:06:331083 IsOk());
Ryan Hamiltona12722b2017-08-12 02:23:201084
Ryan Hamilton8e32a2b2017-08-28 20:06:521085 IPAddress last_address;
1086 EXPECT_FALSE(http_server_properties_.GetSupportsQuic(&last_address));
1087
Yixin Wang7891a39d2017-11-08 20:59:241088 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Ryan Hamiltona12722b2017-08-12 02:23:201089 EXPECT_TRUE(stream.get());
1090
1091 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1092 EXPECT_FALSE(session->require_confirmation());
Ryan Hamilton8e32a2b2017-08-28 20:06:521093
1094 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521095 quic::QuicSession::HANDSHAKE_CONFIRMED);
Ryan Hamilton8e32a2b2017-08-28 20:06:521096
1097 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
Ryan Hamiltona12722b2017-08-12 02:23:201098}
1099
rchd6163f32017-01-30 23:50:381100TEST_P(QuicStreamFactoryTest, CachedInitialRtt) {
1101 ServerNetworkStats stats;
1102 stats.srtt = base::TimeDelta::FromMilliseconds(10);
1103 http_server_properties_.SetServerNetworkStats(url::SchemeHostPort(url_),
1104 stats);
Nick Harper72ade192019-07-17 03:30:421105 test_params_.quic_params.estimate_initial_rtt = true;
rchd6163f32017-01-30 23:50:381106
1107 Initialize();
1108 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1109 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1110
Ryan Hamiltonabad59e2019-06-06 04:02:591111 MockQuicData socket_data(version_);
rchd6163f32017-01-30 23:50:381112 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431113 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171114 socket_data.AddSocketDataToFactory(socket_factory_.get());
rchd6163f32017-01-30 23:50:381115
zhongyi98d6a9262017-05-19 02:47:451116 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331117 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031118 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521119 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1120 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031121 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1122 failed_on_default_network_callback_, callback_.callback()));
rchd6163f32017-01-30 23:50:381123
1124 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241125 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rchd6163f32017-01-30 23:50:381126 EXPECT_TRUE(stream.get());
1127
1128 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1129 EXPECT_EQ(10000u, session->connection()->GetStats().srtt_us);
1130 ASSERT_TRUE(session->config()->HasInitialRoundTripTimeUsToSend());
1131 EXPECT_EQ(10000u, session->config()->GetInitialRoundTripTimeUsToSend());
1132}
1133
1134TEST_P(QuicStreamFactoryTest, 2gInitialRtt) {
1135 ScopedMockNetworkChangeNotifier notifier;
1136 notifier.mock_network_change_notifier()->SetConnectionType(
1137 NetworkChangeNotifier::CONNECTION_2G);
Nick Harper72ade192019-07-17 03:30:421138 test_params_.quic_params.estimate_initial_rtt = true;
rchd6163f32017-01-30 23:50:381139
1140 Initialize();
1141 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1142 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1143
Ryan Hamiltonabad59e2019-06-06 04:02:591144 MockQuicData socket_data(version_);
rchd6163f32017-01-30 23:50:381145 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431146 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171147 socket_data.AddSocketDataToFactory(socket_factory_.get());
rchd6163f32017-01-30 23:50:381148
zhongyi98d6a9262017-05-19 02:47:451149 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331150 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031151 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521152 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1153 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031154 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1155 failed_on_default_network_callback_, callback_.callback()));
rchd6163f32017-01-30 23:50:381156
1157 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241158 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rchd6163f32017-01-30 23:50:381159 EXPECT_TRUE(stream.get());
1160
1161 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1162 EXPECT_EQ(1200000u, session->connection()->GetStats().srtt_us);
1163 ASSERT_TRUE(session->config()->HasInitialRoundTripTimeUsToSend());
1164 EXPECT_EQ(1200000u, session->config()->GetInitialRoundTripTimeUsToSend());
1165}
1166
1167TEST_P(QuicStreamFactoryTest, 3gInitialRtt) {
1168 ScopedMockNetworkChangeNotifier notifier;
1169 notifier.mock_network_change_notifier()->SetConnectionType(
1170 NetworkChangeNotifier::CONNECTION_3G);
Nick Harper72ade192019-07-17 03:30:421171 test_params_.quic_params.estimate_initial_rtt = true;
rchd6163f32017-01-30 23:50:381172
1173 Initialize();
1174 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1175 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1176
Ryan Hamiltonabad59e2019-06-06 04:02:591177 MockQuicData socket_data(version_);
rchd6163f32017-01-30 23:50:381178 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431179 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171180 socket_data.AddSocketDataToFactory(socket_factory_.get());
rchd6163f32017-01-30 23:50:381181
zhongyi98d6a9262017-05-19 02:47:451182 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331183 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031184 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521185 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1186 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031187 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1188 failed_on_default_network_callback_, callback_.callback()));
rchd6163f32017-01-30 23:50:381189
1190 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241191 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rchd6163f32017-01-30 23:50:381192 EXPECT_TRUE(stream.get());
1193
1194 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1195 EXPECT_EQ(400000u, session->connection()->GetStats().srtt_us);
1196 ASSERT_TRUE(session->config()->HasInitialRoundTripTimeUsToSend());
1197 EXPECT_EQ(400000u, session->config()->GetInitialRoundTripTimeUsToSend());
1198}
1199
rch68955482015-09-24 00:14:391200TEST_P(QuicStreamFactoryTest, GoAway) {
jri7046038f2015-10-22 00:29:261201 Initialize();
rch6faa4d42016-01-05 20:48:431202 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1203 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:261204
Ryan Hamiltonabad59e2019-06-06 04:02:591205 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361206 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431207 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171208 socket_data.AddSocketDataToFactory(socket_factory_.get());
rch68955482015-09-24 00:14:391209
zhongyi98d6a9262017-05-19 02:47:451210 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331211 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031212 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521213 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1214 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031215 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1216 failed_on_default_network_callback_, callback_.callback()));
rch68955482015-09-24 00:14:391217
robpercival214763f2016-07-01 23:27:011218 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241219 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rch68955482015-09-24 00:14:391220 EXPECT_TRUE(stream.get());
1221
bnc912a04b2016-04-20 14:19:501222 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
rch68955482015-09-24 00:14:391223
Ryan Hamilton8d9ee76e2018-05-29 23:52:521224 session->OnGoAway(quic::QuicGoAwayFrame());
rch68955482015-09-24 00:14:391225
bnc912a04b2016-04-20 14:19:501226 EXPECT_FALSE(HasActiveSession(host_port_pair_));
rch68955482015-09-24 00:14:391227
1228 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1229 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1230}
1231
zhongyi6b5a3892016-03-12 04:46:201232TEST_P(QuicStreamFactoryTest, GoAwayForConnectionMigrationWithPortOnly) {
1233 Initialize();
1234 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1235 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1236
Ryan Hamiltonabad59e2019-06-06 04:02:591237 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361238 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431239 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171240 socket_data.AddSocketDataToFactory(socket_factory_.get());
zhongyi6b5a3892016-03-12 04:46:201241
zhongyi98d6a9262017-05-19 02:47:451242 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331243 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031244 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521245 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1246 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031247 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1248 failed_on_default_network_callback_, callback_.callback()));
zhongyi6b5a3892016-03-12 04:46:201249
robpercival214763f2016-07-01 23:27:011250 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241251 std::unique_ptr<HttpStream> stream = CreateStream(&request);
zhongyi6b5a3892016-03-12 04:46:201252 EXPECT_TRUE(stream.get());
1253
bnc912a04b2016-04-20 14:19:501254 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
zhongyi6b5a3892016-03-12 04:46:201255
Ryan Hamilton8d9ee76e2018-05-29 23:52:521256 session->OnGoAway(quic::QuicGoAwayFrame(
1257 quic::kInvalidControlFrameId, quic::QUIC_ERROR_MIGRATING_PORT, 0,
1258 "peer connection migration due to port change only"));
zhongyi6b5a3892016-03-12 04:46:201259 NetErrorDetails details;
1260 EXPECT_FALSE(details.quic_port_migration_detected);
1261 session->PopulateNetErrorDetails(&details);
1262 EXPECT_TRUE(details.quic_port_migration_detected);
1263 details.quic_port_migration_detected = false;
1264 stream->PopulateNetErrorDetails(&details);
1265 EXPECT_TRUE(details.quic_port_migration_detected);
1266
bnc912a04b2016-04-20 14:19:501267 EXPECT_FALSE(HasActiveSession(host_port_pair_));
zhongyi6b5a3892016-03-12 04:46:201268
1269 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1270 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1271}
1272
[email protected]5db452202014-08-19 05:22:151273TEST_P(QuicStreamFactoryTest, Pooling) {
jri7046038f2015-10-22 00:29:261274 Initialize();
rch6faa4d42016-01-05 20:48:431275 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1276 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:261277
Ryan Hamiltonabad59e2019-06-06 04:02:591278 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361279 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431280 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171281 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]eed749f92013-12-23 18:57:381282
rch6faa4d42016-01-05 20:48:431283 HostPortPair server2(kServer2HostName, kDefaultServerPort);
Renjiea0cb4a2c2018-09-26 23:37:301284 host_resolver_->set_synchronous_mode(true);
1285 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
1286 "192.168.0.1", "");
1287 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]eed749f92013-12-23 18:57:381288
zhongyi98d6a9262017-05-19 02:47:451289 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:511290 EXPECT_EQ(OK,
1291 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521292 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1293 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:511294 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1295 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241296 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]eed749f92013-12-23 18:57:381297 EXPECT_TRUE(stream.get());
1298
1299 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451300 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:511301 EXPECT_EQ(OK,
1302 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521303 server2, version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
1304 NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:511305 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
1306 failed_on_default_network_callback_, callback.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241307 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]eed749f92013-12-23 18:57:381308 EXPECT_TRUE(stream2.get());
1309
bnc912a04b2016-04-20 14:19:501310 EXPECT_EQ(GetActiveSession(host_port_pair_), GetActiveSession(server2));
[email protected]eed749f92013-12-23 18:57:381311
rch37de576c2015-05-17 20:28:171312 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1313 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]eed749f92013-12-23 18:57:381314}
1315
jri94ddc3142016-08-26 01:32:431316TEST_P(QuicStreamFactoryTest, PoolingWithServerMigration) {
1317 // Set up session to migrate.
Renjiea0cb4a2c2018-09-26 23:37:301318 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
1319 "192.168.0.1", "");
jri94ddc3142016-08-26 01:32:431320 IPEndPoint alt_address = IPEndPoint(IPAddress(1, 2, 3, 4), 443);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521321 quic::QuicConfig config;
Victor Vasiliev4f6fb892019-05-31 16:58:311322 config.SetAlternateServerAddressToSend(ToQuicSocketAddress(alt_address));
jri94ddc3142016-08-26 01:32:431323
1324 VerifyServerMigration(config, alt_address);
1325
1326 // Close server-migrated session.
1327 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Renjieba55fae2018-09-20 03:05:161328 session->CloseSessionOnError(0u, quic::QUIC_NO_ERROR,
1329 quic::ConnectionCloseBehavior::SILENT_CLOSE);
jri94ddc3142016-08-26 01:32:431330
Ryan Hamilton0d65a8c2019-06-07 00:46:021331 client_maker_.Reset();
Ryan Hamilton9f2eac32019-06-27 03:15:541332 client_maker_.set_coalesce_http_frames(false);
jri94ddc3142016-08-26 01:32:431333 // Set up server IP, socket, proof, and config for new session.
1334 HostPortPair server2(kServer2HostName, kDefaultServerPort);
Renjiea0cb4a2c2018-09-26 23:37:301335 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
jri94ddc3142016-08-26 01:32:431336
1337 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521338 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Ryan Hamilton0d65a8c2019-06-07 00:46:021339 client_maker_.MakeInitialSettingsPacket(1));
bnceb9aa7112017-01-05 01:03:461340 MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(),
1341 settings_packet->length(), 1)};
fayang3bcb8b502016-12-07 21:44:371342
Ryan Sleevib8d7ea02018-05-07 20:01:011343 SequencedSocketData socket_data(reads, writes);
Ryan Hamilton0d65a8c2019-06-07 00:46:021344 QuicPacketPrinter printer(version_);
1345 socket_data.set_printer(&printer);
Zhongyi Shi5f587cc2017-11-21 23:24:171346 socket_factory_->AddSocketDataProvider(&socket_data);
jri94ddc3142016-08-26 01:32:431347
1348 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1349 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521350 quic::QuicConfig config2;
jri94ddc3142016-08-26 01:32:431351 crypto_client_stream_factory_.SetConfig(config2);
1352
1353 // Create new request to cause new session creation.
1354 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451355 QuicStreamRequest request2(factory_.get());
jri94ddc3142016-08-26 01:32:431356 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031357 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521358 server2, version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
1359 NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031360 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
1361 failed_on_default_network_callback_, callback.callback()));
jri94ddc3142016-08-26 01:32:431362 EXPECT_EQ(OK, callback.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:241363 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
jri94ddc3142016-08-26 01:32:431364 EXPECT_TRUE(stream2.get());
1365
1366 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1367 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1368 // EXPECT_EQ(GetActiveSession(host_port_pair_), GetActiveSession(server2));
1369}
1370
[email protected]eed749f92013-12-23 18:57:381371TEST_P(QuicStreamFactoryTest, NoPoolingAfterGoAway) {
jri7046038f2015-10-22 00:29:261372 Initialize();
rch6faa4d42016-01-05 20:48:431373 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1374 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1375 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:261376
Ryan Hamiltonabad59e2019-06-06 04:02:591377 MockQuicData socket_data1(version_);
rcha00569732016-08-27 11:09:361378 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431379 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171380 socket_data1.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamilton0d65a8c2019-06-07 00:46:021381 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:591382 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:361383 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431384 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171385 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]eed749f92013-12-23 18:57:381386
rch6faa4d42016-01-05 20:48:431387 HostPortPair server2(kServer2HostName, kDefaultServerPort);
Renjiea0cb4a2c2018-09-26 23:37:301388 host_resolver_->set_synchronous_mode(true);
1389 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
1390 "192.168.0.1", "");
1391 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]eed749f92013-12-23 18:57:381392
zhongyi98d6a9262017-05-19 02:47:451393 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:511394 EXPECT_EQ(OK,
1395 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521396 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1397 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:511398 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1399 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241400 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]eed749f92013-12-23 18:57:381401 EXPECT_TRUE(stream.get());
1402
1403 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451404 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:511405 EXPECT_EQ(OK,
1406 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521407 server2, version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
1408 NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:511409 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
1410 failed_on_default_network_callback_, callback.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241411 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]eed749f92013-12-23 18:57:381412 EXPECT_TRUE(stream2.get());
1413
bnc912a04b2016-04-20 14:19:501414 factory_->OnSessionGoingAway(GetActiveSession(host_port_pair_));
1415 EXPECT_FALSE(HasActiveSession(host_port_pair_));
1416 EXPECT_FALSE(HasActiveSession(server2));
[email protected]eed749f92013-12-23 18:57:381417
1418 TestCompletionCallback callback3;
zhongyi98d6a9262017-05-19 02:47:451419 QuicStreamRequest request3(factory_.get());
Matt Menke26e41542019-06-05 01:09:511420 EXPECT_EQ(OK,
1421 request3.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521422 server2, version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
1423 NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:511424 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
1425 failed_on_default_network_callback_, callback3.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241426 std::unique_ptr<HttpStream> stream3 = CreateStream(&request3);
[email protected]eed749f92013-12-23 18:57:381427 EXPECT_TRUE(stream3.get());
1428
bnc912a04b2016-04-20 14:19:501429 EXPECT_TRUE(HasActiveSession(server2));
[email protected]eed749f92013-12-23 18:57:381430
rch37de576c2015-05-17 20:28:171431 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
1432 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
1433 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1434 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]eed749f92013-12-23 18:57:381435}
1436
[email protected]5db452202014-08-19 05:22:151437TEST_P(QuicStreamFactoryTest, HttpsPooling) {
jri7046038f2015-10-22 00:29:261438 Initialize();
rch6faa4d42016-01-05 20:48:431439
Ryan Hamiltonabad59e2019-06-06 04:02:591440 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361441 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431442 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171443 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]eed749f92013-12-23 18:57:381444
rch6faa4d42016-01-05 20:48:431445 HostPortPair server1(kDefaultServerHostName, 443);
1446 HostPortPair server2(kServer2HostName, 443);
[email protected]eed749f92013-12-23 18:57:381447
bncf8bf0722015-05-19 20:04:131448 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
bnc20daf9a2015-05-15 17:11:011449 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
[email protected]eed749f92013-12-23 18:57:381450
Renjiea0cb4a2c2018-09-26 23:37:301451 host_resolver_->set_synchronous_mode(true);
1452 host_resolver_->rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
1453 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]eed749f92013-12-23 18:57:381454
zhongyi98d6a9262017-05-19 02:47:451455 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:511456 EXPECT_EQ(OK,
1457 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521458 server1, version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
1459 NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:511460 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1461 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241462 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]eed749f92013-12-23 18:57:381463 EXPECT_TRUE(stream.get());
1464
1465 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451466 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:511467 EXPECT_EQ(OK,
1468 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521469 server2, version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
1470 NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:511471 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
1472 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241473 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]eed749f92013-12-23 18:57:381474 EXPECT_TRUE(stream2.get());
1475
bnc912a04b2016-04-20 14:19:501476 EXPECT_EQ(GetActiveSession(server1), GetActiveSession(server2));
[email protected]eed749f92013-12-23 18:57:381477
rch37de576c2015-05-17 20:28:171478 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1479 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]eed749f92013-12-23 18:57:381480}
1481
[email protected]5db452202014-08-19 05:22:151482TEST_P(QuicStreamFactoryTest, HttpsPoolingWithMatchingPins) {
jri7046038f2015-10-22 00:29:261483 Initialize();
Ryan Hamiltonabad59e2019-06-06 04:02:591484 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361485 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431486 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171487 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]5db452202014-08-19 05:22:151488
rch6faa4d42016-01-05 20:48:431489 HostPortPair server1(kDefaultServerHostName, 443);
1490 HostPortPair server2(kServer2HostName, 443);
Matt Mueller230996f12018-10-22 19:39:441491 transport_security_state_.EnableStaticPinsForTesting();
1492 ScopedTransportSecurityStateSource scoped_security_state_source;
[email protected]5db452202014-08-19 05:22:151493
Matt Mueller230996f12018-10-22 19:39:441494 HashValue primary_pin(HASH_VALUE_SHA256);
1495 EXPECT_TRUE(primary_pin.FromString(
1496 "sha256/Nn8jk5By4Vkq6BeOVZ7R7AC6XUUBZsWmUbJR1f1Y5FY="));
bncf8bf0722015-05-19 20:04:131497 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
Matt Mueller230996f12018-10-22 19:39:441498 verify_details.cert_verify_result.public_key_hashes.push_back(primary_pin);
bnc20daf9a2015-05-15 17:11:011499 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
[email protected]5db452202014-08-19 05:22:151500
Renjiea0cb4a2c2018-09-26 23:37:301501 host_resolver_->set_synchronous_mode(true);
1502 host_resolver_->rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
1503 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]5db452202014-08-19 05:22:151504
zhongyi98d6a9262017-05-19 02:47:451505 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:511506 EXPECT_EQ(OK,
1507 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521508 server1, version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
1509 NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:511510 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1511 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241512 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]5db452202014-08-19 05:22:151513 EXPECT_TRUE(stream.get());
1514
1515 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451516 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:511517 EXPECT_EQ(OK,
1518 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521519 server2, version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
1520 NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:511521 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
1522 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241523 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]5db452202014-08-19 05:22:151524 EXPECT_TRUE(stream2.get());
1525
bnc912a04b2016-04-20 14:19:501526 EXPECT_EQ(GetActiveSession(server1), GetActiveSession(server2));
[email protected]5db452202014-08-19 05:22:151527
rch37de576c2015-05-17 20:28:171528 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1529 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]5db452202014-08-19 05:22:151530}
1531
1532TEST_P(QuicStreamFactoryTest, NoHttpsPoolingWithDifferentPins) {
jri7046038f2015-10-22 00:29:261533 Initialize();
rcha00569732016-08-27 11:09:361534
Ryan Hamiltonabad59e2019-06-06 04:02:591535 MockQuicData socket_data1(version_);
rcha00569732016-08-27 11:09:361536 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431537 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171538 socket_data1.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamilton0d65a8c2019-06-07 00:46:021539 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:591540 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:361541 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431542 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171543 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]5db452202014-08-19 05:22:151544
rch6faa4d42016-01-05 20:48:431545 HostPortPair server1(kDefaultServerHostName, 443);
1546 HostPortPair server2(kServer2HostName, 443);
Matt Mueller230996f12018-10-22 19:39:441547 transport_security_state_.EnableStaticPinsForTesting();
1548 ScopedTransportSecurityStateSource scoped_security_state_source;
[email protected]5db452202014-08-19 05:22:151549
bncf8bf0722015-05-19 20:04:131550 ProofVerifyDetailsChromium verify_details1 = DefaultProofVerifyDetails();
Matt Mueller230996f12018-10-22 19:39:441551 uint8_t bad_pin = 3;
bnc20daf9a2015-05-15 17:11:011552 verify_details1.cert_verify_result.public_key_hashes.push_back(
1553 test::GetTestHashValue(bad_pin));
1554 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
1555
Matt Mueller230996f12018-10-22 19:39:441556 HashValue primary_pin(HASH_VALUE_SHA256);
1557 EXPECT_TRUE(primary_pin.FromString(
1558 "sha256/Nn8jk5By4Vkq6BeOVZ7R7AC6XUUBZsWmUbJR1f1Y5FY="));
bncf8bf0722015-05-19 20:04:131559 ProofVerifyDetailsChromium verify_details2 = DefaultProofVerifyDetails();
Matt Mueller230996f12018-10-22 19:39:441560 verify_details2.cert_verify_result.public_key_hashes.push_back(primary_pin);
bnc20daf9a2015-05-15 17:11:011561 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
[email protected]5db452202014-08-19 05:22:151562
Renjiea0cb4a2c2018-09-26 23:37:301563 host_resolver_->set_synchronous_mode(true);
1564 host_resolver_->rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
1565 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]5db452202014-08-19 05:22:151566
zhongyi98d6a9262017-05-19 02:47:451567 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:511568 EXPECT_EQ(OK,
1569 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521570 server1, version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
1571 NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:511572 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1573 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241574 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]5db452202014-08-19 05:22:151575 EXPECT_TRUE(stream.get());
1576
1577 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451578 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:511579 EXPECT_EQ(OK,
1580 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521581 server2, version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
1582 NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:511583 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
1584 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241585 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]5db452202014-08-19 05:22:151586 EXPECT_TRUE(stream2.get());
1587
bnc912a04b2016-04-20 14:19:501588 EXPECT_NE(GetActiveSession(server1), GetActiveSession(server2));
[email protected]5db452202014-08-19 05:22:151589
rch37de576c2015-05-17 20:28:171590 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
1591 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
1592 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1593 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]5db452202014-08-19 05:22:151594}
1595
[email protected]1e960032013-12-20 19:00:201596TEST_P(QuicStreamFactoryTest, Goaway) {
jri7046038f2015-10-22 00:29:261597 Initialize();
rch6faa4d42016-01-05 20:48:431598 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1599 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1600 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1601
Ryan Hamiltonabad59e2019-06-06 04:02:591602 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361603 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431604 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171605 socket_data.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamilton0d65a8c2019-06-07 00:46:021606 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:591607 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:361608 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431609 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171610 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]4d283b32013-10-17 12:57:271611
zhongyi98d6a9262017-05-19 02:47:451612 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331613 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031614 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521615 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1616 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031617 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1618 failed_on_default_network_callback_, callback_.callback()));
[email protected]4d283b32013-10-17 12:57:271619
robpercival214763f2016-07-01 23:27:011620 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241621 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]4d283b32013-10-17 12:57:271622 EXPECT_TRUE(stream.get());
1623
1624 // Mark the session as going away. Ensure that while it is still alive
1625 // that it is no longer active.
bnc912a04b2016-04-20 14:19:501626 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri7046038f2015-10-22 00:29:261627 factory_->OnSessionGoingAway(session);
1628 EXPECT_EQ(true,
1629 QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
bnc912a04b2016-04-20 14:19:501630 EXPECT_FALSE(HasActiveSession(host_port_pair_));
[email protected]4d283b32013-10-17 12:57:271631
1632 // Create a new request for the same destination and verify that a
1633 // new session is created.
zhongyi98d6a9262017-05-19 02:47:451634 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331635 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031636 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521637 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1638 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031639 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1640 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:011641 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241642 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]4d283b32013-10-17 12:57:271643 EXPECT_TRUE(stream2.get());
1644
bnc912a04b2016-04-20 14:19:501645 EXPECT_TRUE(HasActiveSession(host_port_pair_));
1646 EXPECT_NE(session, GetActiveSession(host_port_pair_));
jri7046038f2015-10-22 00:29:261647 EXPECT_EQ(true,
1648 QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
[email protected]4d283b32013-10-17 12:57:271649
1650 stream2.reset();
1651 stream.reset();
1652
rch37de576c2015-05-17 20:28:171653 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1654 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1655 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1656 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]4d283b32013-10-17 12:57:271657}
1658
[email protected]1e960032013-12-20 19:00:201659TEST_P(QuicStreamFactoryTest, MaxOpenStream) {
jri7046038f2015-10-22 00:29:261660 Initialize();
rch6faa4d42016-01-05 20:48:431661 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1662 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1663
Fan Yang32c5a112018-12-10 20:06:331664 quic::QuicStreamId stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
Ryan Hamiltonabad59e2019-06-06 04:02:591665 MockQuicData socket_data(version_);
Zhongyi Shi32f2fd02018-04-16 18:23:431666 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Nick Harper23290b82019-05-02 00:02:561667 if (version_.transport_version == quic::QUIC_VERSION_99) {
David Schinazicc1bc592019-04-24 19:40:311668 socket_data.AddWrite(SYNCHRONOUS, client_maker_.MakeStreamsBlockedPacket(
Ryan Hamilton4aeec562019-05-17 21:22:521669 2, true, 51,
David Schinazicc1bc592019-04-24 19:40:311670 /*unidirectional=*/false));
Frank Kastenholzc9b9bea2018-12-03 20:13:471671 socket_data.AddWrite(
1672 SYNCHRONOUS, client_maker_.MakeRstPacket(3, true, stream_id,
1673 quic::QUIC_STREAM_CANCELLED));
1674 socket_data.AddRead(
1675 ASYNC, server_maker_.MakeRstPacket(1, false, stream_id,
1676 quic::QUIC_STREAM_CANCELLED));
Fan Yang32c5a112018-12-10 20:06:331677 socket_data.AddRead(
Ryan Hamilton4aeec562019-05-17 21:22:521678 ASYNC, server_maker_.MakeMaxStreamsPacket(4, true, 52,
David Schinazicc1bc592019-04-24 19:40:311679 /*unidirectional=*/false));
Frank Kastenholzc9b9bea2018-12-03 20:13:471680 } else {
1681 socket_data.AddWrite(
1682 SYNCHRONOUS, client_maker_.MakeRstPacket(2, true, stream_id,
1683 quic::QUIC_STREAM_CANCELLED));
1684 socket_data.AddRead(
1685 ASYNC, server_maker_.MakeRstPacket(1, false, stream_id,
1686 quic::QUIC_STREAM_CANCELLED));
Frank Kastenholz878763bf2018-11-28 19:14:481687 }
rcha00569732016-08-27 11:09:361688 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:171689 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]0b2294d32013-08-02 00:46:361690
1691 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:391692 request_info.traffic_annotation =
1693 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1694
xunjieli1d2b4272017-04-25 22:37:171695 std::vector<std::unique_ptr<HttpStream>> streams;
Ryan Hamilton9835e662018-08-02 05:36:271696 // The MockCryptoClientStream sets max_open_streams to be
Ryan Hamilton8d9ee76e2018-05-29 23:52:521697 // quic::kDefaultMaxStreamsPerConnection / 2.
1698 for (size_t i = 0; i < quic::kDefaultMaxStreamsPerConnection / 2; i++) {
zhongyi98d6a9262017-05-19 02:47:451699 QuicStreamRequest request(factory_.get());
Zhongyi Shia6b68d112018-09-24 07:49:031700 int rv = request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521701 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
1702 NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031703 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1704 failed_on_default_network_callback_, callback_.callback());
[email protected]0b2294d32013-08-02 00:46:361705 if (i == 0) {
robpercival214763f2016-07-01 23:27:011706 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1707 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]0b2294d32013-08-02 00:46:361708 } else {
robpercival214763f2016-07-01 23:27:011709 EXPECT_THAT(rv, IsOk());
[email protected]0b2294d32013-08-02 00:46:361710 }
Yixin Wang7891a39d2017-11-08 20:59:241711 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0b2294d32013-08-02 00:46:361712 EXPECT_TRUE(stream);
Steven Valdezb4ff0412018-01-18 22:39:271713 EXPECT_EQ(OK,
1714 stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:391715 net_log_, CompletionOnceCallback()));
avib3635452016-10-21 18:33:531716 streams.push_back(std::move(stream));
[email protected]0b2294d32013-08-02 00:46:361717 }
1718
zhongyi98d6a9262017-05-19 02:47:451719 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:511720 EXPECT_EQ(OK,
1721 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521722 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1723 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:511724 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1725 failed_on_default_network_callback_, CompletionOnceCallback()));
Yixin Wang7891a39d2017-11-08 20:59:241726 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0b2294d32013-08-02 00:46:361727 EXPECT_TRUE(stream);
rjshaded5ced072015-12-18 19:26:021728 EXPECT_EQ(ERR_IO_PENDING,
Steven Valdezb4ff0412018-01-18 22:39:271729 stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
1730 net_log_, callback_.callback()));
[email protected]0b2294d32013-08-02 00:46:361731
1732 // Close the first stream.
1733 streams.front()->Close(false);
ckrasicea295fe2015-10-31 05:03:271734 // Trigger exchange of RSTs that in turn allow progress for the last
1735 // stream.
Frank Kastenholz878763bf2018-11-28 19:14:481736 base::RunLoop().RunUntilIdle();
robpercival214763f2016-07-01 23:27:011737 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]0b2294d32013-08-02 00:46:361738
rch37de576c2015-05-17 20:28:171739 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1740 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
ckrasicea295fe2015-10-31 05:03:271741
1742 // Force close of the connection to suppress the generation of RST
1743 // packets when streams are torn down, which wouldn't be relevant to
1744 // this test anyway.
bnc912a04b2016-04-20 14:19:501745 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521746 session->connection()->CloseConnection(
1747 quic::QUIC_PUBLIC_RESET, "test",
1748 quic::ConnectionCloseBehavior::SILENT_CLOSE);
[email protected]0b2294d32013-08-02 00:46:361749}
1750
[email protected]1e960032013-12-20 19:00:201751TEST_P(QuicStreamFactoryTest, ResolutionErrorInCreate) {
jri7046038f2015-10-22 00:29:261752 Initialize();
Ryan Hamiltonabad59e2019-06-06 04:02:591753 MockQuicData socket_data(version_);
Zhongyi Shi5f587cc2017-11-21 23:24:171754 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]e13201d82012-12-12 05:00:321755
Renjiea0cb4a2c2018-09-26 23:37:301756 host_resolver_->rules()->AddSimulatedFailure(kDefaultServerHostName);
[email protected]e13201d82012-12-12 05:00:321757
zhongyi98d6a9262017-05-19 02:47:451758 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331759 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031760 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521761 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1762 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031763 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1764 failed_on_default_network_callback_, callback_.callback()));
[email protected]e13201d82012-12-12 05:00:321765
robpercival214763f2016-07-01 23:27:011766 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
[email protected]e13201d82012-12-12 05:00:321767
rch37de576c2015-05-17 20:28:171768 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1769 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]e13201d82012-12-12 05:00:321770}
1771
[email protected]1e960032013-12-20 19:00:201772TEST_P(QuicStreamFactoryTest, ConnectErrorInCreate) {
jri7046038f2015-10-22 00:29:261773 Initialize();
rcha00569732016-08-27 11:09:361774
Ryan Hamiltonabad59e2019-06-06 04:02:591775 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361776 socket_data.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
Zhongyi Shi5f587cc2017-11-21 23:24:171777 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]3c772402013-12-18 21:38:111778
zhongyi98d6a9262017-05-19 02:47:451779 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331780 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031781 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521782 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1783 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031784 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1785 failed_on_default_network_callback_, callback_.callback()));
[email protected]3c772402013-12-18 21:38:111786
robpercival214763f2016-07-01 23:27:011787 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_ADDRESS_IN_USE));
[email protected]3c772402013-12-18 21:38:111788
rch37de576c2015-05-17 20:28:171789 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1790 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]3c772402013-12-18 21:38:111791}
1792
[email protected]1e960032013-12-20 19:00:201793TEST_P(QuicStreamFactoryTest, CancelCreate) {
jri7046038f2015-10-22 00:29:261794 Initialize();
Ryan Hamiltonabad59e2019-06-06 04:02:591795 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361796 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431797 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171798 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]e13201d82012-12-12 05:00:321799 {
zhongyi98d6a9262017-05-19 02:47:451800 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331801 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031802 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521803 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1804 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031805 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1806 failed_on_default_network_callback_, callback_.callback()));
[email protected]e13201d82012-12-12 05:00:321807 }
1808
mmenke651bae7f2015-12-18 21:26:451809 base::RunLoop().RunUntilIdle();
[email protected]e13201d82012-12-12 05:00:321810
zhongyi98d6a9262017-05-19 02:47:451811 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:511812 EXPECT_EQ(OK,
1813 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521814 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1815 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:511816 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1817 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241818 std::unique_ptr<HttpStream> stream = CreateStream(&request2);
rch68a80eb2017-04-25 05:24:241819
[email protected]e13201d82012-12-12 05:00:321820 EXPECT_TRUE(stream.get());
1821 stream.reset();
1822
rch37de576c2015-05-17 20:28:171823 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1824 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]e13201d82012-12-12 05:00:321825}
1826
[email protected]1e960032013-12-20 19:00:201827TEST_P(QuicStreamFactoryTest, CloseAllSessions) {
jri7046038f2015-10-22 00:29:261828 Initialize();
rch6faa4d42016-01-05 20:48:431829 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1830 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1831 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1832
Ryan Hamiltonabad59e2019-06-06 04:02:591833 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361834 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431835 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Ryan Hamilton8d9ee76e2018-05-29 23:52:521836 socket_data.AddWrite(
1837 SYNCHRONOUS, ConstructClientRstPacket(2, quic::QUIC_RST_ACKNOWLEDGEMENT));
Renjieba55fae2018-09-20 03:05:161838 socket_data.AddWrite(SYNCHRONOUS,
1839 client_maker_.MakeConnectionClosePacket(
Ryan Hamilton1556a722019-06-19 21:04:171840 3, true, quic::QUIC_PEER_GOING_AWAY, "net error"));
Zhongyi Shi5f587cc2017-11-21 23:24:171841 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]56dfb902013-01-03 23:17:551842
Ryan Hamilton0d65a8c2019-06-07 00:46:021843 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:591844 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:361845 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431846 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171847 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]56dfb902013-01-03 23:17:551848
zhongyi98d6a9262017-05-19 02:47:451849 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331850 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031851 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521852 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1853 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031854 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1855 failed_on_default_network_callback_, callback_.callback()));
[email protected]56dfb902013-01-03 23:17:551856
robpercival214763f2016-07-01 23:27:011857 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241858 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0b2294d32013-08-02 00:46:361859 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:391860 request_info.traffic_annotation =
1861 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:271862 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:391863 net_log_, CompletionOnceCallback()));
[email protected]56dfb902013-01-03 23:17:551864
1865 // Close the session and verify that stream saw the error.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521866 factory_->CloseAllSessions(ERR_INTERNET_DISCONNECTED,
Ryan Hamilton1556a722019-06-19 21:04:171867 quic::QUIC_PEER_GOING_AWAY);
[email protected]56dfb902013-01-03 23:17:551868 EXPECT_EQ(ERR_INTERNET_DISCONNECTED,
1869 stream->ReadResponseHeaders(callback_.callback()));
1870
1871 // Now attempting to request a stream to the same origin should create
1872 // a new session.
1873
zhongyi98d6a9262017-05-19 02:47:451874 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331875 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031876 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521877 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1878 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031879 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1880 failed_on_default_network_callback_, callback_.callback()));
[email protected]56dfb902013-01-03 23:17:551881
robpercival214763f2016-07-01 23:27:011882 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241883 stream = CreateStream(&request2);
[email protected]56dfb902013-01-03 23:17:551884 stream.reset(); // Will reset stream 3.
1885
rch37de576c2015-05-17 20:28:171886 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1887 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1888 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1889 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]56dfb902013-01-03 23:17:551890}
1891
zhongyi363c91c2017-03-23 23:16:081892// Regression test for crbug.com/700617. Test a write error during the
1893// crypto handshake will not hang QuicStreamFactory::Job and should
1894// report QUIC_HANDSHAKE_FAILED to upper layers. Subsequent
1895// QuicStreamRequest should succeed without hanging.
1896TEST_P(QuicStreamFactoryTest,
1897 WriteErrorInCryptoConnectWithAsyncHostResolution) {
1898 Initialize();
1899 // Use unmocked crypto stream to do crypto connect.
1900 crypto_client_stream_factory_.set_handshake_mode(
Zhongyi Shi879659422018-08-02 17:58:251901 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
zhongyi363c91c2017-03-23 23:16:081902
Ryan Hamiltonabad59e2019-06-06 04:02:591903 MockQuicData socket_data(version_);
zhongyi363c91c2017-03-23 23:16:081904 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1905 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
1906 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:171907 socket_data.AddSocketDataToFactory(socket_factory_.get());
zhongyi363c91c2017-03-23 23:16:081908
1909 // Create request, should fail after the write of the CHLO fails.
zhongyi98d6a9262017-05-19 02:47:451910 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331911 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031912 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521913 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1914 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031915 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1916 failed_on_default_network_callback_, callback_.callback()));
zhongyi363c91c2017-03-23 23:16:081917 EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED, callback_.WaitForResult());
1918 EXPECT_FALSE(HasActiveSession(host_port_pair_));
1919 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
1920
1921 // Verify new requests can be sent normally without hanging.
1922 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271923 MockCryptoClientStream::COLD_START);
zhongyi363c91c2017-03-23 23:16:081924 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1925 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
Ryan Hamilton0d65a8c2019-06-07 00:46:021926 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:591927 MockQuicData socket_data2(version_);
zhongyi363c91c2017-03-23 23:16:081928 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431929 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171930 socket_data2.AddSocketDataToFactory(socket_factory_.get());
zhongyi363c91c2017-03-23 23:16:081931
zhongyi98d6a9262017-05-19 02:47:451932 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331933 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031934 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521935 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1936 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031937 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1938 failed_on_default_network_callback_, callback_.callback()));
zhongyi363c91c2017-03-23 23:16:081939 EXPECT_FALSE(HasActiveSession(host_port_pair_));
1940 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
1941 // Run the message loop to complete host resolution.
1942 base::RunLoop().RunUntilIdle();
1943
1944 // Complete handshake. QuicStreamFactory::Job should complete and succeed.
1945 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521946 quic::QuicSession::HANDSHAKE_CONFIRMED);
zhongyi363c91c2017-03-23 23:16:081947 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1948 EXPECT_TRUE(HasActiveSession(host_port_pair_));
1949 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
1950
1951 // Create QuicHttpStream.
Yixin Wang7891a39d2017-11-08 20:59:241952 std::unique_ptr<HttpStream> stream = CreateStream(&request2);
zhongyi363c91c2017-03-23 23:16:081953 EXPECT_TRUE(stream.get());
1954 stream.reset();
1955 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1956 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1957 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1958 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
1959}
1960
1961TEST_P(QuicStreamFactoryTest, WriteErrorInCryptoConnectWithSyncHostResolution) {
1962 Initialize();
1963 // Use unmocked crypto stream to do crypto connect.
1964 crypto_client_stream_factory_.set_handshake_mode(
Zhongyi Shi879659422018-08-02 17:58:251965 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
Renjiea0cb4a2c2018-09-26 23:37:301966 host_resolver_->set_synchronous_mode(true);
1967 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
1968 "192.168.0.1", "");
zhongyi363c91c2017-03-23 23:16:081969
Ryan Hamiltonabad59e2019-06-06 04:02:591970 MockQuicData socket_data(version_);
zhongyi363c91c2017-03-23 23:16:081971 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1972 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
1973 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:171974 socket_data.AddSocketDataToFactory(socket_factory_.get());
zhongyi363c91c2017-03-23 23:16:081975
1976 // Create request, should fail immediately.
zhongyi98d6a9262017-05-19 02:47:451977 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331978 EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED,
Zhongyi Shia6b68d112018-09-24 07:49:031979 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:521980 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
1981 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031982 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1983 failed_on_default_network_callback_, callback_.callback()));
zhongyi363c91c2017-03-23 23:16:081984 // Check no active session, or active jobs left for this server.
1985 EXPECT_FALSE(HasActiveSession(host_port_pair_));
1986 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
1987
1988 // Verify new requests can be sent normally without hanging.
1989 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271990 MockCryptoClientStream::COLD_START);
zhongyi363c91c2017-03-23 23:16:081991 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1992 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
Ryan Hamilton0d65a8c2019-06-07 00:46:021993 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:591994 MockQuicData socket_data2(version_);
zhongyi363c91c2017-03-23 23:16:081995 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431996 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171997 socket_data2.AddSocketDataToFactory(socket_factory_.get());
zhongyi363c91c2017-03-23 23:16:081998
zhongyi98d6a9262017-05-19 02:47:451999 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332000 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032001 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:522002 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
2003 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032004 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2005 failed_on_default_network_callback_, callback_.callback()));
zhongyi363c91c2017-03-23 23:16:082006 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2007 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
2008
2009 // Complete handshake.
2010 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522011 quic::QuicSession::HANDSHAKE_CONFIRMED);
zhongyi363c91c2017-03-23 23:16:082012 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2013 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2014 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
2015
2016 // Create QuicHttpStream.
Yixin Wang7891a39d2017-11-08 20:59:242017 std::unique_ptr<HttpStream> stream = CreateStream(&request2);
zhongyi363c91c2017-03-23 23:16:082018 EXPECT_TRUE(stream.get());
2019 stream.reset();
2020 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2021 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2022 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
2023 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
2024}
2025
Zhongyi Shi63574b72018-06-01 20:22:252026TEST_P(QuicStreamFactoryTest, CloseSessionsOnIPAddressChanged) {
Nick Harper72ade192019-07-17 03:30:422027 test_params_.quic_params.close_sessions_on_ip_change = true;
jri7046038f2015-10-22 00:29:262028 Initialize();
rch6faa4d42016-01-05 20:48:432029 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2030 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2031 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri8c44d692015-10-23 23:53:412032
Ryan Hamiltonabad59e2019-06-06 04:02:592033 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:362034 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432035 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Ryan Hamilton8d9ee76e2018-05-29 23:52:522036 socket_data.AddWrite(
2037 SYNCHRONOUS, ConstructClientRstPacket(2, quic::QUIC_RST_ACKNOWLEDGEMENT));
Renjieba55fae2018-09-20 03:05:162038 socket_data.AddWrite(
2039 SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
2040 3, true, quic::QUIC_IP_ADDRESS_CHANGED, "net error"));
Zhongyi Shi5f587cc2017-11-21 23:24:172041 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]f698a012013-05-06 20:18:592042
Ryan Hamilton0d65a8c2019-06-07 00:46:022043 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:592044 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:362045 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432046 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:172047 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]f698a012013-05-06 20:18:592048
zhongyi98d6a9262017-05-19 02:47:452049 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332050 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032051 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:522052 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
2053 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032054 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2055 failed_on_default_network_callback_, callback_.callback()));
[email protected]f698a012013-05-06 20:18:592056
robpercival214763f2016-07-01 23:27:012057 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242058 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0b2294d32013-08-02 00:46:362059 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392060 request_info.traffic_annotation =
2061 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272062 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392063 net_log_, CompletionOnceCallback()));
[email protected]f698a012013-05-06 20:18:592064
Zhongyi Shi63574b72018-06-01 20:22:252065 // Check an active session exisits for the destination.
2066 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2067 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
2068 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2069
Ryan Hamilton8e32a2b2017-08-28 20:06:522070 IPAddress last_address;
2071 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
Zhongyi Shi63574b72018-06-01 20:22:252072 // Change the IP address and verify that stream saw the error and the active
2073 // session is closed.
jri8c44d692015-10-23 23:53:412074 NotifyIPAddressChanged();
[email protected]f698a012013-05-06 20:18:592075 EXPECT_EQ(ERR_NETWORK_CHANGED,
2076 stream->ReadResponseHeaders(callback_.callback()));
jri7046038f2015-10-22 00:29:262077 EXPECT_TRUE(factory_->require_confirmation());
Ryan Hamilton8e32a2b2017-08-28 20:06:522078 EXPECT_FALSE(http_server_properties_.GetSupportsQuic(&last_address));
Zhongyi Shi63574b72018-06-01 20:22:252079 // Check no active session exists for the destination.
2080 EXPECT_FALSE(HasActiveSession(host_port_pair_));
[email protected]f698a012013-05-06 20:18:592081
2082 // Now attempting to request a stream to the same origin should create
2083 // a new session.
zhongyi98d6a9262017-05-19 02:47:452084 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332085 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032086 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:522087 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
2088 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032089 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2090 failed_on_default_network_callback_, callback_.callback()));
[email protected]f698a012013-05-06 20:18:592091
robpercival214763f2016-07-01 23:27:012092 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242093 stream = CreateStream(&request2);
[email protected]f698a012013-05-06 20:18:592094
Zhongyi Shi63574b72018-06-01 20:22:252095 // Check a new active session exisits for the destination and the old session
2096 // is no longer live.
2097 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2098 QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
2099 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
2100
2101 stream.reset(); // Will reset stream 3.
rch37de576c2015-05-17 20:28:172102 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2103 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2104 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
2105 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]f698a012013-05-06 20:18:592106}
2107
Zhongyi Shi63574b72018-06-01 20:22:252108// Test that if goaway_session_on_ip_change is set, old sessions will be marked
2109// as going away on IP address change instead of being closed. New requests will
2110// go to a new connection.
2111TEST_P(QuicStreamFactoryTest, GoAwaySessionsOnIPAddressChanged) {
Nick Harper72ade192019-07-17 03:30:422112 test_params_.quic_params.goaway_sessions_on_ip_change = true;
Zhongyi Shi63574b72018-06-01 20:22:252113 Initialize();
2114 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2115 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2116 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2117
Ryan Hamiltonabad59e2019-06-06 04:02:592118 MockQuicData quic_data1(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:022119 quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Fan Yang32c5a112018-12-10 20:06:332120 quic_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:022121 SYNCHRONOUS,
2122 ConstructGetRequestPacket(
2123 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi63574b72018-06-01 20:22:252124 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
2125 quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:332126 ASYNC,
2127 ConstructOkResponsePacket(
2128 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true));
Zhongyi Shi63574b72018-06-01 20:22:252129 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
2130 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2131
Ryan Hamilton0d65a8c2019-06-07 00:46:022132 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:592133 MockQuicData quic_data2(version_);
Zhongyi Shi63574b72018-06-01 20:22:252134 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
Ryan Hamilton0d65a8c2019-06-07 00:46:022135 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Zhongyi Shi63574b72018-06-01 20:22:252136 quic_data2.AddSocketDataToFactory(socket_factory_.get());
2137
2138 // Create request and QuicHttpStream.
2139 QuicStreamRequest request(factory_.get());
2140 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032141 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:522142 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
2143 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032144 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2145 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi63574b72018-06-01 20:22:252146 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2147 std::unique_ptr<HttpStream> stream = CreateStream(&request);
2148 EXPECT_TRUE(stream.get());
2149
2150 // Cause QUIC stream to be created.
2151 HttpRequestInfo request_info;
2152 request_info.method = "GET";
2153 request_info.url = url_;
2154 request_info.traffic_annotation =
2155 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2156 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
2157 net_log_, CompletionOnceCallback()));
2158
2159 // Ensure that session is alive and active.
2160 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
2161 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2162 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2163
2164 // Send GET request on stream.
2165 HttpResponseInfo response;
2166 HttpRequestHeaders request_headers;
2167 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
2168 callback_.callback()));
2169
2170 // Receive an IP address change notification.
2171 NotifyIPAddressChanged();
2172
2173 // The connection should still be alive, but marked as going away.
2174 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2175 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2176 EXPECT_EQ(1u, session->GetNumActiveStreams());
2177
2178 // Resume the data, response should be read from the original connection.
2179 quic_data1.Resume();
2180 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
2181 EXPECT_EQ(200, response.headers->response_code());
2182 EXPECT_EQ(0u, session->GetNumActiveStreams());
2183
2184 // Second request should be sent on a new connection.
2185 QuicStreamRequest request2(factory_.get());
2186 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032187 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:522188 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
2189 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032190 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2191 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi63574b72018-06-01 20:22:252192 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2193 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
2194 EXPECT_TRUE(stream2.get());
2195
2196 // Check an active session exisits for the destination.
2197 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2198 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2199 QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
2200 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
2201
2202 stream.reset();
2203 stream2.reset();
2204 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
2205 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
2206 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
2207 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
2208}
2209
Jana Iyengarba355772017-09-21 22:03:212210TEST_P(QuicStreamFactoryTest, OnIPAddressChangedWithConnectionMigration) {
Zhongyi Shi1a054612018-06-14 04:59:082211 InitializeConnectionMigrationV2Test(
Jana Iyengarba355772017-09-21 22:03:212212 {kDefaultNetworkForTests, kNewNetworkForTests});
2213 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2214 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2215 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2216
Ryan Hamiltonabad59e2019-06-06 04:02:592217 MockQuicData socket_data(version_);
Jana Iyengarba355772017-09-21 22:03:212218 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432219 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Ryan Hamilton8d9ee76e2018-05-29 23:52:522220 socket_data.AddWrite(
2221 SYNCHRONOUS, ConstructClientRstPacket(2, quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:172222 socket_data.AddSocketDataToFactory(socket_factory_.get());
Jana Iyengarba355772017-09-21 22:03:212223
2224 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332225 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032226 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:522227 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
2228 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032229 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2230 failed_on_default_network_callback_, callback_.callback()));
Jana Iyengarba355772017-09-21 22:03:212231
2232 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242233 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Jana Iyengarba355772017-09-21 22:03:212234 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392235 request_info.traffic_annotation =
2236 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272237 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392238 net_log_, CompletionOnceCallback()));
Jana Iyengarba355772017-09-21 22:03:212239
2240 IPAddress last_address;
2241 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
2242
2243 // Change the IP address and verify that the connection is unaffected.
2244 NotifyIPAddressChanged();
2245 EXPECT_FALSE(factory_->require_confirmation());
2246 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
2247
2248 // Attempting a new request to the same origin uses the same connection.
2249 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:512250 EXPECT_EQ(OK,
2251 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:522252 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
2253 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:512254 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2255 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:242256 stream = CreateStream(&request2);
Jana Iyengarba355772017-09-21 22:03:212257
2258 stream.reset();
2259 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2260 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2261}
2262
Zhongyi Shia0644e32018-06-21 05:19:522263TEST_P(QuicStreamFactoryTest, MigrateOnNetworkMadeDefaultWithSynchronousWrite) {
2264 TestMigrationOnNetworkMadeDefault(SYNCHRONOUS);
jri9f303712016-09-13 01:10:222265}
2266
Zhongyi Shia0644e32018-06-21 05:19:522267TEST_P(QuicStreamFactoryTest, MigrateOnNetworkMadeDefaultWithAsyncWrite) {
2268 TestMigrationOnNetworkMadeDefault(ASYNC);
jri9f303712016-09-13 01:10:222269}
2270
Zhongyi Shia0644e32018-06-21 05:19:522271// Sets up a test which attempts connection migration successfully after probing
2272// when a new network is made as default and the old default is still available.
2273// |write_mode| specifies the write mode for the last write before
2274// OnNetworkMadeDefault is delivered to session.
2275void QuicStreamFactoryTestBase::TestMigrationOnNetworkMadeDefault(
2276 IoMode write_mode) {
2277 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri7e636642016-01-14 06:57:082278 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2279 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2280 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2281
Zhongyi Shia0644e32018-06-21 05:19:522282 // Using a testing task runner so that we can control time.
2283 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
2284 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
2285
2286 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2287 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
2288
Ryan Hamiltonabad59e2019-06-06 04:02:592289 MockQuicData quic_data1(version_);
Zhongyi Shia0644e32018-06-21 05:19:522290 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
Ryan Hamilton0d65a8c2019-06-07 00:46:022291 quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shia0644e32018-06-21 05:19:522292 quic_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:022293 write_mode,
2294 ConstructGetRequestPacket(
2295 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shia0644e32018-06-21 05:19:522296 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2297
2298 // Set up the second socket data provider that is used after migration.
2299 // The response to the earlier request is read on the new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:592300 MockQuicData quic_data2(version_);
Zhongyi Shia0644e32018-06-21 05:19:522301 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:252302 quic_data2.AddWrite(SYNCHRONOUS,
2303 client_maker_.MakeConnectivityProbingPacket(3, true));
Zhongyi Shia0644e32018-06-21 05:19:522304 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
2305 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:252306 quic_data2.AddRead(ASYNC,
2307 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shia0644e32018-06-21 05:19:522308 // Ping packet to send after migration is completed.
2309 quic_data2.AddWrite(ASYNC,
2310 client_maker_.MakeAckAndPingPacket(4, false, 1, 1, 1));
2311 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:332312 ASYNC,
2313 ConstructOkResponsePacket(
2314 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shia0644e32018-06-21 05:19:522315 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:332316 quic_data2.AddWrite(
2317 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
2318 5, false, GetNthClientInitiatedBidirectionalStreamId(0),
2319 quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true));
Zhongyi Shia0644e32018-06-21 05:19:522320 quic_data2.AddSocketDataToFactory(socket_factory_.get());
jri7e636642016-01-14 06:57:082321
2322 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452323 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332324 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032325 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:522326 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
2327 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032328 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2329 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012330 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242331 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri7e636642016-01-14 06:57:082332 EXPECT_TRUE(stream.get());
2333
2334 // Cause QUIC stream to be created.
2335 HttpRequestInfo request_info;
2336 request_info.method = "GET";
bnc3d9035b32016-06-30 18:18:482337 request_info.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:392338 request_info.traffic_annotation =
2339 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272340 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392341 net_log_, CompletionOnceCallback()));
jri7e636642016-01-14 06:57:082342
2343 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502344 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri7e636642016-01-14 06:57:082345 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2346 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2347
2348 // Send GET request on stream.
2349 HttpResponseInfo response;
2350 HttpRequestHeaders request_headers;
2351 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
2352 callback_.callback()));
2353
Zhongyi Shia0644e32018-06-21 05:19:522354 // Deliver a signal that a alternate network is connected now, this should
2355 // cause the connection to start early migration on path degrading.
2356 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2357 ->SetConnectedNetworksList(
2358 {kDefaultNetworkForTests, kNewNetworkForTests});
2359 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2360 ->NotifyNetworkConnected(kNewNetworkForTests);
jri9f303712016-09-13 01:10:222361
Zhongyi Shia0644e32018-06-21 05:19:522362 // Cause the connection to report path degrading to the session.
2363 // Due to lack of alternate network, session will not mgirate connection.
2364 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
jri7e636642016-01-14 06:57:082365 scoped_mock_network_change_notifier_->mock_network_change_notifier()
jrie2661982016-08-20 08:24:342366 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri7e636642016-01-14 06:57:082367
Zhongyi Shia0644e32018-06-21 05:19:522368 // A task will be posted to migrate to the new default network.
2369 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2370 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
2371
2372 // Execute the posted task to migrate back to the default network.
2373 task_runner->RunUntilIdle();
2374 // Another task to try send a new connectivity probe is posted. And a task to
2375 // retry migrate back to default network is scheduled.
2376 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
2377 // Next connectivity probe is scheduled to be sent in 2 *
2378 // kDefaultRTTMilliSecs.
2379 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
2380 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
2381 next_task_delay);
2382
2383 // The connection should still be alive, and not marked as going away.
jri7e636642016-01-14 06:57:082384 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia0644e32018-06-21 05:19:522385 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2386 EXPECT_EQ(1u, session->GetNumActiveStreams());
2387 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
2388
2389 // Resume quic data and a connectivity probe response will be read on the new
2390 // socket, declare probing as successful. And a new task to WriteToNewSocket
2391 // will be posted to complete migration.
2392 quic_data2.Resume();
2393
2394 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2395 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri7e636642016-01-14 06:57:082396 EXPECT_EQ(1u, session->GetNumActiveStreams());
2397
Zhongyi Shia0644e32018-06-21 05:19:522398 // There should be three pending tasks, the nearest one will complete
2399 // migration to the new network.
2400 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
2401 next_task_delay = task_runner->NextPendingTaskDelay();
2402 EXPECT_EQ(base::TimeDelta(), next_task_delay);
2403 task_runner->FastForwardBy(next_task_delay);
2404
2405 // Response headers are received over the new network.
2406 EXPECT_THAT(callback_.WaitForResult(), IsOk());
jri7e636642016-01-14 06:57:082407 EXPECT_EQ(200, response.headers->response_code());
2408
Zhongyi Shia0644e32018-06-21 05:19:522409 // Now there are two pending tasks, the nearest one was to send connectivity
2410 // probe and has been cancelled due to successful migration.
2411 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
2412 next_task_delay = task_runner->NextPendingTaskDelay();
2413 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
2414 next_task_delay);
2415 task_runner->FastForwardBy(next_task_delay);
jri7e636642016-01-14 06:57:082416
Zhongyi Shia0644e32018-06-21 05:19:522417 // There's one more task to mgirate back to the default network in 0.4s, which
2418 // is also cancelled due to the success migration on the previous trial.
2419 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2420 next_task_delay = task_runner->NextPendingTaskDelay();
2421 base::TimeDelta expected_delay =
2422 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
2423 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
2424 EXPECT_EQ(expected_delay, next_task_delay);
2425 task_runner->FastForwardBy(next_task_delay);
2426 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
jri7e636642016-01-14 06:57:082427
Zhongyi Shia0644e32018-06-21 05:19:522428 // Verify that the session is still alive.
jri7e636642016-01-14 06:57:082429 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia0644e32018-06-21 05:19:522430 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri7e636642016-01-14 06:57:082431
Zhongyi Shia0644e32018-06-21 05:19:522432 stream.reset();
2433 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
2434 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
2435 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
2436 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
jri7e636642016-01-14 06:57:082437}
2438
Zhongyi Shib3bc982c2018-07-10 19:59:242439// Regression test for http://859674.
2440// This test veries that a writer will not attempt to write packets until being
2441// unblocked on both socket level and network level. In this test, a probing
2442// writer is used to send two connectivity probes to the peer: where the first
2443// one completes successfully, while a connectivity response is received before
2444// completes sending the second one. The connection migration attempt will
2445// proceed while the probing writer is blocked at the socket level, which will
2446// block the writer on the network level. Once connection migration completes
2447// successfully, the probing writer will be unblocked on the network level, it
2448// will not attempt to write new packets until the socket level is unblocked.
2449TEST_P(QuicStreamFactoryTest, MigratedToBlockedSocketAfterProbing) {
2450 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
2451 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2452 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2453 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2454
2455 // Using a testing task runner so that we can control time.
2456 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
2457 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
2458
2459 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2460 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
2461
Ryan Hamiltonabad59e2019-06-06 04:02:592462 MockQuicData quic_data1(version_);
Zhongyi Shib3bc982c2018-07-10 19:59:242463 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
Ryan Hamilton0d65a8c2019-06-07 00:46:022464 quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Fan Yang32c5a112018-12-10 20:06:332465 quic_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:022466 SYNCHRONOUS,
2467 ConstructGetRequestPacket(
2468 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shib3bc982c2018-07-10 19:59:242469 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2470
2471 // Set up the second socket data provider that is used after migration.
2472 // The response to the earlier request is read on the new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:592473 MockQuicData quic_data2(version_);
Zhongyi Shib3bc982c2018-07-10 19:59:242474 // First connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:252475 quic_data2.AddWrite(SYNCHRONOUS,
2476 client_maker_.MakeConnectivityProbingPacket(3, true));
Zhongyi Shib3bc982c2018-07-10 19:59:242477 quic_data2.AddRead(ASYNC,
2478 ERR_IO_PENDING); // Pause so that we can control time.
2479 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:252480 quic_data2.AddRead(ASYNC,
2481 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shib3bc982c2018-07-10 19:59:242482 // Second connectivity probe which will complete asynchronously.
Zhongyi Shi879659422018-08-02 17:58:252483 quic_data2.AddWrite(ASYNC,
2484 client_maker_.MakeConnectivityProbingPacket(4, true));
Zhongyi Shib3bc982c2018-07-10 19:59:242485 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:332486 ASYNC,
2487 ConstructOkResponsePacket(
2488 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shib3bc982c2018-07-10 19:59:242489 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2490 quic_data2.AddWrite(ASYNC,
2491 client_maker_.MakeAckAndPingPacket(5, false, 1, 1, 1));
Fan Yang32c5a112018-12-10 20:06:332492 quic_data2.AddWrite(
2493 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
2494 6, false, GetNthClientInitiatedBidirectionalStreamId(0),
2495 quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true));
Zhongyi Shib3bc982c2018-07-10 19:59:242496
2497 quic_data2.AddSocketDataToFactory(socket_factory_.get());
2498
2499 // Create request and QuicHttpStream.
2500 QuicStreamRequest request(factory_.get());
2501 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032502 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:522503 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
2504 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032505 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2506 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shib3bc982c2018-07-10 19:59:242507 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2508 std::unique_ptr<HttpStream> stream = CreateStream(&request);
2509 EXPECT_TRUE(stream.get());
2510
2511 // Cause QUIC stream to be created.
2512 HttpRequestInfo request_info;
2513 request_info.method = "GET";
2514 request_info.url = url_;
2515 request_info.traffic_annotation =
2516 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2517 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
2518 net_log_, CompletionOnceCallback()));
2519
2520 // Ensure that session is alive and active.
2521 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
2522 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2523 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2524
2525 // Send GET request on stream.
2526 HttpResponseInfo response;
2527 HttpRequestHeaders request_headers;
2528 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
2529 callback_.callback()));
2530
2531 // Deliver a signal that a alternate network is connected now, this should
2532 // cause the connection to start early migration on path degrading.
2533 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2534 ->SetConnectedNetworksList(
2535 {kDefaultNetworkForTests, kNewNetworkForTests});
2536 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2537 ->NotifyNetworkConnected(kNewNetworkForTests);
2538
2539 // Cause the connection to report path degrading to the session.
2540 // Due to lack of alternate network, session will not mgirate connection.
2541 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
2542 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2543 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2544
2545 // A task will be posted to migrate to the new default network.
2546 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2547 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
2548
2549 // Execute the posted task to migrate back to the default network.
2550 task_runner->RunUntilIdle();
2551 // Another task to resend a new connectivity probe is posted. And a task to
2552 // retry migrate back to default network is scheduled.
2553 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
2554 // Next connectivity probe is scheduled to be sent in 2 *
2555 // kDefaultRTTMilliSecs.
2556 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
2557 base::TimeDelta expected_delay =
2558 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
2559 EXPECT_EQ(expected_delay, next_task_delay);
2560
2561 // Fast forward to send the second connectivity probe. The write will be
2562 // asynchronous and complete after the read completes.
2563 task_runner->FastForwardBy(next_task_delay);
2564
2565 // Resume quic data and a connectivity probe response will be read on the new
2566 // socket, declare probing as successful.
2567 quic_data2.Resume();
2568
2569 // The connection should still be alive, and not marked as going away.
2570 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2571 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2572 EXPECT_EQ(1u, session->GetNumActiveStreams());
2573 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
2574
2575 // There should be three pending tasks, the nearest one will complete
2576 // migration to the new network. Second task will retry migrate back to
2577 // default but cancelled, and the third task will retry send connectivity
2578 // probe but also cancelled.
2579 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
2580 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
2581 task_runner->RunUntilIdle();
2582
2583 // Response headers are received over the new network.
2584 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2585 EXPECT_EQ(200, response.headers->response_code());
2586
2587 // Run the message loop to complete the asynchronous write of ack and ping.
2588 base::RunLoop().RunUntilIdle();
2589
2590 // Now there are two pending tasks, the nearest one was to retry migrate back
2591 // to default network and has been cancelled due to successful migration.
2592 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
2593 expected_delay =
2594 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
2595 expected_delay;
2596 next_task_delay = task_runner->NextPendingTaskDelay();
2597 EXPECT_EQ(expected_delay, next_task_delay);
2598 task_runner->FastForwardBy(next_task_delay);
2599
2600 // There's one more task to retry sending connectivity probe in 0.4s and has
2601 // also been cancelled due to the successful probing.
2602 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2603 next_task_delay = task_runner->NextPendingTaskDelay();
2604 expected_delay =
2605 base::TimeDelta::FromMilliseconds(3 * 2 * kDefaultRTTMilliSecs) -
2606 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs);
2607 EXPECT_EQ(expected_delay, next_task_delay);
2608 task_runner->FastForwardBy(next_task_delay);
2609 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
2610
2611 // Verify that the session is still alive.
2612 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2613 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2614
2615 stream.reset();
2616 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
2617 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
2618 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
2619 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
2620}
2621
Zhongyi Shib1b1fa42018-06-19 23:13:472622// This test verifies that session times out connection migration attempt
2623// with signals delivered in the following order (no alternate network is
2624// available):
2625// - default network disconnected is delivered: session attempts connection
2626// migration but found not alternate network. Session waits for a new network
Zhongyi Shie01f2db2019-02-22 19:53:232627// comes up in the next kWaitTimeForNewNetworkSecs seconds.
Zhongyi Shib1b1fa42018-06-19 23:13:472628// - no new network is connected, migration times out. Session is closed.
2629TEST_P(QuicStreamFactoryTest, MigrationTimeoutWithNoNewNetwork) {
2630 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri7e636642016-01-14 06:57:082631 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2632 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2633
Zhongyi Shib1b1fa42018-06-19 23:13:472634 // Using a testing task runner so that we can control time.
2635 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
2636 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
jri5b785512016-09-13 04:29:112637
Ryan Hamiltonabad59e2019-06-06 04:02:592638 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:362639 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432640 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:172641 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri7e636642016-01-14 06:57:082642
2643 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452644 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332645 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032646 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:522647 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
2648 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032649 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2650 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012651 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242652 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri7e636642016-01-14 06:57:082653 EXPECT_TRUE(stream.get());
2654
2655 // Cause QUIC stream to be created.
2656 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392657 request_info.traffic_annotation =
2658 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272659 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392660 net_log_, CompletionOnceCallback()));
jri7e636642016-01-14 06:57:082661
2662 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502663 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri7e636642016-01-14 06:57:082664 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2665 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2666
2667 // Trigger connection migration. Since there are no networks
jri5b785512016-09-13 04:29:112668 // to migrate to, this should cause the session to wait for a new network.
jri7e636642016-01-14 06:57:082669 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2670 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
2671
jri5b785512016-09-13 04:29:112672 // The migration will not fail until the migration alarm timeout.
2673 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shib1b1fa42018-06-19 23:13:472674 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:112675 EXPECT_EQ(1u, session->GetNumActiveStreams());
2676 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
2677 EXPECT_EQ(true, session->connection()->writer()->IsWriteBlocked());
2678
Zhongyi Shib1b1fa42018-06-19 23:13:472679 // Migration will be timed out after kWaitTimeForNewNetwokSecs.
2680 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2681 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
2682 EXPECT_EQ(base::TimeDelta::FromSeconds(kWaitTimeForNewNetworkSecs),
2683 next_task_delay);
2684 task_runner->FastForwardBy(next_task_delay);
jri5b785512016-09-13 04:29:112685
2686 // The connection should now be closed. A request for response
2687 // headers should fail.
jri7e636642016-01-14 06:57:082688 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2689 EXPECT_FALSE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:112690 EXPECT_EQ(ERR_NETWORK_CHANGED, callback_.WaitForResult());
jri7e636642016-01-14 06:57:082691
2692 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2693 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2694}
2695
Zhongyi Shi21e99532018-07-17 22:23:072696// This test verifies that connectivity probes will be sent even if there is
2697// a non-migratable stream. However, when connection migrates to the
Zhongyi Shic16b4102019-02-12 00:37:402698// successfully probed path, any non-migratable streams will be reset.
Zhongyi Shi32fe14d42019-02-28 00:25:362699TEST_P(QuicStreamFactoryTest,
2700 OnNetworkMadeDefaultNonMigratableStream_MigrateIdleSessions) {
2701 TestOnNetworkMadeDefaultNonMigratableStream(true);
2702}
2703
2704// This test verifies that connectivity probes will be sent even if there is
2705// a non-migratable stream. However, when connection migrates to the
2706// successfully probed path, any non-migratable stream will be reset. And if
2707// the connection becomes idle then, close the connection.
2708TEST_P(QuicStreamFactoryTest,
2709 OnNetworkMadeDefaultNonMigratableStream_DoNotMigrateIdleSessions) {
2710 TestOnNetworkMadeDefaultNonMigratableStream(false);
2711}
2712
2713void QuicStreamFactoryTestBase::TestOnNetworkMadeDefaultNonMigratableStream(
2714 bool migrate_idle_sessions) {
Nick Harper72ade192019-07-17 03:30:422715 test_params_.quic_params.migrate_idle_sessions = migrate_idle_sessions;
Zhongyi Shi5f587cc2017-11-21 23:24:172716 InitializeConnectionMigrationV2Test(
2717 {kDefaultNetworkForTests, kNewNetworkForTests});
2718 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2719 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2720
Ryan Hamiltonabad59e2019-06-06 04:02:592721 MockQuicData socket_data(version_);
Zhongyi Shi5f587cc2017-11-21 23:24:172722 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432723 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi32fe14d42019-02-28 00:25:362724 if (!migrate_idle_sessions) {
2725 socket_data.AddWrite(
2726 SYNCHRONOUS,
2727 client_maker_.MakeRstAckAndConnectionClosePacket(
2728 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
2729 quic::QUIC_STREAM_CANCELLED,
2730 quic::QuicTime::Delta::FromMilliseconds(0), 1, 1, 1,
2731 quic::QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS,
2732 "net error"));
2733 }
Renjieba55fae2018-09-20 03:05:162734
Zhongyi Shi5f587cc2017-11-21 23:24:172735 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri231c2972016-03-08 19:50:112736
Zhongyi Shi21e99532018-07-17 22:23:072737 // Set up the second socket data provider that is used for probing.
Ryan Hamiltonabad59e2019-06-06 04:02:592738 MockQuicData quic_data1(version_);
Zhongyi Shi21e99532018-07-17 22:23:072739 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:252740 quic_data1.AddWrite(SYNCHRONOUS,
2741 client_maker_.MakeConnectivityProbingPacket(2, true));
Zhongyi Shi21e99532018-07-17 22:23:072742 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
2743 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:252744 quic_data1.AddRead(ASYNC,
2745 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shi32fe14d42019-02-28 00:25:362746 if (migrate_idle_sessions) {
2747 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
2748 // A RESET will be sent to the peer to cancel the non-migratable stream.
2749 quic_data1.AddWrite(
2750 SYNCHRONOUS,
2751 client_maker_.MakeRstPacket(
2752 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
2753 quic::QUIC_STREAM_CANCELLED));
2754 // Ping packet to send after migration is completed.
2755 quic_data1.AddWrite(SYNCHRONOUS,
2756 client_maker_.MakeAckAndPingPacket(4, false, 1, 1, 1));
2757 }
Zhongyi Shi21e99532018-07-17 22:23:072758 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2759
jri231c2972016-03-08 19:50:112760 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452761 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332762 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032763 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:522764 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
2765 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032766 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2767 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012768 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242769 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri231c2972016-03-08 19:50:112770 EXPECT_TRUE(stream.get());
2771
2772 // Cause QUIC stream to be created, but marked as non-migratable.
2773 HttpRequestInfo request_info;
Zhongyi Shibb28b1f2018-07-18 02:41:262774 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Ramin Halavati683bcaa92018-02-14 08:42:392775 request_info.traffic_annotation =
2776 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272777 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392778 net_log_, CompletionOnceCallback()));
jri231c2972016-03-08 19:50:112779
2780 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502781 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri231c2972016-03-08 19:50:112782 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2783 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2784
Zhongyi Shi21e99532018-07-17 22:23:072785 // Trigger connection migration. Session will start to probe the alternative
2786 // network. Although there is a non-migratable stream, session will still be
2787 // active until probing is declared as successful.
jri231c2972016-03-08 19:50:112788 scoped_mock_network_change_notifier_->mock_network_change_notifier()
jrie2661982016-08-20 08:24:342789 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri231c2972016-03-08 19:50:112790
2791 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shi21e99532018-07-17 22:23:072792 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri231c2972016-03-08 19:50:112793 EXPECT_EQ(1u, session->GetNumActiveStreams());
2794
Zhongyi Shi21e99532018-07-17 22:23:072795 // Resume data to read a connectivity probing response, which will cause
Zhongyi Shic16b4102019-02-12 00:37:402796 // non-migtable streams to be closed.
Zhongyi Shi21e99532018-07-17 22:23:072797 quic_data1.Resume();
2798 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shi32fe14d42019-02-28 00:25:362799 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(host_port_pair_));
Zhongyi Shi21e99532018-07-17 22:23:072800 EXPECT_EQ(0u, session->GetNumActiveStreams());
jri231c2972016-03-08 19:50:112801
Zhongyi Shic16b4102019-02-12 00:37:402802 base::RunLoop().RunUntilIdle();
2803
Zhongyi Shi21e99532018-07-17 22:23:072804 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
2805 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
jri231c2972016-03-08 19:50:112806 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2807 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2808}
2809
jri9f303712016-09-13 01:10:222810TEST_P(QuicStreamFactoryTest, OnNetworkMadeDefaultConnectionMigrationDisabled) {
Zhongyi Shi5f587cc2017-11-21 23:24:172811 InitializeConnectionMigrationV2Test(
2812 {kDefaultNetworkForTests, kNewNetworkForTests});
2813 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2814 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2815
Ryan Hamiltonabad59e2019-06-06 04:02:592816 MockQuicData socket_data(version_);
Zhongyi Shi5f587cc2017-11-21 23:24:172817 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432818 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
2819 socket_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:332820 SYNCHRONOUS, client_maker_.MakeRstPacket(
2821 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
2822 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:172823 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9c541572016-03-29 17:51:482824
2825 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452826 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332827 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032828 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:522829 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
2830 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032831 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2832 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012833 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242834 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9c541572016-03-29 17:51:482835 EXPECT_TRUE(stream.get());
2836
2837 // Cause QUIC stream to be created.
2838 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392839 request_info.traffic_annotation =
2840 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272841 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392842 net_log_, CompletionOnceCallback()));
jri9c541572016-03-29 17:51:482843
2844 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502845 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri9c541572016-03-29 17:51:482846 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2847 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2848
2849 // Set session config to have connection migration disabled.
Ryan Hamilton8d9ee76e2018-05-29 23:52:522850 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
2851 session->config());
jri9c541572016-03-29 17:51:482852 EXPECT_TRUE(session->config()->DisableConnectionMigration());
2853
2854 // Trigger connection migration. Since there is a non-migratable stream,
2855 // this should cause session to continue but be marked as going away.
2856 scoped_mock_network_change_notifier_->mock_network_change_notifier()
jrie2661982016-08-20 08:24:342857 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri9c541572016-03-29 17:51:482858
2859 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2860 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2861 EXPECT_EQ(1u, session->GetNumActiveStreams());
2862
2863 stream.reset();
2864
2865 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2866 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2867}
2868
Zhongyi Shi32fe14d42019-02-28 00:25:362869TEST_P(QuicStreamFactoryTest,
2870 OnNetworkDisconnectedNonMigratableStream_DoNotMigrateIdleSessions) {
2871 TestOnNetworkDisconnectedNonMigratableStream(false);
2872}
2873
2874TEST_P(QuicStreamFactoryTest,
2875 OnNetworkDisconnectedNonMigratableStream_MigrateIdleSessions) {
2876 TestOnNetworkDisconnectedNonMigratableStream(true);
2877}
2878
2879void QuicStreamFactoryTestBase::TestOnNetworkDisconnectedNonMigratableStream(
2880 bool migrate_idle_sessions) {
Nick Harper72ade192019-07-17 03:30:422881 test_params_.quic_params.migrate_idle_sessions = migrate_idle_sessions;
Zhongyi Shi5f587cc2017-11-21 23:24:172882 InitializeConnectionMigrationV2Test(
2883 {kDefaultNetworkForTests, kNewNetworkForTests});
2884 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2885 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2886
Ryan Hamiltonabad59e2019-06-06 04:02:592887 MockQuicData failed_socket_data(version_);
2888 MockQuicData socket_data(version_);
Zhongyi Shi32fe14d42019-02-28 00:25:362889 if (migrate_idle_sessions) {
Zhongyi Shi32fe14d42019-02-28 00:25:362890 failed_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:022891 failed_socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi32fe14d42019-02-28 00:25:362892 // A RESET will be sent to the peer to cancel the non-migratable stream.
2893 failed_socket_data.AddWrite(
2894 SYNCHRONOUS, client_maker_.MakeRstPacket(
2895 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
2896 quic::QUIC_STREAM_CANCELLED));
2897 failed_socket_data.AddSocketDataToFactory(socket_factory_.get());
2898
2899 // Set up second socket data provider that is used after migration.
2900 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
2901 // Ping packet to send after migration.
2902 socket_data.AddWrite(
2903 SYNCHRONOUS, client_maker_.MakePingPacket(3, /*include_version=*/true));
2904 socket_data.AddSocketDataToFactory(socket_factory_.get());
2905 } else {
2906 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2907 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
2908 socket_data.AddWrite(
2909 SYNCHRONOUS, client_maker_.MakeRstPacket(
2910 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
2911 quic::QUIC_STREAM_CANCELLED));
2912 socket_data.AddSocketDataToFactory(socket_factory_.get());
2913 }
jri231c2972016-03-08 19:50:112914
2915 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452916 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332917 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032918 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:522919 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
2920 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032921 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2922 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012923 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242924 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri231c2972016-03-08 19:50:112925 EXPECT_TRUE(stream.get());
2926
2927 // Cause QUIC stream to be created, but marked as non-migratable.
2928 HttpRequestInfo request_info;
Zhongyi Shibb28b1f2018-07-18 02:41:262929 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Ramin Halavati683bcaa92018-02-14 08:42:392930 request_info.traffic_annotation =
2931 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272932 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392933 net_log_, CompletionOnceCallback()));
jri231c2972016-03-08 19:50:112934
2935 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502936 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri231c2972016-03-08 19:50:112937 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2938 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2939
2940 // Trigger connection migration. Since there is a non-migratable stream,
2941 // this should cause a RST_STREAM frame to be emitted with
Zhongyi Shic16b4102019-02-12 00:37:402942 // quic::QUIC_STREAM_CANCELLED error code.
Zhongyi Shi32fe14d42019-02-28 00:25:362943 // If migate idle session, the connection will then be migrated to the
2944 // alternate network. Otherwise, the connection will be closed.
jri231c2972016-03-08 19:50:112945 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2946 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
2947
Zhongyi Shi32fe14d42019-02-28 00:25:362948 EXPECT_EQ(migrate_idle_sessions,
2949 QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2950 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(host_port_pair_));
jri231c2972016-03-08 19:50:112951
Zhongyi Shi32fe14d42019-02-28 00:25:362952 if (migrate_idle_sessions) {
2953 EXPECT_EQ(0u, session->GetNumActiveStreams());
2954 base::RunLoop().RunUntilIdle();
Zhongyi Shic16b4102019-02-12 00:37:402955
Zhongyi Shi32fe14d42019-02-28 00:25:362956 EXPECT_TRUE(failed_socket_data.AllReadDataConsumed());
2957 EXPECT_TRUE(failed_socket_data.AllWriteDataConsumed());
2958 }
jri231c2972016-03-08 19:50:112959 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2960 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2961}
2962
jri9c541572016-03-29 17:51:482963TEST_P(QuicStreamFactoryTest,
jri9f303712016-09-13 01:10:222964 OnNetworkDisconnectedConnectionMigrationDisabled) {
Zhongyi Shi5f587cc2017-11-21 23:24:172965 InitializeConnectionMigrationV2Test(
2966 {kDefaultNetworkForTests, kNewNetworkForTests});
2967 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2968 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2969
Ryan Hamiltonabad59e2019-06-06 04:02:592970 MockQuicData socket_data(version_);
Zhongyi Shi5f587cc2017-11-21 23:24:172971 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432972 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
2973 socket_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:332974 SYNCHRONOUS, client_maker_.MakeRstPacket(
2975 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
2976 quic::QUIC_RST_ACKNOWLEDGEMENT));
Zhongyi Shi5f587cc2017-11-21 23:24:172977 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9c541572016-03-29 17:51:482978
2979 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452980 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332981 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032982 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:522983 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
2984 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032985 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2986 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012987 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242988 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9c541572016-03-29 17:51:482989 EXPECT_TRUE(stream.get());
2990
2991 // Cause QUIC stream to be created.
2992 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392993 request_info.traffic_annotation =
2994 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272995 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392996 net_log_, CompletionOnceCallback()));
jri9c541572016-03-29 17:51:482997
2998 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502999 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri9c541572016-03-29 17:51:483000 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3001 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3002
3003 // Set session config to have connection migration disabled.
Ryan Hamilton8d9ee76e2018-05-29 23:52:523004 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
3005 session->config());
jri9c541572016-03-29 17:51:483006 EXPECT_TRUE(session->config()->DisableConnectionMigration());
3007
3008 // Trigger connection migration. Since there is a non-migratable stream,
3009 // this should cause a RST_STREAM frame to be emitted with
Ryan Hamilton8d9ee76e2018-05-29 23:52:523010 // quic::QUIC_RST_ACKNOWLEDGEMENT error code, and the session will be closed.
jri9c541572016-03-29 17:51:483011 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3012 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
3013
3014 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3015 EXPECT_FALSE(HasActiveSession(host_port_pair_));
3016
3017 EXPECT_TRUE(socket_data.AllReadDataConsumed());
3018 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
3019}
3020
Zhongyi Shi32fe14d42019-02-28 00:25:363021TEST_P(QuicStreamFactoryTest,
3022 OnNetworkMadeDefaultNoOpenStreams_DoNotMigrateIdleSessions) {
3023 TestOnNetworkMadeDefaultNoOpenStreams(false);
3024}
3025
3026TEST_P(QuicStreamFactoryTest,
3027 OnNetworkMadeDefaultNoOpenStreams_MigrateIdleSessions) {
3028 TestOnNetworkMadeDefaultNoOpenStreams(true);
3029}
3030
3031void QuicStreamFactoryTestBase::TestOnNetworkMadeDefaultNoOpenStreams(
3032 bool migrate_idle_sessions) {
Nick Harper72ade192019-07-17 03:30:423033 test_params_.quic_params.migrate_idle_sessions = migrate_idle_sessions;
Zhongyi Shi5f587cc2017-11-21 23:24:173034 InitializeConnectionMigrationV2Test(
3035 {kDefaultNetworkForTests, kNewNetworkForTests});
3036 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3037 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3038
Ryan Hamiltonabad59e2019-06-06 04:02:593039 MockQuicData socket_data(version_);
Zhongyi Shi5f587cc2017-11-21 23:24:173040 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:433041 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi32fe14d42019-02-28 00:25:363042 if (!migrate_idle_sessions) {
3043 socket_data.AddWrite(
3044 SYNCHRONOUS,
3045 client_maker_.MakeConnectionClosePacket(
3046 2, true, quic::QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS,
3047 "net error"));
3048 }
Zhongyi Shi5f587cc2017-11-21 23:24:173049 socket_data.AddSocketDataToFactory(socket_factory_.get());
3050
Ryan Hamiltonabad59e2019-06-06 04:02:593051 MockQuicData quic_data1(version_);
Zhongyi Shi32fe14d42019-02-28 00:25:363052 if (migrate_idle_sessions) {
3053 // Set up the second socket data provider that is used for probing.
3054 // Connectivity probe to be sent on the new path.
3055 quic_data1.AddWrite(SYNCHRONOUS,
3056 client_maker_.MakeConnectivityProbingPacket(2, true));
3057 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3058 // Connectivity probe to receive from the server.
3059 quic_data1.AddRead(ASYNC,
3060 server_maker_.MakeConnectivityProbingPacket(1, false));
3061 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
3062 // Ping packet to send after migration is completed.
3063 quic_data1.AddWrite(SYNCHRONOUS,
3064 client_maker_.MakeAckAndPingPacket(3, false, 1, 1, 1));
3065 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3066 }
Zhongyi Shic16b4102019-02-12 00:37:403067
Zhongyi Shi5f587cc2017-11-21 23:24:173068 // Create request and QuicHttpStream.
3069 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:333070 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033071 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:523072 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
3073 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033074 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3075 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi5f587cc2017-11-21 23:24:173076 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3077 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3078 EXPECT_TRUE(stream.get());
3079
3080 // Ensure that session is alive and active.
3081 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3082 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3083 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shic16b4102019-02-12 00:37:403084 EXPECT_EQ(0u, session->GetNumActiveStreams());
3085 EXPECT_EQ(0u, session->GetNumDrainingStreams());
Zhongyi Shi5f587cc2017-11-21 23:24:173086
3087 // Trigger connection migration.
3088 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3089 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
Zhongyi Shi32fe14d42019-02-28 00:25:363090 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(host_port_pair_));
Zhongyi Shi5f587cc2017-11-21 23:24:173091
Zhongyi Shi32fe14d42019-02-28 00:25:363092 if (migrate_idle_sessions) {
3093 quic_data1.Resume();
3094 base::RunLoop().RunUntilIdle();
3095 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
3096 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
3097 }
Zhongyi Shi5f587cc2017-11-21 23:24:173098 EXPECT_TRUE(socket_data.AllReadDataConsumed());
3099 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
3100}
3101
Zhongyi Shi32fe14d42019-02-28 00:25:363102TEST_P(QuicStreamFactoryTest,
3103 OnNetworkDisconnectedNoOpenStreams_DoNotMigateIdleSessions) {
3104 TestOnNetworkDisconnectedNoOpenStreams(false);
3105}
3106
3107TEST_P(QuicStreamFactoryTest,
3108 OnNetworkDisconnectedNoOpenStreams_MigateIdleSessions) {
3109 TestOnNetworkDisconnectedNoOpenStreams(true);
3110}
3111
3112void QuicStreamFactoryTestBase::TestOnNetworkDisconnectedNoOpenStreams(
3113 bool migrate_idle_sessions) {
Nick Harper72ade192019-07-17 03:30:423114 test_params_.quic_params.migrate_idle_sessions = migrate_idle_sessions;
Zhongyi Shi5f587cc2017-11-21 23:24:173115 InitializeConnectionMigrationV2Test(
3116 {kDefaultNetworkForTests, kNewNetworkForTests});
3117 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3118 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3119
Ryan Hamiltonabad59e2019-06-06 04:02:593120 MockQuicData default_socket_data(version_);
Zhongyi Shic16b4102019-02-12 00:37:403121 default_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3122 default_socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
3123 default_socket_data.AddSocketDataToFactory(socket_factory_.get());
3124
Ryan Hamiltonabad59e2019-06-06 04:02:593125 MockQuicData alternate_socket_data(version_);
Zhongyi Shi32fe14d42019-02-28 00:25:363126 if (migrate_idle_sessions) {
3127 // Set up second socket data provider that is used after migration.
3128 alternate_socket_data.AddRead(SYNCHRONOUS,
3129 ERR_IO_PENDING); // Hanging read.
3130 // Ping packet to send after migration.
3131 alternate_socket_data.AddWrite(
3132 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
3133 alternate_socket_data.AddSocketDataToFactory(socket_factory_.get());
3134 }
Zhongyi Shi5f587cc2017-11-21 23:24:173135
3136 // Create request and QuicHttpStream.
3137 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:333138 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033139 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:523140 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
3141 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033142 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3143 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi5f587cc2017-11-21 23:24:173144 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3145 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3146 EXPECT_TRUE(stream.get());
3147
Zhongyi Shic16b4102019-02-12 00:37:403148 // Ensure that session is active.
Zhongyi Shi5f587cc2017-11-21 23:24:173149 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3150
3151 // Trigger connection migration. Since there are no active streams,
3152 // the session will be closed.
3153 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3154 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
3155
Zhongyi Shi32fe14d42019-02-28 00:25:363156 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(host_port_pair_));
Zhongyi Shi5f587cc2017-11-21 23:24:173157
Zhongyi Shic16b4102019-02-12 00:37:403158 EXPECT_TRUE(default_socket_data.AllReadDataConsumed());
3159 EXPECT_TRUE(default_socket_data.AllWriteDataConsumed());
Zhongyi Shi32fe14d42019-02-28 00:25:363160 if (migrate_idle_sessions) {
3161 EXPECT_TRUE(alternate_socket_data.AllReadDataConsumed());
3162 EXPECT_TRUE(alternate_socket_data.AllWriteDataConsumed());
3163 }
Zhongyi Shi5f587cc2017-11-21 23:24:173164}
3165
Zhongyi Shi9f316b262018-06-18 22:01:163166// This test verifies session migrates to the alternate network immediately when
3167// default network disconnects with a synchronous write before migration.
3168TEST_P(QuicStreamFactoryTest, MigrateOnDefaultNetworkDisconnectedSync) {
3169 TestMigrationOnNetworkDisconnected(/*async_write_before*/ false);
3170}
3171
3172// This test verifies session migrates to the alternate network immediately when
3173// default network disconnects with an asynchronously write before migration.
3174TEST_P(QuicStreamFactoryTest, MigrateOnDefaultNetworkDisconnectedAsync) {
3175 TestMigrationOnNetworkDisconnected(/*async_write_before*/ true);
3176}
3177
3178void QuicStreamFactoryTestBase::TestMigrationOnNetworkDisconnected(
3179 bool async_write_before) {
3180 InitializeConnectionMigrationV2Test(
3181 {kDefaultNetworkForTests, kNewNetworkForTests});
3182 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3183 ->NotifyNetworkMadeDefault(kDefaultNetworkForTests);
3184 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3185 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3186 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3187
3188 // Use the test task runner.
3189 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
3190
3191 int packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:593192 MockQuicData socket_data(version_);
Zhongyi Shi9f316b262018-06-18 22:01:163193 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:023194 socket_data.AddWrite(SYNCHRONOUS,
3195 ConstructInitialSettingsPacket(packet_number++));
Zhongyi Shi9f316b262018-06-18 22:01:163196 socket_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333197 SYNCHRONOUS,
3198 ConstructGetRequestPacket(packet_number++,
3199 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:023200 true, true));
Zhongyi Shi9f316b262018-06-18 22:01:163201 if (async_write_before) {
3202 socket_data.AddWrite(ASYNC, OK);
3203 packet_number++;
3204 }
3205 socket_data.AddSocketDataToFactory(socket_factory_.get());
3206
3207 // Create request and QuicHttpStream.
3208 QuicStreamRequest request(factory_.get());
3209 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033210 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:523211 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
3212 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033213 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3214 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi9f316b262018-06-18 22:01:163215 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3216 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3217 EXPECT_TRUE(stream.get());
3218
3219 // Cause QUIC stream to be created.
3220 HttpRequestInfo request_info;
3221 request_info.method = "GET";
3222 request_info.url = url_;
3223 request_info.traffic_annotation =
3224 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3225 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3226 net_log_, CompletionOnceCallback()));
3227
3228 // Ensure that session is alive and active.
3229 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3230 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3231 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3232
3233 // Send GET request on stream.
3234 HttpResponseInfo response;
3235 HttpRequestHeaders request_headers;
3236 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3237 callback_.callback()));
3238
Zhongyi Shi22fd5f52018-06-20 17:39:093239 if (async_write_before)
Zhongyi Shi9f316b262018-06-18 22:01:163240 session->SendPing();
Zhongyi Shi9f316b262018-06-18 22:01:163241
3242 // Set up second socket data provider that is used after migration.
3243 // The response to the earlier request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:593244 MockQuicData socket_data1(version_);
Zhongyi Shi9f316b262018-06-18 22:01:163245 socket_data1.AddWrite(
3246 SYNCHRONOUS,
3247 client_maker_.MakePingPacket(packet_number++, /*include_version=*/true));
3248 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:333249 ASYNC,
3250 ConstructOkResponsePacket(
3251 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shi9f316b262018-06-18 22:01:163252 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3253 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333254 SYNCHRONOUS,
3255 client_maker_.MakeAckAndRstPacket(
3256 packet_number++, false, GetNthClientInitiatedBidirectionalStreamId(0),
3257 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi9f316b262018-06-18 22:01:163258 socket_data1.AddSocketDataToFactory(socket_factory_.get());
3259
3260 // Trigger connection migration.
3261 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3262 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
3263
3264 // The connection should still be alive, not marked as going away.
3265 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3266 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3267 EXPECT_EQ(1u, session->GetNumActiveStreams());
3268 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3269
3270 // Ensure that the session is still alive.
3271 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3272 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3273 EXPECT_EQ(1u, session->GetNumActiveStreams());
3274
3275 // Run the message loop so that data queued in the new socket is read by the
3276 // packet reader.
3277 runner_->RunNextTask();
3278
3279 // Response headers are received over the new network.
3280 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3281 EXPECT_EQ(200, response.headers->response_code());
3282
3283 // Check that the session is still alive.
3284 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3285 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3286
3287 // There should be posted tasks not executed, which is to migrate back to
3288 // default network.
3289 EXPECT_FALSE(runner_->GetPostedTasks().empty());
3290
3291 // Receive signal to mark new network as default.
3292 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3293 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3294
3295 stream.reset();
3296 EXPECT_TRUE(socket_data.AllReadDataConsumed());
3297 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
3298 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
3299 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
3300}
3301
Zhongyi Shi5f587cc2017-11-21 23:24:173302// This test receives NCN signals in the following order:
3303// - default network disconnected
3304// - after a pause, new network is connected.
3305// - new network is made default.
3306TEST_P(QuicStreamFactoryTest, NewNetworkConnectedAfterNoNetwork) {
3307 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
3308 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3309 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3310 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3311
3312 // Use the test task runner.
3313 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
3314
Ryan Hamiltonabad59e2019-06-06 04:02:593315 MockQuicData socket_data(version_);
Zhongyi Shi5f587cc2017-11-21 23:24:173316 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:023317 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:173318 socket_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:023319 SYNCHRONOUS,
3320 ConstructGetRequestPacket(
3321 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi5f587cc2017-11-21 23:24:173322 socket_data.AddSocketDataToFactory(socket_factory_.get());
3323
3324 // Create request and QuicHttpStream.
3325 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:333326 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033327 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:523328 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
3329 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033330 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3331 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi5f587cc2017-11-21 23:24:173332 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3333 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3334 EXPECT_TRUE(stream.get());
3335
3336 // Cause QUIC stream to be created.
3337 HttpRequestInfo request_info;
3338 request_info.method = "GET";
3339 request_info.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:393340 request_info.traffic_annotation =
3341 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:273342 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:393343 net_log_, CompletionOnceCallback()));
Zhongyi Shi5f587cc2017-11-21 23:24:173344
3345 // Ensure that session is alive and active.
3346 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3347 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3348 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3349
3350 // Send GET request on stream.
3351 HttpResponseInfo response;
3352 HttpRequestHeaders request_headers;
3353 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3354 callback_.callback()));
3355
3356 // Trigger connection migration. Since there are no networks
3357 // to migrate to, this should cause the session to wait for a new network.
3358 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3359 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
3360
3361 // The connection should still be alive, not marked as going away.
3362 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3363 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3364 EXPECT_EQ(1u, session->GetNumActiveStreams());
3365 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3366
3367 // Set up second socket data provider that is used after migration.
3368 // The response to the earlier request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:593369 MockQuicData socket_data1(version_);
Zhongyi Shi5f587cc2017-11-21 23:24:173370 socket_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433371 SYNCHRONOUS, client_maker_.MakePingPacket(3, /*include_version=*/true));
3372 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:333373 ASYNC,
3374 ConstructOkResponsePacket(
3375 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shi5f587cc2017-11-21 23:24:173376 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:333377 socket_data1.AddWrite(
3378 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
3379 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
3380 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:173381 socket_data1.AddSocketDataToFactory(socket_factory_.get());
3382
3383 // Add a new network and notify the stream factory of a new connected network.
3384 // This causes a PING packet to be sent over the new network.
3385 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3386 ->SetConnectedNetworksList({kNewNetworkForTests});
3387 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3388 ->NotifyNetworkConnected(kNewNetworkForTests);
3389
3390 // Ensure that the session is still alive.
3391 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3392 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3393 EXPECT_EQ(1u, session->GetNumActiveStreams());
3394
3395 // Run the message loop so that data queued in the new socket is read by the
3396 // packet reader.
3397 runner_->RunNextTask();
3398
3399 // Response headers are received over the new network.
3400 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3401 EXPECT_EQ(200, response.headers->response_code());
3402
3403 // Check that the session is still alive.
3404 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3405 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3406
3407 // There should posted tasks not executed, which is to migrate back to default
3408 // network.
3409 EXPECT_FALSE(runner_->GetPostedTasks().empty());
3410
3411 // Receive signal to mark new network as default.
3412 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3413 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3414
3415 stream.reset();
3416 EXPECT_TRUE(socket_data.AllReadDataConsumed());
3417 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
3418 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
3419 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
3420}
3421
Zhongyi Shid3d5f502018-08-10 00:22:223422// Regression test for http://crbug.com/872011.
3423// This test verifies that migrate to the probing socket will not trigger
3424// new packets being read synchronously and generate ACK frame while
3425// processing the initial connectivity probe response, which may cause a
3426// connection being closed with INTERNAL_ERROR as pending ACK frame is not
3427// allowed when processing a new packet.
Zhongyi Shi6a7323b2018-12-07 01:26:323428TEST_P(QuicStreamFactoryTest, MigrateToProbingSocket) {
Zhongyi Shid3d5f502018-08-10 00:22:223429 InitializeConnectionMigrationV2Test(
3430 {kDefaultNetworkForTests, kNewNetworkForTests});
3431 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3432 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3433 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3434
3435 // Using a testing task runner so that we can control time.
3436 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3437 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
3438
3439 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3440 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3441
3442 int packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:593443 MockQuicData quic_data1(version_);
Zhongyi Shid3d5f502018-08-10 00:22:223444 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
Ryan Hamilton0d65a8c2019-06-07 00:46:023445 quic_data1.AddWrite(SYNCHRONOUS,
3446 ConstructInitialSettingsPacket(packet_number++));
Zhongyi Shid3d5f502018-08-10 00:22:223447 quic_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333448 SYNCHRONOUS,
3449 ConstructGetRequestPacket(packet_number++,
3450 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:023451 true, true));
Zhongyi Shid3d5f502018-08-10 00:22:223452 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3453
3454 // Set up the second socket data provider that is used for probing on the
3455 // alternate network.
Ryan Hamiltonabad59e2019-06-06 04:02:593456 MockQuicData quic_data2(version_);
Zhongyi Shid3d5f502018-08-10 00:22:223457 // Connectivity probe to be sent on the new path.
3458 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(
3459 packet_number++, true));
3460 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3461 // First connectivity probe to receive from the server, which will complete
3462 // connection migraiton on path degrading.
3463 quic_data2.AddRead(ASYNC,
3464 server_maker_.MakeConnectivityProbingPacket(1, false));
3465 // Read multiple connectivity probes synchronously.
3466 quic_data2.AddRead(SYNCHRONOUS,
3467 server_maker_.MakeConnectivityProbingPacket(2, false));
3468 quic_data2.AddRead(SYNCHRONOUS,
3469 server_maker_.MakeConnectivityProbingPacket(3, false));
3470 quic_data2.AddRead(SYNCHRONOUS,
3471 server_maker_.MakeConnectivityProbingPacket(4, false));
3472 quic_data2.AddWrite(
3473 ASYNC, client_maker_.MakeAckPacket(packet_number++, 1, 4, 1, 1, true));
3474 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:333475 ASYNC,
3476 ConstructOkResponsePacket(
3477 5, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shid3d5f502018-08-10 00:22:223478 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3479 quic_data2.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333480 SYNCHRONOUS,
3481 client_maker_.MakeAckAndRstPacket(
3482 packet_number++, false, GetNthClientInitiatedBidirectionalStreamId(0),
3483 quic::QUIC_STREAM_CANCELLED, 5, 1, 1, true));
Zhongyi Shid3d5f502018-08-10 00:22:223484 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3485
3486 // Create request and QuicHttpStream.
3487 QuicStreamRequest request(factory_.get());
3488 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033489 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:523490 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
3491 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033492 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3493 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shid3d5f502018-08-10 00:22:223494 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3495 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3496 EXPECT_TRUE(stream.get());
3497
3498 // Cause QUIC stream to be created.
3499 HttpRequestInfo request_info;
3500 request_info.method = "GET";
3501 request_info.url = url_;
3502 request_info.traffic_annotation =
3503 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3504 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3505 net_log_, CompletionOnceCallback()));
3506
3507 // Ensure that session is alive and active.
3508 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3509 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3510 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3511
3512 // Send GET request on stream.
3513 HttpResponseInfo response;
3514 HttpRequestHeaders request_headers;
3515 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3516 callback_.callback()));
3517
3518 // Cause the connection to report path degrading to the session.
3519 // Session will start to probe the alternate network.
3520 session->connection()->OnPathDegradingTimeout();
3521
3522 // Next connectivity probe is scheduled to be sent in 2 *
3523 // kDefaultRTTMilliSecs.
3524 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3525 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
3526 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3527 next_task_delay);
3528
3529 // The connection should still be alive, and not marked as going away.
3530 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3531 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3532 EXPECT_EQ(1u, session->GetNumActiveStreams());
3533 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3534
3535 // Resume quic data and a connectivity probe response will be read on the new
3536 // socket.
3537 quic_data2.Resume();
3538
3539 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3540 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3541 EXPECT_EQ(1u, session->GetNumActiveStreams());
3542
3543 // There should be three pending tasks, the nearest one will complete
3544 // migration to the new network.
3545 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
3546 next_task_delay = task_runner->NextPendingTaskDelay();
3547 EXPECT_EQ(base::TimeDelta(), next_task_delay);
3548 task_runner->FastForwardBy(next_task_delay);
3549
3550 // Response headers are received over the new network.
3551 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3552 EXPECT_EQ(200, response.headers->response_code());
3553
3554 // Now there are two pending tasks, the nearest one was to send connectivity
3555 // probe and has been cancelled due to successful migration.
3556 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
3557 next_task_delay = task_runner->NextPendingTaskDelay();
3558 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3559 next_task_delay);
3560 task_runner->FastForwardBy(next_task_delay);
3561
3562 // There's one more task to mgirate back to the default network in 0.4s.
3563 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3564 next_task_delay = task_runner->NextPendingTaskDelay();
3565 base::TimeDelta expected_delay =
3566 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
3567 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
3568 EXPECT_EQ(expected_delay, next_task_delay);
3569
3570 // Deliver a signal that the alternate network now becomes default to session,
3571 // this will cancel mgirate back to default network timer.
3572 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3573 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3574
3575 task_runner->FastForwardBy(next_task_delay);
3576 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
3577
3578 // Verify that the session is still alive.
3579 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3580 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3581
3582 stream.reset();
3583 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
3584 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
3585 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
3586 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
3587}
3588
Zhongyi Shic4823bd2018-04-27 00:49:193589// This test verifies that the connection migrates to the alternate network
Zhongyi Shi22fd5f52018-06-20 17:39:093590// early when path degrading is detected with an ASYNCHRONOUS write before
3591// migration.
3592TEST_P(QuicStreamFactoryTest, MigrateEarlyOnPathDegradingAysnc) {
3593 TestMigrationOnPathDegrading(/*async_write_before_migration*/ true);
3594}
3595
3596// This test verifies that the connection migrates to the alternate network
3597// early when path degrading is detected with a SYNCHRONOUS write before
3598// migration.
3599TEST_P(QuicStreamFactoryTest, MigrateEarlyOnPathDegradingSync) {
3600 TestMigrationOnPathDegrading(/*async_write_before_migration*/ false);
3601}
3602
3603void QuicStreamFactoryTestBase::TestMigrationOnPathDegrading(
3604 bool async_write_before) {
Zhongyi Shic4823bd2018-04-27 00:49:193605 InitializeConnectionMigrationV2Test(
3606 {kDefaultNetworkForTests, kNewNetworkForTests});
3607 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3608 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3609 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3610
3611 // Using a testing task runner so that we can control time.
3612 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3613 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
3614
3615 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3616 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3617
Zhongyi Shi22fd5f52018-06-20 17:39:093618 int packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:593619 MockQuicData quic_data1(version_);
Zhongyi Shic4823bd2018-04-27 00:49:193620 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
Ryan Hamilton0d65a8c2019-06-07 00:46:023621 quic_data1.AddWrite(SYNCHRONOUS,
3622 ConstructInitialSettingsPacket(packet_number++));
Zhongyi Shi22fd5f52018-06-20 17:39:093623 quic_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333624 SYNCHRONOUS,
3625 ConstructGetRequestPacket(packet_number++,
3626 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:023627 true, true));
Zhongyi Shi22fd5f52018-06-20 17:39:093628 if (async_write_before) {
3629 quic_data1.AddWrite(ASYNC, OK);
3630 packet_number++;
3631 }
Zhongyi Shic4823bd2018-04-27 00:49:193632 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3633
3634 // Set up the second socket data provider that is used after migration.
3635 // The response to the earlier request is read on the new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:593636 MockQuicData quic_data2(version_);
Zhongyi Shic4823bd2018-04-27 00:49:193637 // Connectivity probe to be sent on the new path.
Zhongyi Shi22fd5f52018-06-20 17:39:093638 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(
Zhongyi Shi879659422018-08-02 17:58:253639 packet_number++, true));
Zhongyi Shic4823bd2018-04-27 00:49:193640 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3641 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:253642 quic_data2.AddRead(ASYNC,
3643 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shic4823bd2018-04-27 00:49:193644 // Ping packet to send after migration is completed.
Zhongyi Shi22fd5f52018-06-20 17:39:093645 quic_data2.AddWrite(ASYNC, client_maker_.MakeAckAndPingPacket(
3646 packet_number++, false, 1, 1, 1));
Ryan Hamiltona3ee93a72018-08-01 22:03:083647 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:333648 ASYNC,
3649 ConstructOkResponsePacket(
3650 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shic4823bd2018-04-27 00:49:193651 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi22fd5f52018-06-20 17:39:093652 quic_data2.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333653 SYNCHRONOUS,
3654 client_maker_.MakeAckAndRstPacket(
3655 packet_number++, false, GetNthClientInitiatedBidirectionalStreamId(0),
3656 quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true));
Zhongyi Shic4823bd2018-04-27 00:49:193657 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3658
3659 // Create request and QuicHttpStream.
3660 QuicStreamRequest request(factory_.get());
3661 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033662 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:523663 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
3664 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033665 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3666 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shic4823bd2018-04-27 00:49:193667 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3668 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3669 EXPECT_TRUE(stream.get());
3670
3671 // Cause QUIC stream to be created.
3672 HttpRequestInfo request_info;
3673 request_info.method = "GET";
3674 request_info.url = url_;
3675 request_info.traffic_annotation =
3676 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3677 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3678 net_log_, CompletionOnceCallback()));
3679
3680 // Ensure that session is alive and active.
3681 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3682 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3683 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3684
3685 // Send GET request on stream.
3686 HttpResponseInfo response;
3687 HttpRequestHeaders request_headers;
3688 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3689 callback_.callback()));
3690
Zhongyi Shi22fd5f52018-06-20 17:39:093691 if (async_write_before)
3692 session->SendPing();
3693
Zhongyi Shiaba4a832018-04-30 20:29:083694 // Cause the connection to report path degrading to the session.
3695 // Session will start to probe the alternate network.
3696 session->connection()->OnPathDegradingTimeout();
3697
3698 // Next connectivity probe is scheduled to be sent in 2 *
3699 // kDefaultRTTMilliSecs.
3700 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3701 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
3702 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3703 next_task_delay);
3704
3705 // The connection should still be alive, and not marked as going away.
3706 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3707 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3708 EXPECT_EQ(1u, session->GetNumActiveStreams());
3709 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3710
3711 // Resume quic data and a connectivity probe response will be read on the new
3712 // socket.
3713 quic_data2.Resume();
3714
3715 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3716 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3717 EXPECT_EQ(1u, session->GetNumActiveStreams());
3718
3719 // There should be three pending tasks, the nearest one will complete
3720 // migration to the new network.
3721 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
3722 next_task_delay = task_runner->NextPendingTaskDelay();
3723 EXPECT_EQ(base::TimeDelta(), next_task_delay);
3724 task_runner->FastForwardBy(next_task_delay);
3725
3726 // Response headers are received over the new network.
3727 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3728 EXPECT_EQ(200, response.headers->response_code());
3729
3730 // Now there are two pending tasks, the nearest one was to send connectivity
3731 // probe and has been cancelled due to successful migration.
3732 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
3733 next_task_delay = task_runner->NextPendingTaskDelay();
3734 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3735 next_task_delay);
3736 task_runner->FastForwardBy(next_task_delay);
3737
3738 // There's one more task to mgirate back to the default network in 0.4s.
3739 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3740 next_task_delay = task_runner->NextPendingTaskDelay();
3741 base::TimeDelta expected_delay =
3742 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
3743 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
3744 EXPECT_EQ(expected_delay, next_task_delay);
3745
3746 // Deliver a signal that the alternate network now becomes default to session,
3747 // this will cancel mgirate back to default network timer.
3748 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3749 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3750
3751 task_runner->FastForwardBy(next_task_delay);
3752 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
3753
3754 // Verify that the session is still alive.
3755 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3756 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3757
3758 stream.reset();
3759 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
3760 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
3761 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
3762 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
3763}
3764
Renjiea5722ccf2018-08-10 00:18:493765// This test verifies that the session marks itself GOAWAY on path degrading
3766// and it does not receive any new request
3767TEST_P(QuicStreamFactoryTest, GoawayOnPathDegrading) {
Nick Harper72ade192019-07-17 03:30:423768 test_params_.quic_params.go_away_on_path_degrading = true;
Renjiea5722ccf2018-08-10 00:18:493769 Initialize();
3770 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3771 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3772 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3773
Ryan Hamiltonabad59e2019-06-06 04:02:593774 MockQuicData quic_data1(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:023775 quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Fan Yang32c5a112018-12-10 20:06:333776 quic_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:023777 SYNCHRONOUS,
3778 ConstructGetRequestPacket(
3779 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Renjiea5722ccf2018-08-10 00:18:493780 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3781 quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:333782 ASYNC,
3783 ConstructOkResponsePacket(
3784 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true));
Renjiea5722ccf2018-08-10 00:18:493785 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
3786 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3787
Ryan Hamilton0d65a8c2019-06-07 00:46:023788 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:593789 MockQuicData quic_data2(version_);
Renjiea5722ccf2018-08-10 00:18:493790 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
Ryan Hamilton0d65a8c2019-06-07 00:46:023791 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Renjiea5722ccf2018-08-10 00:18:493792 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3793
3794 // Creat request and QuicHttpStream.
3795 QuicStreamRequest request(factory_.get());
3796 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033797 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:523798 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
3799 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033800 /*cerf_verify_flags=*/0, url_, net_log_, &net_error_details_,
3801 failed_on_default_network_callback_, callback_.callback()));
Renjiea5722ccf2018-08-10 00:18:493802 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3803 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3804 EXPECT_TRUE(stream.get());
3805
3806 // Cause QUIC stream to be created.
3807 HttpRequestInfo request_info;
3808 request_info.method = "GET";
3809 request_info.url = url_;
3810 request_info.traffic_annotation =
3811 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3812 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3813 net_log_, CompletionOnceCallback()));
3814
3815 // Ensure that session is alive and active.
3816 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3817 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3818 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3819
3820 // Send GET request on stream.
3821 HttpResponseInfo response;
3822 HttpRequestHeaders request_headers;
3823 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3824 callback_.callback()));
3825
3826 // Trigger the connection to report path degrading to the session.
3827 // Session will mark itself GOAWAY.
3828 session->connection()->OnPathDegradingTimeout();
3829
3830 // The connection should still be alive, but marked as going away.
3831 EXPECT_FALSE(HasActiveSession(host_port_pair_));
3832 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3833 EXPECT_EQ(1u, session->GetNumActiveStreams());
3834
3835 // Second request should be sent on a new connection.
3836 QuicStreamRequest request2(factory_.get());
3837 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033838 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:523839 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
3840 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033841 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3842 failed_on_default_network_callback_, callback_.callback()));
Renjiea5722ccf2018-08-10 00:18:493843 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3844 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
3845 EXPECT_TRUE(stream2.get());
3846
3847 // Resume the data, verify old request can read response on the old session
3848 // successfully.
3849 quic_data1.Resume();
3850 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
3851 EXPECT_EQ(200, response.headers->response_code());
3852 EXPECT_EQ(0U, session->GetNumActiveStreams());
3853
3854 // Check an active session exists for the destination.
3855 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3856 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3857 QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
3858 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
3859 EXPECT_NE(session, session2);
3860
3861 stream.reset();
3862 stream2.reset();
3863 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
3864 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
3865 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
3866 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
3867}
3868
Zhongyi Shibb770d92018-06-16 02:07:003869// This test verifies that the connection will not migrate to a bad socket
3870// when path degrading is detected.
3871TEST_P(QuicStreamFactoryTest, DoNotMigrateToBadSocketOnPathDegrading) {
3872 InitializeConnectionMigrationV2Test(
3873 {kDefaultNetworkForTests, kNewNetworkForTests});
3874 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3875 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3876 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3877
3878 // Using a testing task runner so that we can control time.
3879 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3880 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
3881
3882 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3883 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3884
Ryan Hamiltonabad59e2019-06-06 04:02:593885 MockQuicData quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:023886 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
3887 quic_data.AddWrite(
3888 SYNCHRONOUS,
3889 ConstructGetRequestPacket(
3890 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Fan Yang32c5a112018-12-10 20:06:333891 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3892 quic_data.AddRead(ASYNC, ConstructOkResponsePacket(
3893 1, GetNthClientInitiatedBidirectionalStreamId(0),
3894 false, false));
3895 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3896 quic_data.AddWrite(
3897 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
3898 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
3899 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shibb770d92018-06-16 02:07:003900 quic_data.AddSocketDataToFactory(socket_factory_.get());
3901
3902 // Set up second socket that will immediately return disconnected.
3903 // The stream factory will abort probe the alternate network.
3904 MockConnect bad_connect = MockConnect(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
3905 SequencedSocketData socket_data(bad_connect, base::span<MockRead>(),
3906 base::span<MockWrite>());
3907 socket_factory_->AddSocketDataProvider(&socket_data);
3908
3909 // Create request and QuicHttpStream.
3910 QuicStreamRequest request(factory_.get());
3911 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033912 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:523913 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
3914 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033915 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3916 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shibb770d92018-06-16 02:07:003917 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3918 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3919 EXPECT_TRUE(stream.get());
3920
3921 // Cause QUIC stream to be created.
3922 HttpRequestInfo request_info;
3923 request_info.method = "GET";
3924 request_info.url = url_;
3925 request_info.traffic_annotation =
3926 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3927 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3928 net_log_, CompletionOnceCallback()));
3929
3930 // Ensure that session is alive and active.
3931 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3932 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3933 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3934
3935 // Send GET request on stream.
3936 HttpResponseInfo response;
3937 HttpRequestHeaders request_headers;
3938 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3939 callback_.callback()));
3940
3941 // Cause the connection to report path degrading to the session.
3942 // Session will start to probe the alternate network.
3943 session->connection()->OnPathDegradingTimeout();
3944
3945 // The connection should still be alive, and not marked as going away.
3946 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3947 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3948 EXPECT_EQ(1u, session->GetNumActiveStreams());
3949 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3950
3951 // Resume the data, and response header is received over the original network.
3952 quic_data.Resume();
3953 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3954 EXPECT_EQ(200, response.headers->response_code());
3955
3956 // Verify there is no pending task as probing alternate network is halted.
3957 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
3958
3959 // Verify that the session is still alive.
3960 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3961 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3962
3963 stream.reset();
3964 EXPECT_TRUE(quic_data.AllReadDataConsumed());
3965 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
3966}
3967
Zhongyi Shif5cc30392018-05-30 18:25:153968// Regression test for http://crbug.com/847569.
3969// This test verifies that the connection migrates to the alternate network
3970// early when there is no active stream but a draining stream.
Zhongyi Shib3bc982c2018-07-10 19:59:243971// The first packet being written after migration is a synchrnous write, which
3972// will cause a PING packet being sent.
3973TEST_P(QuicStreamFactoryTest, MigrateSessionWithDrainingStreamSync) {
3974 TestMigrateSessionWithDrainingStream(SYNCHRONOUS);
3975}
3976
3977// Regression test for http://crbug.com/847569.
3978// This test verifies that the connection migrates to the alternate network
3979// early when there is no active stream but a draining stream.
3980// The first packet being written after migration is an asynchronous write, no
3981// PING packet will be sent.
3982TEST_P(QuicStreamFactoryTest, MigrateSessionWithDrainingStreamAsync) {
3983 TestMigrateSessionWithDrainingStream(ASYNC);
3984}
3985
3986void QuicStreamFactoryTestBase::TestMigrateSessionWithDrainingStream(
3987 IoMode write_mode_for_queued_packet) {
Zhongyi Shif5cc30392018-05-30 18:25:153988 InitializeConnectionMigrationV2Test(
3989 {kDefaultNetworkForTests, kNewNetworkForTests});
3990 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3991 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3992 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3993
3994 // Using a testing task runner so that we can control time.
3995 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3996 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
3997
3998 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3999 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
4000
Zhongyi Shib3bc982c2018-07-10 19:59:244001 int packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:594002 MockQuicData quic_data1(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:024003 quic_data1.AddWrite(SYNCHRONOUS,
4004 ConstructInitialSettingsPacket(packet_number++));
Zhongyi Shib3bc982c2018-07-10 19:59:244005 quic_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334006 SYNCHRONOUS,
4007 ConstructGetRequestPacket(packet_number++,
4008 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:024009 true, true));
Zhongyi Shif5cc30392018-05-30 18:25:154010 // Read an out of order packet with FIN to drain the stream.
4011 quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:334012 ASYNC, ConstructOkResponsePacket(
4013 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
4014 true)); // keep sending version.
Zhongyi Shif5cc30392018-05-30 18:25:154015 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4016 quic_data1.AddSocketDataToFactory(socket_factory_.get());
4017
4018 // Set up the second socket data provider that is used after migration.
Ryan Hamiltonabad59e2019-06-06 04:02:594019 MockQuicData quic_data2(version_);
Zhongyi Shif5cc30392018-05-30 18:25:154020 // Connectivity probe to be sent on the new path.
Zhongyi Shib3bc982c2018-07-10 19:59:244021 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(
Zhongyi Shi879659422018-08-02 17:58:254022 packet_number++, false));
Zhongyi Shif5cc30392018-05-30 18:25:154023 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
4024 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:254025 quic_data2.AddRead(ASYNC,
4026 server_maker_.MakeConnectivityProbingPacket(3, false));
Zhongyi Shif5cc30392018-05-30 18:25:154027 // Ping packet to send after migration is completed.
Zhongyi Shib3bc982c2018-07-10 19:59:244028 quic_data2.AddWrite(
4029 write_mode_for_queued_packet,
4030 client_maker_.MakeAckPacket(packet_number++, 2, 3, 3, 1, true));
4031 if (write_mode_for_queued_packet == SYNCHRONOUS) {
4032 quic_data2.AddWrite(ASYNC,
4033 client_maker_.MakePingPacket(packet_number++, false));
4034 }
Ryan Hamilton0d65a8c2019-06-07 00:46:024035 server_maker_.Reset();
Zhongyi Shif5cc30392018-05-30 18:25:154036 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:334037 ASYNC,
4038 ConstructOkResponsePacket(
4039 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shib3bc982c2018-07-10 19:59:244040 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeAckPacket(
4041 packet_number++, 1, 3, 1, 1, true));
Zhongyi Shif5cc30392018-05-30 18:25:154042 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4043 quic_data2.AddSocketDataToFactory(socket_factory_.get());
4044
4045 // Create request and QuicHttpStream.
4046 QuicStreamRequest request(factory_.get());
4047 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034048 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:524049 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
4050 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:034051 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4052 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shif5cc30392018-05-30 18:25:154053 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4054 std::unique_ptr<HttpStream> stream = CreateStream(&request);
4055 EXPECT_TRUE(stream.get());
4056
4057 // Cause QUIC stream to be created.
4058 HttpRequestInfo request_info;
4059 request_info.method = "GET";
4060 request_info.url = url_;
4061 request_info.traffic_annotation =
4062 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4063 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
4064 net_log_, CompletionOnceCallback()));
4065
4066 // Ensure that session is alive and active.
4067 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
4068 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4069 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4070
4071 // Send GET request on stream.
4072 HttpResponseInfo response;
4073 HttpRequestHeaders request_headers;
4074 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
4075 callback_.callback()));
4076
4077 // Run the message loop to receive the out of order packet which contains a
4078 // FIN and drains the stream.
4079 base::RunLoop().RunUntilIdle();
4080 EXPECT_EQ(0u, session->GetNumActiveStreams());
4081
4082 // Cause the connection to report path degrading to the session.
4083 // Session should still start to probe the alternate network.
4084 session->connection()->OnPathDegradingTimeout();
4085 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4086
4087 // Next connectivity probe is scheduled to be sent in 2 *
4088 // kDefaultRTTMilliSecs.
4089 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4090 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
4091 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
4092 next_task_delay);
4093
4094 // The connection should still be alive, and not marked as going away.
4095 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shif5cc30392018-05-30 18:25:154096
4097 // Resume quic data and a connectivity probe response will be read on the new
4098 // socket.
4099 quic_data2.Resume();
4100
4101 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4102 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:264103 EXPECT_EQ(0u, session->GetNumActiveStreams());
4104 EXPECT_EQ(1u, session->GetNumDrainingStreams());
Zhongyi Shif5cc30392018-05-30 18:25:154105
4106 // There should be three pending tasks, the nearest one will complete
4107 // migration to the new network.
4108 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
4109 next_task_delay = task_runner->NextPendingTaskDelay();
4110 EXPECT_EQ(base::TimeDelta(), next_task_delay);
4111 task_runner->FastForwardBy(next_task_delay);
4112
4113 // Now there are two pending tasks, the nearest one was to send connectivity
4114 // probe and has been cancelled due to successful migration.
4115 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
4116 next_task_delay = task_runner->NextPendingTaskDelay();
4117 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
4118 next_task_delay);
4119 task_runner->FastForwardBy(next_task_delay);
4120
4121 // There's one more task to mgirate back to the default network in 0.4s.
4122 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4123 next_task_delay = task_runner->NextPendingTaskDelay();
4124 base::TimeDelta expected_delay =
4125 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
4126 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
4127 EXPECT_EQ(expected_delay, next_task_delay);
4128
Zhongyi Shib3bc982c2018-07-10 19:59:244129 base::RunLoop().RunUntilIdle();
4130
Zhongyi Shif5cc30392018-05-30 18:25:154131 // Deliver a signal that the alternate network now becomes default to session,
4132 // this will cancel mgirate back to default network timer.
4133 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4134 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
4135
4136 task_runner->FastForwardBy(next_task_delay);
4137 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4138
4139 // Verify that the session is still alive.
4140 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4141 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:264142 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
Zhongyi Shif5cc30392018-05-30 18:25:154143
4144 stream.reset();
4145 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
4146 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
4147 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
4148 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
4149}
4150
Zhongyi Shiaba4a832018-04-30 20:29:084151// Regression test for http://crbug.com/835444.
4152// This test verifies that the connection migrates to the alternate network
4153// when the alternate network is connected after path has been degrading.
4154TEST_P(QuicStreamFactoryTest, MigrateOnNewNetworkConnectAfterPathDegrading) {
4155 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
4156 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4157 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4158 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4159
4160 // Using a testing task runner so that we can control time.
4161 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4162 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4163
4164 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4165 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
4166
Ryan Hamiltonabad59e2019-06-06 04:02:594167 MockQuicData quic_data1(version_);
Zhongyi Shiaba4a832018-04-30 20:29:084168 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
Ryan Hamilton0d65a8c2019-06-07 00:46:024169 quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Fan Yang32c5a112018-12-10 20:06:334170 quic_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:024171 SYNCHRONOUS,
4172 ConstructGetRequestPacket(
4173 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shiaba4a832018-04-30 20:29:084174 quic_data1.AddSocketDataToFactory(socket_factory_.get());
4175
4176 // Set up the second socket data provider that is used after migration.
4177 // The response to the earlier request is read on the new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:594178 MockQuicData quic_data2(version_);
Zhongyi Shiaba4a832018-04-30 20:29:084179 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:254180 quic_data2.AddWrite(SYNCHRONOUS,
4181 client_maker_.MakeConnectivityProbingPacket(3, true));
Zhongyi Shiaba4a832018-04-30 20:29:084182 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
4183 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:254184 quic_data2.AddRead(ASYNC,
4185 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shiaba4a832018-04-30 20:29:084186 // Ping packet to send after migration is completed.
4187 quic_data2.AddWrite(ASYNC,
4188 client_maker_.MakeAckAndPingPacket(4, false, 1, 1, 1));
4189 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:334190 ASYNC,
4191 ConstructOkResponsePacket(
4192 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shiaba4a832018-04-30 20:29:084193 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:334194 quic_data2.AddWrite(
4195 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
4196 5, false, GetNthClientInitiatedBidirectionalStreamId(0),
4197 quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true));
Zhongyi Shiaba4a832018-04-30 20:29:084198 quic_data2.AddSocketDataToFactory(socket_factory_.get());
4199
4200 // Create request and QuicHttpStream.
4201 QuicStreamRequest request(factory_.get());
4202 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034203 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:524204 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
4205 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:034206 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4207 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shiaba4a832018-04-30 20:29:084208 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4209 std::unique_ptr<HttpStream> stream = CreateStream(&request);
4210 EXPECT_TRUE(stream.get());
4211
4212 // Cause QUIC stream to be created.
4213 HttpRequestInfo request_info;
4214 request_info.method = "GET";
4215 request_info.url = url_;
4216 request_info.traffic_annotation =
4217 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4218 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
4219 net_log_, CompletionOnceCallback()));
4220
4221 // Ensure that session is alive and active.
4222 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
4223 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4224 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4225
4226 // Send GET request on stream.
4227 HttpResponseInfo response;
4228 HttpRequestHeaders request_headers;
4229 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
4230 callback_.callback()));
4231
4232 // Cause the connection to report path degrading to the session.
4233 // Due to lack of alternate network, session will not mgirate connection.
4234 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4235 session->connection()->OnPathDegradingTimeout();
4236 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4237
4238 // Deliver a signal that a alternate network is connected now, this should
4239 // cause the connection to start early migration on path degrading.
4240 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4241 ->SetConnectedNetworksList(
4242 {kDefaultNetworkForTests, kNewNetworkForTests});
4243 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4244 ->NotifyNetworkConnected(kNewNetworkForTests);
Zhongyi Shic4823bd2018-04-27 00:49:194245
4246 // Next connectivity probe is scheduled to be sent in 2 *
4247 // kDefaultRTTMilliSecs.
4248 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4249 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
4250 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
4251 next_task_delay);
4252
4253 // The connection should still be alive, and not marked as going away.
4254 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4255 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4256 EXPECT_EQ(1u, session->GetNumActiveStreams());
4257 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
4258
4259 // Resume quic data and a connectivity probe response will be read on the new
4260 // socket.
4261 quic_data2.Resume();
4262
4263 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4264 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4265 EXPECT_EQ(1u, session->GetNumActiveStreams());
4266
4267 // There should be three pending tasks, the nearest one will complete
4268 // migration to the new network.
4269 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
4270 next_task_delay = task_runner->NextPendingTaskDelay();
4271 EXPECT_EQ(base::TimeDelta(), next_task_delay);
4272 task_runner->FastForwardBy(next_task_delay);
4273
4274 // Response headers are received over the new network.
4275 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4276 EXPECT_EQ(200, response.headers->response_code());
4277
4278 // Now there are two pending tasks, the nearest one was to send connectivity
4279 // probe and has been cancelled due to successful migration.
4280 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
4281 next_task_delay = task_runner->NextPendingTaskDelay();
4282 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
4283 next_task_delay);
4284 task_runner->FastForwardBy(next_task_delay);
4285
4286 // There's one more task to mgirate back to the default network in 0.4s.
4287 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4288 next_task_delay = task_runner->NextPendingTaskDelay();
4289 base::TimeDelta expected_delay =
4290 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
4291 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
4292 EXPECT_EQ(expected_delay, next_task_delay);
4293
4294 // Deliver a signal that the alternate network now becomes default to session,
4295 // this will cancel mgirate back to default network timer.
4296 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4297 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
4298
4299 task_runner->FastForwardBy(next_task_delay);
4300 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4301
4302 // Verify that the session is still alive.
4303 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4304 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4305
4306 stream.reset();
4307 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
4308 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
4309 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
4310 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
4311}
4312
Zhongyi Shi28f6e352018-06-20 21:15:434313// This test verifies that multiple sessions are migrated on connection
4314// migration signal.
jrie3d187c2016-09-16 14:29:174315TEST_P(QuicStreamFactoryTest,
Zhongyi Shi28f6e352018-06-20 21:15:434316 MigrateMultipleSessionsToBadSocketsAfterDisconnected) {
4317 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jrie3d187c2016-09-16 14:29:174318
Ryan Hamiltonabad59e2019-06-06 04:02:594319 MockQuicData socket_data1(version_);
jrie3d187c2016-09-16 14:29:174320 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434321 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jrie3d187c2016-09-16 14:29:174322 socket_data1.AddWrite(ASYNC, OK);
Zhongyi Shi5f587cc2017-11-21 23:24:174323 socket_data1.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamilton0d65a8c2019-06-07 00:46:024324 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:594325 MockQuicData socket_data2(version_);
jrie3d187c2016-09-16 14:29:174326 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434327 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jrie3d187c2016-09-16 14:29:174328 socket_data2.AddWrite(ASYNC, OK);
Zhongyi Shi5f587cc2017-11-21 23:24:174329 socket_data2.AddSocketDataToFactory(socket_factory_.get());
jrie3d187c2016-09-16 14:29:174330
4331 HostPortPair server1(kDefaultServerHostName, 443);
4332 HostPortPair server2(kServer2HostName, 443);
4333
4334 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4335 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4336 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4337
Renjiea0cb4a2c2018-09-26 23:37:304338 host_resolver_->set_synchronous_mode(true);
4339 host_resolver_->rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
4340 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.2", "");
jrie3d187c2016-09-16 14:29:174341
4342 // Create request and QuicHttpStream to create session1.
zhongyi98d6a9262017-05-19 02:47:454343 QuicStreamRequest request1(factory_.get());
Matt Menke26e41542019-06-05 01:09:514344 EXPECT_EQ(OK,
4345 request1.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:524346 server1, version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
4347 NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:514348 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4349 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:244350 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
jrie3d187c2016-09-16 14:29:174351 EXPECT_TRUE(stream1.get());
4352
4353 // Create request and QuicHttpStream to create session2.
zhongyi98d6a9262017-05-19 02:47:454354 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:514355 EXPECT_EQ(OK,
4356 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:524357 server2, version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
4358 NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:514359 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
4360 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:244361 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
jrie3d187c2016-09-16 14:29:174362 EXPECT_TRUE(stream2.get());
4363
4364 QuicChromiumClientSession* session1 = GetActiveSession(server1);
4365 QuicChromiumClientSession* session2 = GetActiveSession(server2);
4366 EXPECT_NE(session1, session2);
4367
4368 // Cause QUIC stream to be created and send GET so session1 has an open
4369 // stream.
4370 HttpRequestInfo request_info1;
4371 request_info1.method = "GET";
4372 request_info1.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:394373 request_info1.traffic_annotation =
4374 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274375 EXPECT_EQ(OK,
4376 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394377 net_log_, CompletionOnceCallback()));
jrie3d187c2016-09-16 14:29:174378 HttpResponseInfo response1;
4379 HttpRequestHeaders request_headers1;
4380 EXPECT_EQ(OK, stream1->SendRequest(request_headers1, &response1,
4381 callback_.callback()));
4382
4383 // Cause QUIC stream to be created and send GET so session2 has an open
4384 // stream.
4385 HttpRequestInfo request_info2;
4386 request_info2.method = "GET";
4387 request_info2.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:394388 request_info2.traffic_annotation =
4389 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274390 EXPECT_EQ(OK,
4391 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394392 net_log_, CompletionOnceCallback()));
jrie3d187c2016-09-16 14:29:174393 HttpResponseInfo response2;
4394 HttpRequestHeaders request_headers2;
4395 EXPECT_EQ(OK, stream2->SendRequest(request_headers2, &response2,
4396 callback_.callback()));
4397
4398 // Cause both sessions to be paused due to DISCONNECTED.
4399 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4400 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
4401
4402 // Ensure that both sessions are paused but alive.
4403 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session1));
4404 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
4405
Zhongyi Shi28f6e352018-06-20 21:15:434406 // Add new sockets to use post migration. Those are bad sockets and will cause
4407 // migration to fail.
jrie3d187c2016-09-16 14:29:174408 MockConnect connect_result =
4409 MockConnect(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
Ryan Sleevib8d7ea02018-05-07 20:01:014410 SequencedSocketData socket_data3(connect_result, base::span<MockRead>(),
4411 base::span<MockWrite>());
Zhongyi Shi5f587cc2017-11-21 23:24:174412 socket_factory_->AddSocketDataProvider(&socket_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:014413 SequencedSocketData socket_data4(connect_result, base::span<MockRead>(),
4414 base::span<MockWrite>());
Zhongyi Shi5f587cc2017-11-21 23:24:174415 socket_factory_->AddSocketDataProvider(&socket_data4);
jrie3d187c2016-09-16 14:29:174416
Zhongyi Shi28f6e352018-06-20 21:15:434417 // Connect the new network and cause migration to bad sockets, causing
4418 // sessions to close.
jrie3d187c2016-09-16 14:29:174419 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4420 ->SetConnectedNetworksList({kNewNetworkForTests});
4421 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4422 ->NotifyNetworkConnected(kNewNetworkForTests);
4423
4424 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session1));
4425 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
4426
4427 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
4428 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
4429 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
4430 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
4431}
4432
Zhongyi Shi6ec9b36e2018-06-20 20:32:544433// This test verifies that session attempts connection migration with signals
4434// delivered in the following order (no alternate network is available):
4435// - path degrading is detected: session attempts connection migration but no
4436// alternate network is available, session caches path degrading signal in
4437// connection and stays on the original network.
4438// - original network backs up, request is served in the orignal network,
4439// session is not marked as going away.
4440TEST_P(QuicStreamFactoryTest, MigrateOnPathDegradingWithNoNewNetwork) {
4441 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jrid36ada62016-02-06 02:42:084442 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4443 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4444
Ryan Hamiltonabad59e2019-06-06 04:02:594445 MockQuicData quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:024446 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
4447 quic_data.AddWrite(
4448 SYNCHRONOUS,
4449 ConstructGetRequestPacket(
4450 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi6ec9b36e2018-06-20 20:32:544451 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause for path degrading signal.
4452
4453 // The rest of the data will still flow in the original socket as there is no
4454 // new network after path degrading.
Fan Yang32c5a112018-12-10 20:06:334455 quic_data.AddRead(ASYNC, ConstructOkResponsePacket(
4456 1, GetNthClientInitiatedBidirectionalStreamId(0),
4457 false, false));
Zhongyi Shi6ec9b36e2018-06-20 20:32:544458 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:334459 quic_data.AddWrite(
4460 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
4461 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
4462 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi6ec9b36e2018-06-20 20:32:544463 quic_data.AddSocketDataToFactory(socket_factory_.get());
jrid36ada62016-02-06 02:42:084464
4465 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:454466 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:334467 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034468 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:524469 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
4470 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:034471 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4472 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:014473 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:244474 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jrid36ada62016-02-06 02:42:084475 EXPECT_TRUE(stream.get());
4476
4477 // Cause QUIC stream to be created.
4478 HttpRequestInfo request_info;
Zhongyi Shi6ec9b36e2018-06-20 20:32:544479 request_info.method = "GET";
4480 request_info.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:394481 request_info.traffic_annotation =
4482 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Zhongyi Shi6ec9b36e2018-06-20 20:32:544483 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394484 net_log_, CompletionOnceCallback()));
jrid36ada62016-02-06 02:42:084485
4486 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:504487 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jrid36ada62016-02-06 02:42:084488 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4489 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4490
Zhongyi Shi6ec9b36e2018-06-20 20:32:544491 // Send GET request on stream.
4492 HttpResponseInfo response;
4493 HttpRequestHeaders request_headers;
4494 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
4495 callback_.callback()));
jrid36ada62016-02-06 02:42:084496
Zhongyi Shi6ec9b36e2018-06-20 20:32:544497 // Trigger connection migration on path degrading. Since there are no networks
4498 // to migrate to, the session will remain on the original network, not marked
4499 // as going away.
4500 session->connection()->OnPathDegradingTimeout();
4501 EXPECT_TRUE(session->connection()->IsPathDegrading());
4502
4503 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4504 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4505 EXPECT_EQ(1u, session->GetNumActiveStreams());
4506 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
4507
4508 // Resume so that rest of the data will flow in the original socket.
4509 quic_data.Resume();
jrid36ada62016-02-06 02:42:084510
4511 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4512 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4513 EXPECT_EQ(1u, session->GetNumActiveStreams());
4514
4515 stream.reset();
Zhongyi Shi6ec9b36e2018-06-20 20:32:544516 EXPECT_TRUE(quic_data.AllReadDataConsumed());
4517 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
jrid36ada62016-02-06 02:42:084518}
4519
Zhongyi Shi21e99532018-07-17 22:23:074520// This test verifies that session with non-migratable stream will probe the
4521// alternate network on path degrading, and close the non-migratable streams
4522// when probe is successful.
Zhongyi Shi32fe14d42019-02-28 00:25:364523TEST_P(QuicStreamFactoryTest,
4524 MigrateSessionEarlyNonMigratableStream_DoNotMigrateIdleSessions) {
4525 TestMigrateSessionEarlyNonMigratableStream(false);
4526}
4527
4528TEST_P(QuicStreamFactoryTest,
4529 MigrateSessionEarlyNonMigratableStream_MigrateIdleSessions) {
4530 TestMigrateSessionEarlyNonMigratableStream(true);
4531}
4532
4533void QuicStreamFactoryTestBase::TestMigrateSessionEarlyNonMigratableStream(
4534 bool migrate_idle_sessions) {
Nick Harper72ade192019-07-17 03:30:424535 test_params_.quic_params.migrate_idle_sessions = migrate_idle_sessions;
Zhongyi Shi1a054612018-06-14 04:59:084536 InitializeConnectionMigrationV2Test(
jri231c2972016-03-08 19:50:114537 {kDefaultNetworkForTests, kNewNetworkForTests});
4538 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4539 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4540
Ryan Hamiltonabad59e2019-06-06 04:02:594541 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:364542 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434543 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi32fe14d42019-02-28 00:25:364544 if (!migrate_idle_sessions) {
4545 socket_data.AddWrite(
4546 SYNCHRONOUS,
4547 client_maker_.MakeRstAckAndConnectionClosePacket(
4548 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
4549 quic::QUIC_STREAM_CANCELLED,
4550 quic::QuicTime::Delta::FromMilliseconds(0), 1, 1, 1,
4551 quic::QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS,
4552 "net error"));
4553 }
Zhongyi Shi5f587cc2017-11-21 23:24:174554 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri231c2972016-03-08 19:50:114555
Zhongyi Shi21e99532018-07-17 22:23:074556 // Set up the second socket data provider that is used for probing.
Ryan Hamiltonabad59e2019-06-06 04:02:594557 MockQuicData quic_data1(version_);
Zhongyi Shi21e99532018-07-17 22:23:074558 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:254559 quic_data1.AddWrite(SYNCHRONOUS,
4560 client_maker_.MakeConnectivityProbingPacket(2, true));
Zhongyi Shi21e99532018-07-17 22:23:074561 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
4562 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:254563 quic_data1.AddRead(ASYNC,
4564 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shi32fe14d42019-02-28 00:25:364565 if (migrate_idle_sessions) {
4566 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
4567 // A RESET will be sent to the peer to cancel the non-migratable stream.
4568 quic_data1.AddWrite(
4569 SYNCHRONOUS,
4570 client_maker_.MakeRstPacket(
4571 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
4572 quic::QUIC_STREAM_CANCELLED));
4573 // Ping packet to send after migration is completed.
4574 quic_data1.AddWrite(SYNCHRONOUS,
4575 client_maker_.MakeAckAndPingPacket(4, false, 1, 1, 1));
4576 }
Zhongyi Shi21e99532018-07-17 22:23:074577 quic_data1.AddSocketDataToFactory(socket_factory_.get());
4578
jri231c2972016-03-08 19:50:114579 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:454580 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:334581 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034582 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:524583 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
4584 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:034585 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4586 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:014587 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:244588 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri231c2972016-03-08 19:50:114589 EXPECT_TRUE(stream.get());
4590
4591 // Cause QUIC stream to be created, but marked as non-migratable.
4592 HttpRequestInfo request_info;
Zhongyi Shibb28b1f2018-07-18 02:41:264593 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Ramin Halavati683bcaa92018-02-14 08:42:394594 request_info.traffic_annotation =
4595 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274596 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394597 net_log_, CompletionOnceCallback()));
jri231c2972016-03-08 19:50:114598
4599 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:504600 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri231c2972016-03-08 19:50:114601 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4602 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4603
4604 // Trigger connection migration. Since there is a non-migratable stream,
Zhongyi Shic16b4102019-02-12 00:37:404605 // this should cause session to migrate.
jri231c2972016-03-08 19:50:114606 session->OnPathDegrading();
4607
4608 // Run the message loop so that data queued in the new socket is read by the
4609 // packet reader.
4610 base::RunLoop().RunUntilIdle();
4611
jri231c2972016-03-08 19:50:114612 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4613 EXPECT_EQ(1u, session->GetNumActiveStreams());
4614
Zhongyi Shi21e99532018-07-17 22:23:074615 // Resume the data to read the connectivity probing response to declare probe
4616 // as successful. Non-migratable streams will be closed.
4617 quic_data1.Resume();
Zhongyi Shi32fe14d42019-02-28 00:25:364618 if (migrate_idle_sessions)
4619 base::RunLoop().RunUntilIdle();
Zhongyi Shic16b4102019-02-12 00:37:404620
Zhongyi Shi32fe14d42019-02-28 00:25:364621 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(host_port_pair_));
Zhongyi Shi21e99532018-07-17 22:23:074622 EXPECT_EQ(0u, session->GetNumActiveStreams());
jri231c2972016-03-08 19:50:114623
Zhongyi Shi21e99532018-07-17 22:23:074624 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
4625 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
jri231c2972016-03-08 19:50:114626 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4627 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4628}
4629
jri9c541572016-03-29 17:51:484630TEST_P(QuicStreamFactoryTest, MigrateSessionEarlyConnectionMigrationDisabled) {
Zhongyi Shi1a054612018-06-14 04:59:084631 InitializeConnectionMigrationV2Test(
jri9c541572016-03-29 17:51:484632 {kDefaultNetworkForTests, kNewNetworkForTests});
4633 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4634 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4635
Ryan Hamiltonabad59e2019-06-06 04:02:594636 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:364637 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434638 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
4639 socket_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334640 SYNCHRONOUS, client_maker_.MakeRstPacket(
4641 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
4642 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:174643 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9c541572016-03-29 17:51:484644
4645 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:454646 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:334647 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034648 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:524649 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
4650 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:034651 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4652 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:014653 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:244654 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9c541572016-03-29 17:51:484655 EXPECT_TRUE(stream.get());
4656
4657 // Cause QUIC stream to be created.
4658 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:394659 request_info.traffic_annotation =
4660 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274661 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394662 net_log_, CompletionOnceCallback()));
jri9c541572016-03-29 17:51:484663
4664 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:504665 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri9c541572016-03-29 17:51:484666 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4667 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4668
4669 // Set session config to have connection migration disabled.
Ryan Hamilton8d9ee76e2018-05-29 23:52:524670 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
4671 session->config());
jri9c541572016-03-29 17:51:484672 EXPECT_TRUE(session->config()->DisableConnectionMigration());
4673
4674 // Trigger connection migration. Since there is a non-migratable stream,
4675 // this should cause session to be continue without migrating.
4676 session->OnPathDegrading();
4677
4678 // Run the message loop so that data queued in the new socket is read by the
4679 // packet reader.
4680 base::RunLoop().RunUntilIdle();
4681
4682 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4683 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4684 EXPECT_EQ(1u, session->GetNumActiveStreams());
4685
4686 stream.reset();
4687
4688 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4689 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4690}
4691
Zhongyi Shi3c4c9e92018-07-02 23:16:234692// Regression test for http://crbug.com/791886.
4693// This test verifies that the old packet writer which encountered an
4694// asynchronous write error will be blocked during migration on write error. New
4695// packets would not be written until the one with write error is rewritten on
4696// the new network.
4697TEST_P(QuicStreamFactoryTest, MigrateSessionOnAysncWriteError) {
4698 InitializeConnectionMigrationV2Test(
4699 {kDefaultNetworkForTests, kNewNetworkForTests});
4700 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4701 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4702 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4703
4704 // Using a testing task runner so that we can control time.
4705 // base::RunLoop() controls mocked socket writes and reads.
4706 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4707 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4708
Ryan Hamiltonabad59e2019-06-06 04:02:594709 MockQuicData socket_data(version_);
Zhongyi Shi3c4c9e92018-07-02 23:16:234710 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:024711 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi3c4c9e92018-07-02 23:16:234712 socket_data.AddWrite(ASYNC, ERR_ADDRESS_UNREACHABLE);
4713 socket_data.AddSocketDataToFactory(socket_factory_.get());
4714
4715 // Set up second socket data provider that is used after
4716 // migration. The request is rewritten to this new socket, and the
4717 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:594718 MockQuicData socket_data1(version_);
Zhongyi Shi3c4c9e92018-07-02 23:16:234719 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:024720 SYNCHRONOUS,
4721 ConstructGetRequestPacket(
4722 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Ryan Hamilton9f2eac32019-06-27 03:15:544723 client_maker_.set_coalesce_http_frames(true);
Ryan Hamilton0d65a8c2019-06-07 00:46:024724 socket_data1.AddWrite(
4725 SYNCHRONOUS,
4726 ConstructGetRequestPacket(
4727 3, GetNthClientInitiatedBidirectionalStreamId(1),
4728 GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Fan Yang32c5a112018-12-10 20:06:334729 socket_data1.AddRead(
4730 ASYNC,
4731 ConstructOkResponsePacket(
4732 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
4733 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4734 socket_data1.AddWrite(
4735 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
4736 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
4737 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
4738 socket_data1.AddWrite(
4739 SYNCHRONOUS, client_maker_.MakeRstPacket(
4740 5, false, GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:414741 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:184742 /*include_stop_sending_if_v99=*/true));
Zhongyi Shi3c4c9e92018-07-02 23:16:234743
4744 socket_data1.AddSocketDataToFactory(socket_factory_.get());
4745
4746 // Create request #1 and QuicHttpStream.
4747 QuicStreamRequest request1(factory_.get());
4748 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034749 request1.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:524750 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
4751 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:034752 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4753 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi3c4c9e92018-07-02 23:16:234754 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4755 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
4756 EXPECT_TRUE(stream1.get());
4757
4758 HttpRequestInfo request_info1;
4759 request_info1.method = "GET";
4760 request_info1.url = GURL("https://www.example.org/");
4761 request_info1.traffic_annotation =
4762 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4763 EXPECT_EQ(OK,
4764 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
4765 net_log_, CompletionOnceCallback()));
4766
4767 // Request #2 returns synchronously because it pools to existing session.
4768 TestCompletionCallback callback2;
4769 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:514770 EXPECT_EQ(OK,
4771 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:524772 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
4773 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:514774 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4775 failed_on_default_network_callback_, callback2.callback()));
Zhongyi Shi3c4c9e92018-07-02 23:16:234776 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
4777 EXPECT_TRUE(stream2.get());
4778
4779 HttpRequestInfo request_info2;
4780 request_info2.method = "GET";
4781 request_info2.url = GURL("https://www.example.org/");
4782 request_info2.traffic_annotation =
4783 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4784 EXPECT_EQ(OK,
4785 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
4786 net_log_, CompletionOnceCallback()));
4787
4788 // Ensure that session is alive and active.
4789 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
4790 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4791 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4792 EXPECT_EQ(2u, session->GetNumActiveStreams());
4793
4794 // Send GET request on stream1. This should cause an async write error.
4795 HttpResponseInfo response;
4796 HttpRequestHeaders request_headers;
4797 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
4798 callback_.callback()));
4799 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4800
4801 // Run the message loop so that asynchronous write completes and a connection
4802 // migration on write error attempt is posted in QuicStreamFactory's task
4803 // runner.
4804 base::RunLoop().RunUntilIdle();
4805 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4806
4807 // Send GET request on stream. This will cause another write attempt before
4808 // migration on write error is exectued.
4809 HttpResponseInfo response2;
4810 HttpRequestHeaders request_headers2;
4811 EXPECT_EQ(OK, stream2->SendRequest(request_headers2, &response2,
4812 callback2.callback()));
4813
4814 // Run the task runner so that migration on write error is finally executed.
4815 task_runner->RunUntilIdle();
4816
Zhongyi Shia7dd46b2018-07-12 22:59:294817 // Verify the session is still alive and not marked as going away.
Zhongyi Shi3c4c9e92018-07-02 23:16:234818 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:294819 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi3c4c9e92018-07-02 23:16:234820 EXPECT_EQ(2u, session->GetNumActiveStreams());
Zhongyi Shia7dd46b2018-07-12 22:59:294821 // There should be one task posted to migrate back to the default network in
4822 // kMinRetryTimeForDefaultNetworkSecs.
4823 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4824 EXPECT_EQ(base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs),
4825 task_runner->NextPendingTaskDelay());
Zhongyi Shi3c4c9e92018-07-02 23:16:234826
4827 // Verify that response headers on the migrated socket were delivered to the
4828 // stream.
4829 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
4830 EXPECT_EQ(200, response.headers->response_code());
4831
4832 stream1.reset();
4833 stream2.reset();
4834
4835 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4836 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4837 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
4838 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
4839}
4840
Zhongyi Shia7dd46b2018-07-12 22:59:294841// Verify session is not marked as going away after connection migration on
4842// write error and migrate back to default network logic is applied to bring the
4843// migrated session back to the default network. Migration singals delivered
4844// in the following order (alternate network is always availabe):
4845// - session on the default network encountered a write error;
4846// - session successfully migrated to the non-default network;
4847// - session attempts to migrate back to default network post migration;
4848// - migration back to the default network is successful.
4849TEST_P(QuicStreamFactoryTest, MigrateBackToDefaultPostMigrationOnWriteError) {
4850 InitializeConnectionMigrationV2Test(
4851 {kDefaultNetworkForTests, kNewNetworkForTests});
4852 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4853 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4854 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4855
4856 // Using a testing task runner so that we can control time.
4857 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4858 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4859
Ryan Hamiltonabad59e2019-06-06 04:02:594860 MockQuicData socket_data(version_);
Zhongyi Shia7dd46b2018-07-12 22:59:294861 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:024862 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shia7dd46b2018-07-12 22:59:294863 socket_data.AddWrite(ASYNC, ERR_ADDRESS_UNREACHABLE);
4864 socket_data.AddSocketDataToFactory(socket_factory_.get());
4865
4866 // Set up second socket data provider that is used after
4867 // migration. The request is rewritten to this new socket, and the
4868 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:594869 MockQuicData quic_data2(version_);
Fan Yang32c5a112018-12-10 20:06:334870 quic_data2.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:024871 SYNCHRONOUS,
4872 ConstructGetRequestPacket(
4873 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shia7dd46b2018-07-12 22:59:294874 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:334875 ASYNC,
4876 ConstructOkResponsePacket(
4877 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shia7dd46b2018-07-12 22:59:294878 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4879 quic_data2.AddSocketDataToFactory(socket_factory_.get());
4880
4881 // Create request QuicHttpStream.
4882 QuicStreamRequest request1(factory_.get());
4883 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034884 request1.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:524885 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
4886 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:034887 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4888 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shia7dd46b2018-07-12 22:59:294889 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4890 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
4891 EXPECT_TRUE(stream1.get());
4892
4893 HttpRequestInfo request_info1;
4894 request_info1.method = "GET";
4895 request_info1.url = GURL("https://www.example.org/");
4896 request_info1.traffic_annotation =
4897 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4898 EXPECT_EQ(OK,
4899 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
4900 net_log_, CompletionOnceCallback()));
4901
4902 // Ensure that session is alive and active.
4903 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
4904 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4905 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4906 EXPECT_EQ(1u, session->GetNumActiveStreams());
4907
4908 // Send GET request. This should cause an async write error.
4909 HttpResponseInfo response;
4910 HttpRequestHeaders request_headers;
4911 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
4912 callback_.callback()));
4913 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4914
4915 // Run the message loop so that asynchronous write completes and a connection
4916 // migration on write error attempt is posted in QuicStreamFactory's task
4917 // runner.
4918 base::RunLoop().RunUntilIdle();
4919 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4920
4921 // Run the task runner so that migration on write error is finally executed.
4922 task_runner->RunUntilIdle();
4923
4924 // Verify the session is still alive and not marked as going away.
4925 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4926 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4927 EXPECT_EQ(1u, session->GetNumActiveStreams());
4928 // There should be one task posted to migrate back to the default network in
4929 // kMinRetryTimeForDefaultNetworkSecs.
4930 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4931 base::TimeDelta expected_delay =
4932 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs);
4933 EXPECT_EQ(expected_delay, task_runner->NextPendingTaskDelay());
4934
4935 // Verify that response headers on the migrated socket were delivered to the
4936 // stream.
4937 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
4938 EXPECT_EQ(200, response.headers->response_code());
4939
4940 // Set up the third socket data provider for migrate back to default network.
Ryan Hamiltonabad59e2019-06-06 04:02:594941 MockQuicData quic_data3(version_);
Zhongyi Shia7dd46b2018-07-12 22:59:294942 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:254943 quic_data3.AddWrite(SYNCHRONOUS,
4944 client_maker_.MakeConnectivityProbingPacket(3, false));
Zhongyi Shia7dd46b2018-07-12 22:59:294945 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:254946 quic_data3.AddRead(ASYNC,
4947 server_maker_.MakeConnectivityProbingPacket(2, false));
Zhongyi Shia7dd46b2018-07-12 22:59:294948 quic_data3.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4949 quic_data3.AddWrite(ASYNC, client_maker_.MakeAckPacket(4, 1, 2, 1, 1, true));
4950 quic_data3.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334951 SYNCHRONOUS, client_maker_.MakeRstPacket(
4952 5, false, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:414953 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:184954 /*include_stop_sending_if_v99=*/true));
Zhongyi Shia7dd46b2018-07-12 22:59:294955 quic_data3.AddSocketDataToFactory(socket_factory_.get());
4956
4957 // Fast forward to fire the migrate back timer and verify the session
4958 // successfully migrates back to the default network.
4959 task_runner->FastForwardBy(expected_delay);
4960
4961 // Verify the session is still alive and not marked as going away.
4962 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4963 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4964 EXPECT_EQ(1u, session->GetNumActiveStreams());
4965
4966 // There should be one task posted to one will resend a connectivity probe and
4967 // the other will retry migrate back, both are cancelled.
4968 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
4969 task_runner->FastForwardBy(
4970 base::TimeDelta::FromSeconds(2 * kMinRetryTimeForDefaultNetworkSecs));
4971 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4972
4973 stream1.reset();
4974 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4975 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4976 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
4977 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
4978 EXPECT_TRUE(quic_data3.AllReadDataConsumed());
4979 EXPECT_TRUE(quic_data3.AllWriteDataConsumed());
4980}
4981
Zhongyi Shic1449372018-08-09 09:58:584982// This test verifies that the connection will not attempt connection migration
4983// (send connectivity probes on alternate path) when path degrading is detected
4984// and handshake is not confirmed.
4985TEST_P(QuicStreamFactoryTest,
4986 NoMigrationOnPathDegradingBeforeHandshakeConfirmed) {
4987 InitializeConnectionMigrationV2Test(
4988 {kDefaultNetworkForTests, kNewNetworkForTests});
4989
4990 // Using a testing task runner.
4991 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4992 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4993
4994 // Use cold start mode to send crypto message for handshake.
4995 crypto_client_stream_factory_.set_handshake_mode(
4996 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
4997
Ryan Hamiltonabad59e2019-06-06 04:02:594998 MockQuicData socket_data(version_);
Zhongyi Shic1449372018-08-09 09:58:584999 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5000 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
5001 socket_data.AddSocketDataToFactory(socket_factory_.get());
5002
5003 // Create request and QuicHttpStream.
5004 QuicStreamRequest request(factory_.get());
5005 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035006 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:525007 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
5008 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035009 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5010 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shic1449372018-08-09 09:58:585011
5012 base::RunLoop().RunUntilIdle();
5013
5014 // Ensure that session is alive but not active.
5015 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5016 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5017 QuicChromiumClientSession* session = GetPendingSession(host_port_pair_);
5018 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5019 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
5020
5021 // Cause the connection to report path degrading to the session.
5022 // Session will ignore the signal as handshake is not completed.
5023 session->connection()->OnPathDegradingTimeout();
5024 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
5025
5026 EXPECT_FALSE(HasActiveSession(host_port_pair_));
Zhongyi Shi8de43832018-08-15 23:40:005027 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
Zhongyi Shic1449372018-08-09 09:58:585028 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5029 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5030}
5031
Zhongyi Shi634c1882018-08-16 04:05:595032// This test verifies that if a connection is closed with
5033// QUIC_NETWORK_IDLE_TIMEOUT before handshake is completed and there is no
5034// alternate network, no new connection will be created.
5035TEST_P(QuicStreamFactoryTest, NoAlternateNetworkBeforeHandshakeOnIdleTimeout) {
5036 TestNoAlternateNetworkBeforeHandshake(quic::QUIC_NETWORK_IDLE_TIMEOUT);
5037}
5038
5039// This test verifies that if a connection is closed with QUIC_HANDSHAKE_TIMEOUT
5040// and there is no alternate network, no new connection will be created.
5041TEST_P(QuicStreamFactoryTest, NoAlternateNetworkOnHandshakeTimeout) {
5042 TestNoAlternateNetworkBeforeHandshake(quic::QUIC_HANDSHAKE_TIMEOUT);
5043}
5044
5045void QuicStreamFactoryTestBase::TestNoAlternateNetworkBeforeHandshake(
5046 quic::QuicErrorCode quic_error) {
5047 DCHECK(quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT ||
5048 quic_error == quic::QUIC_HANDSHAKE_TIMEOUT);
5049 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
5050
5051 // Using a testing task runner.
5052 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
5053 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
5054
5055 // Use cold start mode to send crypto message for handshake.
5056 crypto_client_stream_factory_.set_handshake_mode(
5057 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
5058
Ryan Hamiltonabad59e2019-06-06 04:02:595059 MockQuicData socket_data(version_);
Zhongyi Shi634c1882018-08-16 04:05:595060 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5061 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
5062 socket_data.AddSocketDataToFactory(socket_factory_.get());
5063
5064 // Create request.
5065 QuicStreamRequest request(factory_.get());
5066 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035067 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:525068 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
5069 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035070 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5071 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi634c1882018-08-16 04:05:595072
5073 base::RunLoop().RunUntilIdle();
5074
5075 // Ensure that session is alive but not active.
5076 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5077 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5078 QuicChromiumClientSession* session = GetPendingSession(host_port_pair_);
5079 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5080 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
5081
5082 // Cause the connection to report path degrading to the session.
5083 // Session will ignore the signal as handshake is not completed.
5084 session->connection()->OnPathDegradingTimeout();
5085 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
5086 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5087 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5088
5089 // Cause the connection to close due to |quic_error| before handshake.
Victor Vasiliev076657c2019-03-12 02:46:435090 std::string error_details;
Zhongyi Shi634c1882018-08-16 04:05:595091 if (quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT) {
5092 error_details = "No recent network activity.";
5093 } else {
5094 error_details = "Handshake timeout expired.";
5095 }
5096 session->connection()->CloseConnection(
5097 quic_error, error_details, quic::ConnectionCloseBehavior::SILENT_CLOSE);
5098
5099 // A task will be posted to clean up the session in the factory.
5100 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
5101 task_runner->FastForwardUntilNoTasksRemain();
5102
5103 // No new session should be created as there is no alternate network.
5104 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5105 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
5106 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5107 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5108}
5109
Zhongyi Shi8de43832018-08-15 23:40:005110TEST_P(QuicStreamFactoryTest, NewConnectionBeforeHandshakeAfterIdleTimeout) {
5111 TestNewConnectionOnAlternateNetworkBeforeHandshake(
5112 quic::QUIC_NETWORK_IDLE_TIMEOUT);
5113}
5114
5115TEST_P(QuicStreamFactoryTest, NewConnectionAfterHandshakeTimeout) {
5116 TestNewConnectionOnAlternateNetworkBeforeHandshake(
5117 quic::QUIC_HANDSHAKE_TIMEOUT);
5118}
5119
Zhongyi Shif3fcbbe62018-08-16 22:52:085120// Sets up a test to verify that a new connection will be created on the
5121// alternate network after the initial connection fails before handshake with
5122// signals delivered in the following order (alternate network is available):
5123// - the default network is not able to complete crypto handshake;
5124// - the original connection is closed with |quic_error|;
5125// - a new connection is created on the alternate network and is able to finish
5126// crypto handshake;
5127// - the new session on the alternate network attempts to migrate back to the
5128// default network by sending probes;
5129// - default network being disconnected is delivered: session will stop probing
5130// the original network.
5131// - alternate network is made by default.
Zhongyi Shi8de43832018-08-15 23:40:005132void QuicStreamFactoryTestBase::
5133 TestNewConnectionOnAlternateNetworkBeforeHandshake(
5134 quic::QuicErrorCode quic_error) {
5135 DCHECK(quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT ||
5136 quic_error == quic::QUIC_HANDSHAKE_TIMEOUT);
Nick Harper72ade192019-07-17 03:30:425137 test_params_.quic_params.retry_on_alternate_network_before_handshake = true;
Zhongyi Shi8de43832018-08-15 23:40:005138 InitializeConnectionMigrationV2Test(
5139 {kDefaultNetworkForTests, kNewNetworkForTests});
5140
5141 // Using a testing task runner.
5142 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
5143 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
5144
5145 // Use cold start mode to send crypto message for handshake.
5146 crypto_client_stream_factory_.set_handshake_mode(
5147 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
5148
5149 // Socket data for connection on the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:595150 MockQuicData socket_data(version_);
Zhongyi Shi8de43832018-08-15 23:40:005151 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5152 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
5153 socket_data.AddSocketDataToFactory(socket_factory_.get());
5154
5155 // Socket data for connection on the alternate network.
Ryan Hamiltonabad59e2019-06-06 04:02:595156 MockQuicData socket_data2(version_);
Zhongyi Shi8de43832018-08-15 23:40:005157 socket_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5158 socket_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
5159 // Change the encryption level after handshake is confirmed.
5160 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamilton0d65a8c2019-06-07 00:46:025161 socket_data2.AddWrite(ASYNC, ConstructInitialSettingsPacket(2));
Zhongyi Shi8de43832018-08-15 23:40:005162 socket_data2.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335163 ASYNC, ConstructGetRequestPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:025164 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi8de43832018-08-15 23:40:005165 socket_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:335166 ASYNC,
5167 ConstructOkResponsePacket(
5168 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shi8de43832018-08-15 23:40:005169 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:335170 socket_data2.AddWrite(
5171 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
5172 5, false, GetNthClientInitiatedBidirectionalStreamId(0),
5173 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi8de43832018-08-15 23:40:005174 socket_data2.AddSocketDataToFactory(socket_factory_.get());
5175
Zhongyi Shif3fcbbe62018-08-16 22:52:085176 // Socket data for probing on the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:595177 MockQuicData probing_data(version_);
Zhongyi Shif3fcbbe62018-08-16 22:52:085178 probing_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
5179 probing_data.AddWrite(SYNCHRONOUS,
5180 client_maker_.MakeConnectivityProbingPacket(4, false));
5181 probing_data.AddSocketDataToFactory(socket_factory_.get());
5182
Zhongyi Shi8de43832018-08-15 23:40:005183 // Create request and QuicHttpStream.
5184 QuicStreamRequest request(factory_.get());
5185 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035186 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:525187 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
5188 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035189 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5190 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi8de43832018-08-15 23:40:005191
5192 base::RunLoop().RunUntilIdle();
5193
5194 // Ensure that session is alive but not active.
5195 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5196 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5197 QuicChromiumClientSession* session = GetPendingSession(host_port_pair_);
5198 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5199 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
Zhongyi Shia6b68d112018-09-24 07:49:035200 EXPECT_FALSE(failed_on_default_network_);
Zhongyi Shi8de43832018-08-15 23:40:005201
Victor Vasiliev076657c2019-03-12 02:46:435202 std::string error_details;
Zhongyi Shi8de43832018-08-15 23:40:005203 if (quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT) {
5204 error_details = "No recent network activity.";
5205 } else {
5206 error_details = "Handshake timeout expired.";
5207 }
5208 session->connection()->CloseConnection(
5209 quic_error, error_details, quic::ConnectionCloseBehavior::SILENT_CLOSE);
5210
5211 // A task will be posted to clean up the session in the factory.
5212 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
5213 task_runner->FastForwardUntilNoTasksRemain();
5214
5215 // Verify a new session is created on the alternate network.
5216 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5217 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5218 QuicChromiumClientSession* session2 = GetPendingSession(host_port_pair_);
5219 EXPECT_NE(session, session2);
Zhongyi Shia6b68d112018-09-24 07:49:035220 EXPECT_TRUE(failed_on_default_network_);
Zhongyi Shi8de43832018-08-15 23:40:005221
5222 // Confirm the handshake on the alternate network.
5223 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5224 quic::QuicSession::HANDSHAKE_CONFIRMED);
5225 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5226 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5227 // Resume the data now so that data can be sent and read.
5228 socket_data2.Resume();
5229
5230 // Create the stream.
5231 std::unique_ptr<HttpStream> stream = CreateStream(&request);
5232 EXPECT_TRUE(stream.get());
5233 HttpRequestInfo request_info;
5234 request_info.method = "GET";
5235 request_info.url = GURL("https://www.example.org/");
5236 request_info.traffic_annotation =
5237 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5238 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
5239 net_log_, CompletionOnceCallback()));
5240 // Send the request.
5241 HttpResponseInfo response;
5242 HttpRequestHeaders request_headers;
5243 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5244 callback_.callback()));
5245 // Run the message loop to finish asynchronous mock write.
5246 base::RunLoop().RunUntilIdle();
5247 // Read the response.
5248 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
5249 EXPECT_EQ(200, response.headers->response_code());
5250
Zhongyi Shif3fcbbe62018-08-16 22:52:085251 // There should be a new task posted to migrate back to the default network.
5252 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
5253 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
5254 EXPECT_EQ(base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs),
5255 next_task_delay);
5256 task_runner->FastForwardBy(next_task_delay);
5257
5258 // There should be two tasks posted. One will retry probing and the other
5259 // will retry migrate back.
5260 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
5261 next_task_delay = task_runner->NextPendingTaskDelay();
5262 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
5263 next_task_delay);
5264
5265 // Deliver the signal that the default network is disconnected.
5266 scoped_mock_network_change_notifier_->mock_network_change_notifier()
5267 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
5268 // Verify no connectivity probes will be sent as probing will be cancelled.
5269 task_runner->FastForwardUntilNoTasksRemain();
5270 // Deliver the signal that the alternate network is made default.
5271 scoped_mock_network_change_notifier_->mock_network_change_notifier()
5272 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
5273 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
5274
Zhongyi Shi8de43832018-08-15 23:40:005275 stream.reset();
5276 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5277 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5278 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
5279 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
5280}
5281
Zhongyi Shi247d6322018-07-24 07:03:355282// Test that connection will be closed with PACKET_WRITE_ERROR if a write error
5283// is triggered before handshake is confirmed and connection migration is turned
5284// on.
5285TEST_P(QuicStreamFactoryTest, MigrationOnWriteErrorBeforeHandshakeConfirmed) {
Nick Harper72ade192019-07-17 03:30:425286 DCHECK(!test_params_.quic_params.retry_on_alternate_network_before_handshake);
Zhongyi Shi247d6322018-07-24 07:03:355287 InitializeConnectionMigrationV2Test(
5288 {kDefaultNetworkForTests, kNewNetworkForTests});
5289
5290 // Use unmocked crypto stream to do crypto connect.
5291 crypto_client_stream_factory_.set_handshake_mode(
Zhongyi Shi879659422018-08-02 17:58:255292 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
Zhongyi Shi247d6322018-07-24 07:03:355293
Ryan Hamiltonabad59e2019-06-06 04:02:595294 MockQuicData socket_data(version_);
Zhongyi Shi247d6322018-07-24 07:03:355295 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5296 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
5297 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
5298 socket_data.AddSocketDataToFactory(socket_factory_.get());
5299
5300 // Create request, should fail after the write of the CHLO fails.
5301 QuicStreamRequest request(factory_.get());
5302 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035303 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:525304 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
5305 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035306 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5307 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi247d6322018-07-24 07:03:355308 EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED, callback_.WaitForResult());
5309 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5310 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
5311
5312 // Verify new requests can be sent normally.
5313 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:275314 MockCryptoClientStream::COLD_START);
Zhongyi Shi247d6322018-07-24 07:03:355315 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5316 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
Ryan Hamilton0d65a8c2019-06-07 00:46:025317 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:595318 MockQuicData socket_data2(version_);
Zhongyi Shi247d6322018-07-24 07:03:355319 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5320 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
5321 socket_data2.AddSocketDataToFactory(socket_factory_.get());
5322
5323 QuicStreamRequest request2(factory_.get());
5324 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035325 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:525326 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
5327 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035328 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5329 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi247d6322018-07-24 07:03:355330 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5331 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5332 // Run the message loop to complete host resolution.
5333 base::RunLoop().RunUntilIdle();
5334
5335 // Complete handshake. QuicStreamFactory::Job should complete and succeed.
5336 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5337 quic::QuicSession::HANDSHAKE_CONFIRMED);
5338 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5339 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5340 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
5341
5342 // Create QuicHttpStream.
5343 std::unique_ptr<HttpStream> stream = CreateStream(&request2);
5344 EXPECT_TRUE(stream.get());
5345 stream.reset();
5346 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5347 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5348 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
5349 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
5350}
5351
Zhongyi Shif2524bf2019-01-27 07:44:035352// Test that if the original connection is closed with QUIC_PACKET_WRITE_ERROR
5353// before handshake is confirmed and new connection before handshake is turned
5354// on, a new connection will be retried on the alternate network.
5355TEST_P(QuicStreamFactoryTest,
5356 RetryConnectionOnWriteErrorBeforeHandshakeConfirmed) {
Nick Harper72ade192019-07-17 03:30:425357 test_params_.quic_params.retry_on_alternate_network_before_handshake = true;
Zhongyi Shif2524bf2019-01-27 07:44:035358 InitializeConnectionMigrationV2Test(
5359 {kDefaultNetworkForTests, kNewNetworkForTests});
5360
5361 // Use unmocked crypto stream to do crypto connect.
5362 crypto_client_stream_factory_.set_handshake_mode(
5363 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
5364
5365 // Socket data for connection on the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:595366 MockQuicData socket_data(version_);
Zhongyi Shif2524bf2019-01-27 07:44:035367 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5368 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
5369 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
5370 socket_data.AddSocketDataToFactory(socket_factory_.get());
5371
5372 // Socket data for connection on the alternate network.
Ryan Hamiltonabad59e2019-06-06 04:02:595373 MockQuicData socket_data2(version_);
Zhongyi Shif2524bf2019-01-27 07:44:035374 socket_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5375 socket_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
5376 // Change the encryption level after handshake is confirmed.
5377 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamilton0d65a8c2019-06-07 00:46:025378 socket_data2.AddWrite(ASYNC, ConstructInitialSettingsPacket(2));
Zhongyi Shif2524bf2019-01-27 07:44:035379 socket_data2.AddWrite(
5380 ASYNC, ConstructGetRequestPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:025381 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shif2524bf2019-01-27 07:44:035382 socket_data2.AddRead(
5383 ASYNC,
5384 ConstructOkResponsePacket(
5385 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
5386 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5387 socket_data2.AddWrite(
5388 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
5389 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
5390 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
5391 socket_data2.AddSocketDataToFactory(socket_factory_.get());
5392
5393 // Create request, should fail after the write of the CHLO fails.
5394 QuicStreamRequest request(factory_.get());
5395 EXPECT_EQ(ERR_IO_PENDING,
5396 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:525397 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
5398 SocketTag(), NetworkIsolationKey(),
Zhongyi Shif2524bf2019-01-27 07:44:035399 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5400 failed_on_default_network_callback_, callback_.callback()));
5401 // Ensure that the session is alive but not active.
5402 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5403 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5404 base::RunLoop().RunUntilIdle();
5405 QuicChromiumClientSession* session = GetPendingSession(host_port_pair_);
5406 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5407
5408 // Confirm the handshake on the alternate network.
5409 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5410 quic::QuicSession::HANDSHAKE_CONFIRMED);
5411 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5412 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5413
5414 // Resume the data now so that data can be sent and read.
5415 socket_data2.Resume();
5416
5417 // Create the stream.
5418 std::unique_ptr<HttpStream> stream = CreateStream(&request);
5419 EXPECT_TRUE(stream.get());
5420 HttpRequestInfo request_info;
5421 request_info.method = "GET";
5422 request_info.url = GURL("https://www.example.org/");
5423 request_info.traffic_annotation =
5424 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5425 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
5426 net_log_, CompletionOnceCallback()));
5427 // Send the request.
5428 HttpResponseInfo response;
5429 HttpRequestHeaders request_headers;
5430 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5431 callback_.callback()));
5432 // Run the message loop to finish asynchronous mock write.
5433 base::RunLoop().RunUntilIdle();
5434 // Read the response.
5435 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
5436 EXPECT_EQ(200, response.headers->response_code());
5437
5438 stream.reset();
5439 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5440 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5441 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
5442 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
5443}
5444
jri9f303712016-09-13 01:10:225445void QuicStreamFactoryTestBase::TestMigrationOnWriteError(
5446 IoMode write_error_mode) {
Zhongyi Shi1a054612018-06-14 04:59:085447 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:225448 {kDefaultNetworkForTests, kNewNetworkForTests});
5449 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5450 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5451 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5452
Zhongyi Shi3c4c9e92018-07-02 23:16:235453 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
5454
Ryan Hamiltonabad59e2019-06-06 04:02:595455 MockQuicData socket_data(version_);
jri9f303712016-09-13 01:10:225456 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:025457 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jri9f303712016-09-13 01:10:225458 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:175459 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:225460
5461 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:455462 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:335463 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035464 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:525465 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
5466 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035467 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5468 failed_on_default_network_callback_, callback_.callback()));
jri9f303712016-09-13 01:10:225469 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:245470 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:225471 EXPECT_TRUE(stream.get());
5472
5473 // Cause QUIC stream to be created.
5474 HttpRequestInfo request_info;
5475 request_info.method = "GET";
5476 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:395477 request_info.traffic_annotation =
5478 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:275479 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:395480 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:225481
5482 // Ensure that session is alive and active.
5483 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5484 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5485 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5486
5487 // Set up second socket data provider that is used after
5488 // migration. The request is rewritten to this new socket, and the
5489 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:595490 MockQuicData socket_data1(version_);
Fan Yang32c5a112018-12-10 20:06:335491 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:025492 SYNCHRONOUS,
5493 ConstructGetRequestPacket(
5494 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi32f2fd02018-04-16 18:23:435495 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:335496 ASYNC,
5497 ConstructOkResponsePacket(
5498 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
jri9f303712016-09-13 01:10:225499 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:335500 socket_data1.AddWrite(
5501 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
5502 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
5503 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:175504 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:225505
5506 // Send GET request on stream. This should cause a write error, which triggers
5507 // a connection migration attempt.
5508 HttpResponseInfo response;
5509 HttpRequestHeaders request_headers;
5510 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5511 callback_.callback()));
5512
5513 // Run the message loop so that the migration attempt is executed and
5514 // data queued in the new socket is read by the packet reader.
5515 base::RunLoop().RunUntilIdle();
5516
Zhongyi Shia7dd46b2018-07-12 22:59:295517 // Verify that session is alive and not marked as going awya.
jri9f303712016-09-13 01:10:225518 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:295519 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri9f303712016-09-13 01:10:225520 EXPECT_EQ(1u, session->GetNumActiveStreams());
5521
5522 // Verify that response headers on the migrated socket were delivered to the
5523 // stream.
5524 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
5525 EXPECT_EQ(200, response.headers->response_code());
5526
5527 stream.reset();
5528
5529 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5530 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5531 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
5532 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
5533}
5534
5535TEST_P(QuicStreamFactoryTest, MigrateSessionOnWriteErrorSynchronous) {
5536 TestMigrationOnWriteError(SYNCHRONOUS);
5537}
5538
5539TEST_P(QuicStreamFactoryTest, MigrateSessionOnWriteErrorAsync) {
5540 TestMigrationOnWriteError(ASYNC);
5541}
5542
5543void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorNoNewNetwork(
5544 IoMode write_error_mode) {
Zhongyi Shi1a054612018-06-14 04:59:085545 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri9f303712016-09-13 01:10:225546 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5547 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5548
jri5b785512016-09-13 04:29:115549 // Use the test task runner, to force the migration alarm timeout later.
5550 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
5551
Ryan Hamiltonabad59e2019-06-06 04:02:595552 MockQuicData socket_data(version_);
jri9f303712016-09-13 01:10:225553 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:435554 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jri9f303712016-09-13 01:10:225555 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:175556 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:225557
5558 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:455559 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:335560 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035561 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:525562 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
5563 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035564 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5565 failed_on_default_network_callback_, callback_.callback()));
jri9f303712016-09-13 01:10:225566 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:245567 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:225568 EXPECT_TRUE(stream.get());
5569
5570 // Cause QUIC stream to be created.
5571 HttpRequestInfo request_info;
5572 request_info.method = "GET";
5573 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:395574 request_info.traffic_annotation =
5575 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:275576 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:395577 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:225578
5579 // Ensure that session is alive and active.
5580 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5581 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5582 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5583
jri5b785512016-09-13 04:29:115584 // Send GET request on stream. This causes a write error, which triggers
5585 // a connection migration attempt. Since there are no networks
5586 // to migrate to, this causes the session to wait for a new network.
jri9f303712016-09-13 01:10:225587 HttpResponseInfo response;
5588 HttpRequestHeaders request_headers;
5589 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5590 callback_.callback()));
jri5b785512016-09-13 04:29:115591
5592 // Complete any pending writes. Pending async MockQuicData writes
5593 // are run on the message loop, not on the test runner.
jri9f303712016-09-13 01:10:225594 base::RunLoop().RunUntilIdle();
jri5b785512016-09-13 04:29:115595
5596 // Write error causes migration task to be posted. Spin the loop.
5597 if (write_error_mode == ASYNC)
5598 runner_->RunNextTask();
5599
5600 // Migration has not yet failed. The session should be alive and active.
5601 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5602 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5603 EXPECT_EQ(1u, session->GetNumActiveStreams());
5604 EXPECT_TRUE(session->connection()->writer()->IsWriteBlocked());
5605
5606 // The migration will not fail until the migration alarm timeout.
5607 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5608 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5609 EXPECT_EQ(1u, session->GetNumActiveStreams());
5610 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
5611
5612 // Force migration alarm timeout to run.
5613 RunTestLoopUntilIdle();
5614
5615 // The connection should be closed. A request for response headers
5616 // should fail.
jri9f303712016-09-13 01:10:225617 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5618 EXPECT_FALSE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:115619 EXPECT_EQ(ERR_NETWORK_CHANGED, callback_.WaitForResult());
5620 EXPECT_EQ(ERR_NETWORK_CHANGED,
5621 stream->ReadResponseHeaders(callback_.callback()));
jri9f303712016-09-13 01:10:225622
Zhongyi Shi59aaf072019-01-17 03:32:135623 NetErrorDetails error_details;
5624 stream->PopulateNetErrorDetails(&error_details);
5625 EXPECT_EQ(error_details.quic_connection_error,
5626 quic::QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK);
5627
jri9f303712016-09-13 01:10:225628 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5629 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5630}
5631
5632TEST_P(QuicStreamFactoryTest,
5633 MigrateSessionOnWriteErrorNoNewNetworkSynchronous) {
5634 TestMigrationOnWriteErrorNoNewNetwork(SYNCHRONOUS);
5635}
5636
5637TEST_P(QuicStreamFactoryTest, MigrateSessionOnWriteErrorNoNewNetworkAsync) {
5638 TestMigrationOnWriteErrorNoNewNetwork(ASYNC);
5639}
5640
Zhongyi Shi0439ecc72018-07-11 04:41:265641TEST_P(QuicStreamFactoryTest,
5642 MigrateSessionOnWriteErrorWithMultipleRequestsSync) {
5643 TestMigrationOnWriteErrorWithMultipleRequests(SYNCHRONOUS);
5644}
5645
5646TEST_P(QuicStreamFactoryTest,
5647 MigrateSessionOnWriteErrorWithMultipleRequestsAsync) {
5648 TestMigrationOnWriteErrorWithMultipleRequests(ASYNC);
5649}
5650
5651// Sets up a test which verifies that connection migration on write error can
5652// eventually succeed and rewrite the packet on the new network with *multiple*
5653// migratable streams.
5654void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorWithMultipleRequests(
5655 IoMode write_error_mode) {
5656 InitializeConnectionMigrationV2Test(
5657 {kDefaultNetworkForTests, kNewNetworkForTests});
5658 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5659 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5660 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5661
Ryan Hamiltonabad59e2019-06-06 04:02:595662 MockQuicData socket_data(version_);
Zhongyi Shi0439ecc72018-07-11 04:41:265663 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:025664 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi0439ecc72018-07-11 04:41:265665 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
5666 socket_data.AddSocketDataToFactory(socket_factory_.get());
5667
5668 // Set up second socket data provider that is used after
5669 // migration. The request is rewritten to this new socket, and the
5670 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:595671 MockQuicData socket_data1(version_);
Zhongyi Shi0439ecc72018-07-11 04:41:265672 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:025673 SYNCHRONOUS,
5674 ConstructGetRequestPacket(
5675 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Fan Yang32c5a112018-12-10 20:06:335676 socket_data1.AddRead(
5677 ASYNC,
5678 ConstructOkResponsePacket(
5679 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
5680 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5681 socket_data1.AddWrite(
5682 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
5683 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
5684 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
5685 socket_data1.AddWrite(
5686 SYNCHRONOUS, client_maker_.MakeRstPacket(
5687 4, false, GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:415688 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:185689 /*include_stop_sending_if_v99=*/true));
Zhongyi Shi0439ecc72018-07-11 04:41:265690
5691 socket_data1.AddSocketDataToFactory(socket_factory_.get());
5692
5693 // Create request #1 and QuicHttpStream.
5694 QuicStreamRequest request1(factory_.get());
5695 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035696 request1.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:525697 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
5698 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035699 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5700 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi0439ecc72018-07-11 04:41:265701 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5702 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
5703 EXPECT_TRUE(stream1.get());
5704
5705 HttpRequestInfo request_info1;
5706 request_info1.method = "GET";
5707 request_info1.url = GURL("https://www.example.org/");
5708 request_info1.traffic_annotation =
5709 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5710 EXPECT_EQ(OK,
5711 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
5712 net_log_, CompletionOnceCallback()));
5713
5714 // Second request returns synchronously because it pools to existing session.
5715 TestCompletionCallback callback2;
5716 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:515717 EXPECT_EQ(OK,
5718 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:525719 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
5720 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:515721 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5722 failed_on_default_network_callback_, callback2.callback()));
Zhongyi Shi0439ecc72018-07-11 04:41:265723 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
5724 EXPECT_TRUE(stream2.get());
5725 HttpRequestInfo request_info2;
5726 request_info2.method = "GET";
5727 request_info2.url = GURL("https://www.example.org/");
5728 request_info2.traffic_annotation =
5729 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5730 EXPECT_EQ(OK,
5731 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
5732 net_log_, CompletionOnceCallback()));
5733
5734 // Ensure that session is alive and active.
5735 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5736 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5737 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5738 EXPECT_EQ(2u, session->GetNumActiveStreams());
5739
5740 // Send GET request on stream. This should cause a write error, which triggers
5741 // a connection migration attempt.
5742 HttpResponseInfo response;
5743 HttpRequestHeaders request_headers;
5744 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
5745 callback_.callback()));
5746
5747 // Run the message loop so that the migration attempt is executed and
5748 // data queued in the new socket is read by the packet reader.
5749 base::RunLoop().RunUntilIdle();
5750
Zhongyi Shia7dd46b2018-07-12 22:59:295751 // Verify session is still alive and not marked as going away.
Zhongyi Shi0439ecc72018-07-11 04:41:265752 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:295753 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:265754 EXPECT_EQ(2u, session->GetNumActiveStreams());
5755
5756 // Verify that response headers on the migrated socket were delivered to the
5757 // stream.
5758 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
5759 EXPECT_EQ(200, response.headers->response_code());
5760
5761 stream1.reset();
5762 stream2.reset();
5763
5764 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5765 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5766 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
5767 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
5768}
5769
5770TEST_P(QuicStreamFactoryTest, MigrateOnWriteErrorWithMixedRequestsSync) {
5771 TestMigrationOnWriteErrorMixedStreams(SYNCHRONOUS);
5772}
5773
5774TEST_P(QuicStreamFactoryTest, MigrateOnWriteErrorWithMixedRequestsAsync) {
5775 TestMigrationOnWriteErrorMixedStreams(ASYNC);
5776}
5777
5778// Sets up a test that verifies connection migration manages to migrate to
5779// alternate network after encountering a SYNC/ASYNC write error based on
5780// |write_error_mode| on the original network.
5781// Note there are mixed types of unfinished requests before migration: one
5782// migratable and one non-migratable. The *migratable* one triggers write
5783// error.
5784void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorMixedStreams(
5785 IoMode write_error_mode) {
5786 InitializeConnectionMigrationV2Test(
5787 {kDefaultNetworkForTests, kNewNetworkForTests});
5788 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5789 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5790 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5791
5792 int packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595793 MockQuicData socket_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:025794
Zhongyi Shi0439ecc72018-07-11 04:41:265795 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:025796 socket_data.AddWrite(SYNCHRONOUS,
5797 ConstructInitialSettingsPacket(packet_number++));
Zhongyi Shi0439ecc72018-07-11 04:41:265798 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
5799 socket_data.AddSocketDataToFactory(socket_factory_.get());
5800
5801 // Set up second socket data provider that is used after
5802 // migration. The request is rewritten to this new socket, and the
5803 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:595804 MockQuicData socket_data1(version_);
Zhongyi Shi0439ecc72018-07-11 04:41:265805 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335806 SYNCHRONOUS,
5807 ConstructGetRequestPacket(packet_number++,
5808 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:025809 true, true));
Zhongyi Shi0439ecc72018-07-11 04:41:265810 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335811 SYNCHRONOUS,
5812 client_maker_.MakeRstPacket(packet_number++, true,
5813 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:415814 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:185815 /*include_stop_sending_if_v99=*/true));
Zhongyi Shi0439ecc72018-07-11 04:41:265816 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:335817 ASYNC,
5818 ConstructOkResponsePacket(
5819 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shi0439ecc72018-07-11 04:41:265820 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5821 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335822 SYNCHRONOUS,
5823 client_maker_.MakeAckAndRstPacket(
5824 packet_number++, false, GetNthClientInitiatedBidirectionalStreamId(0),
5825 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi0439ecc72018-07-11 04:41:265826 socket_data1.AddSocketDataToFactory(socket_factory_.get());
5827
5828 // Create request #1 and QuicHttpStream.
5829 QuicStreamRequest request1(factory_.get());
5830 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035831 request1.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:525832 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
5833 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035834 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5835 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi0439ecc72018-07-11 04:41:265836 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5837 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
5838 EXPECT_TRUE(stream1.get());
5839
5840 HttpRequestInfo request_info1;
5841 request_info1.method = "GET";
5842 request_info1.url = GURL("https://www.example.org/");
5843 request_info1.traffic_annotation =
5844 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5845 EXPECT_EQ(OK,
5846 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
5847 net_log_, CompletionOnceCallback()));
5848
5849 // Second request returns synchronously because it pools to existing session.
5850 TestCompletionCallback callback2;
5851 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:515852 EXPECT_EQ(OK,
5853 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:525854 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
5855 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:515856 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5857 failed_on_default_network_callback_, callback2.callback()));
Zhongyi Shi0439ecc72018-07-11 04:41:265858 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
5859 EXPECT_TRUE(stream2.get());
5860
5861 HttpRequestInfo request_info2;
5862 request_info2.method = "GET";
Zhongyi Shibb28b1f2018-07-18 02:41:265863 request_info2.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Zhongyi Shi0439ecc72018-07-11 04:41:265864 request_info2.url = GURL("https://www.example.org/");
5865 request_info2.traffic_annotation =
5866 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5867 EXPECT_EQ(OK,
5868 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
5869 net_log_, CompletionOnceCallback()));
5870
5871 // Ensure that session is alive and active.
5872 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5873 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5874 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5875 EXPECT_EQ(2u, session->GetNumActiveStreams());
5876
5877 // Send GET request on stream 1. This should cause a write error, which
5878 // triggers a connection migration attempt.
5879 HttpResponseInfo response;
5880 HttpRequestHeaders request_headers;
5881 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
5882 callback_.callback()));
5883
5884 // Run the message loop so that the migration attempt is executed and
5885 // data queued in the new socket is read by the packet reader.
5886 base::RunLoop().RunUntilIdle();
5887
Zhongyi Shia7dd46b2018-07-12 22:59:295888 // Verify that the session is still alive and not marked as going away.
5889 // Non-migratable stream should be closed due to migration.
Zhongyi Shi0439ecc72018-07-11 04:41:265890 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:295891 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:265892 EXPECT_EQ(1u, session->GetNumActiveStreams());
5893
5894 // Verify that response headers on the migrated socket were delivered to the
5895 // stream.
5896 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
5897 EXPECT_EQ(200, response.headers->response_code());
5898
5899 stream1.reset();
5900
5901 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5902 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5903 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
5904 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
5905}
5906
5907TEST_P(QuicStreamFactoryTest, MigrateOnWriteErrorWithMixedRequests2Sync) {
5908 TestMigrationOnWriteErrorMixedStreams2(SYNCHRONOUS);
5909}
5910
5911TEST_P(QuicStreamFactoryTest, MigrateOnWriteErrorWithMixedRequests2Async) {
5912 TestMigrationOnWriteErrorMixedStreams2(ASYNC);
5913}
5914
5915// The one triggers write error is a non-migratable stream.
5916// Sets up a test that verifies connection migration manages to migrate to
5917// alternate network after encountering a SYNC/ASYNC write error based on
5918// |write_error_mode| on the original network.
5919// Note there are mixed types of unfinished requests before migration: one
5920// migratable and one non-migratable. The *non-migratable* one triggers write
5921// error.
5922void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorMixedStreams2(
5923 IoMode write_error_mode) {
5924 InitializeConnectionMigrationV2Test(
5925 {kDefaultNetworkForTests, kNewNetworkForTests});
5926 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5927 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5928 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5929
5930 int packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595931 MockQuicData socket_data(version_);
Zhongyi Shi0439ecc72018-07-11 04:41:265932 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:025933 socket_data.AddWrite(SYNCHRONOUS,
5934 ConstructInitialSettingsPacket(packet_number++));
Zhongyi Shi0439ecc72018-07-11 04:41:265935 socket_data.AddWrite(write_error_mode,
5936 ERR_ADDRESS_UNREACHABLE); // Write error.
5937 socket_data.AddSocketDataToFactory(socket_factory_.get());
5938
5939 // Set up second socket data provider that is used after
5940 // migration. The request is rewritten to this new socket, and the
5941 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:595942 MockQuicData socket_data1(version_);
Zhongyi Shi0439ecc72018-07-11 04:41:265943 // The packet triggered writer error will be sent anyway even if the stream
5944 // will be cancelled later.
5945 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335946 SYNCHRONOUS,
5947 ConstructGetRequestPacket(packet_number++,
5948 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamilton0d65a8c2019-06-07 00:46:025949 true, true));
Zhongyi Shi0439ecc72018-07-11 04:41:265950 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335951 SYNCHRONOUS,
5952 client_maker_.MakeRstPacket(packet_number++, true,
5953 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:415954 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:185955 /*include_stop_sending_if_v99=*/true));
Zhongyi Shi0439ecc72018-07-11 04:41:265956 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335957 SYNCHRONOUS,
5958 ConstructGetRequestPacket(packet_number++,
5959 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:025960 true, true));
Zhongyi Shi0439ecc72018-07-11 04:41:265961 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:335962 ASYNC,
5963 ConstructOkResponsePacket(
5964 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shi0439ecc72018-07-11 04:41:265965 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5966 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335967 SYNCHRONOUS,
5968 client_maker_.MakeAckAndRstPacket(
5969 packet_number++, false, GetNthClientInitiatedBidirectionalStreamId(0),
5970 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi0439ecc72018-07-11 04:41:265971 socket_data1.AddSocketDataToFactory(socket_factory_.get());
5972
5973 // Create request #1 and QuicHttpStream.
5974 QuicStreamRequest request1(factory_.get());
5975 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035976 request1.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:525977 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
5978 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035979 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5980 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi0439ecc72018-07-11 04:41:265981 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5982 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
5983 EXPECT_TRUE(stream1.get());
5984
5985 HttpRequestInfo request_info1;
5986 request_info1.method = "GET";
5987 request_info1.url = GURL("https://www.example.org/");
5988 request_info1.traffic_annotation =
5989 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5990 EXPECT_EQ(OK,
5991 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
5992 net_log_, CompletionOnceCallback()));
5993
5994 // Second request returns synchronously because it pools to existing session.
5995 TestCompletionCallback callback2;
5996 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:515997 EXPECT_EQ(OK,
5998 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:525999 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
6000 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:516001 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6002 failed_on_default_network_callback_, callback2.callback()));
Zhongyi Shi0439ecc72018-07-11 04:41:266003 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
6004 EXPECT_TRUE(stream2.get());
6005
6006 HttpRequestInfo request_info2;
6007 request_info2.method = "GET";
Zhongyi Shibb28b1f2018-07-18 02:41:266008 request_info2.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Zhongyi Shi0439ecc72018-07-11 04:41:266009 request_info2.url = GURL("https://www.example.org/");
6010 request_info2.traffic_annotation =
6011 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6012 EXPECT_EQ(OK,
6013 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
6014 net_log_, CompletionOnceCallback()));
6015
6016 // Ensure that session is alive and active.
6017 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6018 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6019 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6020 EXPECT_EQ(2u, session->GetNumActiveStreams());
6021
6022 // Send GET request on stream 2 which is non-migratable. This should cause a
6023 // write error, which triggers a connection migration attempt.
6024 HttpResponseInfo response2;
6025 HttpRequestHeaders request_headers2;
6026 EXPECT_EQ(OK, stream2->SendRequest(request_headers2, &response2,
6027 callback2.callback()));
6028
6029 // Run the message loop so that the migration attempt is executed and
Zhongyi Shia7dd46b2018-07-12 22:59:296030 // data queued in the new socket is read by the packet reader. Session is
6031 // still alive and not marked as going away, non-migratable stream will be
6032 // closed.
Zhongyi Shi0439ecc72018-07-11 04:41:266033 base::RunLoop().RunUntilIdle();
6034 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:296035 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:266036 EXPECT_EQ(1u, session->GetNumActiveStreams());
6037
6038 // Send GET request on stream 1.
6039 HttpResponseInfo response;
6040 HttpRequestHeaders request_headers;
6041 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
6042 callback_.callback()));
6043
6044 base::RunLoop().RunUntilIdle();
6045
6046 // Verify that response headers on the migrated socket were delivered to the
6047 // stream.
6048 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
6049 EXPECT_EQ(200, response.headers->response_code());
6050
6051 stream1.reset();
6052
6053 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6054 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6055 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6056 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6057}
6058
Zhongyi Shic16b4102019-02-12 00:37:406059// This test verifies that when a connection encounters a packet write error, it
6060// will cancel non-migratable streams, and migrate to the alternate network.
jri9f303712016-09-13 01:10:226061void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorNonMigratableStream(
Zhongyi Shi32fe14d42019-02-28 00:25:366062 IoMode write_error_mode,
6063 bool migrate_idle_sessions) {
Zhongyi Shic16b4102019-02-12 00:37:406064 DVLOG(1) << "Write error mode: "
jri9f303712016-09-13 01:10:226065 << ((write_error_mode == SYNCHRONOUS) ? "SYNCHRONOUS" : "ASYNC");
Zhongyi Shi32fe14d42019-02-28 00:25:366066 DVLOG(1) << "Migrate idle sessions: " << migrate_idle_sessions;
Nick Harper72ade192019-07-17 03:30:426067 test_params_.quic_params.migrate_idle_sessions = migrate_idle_sessions;
Zhongyi Shi1a054612018-06-14 04:59:086068 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:226069 {kDefaultNetworkForTests, kNewNetworkForTests});
6070 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6071 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6072
Ryan Hamiltonabad59e2019-06-06 04:02:596073 MockQuicData failed_socket_data(version_);
6074 MockQuicData socket_data(version_);
Zhongyi Shi32fe14d42019-02-28 00:25:366075 if (migrate_idle_sessions) {
Zhongyi Shi32fe14d42019-02-28 00:25:366076 // The socket data provider for the original socket before migration.
6077 failed_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:026078 failed_socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi32fe14d42019-02-28 00:25:366079 failed_socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
6080 failed_socket_data.AddSocketDataToFactory(socket_factory_.get());
6081
6082 // Set up second socket data provider that is used after migration.
6083 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
6084 // Although the write error occurs when writing a packet for the
6085 // non-migratable stream and the stream will be cancelled during migration,
6086 // the packet will still be retransimitted at the connection level.
6087 socket_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:026088 SYNCHRONOUS,
6089 ConstructGetRequestPacket(
6090 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi32fe14d42019-02-28 00:25:366091 // A RESET will be sent to the peer to cancel the non-migratable stream.
6092 socket_data.AddWrite(
6093 SYNCHRONOUS, client_maker_.MakeRstPacket(
6094 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
6095 quic::QUIC_STREAM_CANCELLED));
6096 socket_data.AddSocketDataToFactory(socket_factory_.get());
6097 } else {
6098 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6099 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
6100 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
6101 socket_data.AddSocketDataToFactory(socket_factory_.get());
6102 }
jri9f303712016-09-13 01:10:226103
6104 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456105 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336106 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036107 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:526108 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
6109 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036110 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6111 failed_on_default_network_callback_, callback_.callback()));
jri9f303712016-09-13 01:10:226112 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246113 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:226114 EXPECT_TRUE(stream.get());
6115
6116 // Cause QUIC stream to be created, but marked as non-migratable.
6117 HttpRequestInfo request_info;
Zhongyi Shibb28b1f2018-07-18 02:41:266118 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
jri9f303712016-09-13 01:10:226119 request_info.method = "GET";
6120 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396121 request_info.traffic_annotation =
6122 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276123 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396124 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:226125
6126 // Ensure that session is alive and active.
6127 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6128 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6129 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6130
6131 // Send GET request on stream. This should cause a write error, which triggers
6132 // a connection migration attempt.
6133 HttpResponseInfo response;
6134 HttpRequestHeaders request_headers;
6135 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6136 callback_.callback()));
6137
6138 // Run message loop to execute migration attempt.
6139 base::RunLoop().RunUntilIdle();
6140
Zhongyi Shi32fe14d42019-02-28 00:25:366141 // Migration closes the non-migratable stream and:
6142 // if migrate idle session is enabled, it migrates to the alternate network
6143 // successfully; otherwise the connection is closed.
6144 EXPECT_EQ(migrate_idle_sessions,
6145 QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6146 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(host_port_pair_));
jri9f303712016-09-13 01:10:226147
Zhongyi Shi32fe14d42019-02-28 00:25:366148 if (migrate_idle_sessions) {
6149 EXPECT_TRUE(failed_socket_data.AllReadDataConsumed());
6150 EXPECT_TRUE(failed_socket_data.AllWriteDataConsumed());
6151 }
jri9f303712016-09-13 01:10:226152 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6153 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6154}
6155
Zhongyi Shi32fe14d42019-02-28 00:25:366156TEST_P(
6157 QuicStreamFactoryTest,
6158 MigrateSessionOnWriteErrorNonMigratableStreamSync_DoNotMigrateIdleSessions) {
6159 TestMigrationOnWriteErrorNonMigratableStream(SYNCHRONOUS, false);
6160}
6161
6162TEST_P(
6163 QuicStreamFactoryTest,
6164 MigrateSessionOnWriteErrorNonMigratableStreamAsync_DoNotMigrateIdleSessions) {
6165 TestMigrationOnWriteErrorNonMigratableStream(ASYNC, false);
jri9f303712016-09-13 01:10:226166}
6167
6168TEST_P(QuicStreamFactoryTest,
Zhongyi Shi32fe14d42019-02-28 00:25:366169 MigrateSessionOnWriteErrorNonMigratableStreamSync_MigrateIdleSessions) {
6170 TestMigrationOnWriteErrorNonMigratableStream(SYNCHRONOUS, true);
6171}
6172
6173TEST_P(QuicStreamFactoryTest,
6174 MigrateSessionOnWriteErrorNonMigratableStreamAsync_MigrateIdleSessions) {
6175 TestMigrationOnWriteErrorNonMigratableStream(ASYNC, true);
jri9f303712016-09-13 01:10:226176}
6177
6178void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorMigrationDisabled(
6179 IoMode write_error_mode) {
Zhongyi Shi1a054612018-06-14 04:59:086180 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:226181 {kDefaultNetworkForTests, kNewNetworkForTests});
6182 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6183 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6184
Ryan Hamiltonabad59e2019-06-06 04:02:596185 MockQuicData socket_data(version_);
jri9f303712016-09-13 01:10:226186 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436187 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jri9f303712016-09-13 01:10:226188 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:176189 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:226190
6191 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456192 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336193 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036194 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:526195 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
6196 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036197 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6198 failed_on_default_network_callback_, callback_.callback()));
jri9f303712016-09-13 01:10:226199 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246200 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:226201 EXPECT_TRUE(stream.get());
6202
6203 // Cause QUIC stream to be created.
6204 HttpRequestInfo request_info;
6205 request_info.method = "GET";
6206 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396207 request_info.traffic_annotation =
6208 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276209 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396210 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:226211
6212 // Ensure that session is alive and active.
6213 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6214 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6215 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6216
6217 // Set session config to have connection migration disabled.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526218 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
6219 session->config());
jri9f303712016-09-13 01:10:226220 EXPECT_TRUE(session->config()->DisableConnectionMigration());
6221
6222 // Send GET request on stream. This should cause a write error, which triggers
6223 // a connection migration attempt.
6224 HttpResponseInfo response;
6225 HttpRequestHeaders request_headers;
6226 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6227 callback_.callback()));
6228 // Run message loop to execute migration attempt.
6229 base::RunLoop().RunUntilIdle();
6230 // Migration fails, and session is closed and deleted.
6231 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6232 EXPECT_FALSE(HasActiveSession(host_port_pair_));
6233 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6234 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6235}
6236
6237TEST_P(QuicStreamFactoryTest,
6238 MigrateSessionOnWriteErrorMigrationDisabledSynchronous) {
6239 TestMigrationOnWriteErrorMigrationDisabled(SYNCHRONOUS);
6240}
6241
6242TEST_P(QuicStreamFactoryTest,
6243 MigrateSessionOnWriteErrorMigrationDisabledAsync) {
6244 TestMigrationOnWriteErrorMigrationDisabled(ASYNC);
6245}
6246
Zhongyi Shi7f1d9212018-06-22 23:24:366247// Sets up a test which verifies that connection migration on write error can
6248// eventually succeed and rewrite the packet on the new network with singals
6249// delivered in the following order (alternate network is always availabe):
6250// - original network encounters a SYNC/ASYNC write error based on
6251// |write_error_mode_on_old_network|, the packet failed to be written is
6252// cached, session migrates immediately to the alternate network.
6253// - an immediate SYNC/ASYNC write error based on
6254// |write_error_mode_on_new_network| is encountered after migration to the
6255// alternate network, session migrates immediately to the original network.
6256// - an immediate SYNC/ASYNC write error based on
6257// |write_error_mode_on_old_network| is encountered after migration to the
6258// original network, session migrates immediately to the alternate network.
6259// - finally, session successfully sends the packet and reads the response on
6260// the alternate network.
6261// TODO(zhongyi): once https://crbug.com/855666 is fixed, this test should be
6262// modified to test that session is closed early if hopping between networks
6263// with consecutive write errors is detected.
jri9f303712016-09-13 01:10:226264void QuicStreamFactoryTestBase::TestMigrationOnMultipleWriteErrors(
Zhongyi Shi7f1d9212018-06-22 23:24:366265 IoMode write_error_mode_on_old_network,
6266 IoMode write_error_mode_on_new_network) {
6267 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:226268 {kDefaultNetworkForTests, kNewNetworkForTests});
6269 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6270 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6271 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6272
Zhongyi Shi7f1d9212018-06-22 23:24:366273 // Set up the socket data used by the original network, which encounters a
6274 // write erorr.
Ryan Hamiltonabad59e2019-06-06 04:02:596275 MockQuicData socket_data1(version_);
Zhongyi Shi7f1d9212018-06-22 23:24:366276 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:026277 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi7f1d9212018-06-22 23:24:366278 socket_data1.AddWrite(write_error_mode_on_old_network,
6279 ERR_ADDRESS_UNREACHABLE); // Write Error
6280 socket_data1.AddSocketDataToFactory(socket_factory_.get());
6281
6282 // Set up the socket data used by the alternate network, which also
6283 // encounters a write error.
Ryan Hamiltonabad59e2019-06-06 04:02:596284 MockQuicData failed_quic_data2(version_);
Zhongyi Shi7f1d9212018-06-22 23:24:366285 failed_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6286 failed_quic_data2.AddWrite(write_error_mode_on_new_network, ERR_FAILED);
6287 failed_quic_data2.AddSocketDataToFactory(socket_factory_.get());
6288
6289 // Set up the third socket data used by original network, which encounters a
6290 // write error again.
Ryan Hamiltonabad59e2019-06-06 04:02:596291 MockQuicData failed_quic_data1(version_);
Zhongyi Shi7f1d9212018-06-22 23:24:366292 failed_quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6293 failed_quic_data1.AddWrite(write_error_mode_on_old_network, ERR_FAILED);
6294 failed_quic_data1.AddSocketDataToFactory(socket_factory_.get());
6295
6296 // Set up the last socket data used by the alternate network, which will
6297 // finish migration successfully. The request is rewritten to this new socket,
6298 // and the response to the request is read on this socket.
Ryan Hamiltonabad59e2019-06-06 04:02:596299 MockQuicData socket_data2(version_);
Fan Yang32c5a112018-12-10 20:06:336300 socket_data2.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:026301 SYNCHRONOUS,
6302 ConstructGetRequestPacket(
6303 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi7f1d9212018-06-22 23:24:366304 socket_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:336305 ASYNC,
6306 ConstructOkResponsePacket(
6307 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shi7f1d9212018-06-22 23:24:366308 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:336309 socket_data2.AddWrite(
6310 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
6311 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
6312 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi7f1d9212018-06-22 23:24:366313 socket_data2.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:226314
6315 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456316 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336317 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036318 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:526319 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
6320 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036321 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6322 failed_on_default_network_callback_, callback_.callback()));
jri9f303712016-09-13 01:10:226323 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246324 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:226325 EXPECT_TRUE(stream.get());
6326
6327 // Cause QUIC stream to be created.
6328 HttpRequestInfo request_info;
6329 request_info.method = "GET";
6330 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396331 request_info.traffic_annotation =
6332 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276333 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396334 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:226335
6336 // Ensure that session is alive and active.
6337 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6338 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6339 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6340
Zhongyi Shi7f1d9212018-06-22 23:24:366341 // Send GET request on stream.
6342 // This should encounter a write error on network 1,
6343 // then migrate to network 2, which encounters another write error,
6344 // and migrate again to network 1, which encoutners one more write error.
6345 // Finally the session migrates to network 2 successfully.
jri9f303712016-09-13 01:10:226346 HttpResponseInfo response;
6347 HttpRequestHeaders request_headers;
6348 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6349 callback_.callback()));
jri9f303712016-09-13 01:10:226350
jri9f303712016-09-13 01:10:226351 base::RunLoop().RunUntilIdle();
Zhongyi Shi7f1d9212018-06-22 23:24:366352 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6353 EXPECT_EQ(1u, session->GetNumActiveStreams());
jri9f303712016-09-13 01:10:226354
Zhongyi Shi7f1d9212018-06-22 23:24:366355 // Verify that response headers on the migrated socket were delivered to the
6356 // stream.
6357 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6358 EXPECT_EQ(200, response.headers->response_code());
jri9f303712016-09-13 01:10:226359
6360 stream.reset();
Zhongyi Shi7f1d9212018-06-22 23:24:366361 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6362 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6363 EXPECT_TRUE(failed_quic_data2.AllReadDataConsumed());
6364 EXPECT_TRUE(failed_quic_data2.AllWriteDataConsumed());
6365 EXPECT_TRUE(failed_quic_data1.AllReadDataConsumed());
6366 EXPECT_TRUE(failed_quic_data1.AllWriteDataConsumed());
6367 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
6368 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
jri9f303712016-09-13 01:10:226369}
6370
6371TEST_P(QuicStreamFactoryTest, MigrateSessionOnMultipleWriteErrorsSyncSync) {
Zhongyi Shi7f1d9212018-06-22 23:24:366372 TestMigrationOnMultipleWriteErrors(
6373 /*write_error_mode_on_old_network*/ SYNCHRONOUS,
6374 /*write_error_mode_on_new_network*/ SYNCHRONOUS);
jri9f303712016-09-13 01:10:226375}
6376
6377TEST_P(QuicStreamFactoryTest, MigrateSessionOnMultipleWriteErrorsSyncAsync) {
Zhongyi Shi7f1d9212018-06-22 23:24:366378 TestMigrationOnMultipleWriteErrors(
6379 /*write_error_mode_on_old_network*/ SYNCHRONOUS,
6380 /*write_error_mode_on_new_network*/ ASYNC);
jri9f303712016-09-13 01:10:226381}
6382
6383TEST_P(QuicStreamFactoryTest, MigrateSessionOnMultipleWriteErrorsAsyncSync) {
Zhongyi Shi7f1d9212018-06-22 23:24:366384 TestMigrationOnMultipleWriteErrors(
6385 /*write_error_mode_on_old_network*/ ASYNC,
6386 /*write_error_mode_on_new_network*/ SYNCHRONOUS);
jri9f303712016-09-13 01:10:226387}
6388
6389TEST_P(QuicStreamFactoryTest, MigrateSessionOnMultipleWriteErrorsAsyncAsync) {
Zhongyi Shi7f1d9212018-06-22 23:24:366390 TestMigrationOnMultipleWriteErrors(
6391 /*write_error_mode_on_old_network*/ ASYNC,
6392 /*write_error_mode_on_new_network*/ ASYNC);
jri9f303712016-09-13 01:10:226393}
6394
Zhongyi Shi6abe33812018-07-24 19:43:116395// Verifies that a connection is closed when connection migration is triggered
6396// on network being disconnected and the handshake is not confirmed.
6397TEST_P(QuicStreamFactoryTest, NoMigrationBeforeHandshakeOnNetworkDisconnected) {
6398 InitializeConnectionMigrationV2Test(
6399 {kDefaultNetworkForTests, kNewNetworkForTests});
6400
Zhongyi Shi879659422018-08-02 17:58:256401 // Use cold start mode to do crypto connect, and send CHLO packet on wire.
Zhongyi Shi6abe33812018-07-24 19:43:116402 crypto_client_stream_factory_.set_handshake_mode(
Zhongyi Shi879659422018-08-02 17:58:256403 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
Zhongyi Shi6abe33812018-07-24 19:43:116404
Ryan Hamiltonabad59e2019-06-06 04:02:596405 MockQuicData socket_data(version_);
Zhongyi Shi879659422018-08-02 17:58:256406 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5068bb02018-08-03 02:44:096407 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
Zhongyi Shi6abe33812018-07-24 19:43:116408 socket_data.AddSocketDataToFactory(socket_factory_.get());
6409
6410 // Create request and QuicHttpStream.
6411 QuicStreamRequest request(factory_.get());
6412 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036413 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:526414 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
6415 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036416 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6417 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi6abe33812018-07-24 19:43:116418 // Deliver the network notification, which should cause the connection to be
6419 // closed.
6420 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6421 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
6422 EXPECT_EQ(ERR_NETWORK_CHANGED, callback_.WaitForResult());
Zhongyi Shi4293b142018-07-25 00:33:576423
Zhongyi Shi6abe33812018-07-24 19:43:116424 EXPECT_FALSE(HasActiveSession(host_port_pair_));
6425 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
Zhongyi Shi4293b142018-07-25 00:33:576426 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6427 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
Zhongyi Shi6abe33812018-07-24 19:43:116428}
6429
Zhongyi Shib24001c02018-06-18 20:01:526430// Sets up the connection migration test where network change notification is
6431// queued BEFORE connection migration attempt on write error is posted.
6432void QuicStreamFactoryTestBase::
6433 TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
6434 bool disconnected) {
6435 InitializeConnectionMigrationV2Test(
jried79618b2016-07-02 03:18:526436 {kDefaultNetworkForTests, kNewNetworkForTests});
6437 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6438 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6439 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6440
Ryan Hamiltonabad59e2019-06-06 04:02:596441 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:366442 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:026443 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
rcha00569732016-08-27 11:09:366444 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:176445 socket_data.AddSocketDataToFactory(socket_factory_.get());
jried79618b2016-07-02 03:18:526446
6447 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456448 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336449 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036450 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:526451 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
6452 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036453 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6454 failed_on_default_network_callback_, callback_.callback()));
jried79618b2016-07-02 03:18:526455 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246456 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jried79618b2016-07-02 03:18:526457 EXPECT_TRUE(stream.get());
6458
6459 // Cause QUIC stream to be created.
6460 HttpRequestInfo request_info;
6461 request_info.method = "GET";
6462 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396463 request_info.traffic_annotation =
6464 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276465 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396466 net_log_, CompletionOnceCallback()));
jried79618b2016-07-02 03:18:526467
6468 // Ensure that session is alive and active.
6469 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6470 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6471 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6472
6473 // Set up second socket data provider that is used after
6474 // migration. The request is rewritten to this new socket, and the
6475 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:596476 MockQuicData socket_data1(version_);
Fan Yang32c5a112018-12-10 20:06:336477 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:026478 SYNCHRONOUS,
6479 ConstructGetRequestPacket(
6480 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi32f2fd02018-04-16 18:23:436481 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:336482 ASYNC,
6483 ConstructOkResponsePacket(
6484 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
rcha00569732016-08-27 11:09:366485 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:336486 socket_data1.AddWrite(
6487 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
6488 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
6489 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:176490 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jried79618b2016-07-02 03:18:526491
jri9f303712016-09-13 01:10:226492 // First queue a network change notification in the message loop.
6493 if (disconnected) {
6494 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6495 ->QueueNetworkDisconnected(kDefaultNetworkForTests);
6496 } else {
6497 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6498 ->QueueNetworkMadeDefault(kNewNetworkForTests);
6499 }
6500 // Send GET request on stream. This should cause a write error,
6501 // which triggers a connection migration attempt. This will queue a
6502 // migration attempt behind the notification in the message loop.
jried79618b2016-07-02 03:18:526503 HttpResponseInfo response;
6504 HttpRequestHeaders request_headers;
6505 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6506 callback_.callback()));
6507
jried79618b2016-07-02 03:18:526508 base::RunLoop().RunUntilIdle();
Zhongyi Shia7dd46b2018-07-12 22:59:296509 // Verify the session is still alive and not marked as going away post
6510 // migration.
jried79618b2016-07-02 03:18:526511 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:296512 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jried79618b2016-07-02 03:18:526513 EXPECT_EQ(1u, session->GetNumActiveStreams());
6514
6515 // Verify that response headers on the migrated socket were delivered to the
6516 // stream.
6517 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6518 EXPECT_EQ(200, response.headers->response_code());
6519
6520 stream.reset();
6521
6522 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6523 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6524 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6525 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6526}
6527
Zhongyi Shib24001c02018-06-18 20:01:526528// This test verifies that session attempts connection migration successfully
6529// with signals delivered in the following order (alternate network is always
6530// available):
6531// - a notification that default network is disconnected is queued.
6532// - write error is triggered: session posts a task to attempt connection
6533// migration, |migration_pending_| set to true.
6534// - default network disconnected is delivered: session immediately migrates to
6535// the alternate network, |migration_pending_| set to false.
Zhongyi Shif3d6cddb2018-07-11 03:30:026536// - connection migration on write error attempt aborts: writer encountered
6537// error is no longer in active use.
jri9f303712016-09-13 01:10:226538TEST_P(QuicStreamFactoryTest,
Zhongyi Shib24001c02018-06-18 20:01:526539 MigrateOnNetworkDisconnectedWithWriteErrorQueuedLater) {
6540 TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
6541 /*disconnected=*/true);
jri9f303712016-09-13 01:10:226542}
6543
Zhongyi Shib24001c02018-06-18 20:01:526544// This test verifies that session attempts connection migration successfully
6545// with signals delivered in the following order (alternate network is always
6546// available):
6547// - a notification that alternate network is made default is queued.
6548// - write error is triggered: session posts a task to attempt connection
6549// migration, block future migrations.
6550// - new default notification is delivered: migrate back timer spins and task is
6551// posted to migrate to the new default network.
6552// - connection migration on write error attempt proceeds successfully: session
6553// is
6554// marked as going away, future migrations unblocked.
6555// - migrate back to default network task executed: session is already on the
6556// default network, no-op.
jri9f303712016-09-13 01:10:226557TEST_P(QuicStreamFactoryTest,
Zhongyi Shib24001c02018-06-18 20:01:526558 MigrateOnWriteErrorWithNetworkMadeDefaultQueuedEarlier) {
6559 TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
6560 /*disconnected=*/false);
jri9f303712016-09-13 01:10:226561}
6562
Zhongyi Shi1e2bc742018-06-16 02:06:076563// Sets up the connection migration test where network change notification is
6564// queued AFTER connection migration attempt on write error is posted.
6565void QuicStreamFactoryTestBase::
6566 TestMigrationOnWriteErrorWithNotificationQueuedLater(bool disconnected) {
Zhongyi Shi1a054612018-06-14 04:59:086567 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:226568 {kDefaultNetworkForTests, kNewNetworkForTests});
jried79618b2016-07-02 03:18:526569 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6570 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri9f303712016-09-13 01:10:226571 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jried79618b2016-07-02 03:18:526572
Ryan Hamiltonabad59e2019-06-06 04:02:596573 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:366574 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:026575 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
rcha00569732016-08-27 11:09:366576 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:176577 socket_data.AddSocketDataToFactory(socket_factory_.get());
jried79618b2016-07-02 03:18:526578
6579 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456580 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336581 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036582 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:526583 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
6584 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036585 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6586 failed_on_default_network_callback_, callback_.callback()));
jried79618b2016-07-02 03:18:526587 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246588 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jried79618b2016-07-02 03:18:526589 EXPECT_TRUE(stream.get());
6590
6591 // Cause QUIC stream to be created.
6592 HttpRequestInfo request_info;
6593 request_info.method = "GET";
6594 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396595 request_info.traffic_annotation =
6596 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276597 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396598 net_log_, CompletionOnceCallback()));
jried79618b2016-07-02 03:18:526599
6600 // Ensure that session is alive and active.
6601 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6602 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6603 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6604
jri9f303712016-09-13 01:10:226605 // Set up second socket data provider that is used after
6606 // migration. The request is rewritten to this new socket, and the
6607 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:596608 MockQuicData socket_data1(version_);
Fan Yang32c5a112018-12-10 20:06:336609 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:026610 SYNCHRONOUS,
6611 ConstructGetRequestPacket(
6612 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi32f2fd02018-04-16 18:23:436613 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:336614 ASYNC,
6615 ConstructOkResponsePacket(
6616 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
jri9f303712016-09-13 01:10:226617 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:336618 socket_data1.AddWrite(
6619 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
6620 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
6621 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:176622 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:226623
6624 // Send GET request on stream. This should cause a write error,
6625 // which triggers a connection migration attempt. This will queue a
6626 // migration attempt in the message loop.
jried79618b2016-07-02 03:18:526627 HttpResponseInfo response;
6628 HttpRequestHeaders request_headers;
jri9f303712016-09-13 01:10:226629 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6630 callback_.callback()));
jried79618b2016-07-02 03:18:526631
jri9f303712016-09-13 01:10:226632 // Now queue a network change notification in the message loop behind
6633 // the migration attempt.
6634 if (disconnected) {
6635 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6636 ->QueueNetworkDisconnected(kDefaultNetworkForTests);
6637 } else {
6638 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6639 ->QueueNetworkMadeDefault(kNewNetworkForTests);
6640 }
6641
6642 base::RunLoop().RunUntilIdle();
Zhongyi Shia7dd46b2018-07-12 22:59:296643 // Verify session is still alive and not marked as going away.
jri9f303712016-09-13 01:10:226644 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:296645 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri9f303712016-09-13 01:10:226646 EXPECT_EQ(1u, session->GetNumActiveStreams());
6647
6648 // Verify that response headers on the migrated socket were delivered to the
6649 // stream.
6650 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6651 EXPECT_EQ(200, response.headers->response_code());
6652
6653 stream.reset();
jried79618b2016-07-02 03:18:526654
6655 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6656 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
jri9f303712016-09-13 01:10:226657 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6658 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
jried79618b2016-07-02 03:18:526659}
6660
Zhongyi Shi1e2bc742018-06-16 02:06:076661// This test verifies that session attempts connection migration successfully
6662// with signals delivered in the following order (alternate network is always
6663// available):
6664// - write error is triggered: session posts a task to complete connection
6665// migration.
6666// - a notification that alternate network is made default is queued.
6667// - connection migration attempt proceeds successfully, session is marked as
6668// going away.
6669// - new default notification is delivered after connection migration has been
6670// completed.
jri9f303712016-09-13 01:10:226671TEST_P(QuicStreamFactoryTest,
Zhongyi Shi1e2bc742018-06-16 02:06:076672 MigrateOnWriteErrorWithNetworkMadeDefaultQueuedLater) {
6673 TestMigrationOnWriteErrorWithNotificationQueuedLater(/*disconnected=*/false);
jried79618b2016-07-02 03:18:526674}
6675
Zhongyi Shi1e2bc742018-06-16 02:06:076676// This test verifies that session attempts connection migration successfully
6677// with signals delivered in the following order (alternate network is always
6678// available):
6679// - write error is triggered: session posts a task to complete connection
6680// migration.
6681// - a notification that default network is diconnected is queued.
6682// - connection migration attempt proceeds successfully, session is marked as
6683// going away.
6684// - disconnect notification is delivered after connection migration has been
6685// completed.
jri9f303712016-09-13 01:10:226686TEST_P(QuicStreamFactoryTest,
Zhongyi Shi1e2bc742018-06-16 02:06:076687 MigrateOnWriteErrorWithNetworkDisconnectedQueuedLater) {
6688 TestMigrationOnWriteErrorWithNotificationQueuedLater(/*disconnected=*/true);
jried79618b2016-07-02 03:18:526689}
6690
Zhongyi Shia3810c52018-06-15 23:07:196691// This tests connection migration on write error with signals delivered in the
6692// following order:
6693// - a synchronous/asynchronous write error is triggered base on
Zhongyi Shif3d6cddb2018-07-11 03:30:026694// |write_error_mode|: connection migration attempt is posted.
6695// - old default network disconnects, migration waits for a new network.
Zhongyi Shia3810c52018-06-15 23:07:196696// - after a pause, new network is connected: session will migrate to new
6697// network immediately.
Zhongyi Shif3d6cddb2018-07-11 03:30:026698// - migration on writer error is exectued and aborts as writer passed in is no
6699// longer active in use.
Zhongyi Shia3810c52018-06-15 23:07:196700// - new network is made default.
jri5b785512016-09-13 04:29:116701void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorPauseBeforeConnected(
6702 IoMode write_error_mode) {
Zhongyi Shia3810c52018-06-15 23:07:196703 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri5b785512016-09-13 04:29:116704 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6705 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6706 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6707
Zhongyi Shia3810c52018-06-15 23:07:196708 // Use the test task runner.
6709 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
6710
Ryan Hamiltonabad59e2019-06-06 04:02:596711 MockQuicData socket_data(version_);
Zhongyi Shia3810c52018-06-15 23:07:196712 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
Ryan Hamilton0d65a8c2019-06-07 00:46:026713 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shia3810c52018-06-15 23:07:196714 socket_data.AddWrite(write_error_mode, ERR_FAILED);
Zhongyi Shi5f587cc2017-11-21 23:24:176715 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri5b785512016-09-13 04:29:116716
6717 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456718 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336719 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036720 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:526721 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
6722 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036723 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6724 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shia3810c52018-06-15 23:07:196725 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:246726 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri5b785512016-09-13 04:29:116727 EXPECT_TRUE(stream.get());
6728
6729 // Cause QUIC stream to be created.
6730 HttpRequestInfo request_info;
6731 request_info.method = "GET";
Zhongyi Shia3810c52018-06-15 23:07:196732 request_info.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:396733 request_info.traffic_annotation =
6734 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276735 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396736 net_log_, CompletionOnceCallback()));
jri5b785512016-09-13 04:29:116737
6738 // Ensure that session is alive and active.
6739 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6740 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6741 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6742
Zhongyi Shia3810c52018-06-15 23:07:196743 // Send GET request on stream.
jri5b785512016-09-13 04:29:116744 HttpResponseInfo response;
6745 HttpRequestHeaders request_headers;
6746 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6747 callback_.callback()));
6748
Zhongyi Shia3810c52018-06-15 23:07:196749 // The connection should still be alive, not marked as going away.
jri5b785512016-09-13 04:29:116750 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6751 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6752 EXPECT_EQ(1u, session->GetNumActiveStreams());
6753 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
6754
Zhongyi Shia3810c52018-06-15 23:07:196755 // Set up second socket data provider that is used after migration.
6756 // The response to the earlier request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:596757 MockQuicData socket_data1(version_);
Fan Yang32c5a112018-12-10 20:06:336758 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:026759 SYNCHRONOUS,
6760 ConstructGetRequestPacket(
6761 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi32f2fd02018-04-16 18:23:436762 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:336763 ASYNC,
6764 ConstructOkResponsePacket(
6765 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
jri5b785512016-09-13 04:29:116766 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:336767 socket_data1.AddWrite(
6768 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
6769 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
6770 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:176771 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri5b785512016-09-13 04:29:116772
Zhongyi Shia3810c52018-06-15 23:07:196773 // On a DISCONNECTED notification, nothing happens.
6774 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6775 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
6776 // Add a new network and notify the stream factory of a new connected network.
6777 // This causes a PING packet to be sent over the new network.
jri5b785512016-09-13 04:29:116778 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6779 ->SetConnectedNetworksList({kNewNetworkForTests});
6780 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6781 ->NotifyNetworkConnected(kNewNetworkForTests);
6782
Zhongyi Shia3810c52018-06-15 23:07:196783 // Ensure that the session is still alive.
jri5b785512016-09-13 04:29:116784 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia3810c52018-06-15 23:07:196785 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:116786 EXPECT_EQ(1u, session->GetNumActiveStreams());
6787
Zhongyi Shia3810c52018-06-15 23:07:196788 // Run the message loop migration for write error can finish.
6789 runner_->RunUntilIdle();
6790
6791 // Response headers are received over the new network.
jri5b785512016-09-13 04:29:116792 EXPECT_THAT(callback_.WaitForResult(), IsOk());
6793 EXPECT_EQ(200, response.headers->response_code());
6794
Zhongyi Shia3810c52018-06-15 23:07:196795 // Check that the session is still alive.
6796 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
jri5b785512016-09-13 04:29:116797 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shia3810c52018-06-15 23:07:196798
6799 // There should be no posted tasks not executed, no way to migrate back to
6800 // default network.
6801 EXPECT_TRUE(runner_->GetPostedTasks().empty());
6802
6803 // Receive signal to mark new network as default.
6804 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6805 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri5b785512016-09-13 04:29:116806
6807 stream.reset();
jri5b785512016-09-13 04:29:116808 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6809 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6810 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6811 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
jri5b785512016-09-13 04:29:116812}
6813
6814TEST_P(QuicStreamFactoryTest,
Zhongyi Shia3810c52018-06-15 23:07:196815 MigrateSessionOnSyncWriteErrorPauseBeforeConnected) {
jri5b785512016-09-13 04:29:116816 TestMigrationOnWriteErrorPauseBeforeConnected(SYNCHRONOUS);
6817}
6818
6819TEST_P(QuicStreamFactoryTest,
Zhongyi Shia3810c52018-06-15 23:07:196820 MigrateSessionOnAsyncWriteErrorPauseBeforeConnected) {
jri5b785512016-09-13 04:29:116821 TestMigrationOnWriteErrorPauseBeforeConnected(ASYNC);
6822}
6823
Zhongyi Shif3d6cddb2018-07-11 03:30:026824// This test verifies that when session successfully migrate to the alternate
6825// network, packet write error on the old writer will be ignored and will not
6826// trigger connection migration on write error.
6827TEST_P(QuicStreamFactoryTest, IgnoreWriteErrorFromOldWriterAfterMigration) {
6828 InitializeConnectionMigrationV2Test(
6829 {kDefaultNetworkForTests, kNewNetworkForTests});
6830 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6831 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6832 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6833
6834 // Using a testing task runner so that we can verify whether the migrate on
6835 // write error task is posted.
6836 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
6837 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
6838
Ryan Hamiltonabad59e2019-06-06 04:02:596839 MockQuicData socket_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:026840 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shif3d6cddb2018-07-11 03:30:026841 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
Ryan Hamilton9f2eac32019-06-27 03:15:546842 socket_data.AddWrite(
6843 ASYNC, ERR_ADDRESS_UNREACHABLE,
6844 ConstructGetRequestPacket(
6845 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shif3d6cddb2018-07-11 03:30:026846 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6847 socket_data.AddSocketDataToFactory(socket_factory_.get());
6848
6849 // Create request and QuicHttpStream.
6850 QuicStreamRequest request(factory_.get());
6851 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036852 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:526853 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
6854 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036855 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6856 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shif3d6cddb2018-07-11 03:30:026857 EXPECT_EQ(OK, callback_.WaitForResult());
6858 std::unique_ptr<HttpStream> stream = CreateStream(&request);
6859 EXPECT_TRUE(stream.get());
6860
6861 // Cause QUIC stream to be created.
6862 HttpRequestInfo request_info;
6863 request_info.method = "GET";
6864 request_info.url = GURL("https://www.example.org/");
6865 request_info.traffic_annotation =
6866 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6867 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
6868 net_log_, CompletionOnceCallback()));
6869
6870 // Ensure that session is alive and active.
6871 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6872 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6873 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6874
6875 // Set up second socket data provider that is used after
6876 // migration. The response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:596877 MockQuicData socket_data1(version_);
Zhongyi Shif3d6cddb2018-07-11 03:30:026878 socket_data1.AddWrite(
6879 SYNCHRONOUS, client_maker_.MakePingPacket(3, /*include_version=*/true));
6880 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:336881 ASYNC,
6882 ConstructOkResponsePacket(
6883 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shif3d6cddb2018-07-11 03:30:026884 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:336885 socket_data1.AddWrite(
6886 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
6887 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
6888 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shif3d6cddb2018-07-11 03:30:026889 socket_data1.AddSocketDataToFactory(socket_factory_.get());
6890
6891 // Send GET request on stream.
6892 HttpResponseInfo response;
6893 HttpRequestHeaders request_headers;
6894 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6895 callback_.callback()));
6896
6897 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
6898 // Now notify network is disconnected, cause the migration to complete
6899 // immediately.
6900 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6901 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
6902 // There will be two pending task, one will complete migration with no delay
6903 // and the other will attempt to migrate back to the default network with
6904 // delay.
6905 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
6906
6907 // Complete migration.
6908 task_runner->RunUntilIdle();
6909 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
6910
6911 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6912 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6913 EXPECT_EQ(1u, session->GetNumActiveStreams());
6914
6915 // Verify that response headers on the migrated socket were delivered to the
6916 // stream.
6917 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6918 EXPECT_EQ(200, response.headers->response_code());
6919
6920 // Resume the old socket data, a write error will be delivered to the old
6921 // packet writer. Verify no additional task is posted.
6922 socket_data.Resume();
6923 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
6924
6925 stream.reset();
6926 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6927 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6928 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6929}
6930
6931// This test verifies that when session successfully migrate to the alternate
6932// network, packet read error on the old reader will be ignored and will not
6933// close the connection.
6934TEST_P(QuicStreamFactoryTest, IgnoreReadErrorFromOldReaderAfterMigration) {
6935 InitializeConnectionMigrationV2Test(
6936 {kDefaultNetworkForTests, kNewNetworkForTests});
6937 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6938 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6939 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6940
6941 // Using a testing task runner.
6942 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
6943 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
6944
Ryan Hamiltonabad59e2019-06-06 04:02:596945 MockQuicData socket_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:026946 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shif3d6cddb2018-07-11 03:30:026947 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
6948 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE);
6949 socket_data.AddSocketDataToFactory(socket_factory_.get());
6950
6951 // Create request and QuicHttpStream.
6952 QuicStreamRequest request(factory_.get());
6953 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036954 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:526955 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
6956 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036957 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6958 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shif3d6cddb2018-07-11 03:30:026959 EXPECT_EQ(OK, callback_.WaitForResult());
6960 std::unique_ptr<HttpStream> stream = CreateStream(&request);
6961 EXPECT_TRUE(stream.get());
6962
6963 // Cause QUIC stream to be created.
6964 HttpRequestInfo request_info;
6965 request_info.method = "GET";
6966 request_info.url = GURL("https://www.example.org/");
6967 request_info.traffic_annotation =
6968 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6969 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
6970 net_log_, CompletionOnceCallback()));
6971
6972 // Ensure that session is alive and active.
6973 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6974 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6975 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6976
6977 // Set up second socket data provider that is used after
6978 // migration. The request is written to this new socket, and the
6979 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:596980 MockQuicData socket_data1(version_);
Zhongyi Shif3d6cddb2018-07-11 03:30:026981 socket_data1.AddWrite(
6982 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
Fan Yang32c5a112018-12-10 20:06:336983 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:026984 SYNCHRONOUS,
6985 ConstructGetRequestPacket(
6986 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shif3d6cddb2018-07-11 03:30:026987 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:336988 ASYNC,
6989 ConstructOkResponsePacket(
6990 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shif3d6cddb2018-07-11 03:30:026991 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:336992 socket_data1.AddWrite(
6993 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
6994 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
6995 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shif3d6cddb2018-07-11 03:30:026996 socket_data1.AddSocketDataToFactory(socket_factory_.get());
6997
6998 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
6999 // Now notify network is disconnected, cause the migration to complete
7000 // immediately.
7001 scoped_mock_network_change_notifier_->mock_network_change_notifier()
7002 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
7003 // There will be two pending task, one will complete migration with no delay
7004 // and the other will attempt to migrate back to the default network with
7005 // delay.
7006 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
7007
7008 // Complete migration.
7009 task_runner->RunUntilIdle();
7010 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
7011
7012 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7013 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7014 EXPECT_EQ(1u, session->GetNumActiveStreams());
7015
7016 // Send GET request on stream.
7017 HttpResponseInfo response;
7018 HttpRequestHeaders request_headers;
7019 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7020 callback_.callback()));
7021
7022 // Verify that response headers on the migrated socket were delivered to the
7023 // stream.
7024 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
7025 EXPECT_EQ(OK, callback_.WaitForResult());
7026 EXPECT_EQ(200, response.headers->response_code());
7027
7028 // Resume the old socket data, a read error will be delivered to the old
7029 // packet reader. Verify that the session is not affected.
7030 socket_data.Resume();
7031 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
7032 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7033 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7034 EXPECT_EQ(1u, session->GetNumActiveStreams());
7035
7036 stream.reset();
7037 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7038 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7039 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7040 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7041}
7042
7043// This test verifies that after migration on network is executed, packet
7044// read error on the old reader will be ignored and will not close the
7045// connection.
7046TEST_P(QuicStreamFactoryTest, IgnoreReadErrorOnOldReaderDuringMigration) {
7047 InitializeConnectionMigrationV2Test(
7048 {kDefaultNetworkForTests, kNewNetworkForTests});
7049 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7050 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7051 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7052
7053 // Using a testing task runner.
7054 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7055 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7056
Ryan Hamiltonabad59e2019-06-06 04:02:597057 MockQuicData socket_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027058 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shif3d6cddb2018-07-11 03:30:027059 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
7060 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE);
7061 socket_data.AddSocketDataToFactory(socket_factory_.get());
7062
7063 // Create request and QuicHttpStream.
7064 QuicStreamRequest request(factory_.get());
7065 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:037066 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:527067 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
7068 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:037069 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7070 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shif3d6cddb2018-07-11 03:30:027071 EXPECT_EQ(OK, callback_.WaitForResult());
7072 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7073 EXPECT_TRUE(stream.get());
7074
7075 // Cause QUIC stream to be created.
7076 HttpRequestInfo request_info;
7077 request_info.method = "GET";
7078 request_info.url = GURL("https://www.example.org/");
7079 request_info.traffic_annotation =
7080 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7081 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7082 net_log_, CompletionOnceCallback()));
7083
7084 // Ensure that session is alive and active.
7085 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7086 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7087 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7088
7089 // Set up second socket data provider that is used after
7090 // migration. The request is written to this new socket, and the
7091 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:597092 MockQuicData socket_data1(version_);
Zhongyi Shif3d6cddb2018-07-11 03:30:027093 socket_data1.AddWrite(
7094 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
Fan Yang32c5a112018-12-10 20:06:337095 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027096 SYNCHRONOUS,
7097 ConstructGetRequestPacket(
7098 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shif3d6cddb2018-07-11 03:30:027099 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337100 ASYNC,
7101 ConstructOkResponsePacket(
7102 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shif3d6cddb2018-07-11 03:30:027103 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:337104 socket_data1.AddWrite(
7105 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
7106 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
7107 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shif3d6cddb2018-07-11 03:30:027108 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7109
7110 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
7111 // Now notify network is disconnected, cause the migration to complete
7112 // immediately.
7113 scoped_mock_network_change_notifier_->mock_network_change_notifier()
7114 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
7115 // There will be two pending task, one will complete migration with no delay
7116 // and the other will attempt to migrate back to the default network with
7117 // delay.
7118 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
7119
7120 // Resume the old socket data, a read error will be delivered to the old
7121 // packet reader. Verify that the session is not affected.
7122 socket_data.Resume();
7123 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
7124 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7125 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7126 EXPECT_EQ(1u, session->GetNumActiveStreams());
7127
7128 // Complete migration.
7129 task_runner->RunUntilIdle();
7130 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
7131
7132 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7133 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7134 EXPECT_EQ(1u, session->GetNumActiveStreams());
7135
7136 // Send GET request on stream.
7137 HttpResponseInfo response;
7138 HttpRequestHeaders request_headers;
7139 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7140 callback_.callback()));
7141
7142 // Verify that response headers on the migrated socket were delivered to the
7143 // stream.
7144 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
7145 EXPECT_EQ(OK, callback_.WaitForResult());
7146 EXPECT_EQ(200, response.headers->response_code());
7147
7148 stream.reset();
Zhongyi Shi99d0cdd2019-05-21 01:18:427149 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7150 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7151 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7152}
7153
7154// This test verifies that when connection migration on path degrading is
7155// enabled, and no custom retransmittable on wire timeout is specified, the
7156// default value is used.
7157TEST_P(QuicStreamFactoryTest, DefaultRetransmittableOnWireTimeoutForMigration) {
7158 InitializeConnectionMigrationV2Test(
7159 {kDefaultNetworkForTests, kNewNetworkForTests});
7160 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7161 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7162 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7163
7164 // Using a testing task runner.
7165 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7166 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7167 QuicStreamFactoryPeer::SetAlarmFactory(
7168 factory_.get(),
7169 std::make_unique<QuicChromiumAlarmFactory>(task_runner.get(), &clock_));
7170
Ryan Hamiltonabad59e2019-06-06 04:02:597171 MockQuicData socket_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027172 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi99d0cdd2019-05-21 01:18:427173 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
7174 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE);
7175 socket_data.AddSocketDataToFactory(socket_factory_.get());
7176
7177 // Set up second socket data provider that is used after
7178 // migration. The request is written to this new socket, and the
7179 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:597180 MockQuicData socket_data1(version_);
Zhongyi Shi99d0cdd2019-05-21 01:18:427181 // The PING packet sent post migration.
7182 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(2, true));
7183 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027184 SYNCHRONOUS,
7185 ConstructGetRequestPacket(
7186 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi99d0cdd2019-05-21 01:18:427187 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7188 // Read two packets so that client will send ACK immedaitely.
Ryan Hamilton9f2eac32019-06-27 03:15:547189 socket_data1.AddRead(
7190 ASYNC,
7191 ConstructOkResponsePacket(
7192 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
7193 socket_data1.AddRead(
7194 ASYNC, server_maker_.MakeDataPacket(
7195 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7196 base::StringPiece("Hello World")));
7197
Zhongyi Shi99d0cdd2019-05-21 01:18:427198 // Read an ACK from server which acks all client data.
7199 socket_data1.AddRead(SYNCHRONOUS,
7200 server_maker_.MakeAckPacket(3, 3, 1, 1, false));
7201 socket_data1.AddWrite(ASYNC, client_maker_.MakeAckPacket(4, 2, 1, 1, false));
7202 // The PING packet sent for retransmittable on wire.
7203 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(5, false));
7204 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7205 std::string header = ConstructDataHeader(6);
7206 socket_data1.AddRead(
7207 ASYNC, ConstructServerDataPacket(
7208 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177209 header + "hello!"));
Zhongyi Shi99d0cdd2019-05-21 01:18:427210 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read.
7211 socket_data1.AddWrite(
7212 SYNCHRONOUS, client_maker_.MakeRstPacket(
7213 6, false, GetNthClientInitiatedBidirectionalStreamId(0),
7214 quic::QUIC_STREAM_CANCELLED));
7215 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7216
7217 // Create request and QuicHttpStream.
7218 QuicStreamRequest request(factory_.get());
7219 EXPECT_EQ(ERR_IO_PENDING,
7220 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:527221 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
7222 SocketTag(), NetworkIsolationKey(),
Zhongyi Shi99d0cdd2019-05-21 01:18:427223 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7224 failed_on_default_network_callback_, callback_.callback()));
7225 EXPECT_EQ(OK, callback_.WaitForResult());
7226 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7227 EXPECT_TRUE(stream.get());
7228
7229 // Cause QUIC stream to be created.
7230 HttpRequestInfo request_info;
7231 request_info.method = "GET";
7232 request_info.url = GURL("https://www.example.org/");
7233 request_info.traffic_annotation =
7234 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7235 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7236 net_log_, CompletionOnceCallback()));
7237
7238 // Ensure that session is alive and active.
7239 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7240 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7241
7242 // Now notify network is disconnected, cause the migration to complete
7243 // immediately.
7244 scoped_mock_network_change_notifier_->mock_network_change_notifier()
7245 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
7246
7247 // Complete migration.
7248 task_runner->RunUntilIdle();
7249 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7250 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7251 EXPECT_EQ(1u, session->GetNumActiveStreams());
7252
7253 // Send GET request on stream.
7254 HttpResponseInfo response;
7255 HttpRequestHeaders request_headers;
7256 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7257 callback_.callback()));
7258 socket_data1.Resume();
7259 // Spin up the message loop to read incoming data from server till the ACK.
7260 base::RunLoop().RunUntilIdle();
7261
7262 // Ack delay time.
7263 int delay = task_runner->NextPendingTaskDelay().InMilliseconds();
7264 EXPECT_GT(kDefaultRetransmittableOnWireTimeoutMillisecs, delay);
7265 // Fire the ack alarm, since ack has been sent, no ack will be sent.
7266 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7267 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7268
7269 // Fire the ping alarm with retransmittable-on-wire timeout, send PING.
7270 delay = kDefaultRetransmittableOnWireTimeoutMillisecs - delay;
7271 EXPECT_EQ(base::TimeDelta::FromMilliseconds(delay),
7272 task_runner->NextPendingTaskDelay());
7273 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7274 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7275
7276 socket_data1.Resume();
7277
7278 // Verify that response headers on the migrated socket were delivered to the
7279 // stream.
7280 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
7281 EXPECT_EQ(200, response.headers->response_code());
7282
7283 // Resume the old socket data, a read error will be delivered to the old
7284 // packet reader. Verify that the session is not affected.
7285 socket_data.Resume();
7286 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7287 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7288 EXPECT_EQ(1u, session->GetNumActiveStreams());
7289
7290 stream.reset();
Zhongyi Shif3d6cddb2018-07-11 03:30:027291 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7292 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7293 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7294 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7295}
7296
Zhongyi Shi99d0cdd2019-05-21 01:18:427297// This test verifies that when connection migration on path degrading is
7298// enabled, and a custom retransmittable on wire timeout is specified, the
7299// custom value is used.
7300TEST_P(QuicStreamFactoryTest, CustomRetransmittableOnWireTimeoutForMigration) {
7301 int custom_timeout_value = 200;
Nick Harper72ade192019-07-17 03:30:427302 test_params_.quic_params.retransmittable_on_wire_timeout_milliseconds =
Zhongyi Shi99d0cdd2019-05-21 01:18:427303 custom_timeout_value;
7304 InitializeConnectionMigrationV2Test(
7305 {kDefaultNetworkForTests, kNewNetworkForTests});
7306 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7307 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7308 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7309
7310 // Using a testing task runner.
7311 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7312 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7313 QuicStreamFactoryPeer::SetAlarmFactory(
7314 factory_.get(),
7315 std::make_unique<QuicChromiumAlarmFactory>(task_runner.get(), &clock_));
7316
Ryan Hamiltonabad59e2019-06-06 04:02:597317 MockQuicData socket_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027318 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi99d0cdd2019-05-21 01:18:427319 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
7320 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE);
7321 socket_data.AddSocketDataToFactory(socket_factory_.get());
7322
7323 // Set up second socket data provider that is used after
7324 // migration. The request is written to this new socket, and the
7325 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:597326 MockQuicData socket_data1(version_);
Zhongyi Shi99d0cdd2019-05-21 01:18:427327 // The PING packet sent post migration.
7328 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(2, true));
7329 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027330 SYNCHRONOUS,
7331 ConstructGetRequestPacket(
7332 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi99d0cdd2019-05-21 01:18:427333 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7334 // Read two packets so that client will send ACK immedaitely.
Ryan Hamilton9f2eac32019-06-27 03:15:547335 socket_data1.AddRead(
7336 ASYNC,
7337 ConstructOkResponsePacket(
7338 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
7339 socket_data1.AddRead(
7340 ASYNC, server_maker_.MakeDataPacket(
7341 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7342 base::StringPiece("Hello World")));
Zhongyi Shi99d0cdd2019-05-21 01:18:427343 // Read an ACK from server which acks all client data.
7344 socket_data1.AddRead(SYNCHRONOUS,
7345 server_maker_.MakeAckPacket(3, 3, 1, 1, false));
7346 socket_data1.AddWrite(ASYNC, client_maker_.MakeAckPacket(4, 2, 1, 1, false));
7347 // The PING packet sent for retransmittable on wire.
7348 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(5, false));
7349 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7350 std::string header = ConstructDataHeader(6);
7351 socket_data1.AddRead(
7352 ASYNC, ConstructServerDataPacket(
7353 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177354 header + "hello!"));
Zhongyi Shi99d0cdd2019-05-21 01:18:427355 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read.
7356 socket_data1.AddWrite(
7357 SYNCHRONOUS, client_maker_.MakeRstPacket(
7358 6, false, GetNthClientInitiatedBidirectionalStreamId(0),
7359 quic::QUIC_STREAM_CANCELLED));
7360 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7361
7362 // Create request and QuicHttpStream.
7363 QuicStreamRequest request(factory_.get());
7364 EXPECT_EQ(ERR_IO_PENDING,
7365 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:527366 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
7367 SocketTag(), NetworkIsolationKey(),
Zhongyi Shi99d0cdd2019-05-21 01:18:427368 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7369 failed_on_default_network_callback_, callback_.callback()));
7370 EXPECT_EQ(OK, callback_.WaitForResult());
7371 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7372 EXPECT_TRUE(stream.get());
7373
7374 // Cause QUIC stream to be created.
7375 HttpRequestInfo request_info;
7376 request_info.method = "GET";
7377 request_info.url = GURL("https://www.example.org/");
7378 request_info.traffic_annotation =
7379 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7380 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7381 net_log_, CompletionOnceCallback()));
7382
7383 // Ensure that session is alive and active.
7384 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7385 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7386
7387 // Now notify network is disconnected, cause the migration to complete
7388 // immediately.
7389 scoped_mock_network_change_notifier_->mock_network_change_notifier()
7390 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
7391
7392 // Complete migration.
7393 task_runner->RunUntilIdle();
7394 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7395 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7396 EXPECT_EQ(1u, session->GetNumActiveStreams());
7397
7398 // Send GET request on stream.
7399 HttpResponseInfo response;
7400 HttpRequestHeaders request_headers;
7401 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7402 callback_.callback()));
7403 socket_data1.Resume();
7404 // Spin up the message loop to read incoming data from server till the ACK.
7405 base::RunLoop().RunUntilIdle();
7406
7407 // Ack delay time.
7408 int delay = task_runner->NextPendingTaskDelay().InMilliseconds();
7409 EXPECT_GT(custom_timeout_value, delay);
7410 // Fire the ack alarm, since ack has been sent, no ack will be sent.
7411 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7412 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7413
7414 // Fire the ping alarm with retransmittable-on-wire timeout, send PING.
7415 delay = custom_timeout_value - delay;
7416 EXPECT_EQ(base::TimeDelta::FromMilliseconds(delay),
7417 task_runner->NextPendingTaskDelay());
7418 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7419 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7420
7421 socket_data1.Resume();
7422
7423 // Verify that response headers on the migrated socket were delivered to the
7424 // stream.
7425 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
7426 EXPECT_EQ(200, response.headers->response_code());
7427
7428 // Resume the old socket data, a read error will be delivered to the old
7429 // packet reader. Verify that the session is not affected.
7430 socket_data.Resume();
7431 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7432 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7433 EXPECT_EQ(1u, session->GetNumActiveStreams());
7434
7435 stream.reset();
7436 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7437 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7438 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7439 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7440}
7441
7442// This test verifies that when no migration is enabled, but a custom value for
7443// retransmittable-on-wire timeout is specified, the ping alarm is set up to
7444// send retransmittable pings with the custom value.
7445TEST_P(QuicStreamFactoryTest, CustomRetransmittableOnWireTimeout) {
7446 int custom_timeout_value = 200;
Nick Harper72ade192019-07-17 03:30:427447 test_params_.quic_params.retransmittable_on_wire_timeout_milliseconds =
Zhongyi Shi99d0cdd2019-05-21 01:18:427448 custom_timeout_value;
7449 Initialize();
7450 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7451 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7452 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7453
7454 // Using a testing task runner.
7455 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7456 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7457 QuicStreamFactoryPeer::SetAlarmFactory(
7458 factory_.get(),
7459 std::make_unique<QuicChromiumAlarmFactory>(task_runner.get(), &clock_));
7460
Ryan Hamiltonabad59e2019-06-06 04:02:597461 MockQuicData socket_data1(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027462 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi99d0cdd2019-05-21 01:18:427463 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027464 SYNCHRONOUS,
7465 ConstructGetRequestPacket(
7466 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi99d0cdd2019-05-21 01:18:427467 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7468 // Read two packets so that client will send ACK immedaitely.
Ryan Hamilton9f2eac32019-06-27 03:15:547469 socket_data1.AddRead(
7470 ASYNC,
7471 ConstructOkResponsePacket(
7472 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
7473 socket_data1.AddRead(
7474 ASYNC, server_maker_.MakeDataPacket(
7475 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7476 base::StringPiece("Hello World")));
Zhongyi Shi99d0cdd2019-05-21 01:18:427477 // Read an ACK from server which acks all client data.
7478 socket_data1.AddRead(SYNCHRONOUS,
7479 server_maker_.MakeAckPacket(3, 2, 1, 1, false));
7480 socket_data1.AddWrite(ASYNC, client_maker_.MakeAckPacket(3, 2, 1, 1, false));
7481 // The PING packet sent for retransmittable on wire.
7482 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(4, false));
7483 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7484 std::string header = ConstructDataHeader(6);
7485 socket_data1.AddRead(
7486 ASYNC, ConstructServerDataPacket(
7487 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177488 header + "hello!"));
Zhongyi Shi99d0cdd2019-05-21 01:18:427489 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read.
7490 socket_data1.AddWrite(
7491 SYNCHRONOUS, client_maker_.MakeRstPacket(
7492 5, false, GetNthClientInitiatedBidirectionalStreamId(0),
7493 quic::QUIC_STREAM_CANCELLED));
7494 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7495
7496 // Create request and QuicHttpStream.
7497 QuicStreamRequest request(factory_.get());
7498 EXPECT_EQ(ERR_IO_PENDING,
7499 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:527500 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
7501 SocketTag(), NetworkIsolationKey(),
Zhongyi Shi99d0cdd2019-05-21 01:18:427502 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7503 failed_on_default_network_callback_, callback_.callback()));
7504 EXPECT_EQ(OK, callback_.WaitForResult());
7505 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7506 EXPECT_TRUE(stream.get());
7507
7508 // Cause QUIC stream to be created.
7509 HttpRequestInfo request_info;
7510 request_info.method = "GET";
7511 request_info.url = GURL("https://www.example.org/");
7512 request_info.traffic_annotation =
7513 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7514 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7515 net_log_, CompletionOnceCallback()));
7516
7517 // Ensure that session is alive and active.
7518 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7519 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7520
7521 // Complete migration.
7522 task_runner->RunUntilIdle();
7523 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7524 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7525 EXPECT_EQ(1u, session->GetNumActiveStreams());
7526
7527 // Send GET request on stream.
7528 HttpResponseInfo response;
7529 HttpRequestHeaders request_headers;
7530 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7531 callback_.callback()));
7532 socket_data1.Resume();
7533 // Spin up the message loop to read incoming data from server till the ACK.
7534 base::RunLoop().RunUntilIdle();
7535
7536 // Ack delay time.
7537 int delay = task_runner->NextPendingTaskDelay().InMilliseconds();
7538 EXPECT_GT(custom_timeout_value, delay);
7539 // Fire the ack alarm, since ack has been sent, no ack will be sent.
7540 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7541 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7542
7543 // Fire the ping alarm with retransmittable-on-wire timeout, send PING.
7544 delay = custom_timeout_value - delay;
7545 EXPECT_EQ(base::TimeDelta::FromMilliseconds(delay),
7546 task_runner->NextPendingTaskDelay());
7547 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7548 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7549
7550 socket_data1.Resume();
7551
7552 // Verify that response headers on the migrated socket were delivered to the
7553 // stream.
7554 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
7555 EXPECT_EQ(200, response.headers->response_code());
7556
7557 // Resume the old socket data, a read error will be delivered to the old
7558 // packet reader. Verify that the session is not affected.
7559 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7560 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7561 EXPECT_EQ(1u, session->GetNumActiveStreams());
7562
7563 stream.reset();
7564 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7565 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7566}
7567
7568// This test verifies that when no migration is enabled, and no custom value
7569// for retransmittable-on-wire timeout is specified, the ping alarm will not
7570// send any retransmittable pings.
7571TEST_P(QuicStreamFactoryTest, NoRetransmittableOnWireTimeout) {
7572 Initialize();
7573 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7574 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7575 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7576
7577 // Using a testing task runner.
7578 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7579 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7580 QuicStreamFactoryPeer::SetAlarmFactory(
7581 factory_.get(),
7582 std::make_unique<QuicChromiumAlarmFactory>(task_runner.get(), &clock_));
7583
Ryan Hamiltonabad59e2019-06-06 04:02:597584 MockQuicData socket_data1(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027585 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi99d0cdd2019-05-21 01:18:427586 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027587 SYNCHRONOUS,
7588 ConstructGetRequestPacket(
7589 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi99d0cdd2019-05-21 01:18:427590 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7591 // Read two packets so that client will send ACK immedaitely.
Ryan Hamilton9f2eac32019-06-27 03:15:547592 socket_data1.AddRead(
7593 ASYNC,
7594 ConstructOkResponsePacket(
7595 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
7596 socket_data1.AddRead(
7597 ASYNC, server_maker_.MakeDataPacket(
7598 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7599 base::StringPiece("Hello World")));
Zhongyi Shi99d0cdd2019-05-21 01:18:427600 // Read an ACK from server which acks all client data.
7601 socket_data1.AddRead(SYNCHRONOUS,
7602 server_maker_.MakeAckPacket(3, 2, 1, 1, false));
7603 socket_data1.AddWrite(ASYNC, client_maker_.MakeAckPacket(3, 2, 1, 1, false));
7604 std::string header = ConstructDataHeader(6);
7605 socket_data1.AddRead(
7606 ASYNC, ConstructServerDataPacket(
7607 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177608 header + "hello!"));
Zhongyi Shi99d0cdd2019-05-21 01:18:427609 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read.
7610 socket_data1.AddWrite(
7611 SYNCHRONOUS, client_maker_.MakeRstPacket(
7612 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
7613 quic::QUIC_STREAM_CANCELLED));
7614 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7615
7616 // Create request and QuicHttpStream.
7617 QuicStreamRequest request(factory_.get());
7618 EXPECT_EQ(ERR_IO_PENDING,
7619 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:527620 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
7621 SocketTag(), NetworkIsolationKey(),
Zhongyi Shi99d0cdd2019-05-21 01:18:427622 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7623 failed_on_default_network_callback_, callback_.callback()));
7624 EXPECT_EQ(OK, callback_.WaitForResult());
7625 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7626 EXPECT_TRUE(stream.get());
7627
7628 // Cause QUIC stream to be created.
7629 HttpRequestInfo request_info;
7630 request_info.method = "GET";
7631 request_info.url = GURL("https://www.example.org/");
7632 request_info.traffic_annotation =
7633 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7634 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7635 net_log_, CompletionOnceCallback()));
7636
7637 // Ensure that session is alive and active.
7638 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7639 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7640
7641 // Complete migration.
7642 task_runner->RunUntilIdle();
7643 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7644 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7645 EXPECT_EQ(1u, session->GetNumActiveStreams());
7646
7647 // Send GET request on stream.
7648 HttpResponseInfo response;
7649 HttpRequestHeaders request_headers;
7650 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7651 callback_.callback()));
7652 socket_data1.Resume();
7653 // Spin up the message loop to read incoming data from server till the ACK.
7654 base::RunLoop().RunUntilIdle();
7655
7656 // Ack delay time.
7657 int delay = task_runner->NextPendingTaskDelay().InMilliseconds();
7658 EXPECT_GT(kDefaultRetransmittableOnWireTimeoutMillisecs, delay);
7659 // Fire the ack alarm, since ack has been sent, no ack will be sent.
7660 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7661 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7662
7663 // Verify that the ping alarm is not set with any default value.
7664 int wrong_delay = kDefaultRetransmittableOnWireTimeoutMillisecs - delay;
7665 delay = task_runner->NextPendingTaskDelay().InMilliseconds();
7666 EXPECT_NE(wrong_delay, delay);
7667 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7668 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7669
7670 // Verify that response headers on the migrated socket were delivered to the
7671 // stream.
7672 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
7673 EXPECT_EQ(200, response.headers->response_code());
7674
7675 // Resume the old socket data, a read error will be delivered to the old
7676 // packet reader. Verify that the session is not affected.
7677 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7678 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7679 EXPECT_EQ(1u, session->GetNumActiveStreams());
7680
7681 stream.reset();
7682 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7683 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7684}
7685
7686// This test verifies that when only migration on network change is enabled, and
7687// a custom value for retransmittable-on-wire is specified, the ping alarm will
7688// send retransmittable pings to the peer with custom value.
7689TEST_P(QuicStreamFactoryTest,
7690 CustomeRetransmittableOnWireTimeoutWithMigrationOnNetworkChangeOnly) {
7691 int custom_timeout_value = 200;
Nick Harper72ade192019-07-17 03:30:427692 test_params_.quic_params.retransmittable_on_wire_timeout_milliseconds =
Zhongyi Shi99d0cdd2019-05-21 01:18:427693 custom_timeout_value;
Nick Harper72ade192019-07-17 03:30:427694 test_params_.quic_params.migrate_sessions_on_network_change_v2 = true;
Zhongyi Shi99d0cdd2019-05-21 01:18:427695 Initialize();
7696 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7697 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7698 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7699
7700 // Using a testing task runner.
7701 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7702 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7703 QuicStreamFactoryPeer::SetAlarmFactory(
7704 factory_.get(),
7705 std::make_unique<QuicChromiumAlarmFactory>(task_runner.get(), &clock_));
7706
Ryan Hamiltonabad59e2019-06-06 04:02:597707 MockQuicData socket_data1(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027708 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi99d0cdd2019-05-21 01:18:427709 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027710 SYNCHRONOUS,
7711 ConstructGetRequestPacket(
7712 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi99d0cdd2019-05-21 01:18:427713 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7714 // Read two packets so that client will send ACK immedaitely.
Ryan Hamilton9f2eac32019-06-27 03:15:547715 socket_data1.AddRead(
7716 ASYNC,
7717 ConstructOkResponsePacket(
7718 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
7719 socket_data1.AddRead(
7720 ASYNC, server_maker_.MakeDataPacket(
7721 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7722 base::StringPiece("Hello World")));
Zhongyi Shi99d0cdd2019-05-21 01:18:427723 // Read an ACK from server which acks all client data.
7724 socket_data1.AddRead(SYNCHRONOUS,
7725 server_maker_.MakeAckPacket(3, 2, 1, 1, false));
7726 socket_data1.AddWrite(ASYNC, client_maker_.MakeAckPacket(3, 2, 1, 1, false));
7727 // The PING packet sent for retransmittable on wire.
7728 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(4, false));
7729 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7730 std::string header = ConstructDataHeader(6);
7731 socket_data1.AddRead(
7732 ASYNC, ConstructServerDataPacket(
7733 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177734 header + "hello!"));
Zhongyi Shi99d0cdd2019-05-21 01:18:427735 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read.
7736 socket_data1.AddWrite(
7737 SYNCHRONOUS, client_maker_.MakeRstPacket(
7738 5, false, GetNthClientInitiatedBidirectionalStreamId(0),
7739 quic::QUIC_STREAM_CANCELLED));
7740 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7741
7742 // Create request and QuicHttpStream.
7743 QuicStreamRequest request(factory_.get());
7744 EXPECT_EQ(ERR_IO_PENDING,
7745 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:527746 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
7747 SocketTag(), NetworkIsolationKey(),
Zhongyi Shi99d0cdd2019-05-21 01:18:427748 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7749 failed_on_default_network_callback_, callback_.callback()));
7750 EXPECT_EQ(OK, callback_.WaitForResult());
7751 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7752 EXPECT_TRUE(stream.get());
7753
7754 // Cause QUIC stream to be created.
7755 HttpRequestInfo request_info;
7756 request_info.method = "GET";
7757 request_info.url = GURL("https://www.example.org/");
7758 request_info.traffic_annotation =
7759 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7760 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7761 net_log_, CompletionOnceCallback()));
7762
7763 // Ensure that session is alive and active.
7764 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7765 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7766
7767 // Complete migration.
7768 task_runner->RunUntilIdle();
7769 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7770 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7771 EXPECT_EQ(1u, session->GetNumActiveStreams());
7772
7773 // Send GET request on stream.
7774 HttpResponseInfo response;
7775 HttpRequestHeaders request_headers;
7776 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7777 callback_.callback()));
7778 socket_data1.Resume();
7779 // Spin up the message loop to read incoming data from server till the ACK.
7780 base::RunLoop().RunUntilIdle();
7781
7782 // Ack delay time.
7783 int delay = task_runner->NextPendingTaskDelay().InMilliseconds();
7784 EXPECT_GT(custom_timeout_value, delay);
7785 // Fire the ack alarm, since ack has been sent, no ack will be sent.
7786 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7787 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7788
7789 // Fire the ping alarm with retransmittable-on-wire timeout, send PING.
7790 delay = custom_timeout_value - delay;
7791 EXPECT_EQ(base::TimeDelta::FromMilliseconds(delay),
7792 task_runner->NextPendingTaskDelay());
7793 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7794 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7795
7796 socket_data1.Resume();
7797
7798 // Verify that response headers on the migrated socket were delivered to the
7799 // stream.
7800 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
7801 EXPECT_EQ(200, response.headers->response_code());
7802
7803 // Resume the old socket data, a read error will be delivered to the old
7804 // packet reader. Verify that the session is not affected.
7805 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7806 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7807 EXPECT_EQ(1u, session->GetNumActiveStreams());
7808
7809 stream.reset();
7810 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7811 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7812}
7813
7814// This test verifies that when only migration on network change is enabled, and
7815// no custom value for retransmittable-on-wire is specified, the ping alarm will
7816// NOT send retransmittable pings to the peer with custom value.
7817TEST_P(QuicStreamFactoryTest,
7818 NoRetransmittableOnWireTimeoutWithMigrationOnNetworkChangeOnly) {
Nick Harper72ade192019-07-17 03:30:427819 test_params_.quic_params.migrate_sessions_on_network_change_v2 = true;
Zhongyi Shi99d0cdd2019-05-21 01:18:427820 Initialize();
7821 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7822 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7823 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7824
7825 // Using a testing task runner.
7826 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7827 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7828 QuicStreamFactoryPeer::SetAlarmFactory(
7829 factory_.get(),
7830 std::make_unique<QuicChromiumAlarmFactory>(task_runner.get(), &clock_));
7831
Ryan Hamiltonabad59e2019-06-06 04:02:597832 MockQuicData socket_data1(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027833 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi99d0cdd2019-05-21 01:18:427834 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027835 SYNCHRONOUS,
7836 ConstructGetRequestPacket(
7837 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi99d0cdd2019-05-21 01:18:427838 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7839 // Read two packets so that client will send ACK immedaitely.
Ryan Hamilton9f2eac32019-06-27 03:15:547840 socket_data1.AddRead(
7841 ASYNC,
7842 ConstructOkResponsePacket(
7843 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
7844 socket_data1.AddRead(
7845 ASYNC, server_maker_.MakeDataPacket(
7846 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7847 base::StringPiece("Hello World")));
Zhongyi Shi99d0cdd2019-05-21 01:18:427848 // Read an ACK from server which acks all client data.
7849 socket_data1.AddRead(SYNCHRONOUS,
7850 server_maker_.MakeAckPacket(3, 2, 1, 1, false));
7851 socket_data1.AddWrite(ASYNC, client_maker_.MakeAckPacket(3, 2, 1, 1, false));
7852 std::string header = ConstructDataHeader(6);
7853 socket_data1.AddRead(
7854 ASYNC, ConstructServerDataPacket(
7855 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177856 header + "hello!"));
Zhongyi Shi99d0cdd2019-05-21 01:18:427857 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read.
7858 socket_data1.AddWrite(
7859 SYNCHRONOUS, client_maker_.MakeRstPacket(
7860 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
7861 quic::QUIC_STREAM_CANCELLED));
7862 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7863
7864 // Create request and QuicHttpStream.
7865 QuicStreamRequest request(factory_.get());
7866 EXPECT_EQ(ERR_IO_PENDING,
7867 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:527868 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
7869 SocketTag(), NetworkIsolationKey(),
Zhongyi Shi99d0cdd2019-05-21 01:18:427870 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7871 failed_on_default_network_callback_, callback_.callback()));
7872 EXPECT_EQ(OK, callback_.WaitForResult());
7873 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7874 EXPECT_TRUE(stream.get());
7875
7876 // Cause QUIC stream to be created.
7877 HttpRequestInfo request_info;
7878 request_info.method = "GET";
7879 request_info.url = GURL("https://www.example.org/");
7880 request_info.traffic_annotation =
7881 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7882 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7883 net_log_, CompletionOnceCallback()));
7884
7885 // Ensure that session is alive and active.
7886 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7887 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7888
7889 // Complete migration.
7890 task_runner->RunUntilIdle();
7891 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7892 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7893 EXPECT_EQ(1u, session->GetNumActiveStreams());
7894
7895 // Send GET request on stream.
7896 HttpResponseInfo response;
7897 HttpRequestHeaders request_headers;
7898 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7899 callback_.callback()));
7900 socket_data1.Resume();
7901 // Spin up the message loop to read incoming data from server till the ACK.
7902 base::RunLoop().RunUntilIdle();
7903
7904 // Ack delay time.
7905 int delay = task_runner->NextPendingTaskDelay().InMilliseconds();
7906 EXPECT_GT(kDefaultRetransmittableOnWireTimeoutMillisecs, delay);
7907 // Fire the ack alarm, since ack has been sent, no ack will be sent.
7908 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7909 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7910
7911 // Verify ping alarm is not set with default value.
7912 int wrong_delay = kDefaultRetransmittableOnWireTimeoutMillisecs - delay;
7913 delay = task_runner->NextPendingTaskDelay().InMilliseconds();
7914 EXPECT_NE(wrong_delay, delay);
7915 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7916 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7917
7918 // Verify that response headers on the migrated socket were delivered to the
7919 // stream.
7920 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
7921 EXPECT_EQ(200, response.headers->response_code());
7922
7923 // Resume the old socket data, a read error will be delivered to the old
7924 // packet reader. Verify that the session is not affected.
7925 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7926 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7927 EXPECT_EQ(1u, session->GetNumActiveStreams());
7928
7929 stream.reset();
7930 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7931 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7932}
7933
Zhongyi Shif3d6cddb2018-07-11 03:30:027934// This test verifies that after migration on write error is posted, packet
7935// read error on the old reader will be ignored and will not close the
7936// connection.
7937TEST_P(QuicStreamFactoryTest,
7938 IgnoreReadErrorOnOldReaderDuringPendingMigrationOnWriteError) {
7939 InitializeConnectionMigrationV2Test(
7940 {kDefaultNetworkForTests, kNewNetworkForTests});
7941 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7942 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7943 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7944
7945 // Using a testing task runner.
7946 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7947 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7948
Ryan Hamiltonabad59e2019-06-06 04:02:597949 MockQuicData socket_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:027950 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shif3d6cddb2018-07-11 03:30:027951 socket_data.AddWrite(ASYNC, ERR_FAILED); // Write error.
7952 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE); // Read error.
7953 socket_data.AddSocketDataToFactory(socket_factory_.get());
7954
7955 // Create request and QuicHttpStream.
7956 QuicStreamRequest request(factory_.get());
7957 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:037958 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:527959 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
7960 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:037961 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7962 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shif3d6cddb2018-07-11 03:30:027963 EXPECT_EQ(OK, callback_.WaitForResult());
7964 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7965 EXPECT_TRUE(stream.get());
7966
7967 // Cause QUIC stream to be created.
7968 HttpRequestInfo request_info;
7969 request_info.method = "GET";
7970 request_info.url = GURL("https://www.example.org/");
7971 request_info.traffic_annotation =
7972 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7973 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7974 net_log_, CompletionOnceCallback()));
7975
7976 // Ensure that session is alive and active.
7977 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7978 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7979 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7980
7981 // Set up second socket data provider that is used after
7982 // migration. The request is written to this new socket, and the
7983 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:597984 MockQuicData socket_data1(version_);
Fan Yang32c5a112018-12-10 20:06:337985 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027986 SYNCHRONOUS,
7987 ConstructGetRequestPacket(
7988 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Ryan Hamilton9f2eac32019-06-27 03:15:547989 client_maker_.set_coalesce_http_frames(true);
Zhongyi Shif3d6cddb2018-07-11 03:30:027990 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337991 ASYNC,
7992 ConstructOkResponsePacket(
7993 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shif3d6cddb2018-07-11 03:30:027994
7995 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7996 socket_data1.AddRead(ASYNC, ERR_FAILED); // Read error to close connection.
7997 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7998
7999 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
8000 // Send GET request on stream.
8001 HttpResponseInfo response;
8002 HttpRequestHeaders request_headers;
8003 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
8004 callback_.callback()));
8005 // Run the message loop to complete asynchronous write and read with errors.
8006 base::RunLoop().RunUntilIdle();
8007 // There will be one pending task to complete migration on write error.
8008 // Verify session is not closed with read error.
8009 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
8010 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8011 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8012 EXPECT_EQ(1u, session->GetNumActiveStreams());
8013
8014 // Complete migration.
8015 task_runner->RunUntilIdle();
Zhongyi Shia7dd46b2018-07-12 22:59:298016 // There will be one more task posted attempting to migrate back to the
8017 // default network.
8018 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
Zhongyi Shif3d6cddb2018-07-11 03:30:028019 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:298020 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shif3d6cddb2018-07-11 03:30:028021 EXPECT_EQ(1u, session->GetNumActiveStreams());
8022
8023 // Verify that response headers on the migrated socket were delivered to the
8024 // stream.
8025 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
8026 EXPECT_EQ(200, response.headers->response_code());
8027
8028 // Resume to consume the read error on new socket, which will close
8029 // the connection.
8030 socket_data1.Resume();
8031
8032 EXPECT_TRUE(socket_data.AllReadDataConsumed());
8033 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
8034 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
8035 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
8036}
8037
Zhongyi Shi4ac9e1f2018-06-21 05:21:478038// Migrate on asynchronous write error, old network disconnects after alternate
8039// network connects.
8040TEST_P(QuicStreamFactoryTest,
8041 MigrateSessionOnWriteErrorWithDisconnectAfterConnectAysnc) {
8042 TestMigrationOnWriteErrorWithMultipleNotifications(
8043 ASYNC, /*disconnect_before_connect*/ false);
8044}
8045
8046// Migrate on synchronous write error, old network disconnects after alternate
8047// network connects.
8048TEST_P(QuicStreamFactoryTest,
8049 MigrateSessionOnWriteErrorWithDisconnectAfterConnectSync) {
8050 TestMigrationOnWriteErrorWithMultipleNotifications(
8051 SYNCHRONOUS, /*disconnect_before_connect*/ false);
8052}
8053
8054// Migrate on asynchronous write error, old network disconnects before alternate
8055// network connects.
8056TEST_P(QuicStreamFactoryTest,
8057 MigrateSessionOnWriteErrorWithDisconnectBeforeConnectAysnc) {
8058 TestMigrationOnWriteErrorWithMultipleNotifications(
8059 ASYNC, /*disconnect_before_connect*/ true);
8060}
8061
8062// Migrate on synchronous write error, old network disconnects before alternate
8063// network connects.
8064TEST_P(QuicStreamFactoryTest,
8065 MigrateSessionOnWriteErrorWithDisconnectBeforeConnectSync) {
8066 TestMigrationOnWriteErrorWithMultipleNotifications(
8067 SYNCHRONOUS, /*disconnect_before_connect*/ true);
8068}
8069
8070// Setps up test which verifies that session successfully migrate to alternate
8071// network with signals delivered in the following order:
8072// *NOTE* Signal (A) and (B) can reverse order based on
8073// |disconnect_before_connect|.
8074// - (No alternate network is connected) session connects to
8075// kDefaultNetworkForTests.
8076// - An async/sync write error is encountered based on |write_error_mode|:
8077// session posted task to migrate session on write error.
8078// - Posted task is executed, miration moves to pending state due to lack of
8079// alternate network.
8080// - (A) An alternate network is connected, pending migration completes.
8081// - (B) Old default network disconnects, no migration will be attempted as
Zhongyi Shi329f5cbd2018-06-22 23:51:188082// session has already migrate to the alternate network.
Zhongyi Shi4ac9e1f2018-06-21 05:21:478083// - The alternate network is made default.
jri5b785512016-09-13 04:29:118084void QuicStreamFactoryTestBase::
Zhongyi Shi4ac9e1f2018-06-21 05:21:478085 TestMigrationOnWriteErrorWithMultipleNotifications(
jri5b785512016-09-13 04:29:118086 IoMode write_error_mode,
Zhongyi Shi4ac9e1f2018-06-21 05:21:478087 bool disconnect_before_connect) {
Zhongyi Shi329f5cbd2018-06-22 23:51:188088 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri5b785512016-09-13 04:29:118089 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8090 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8091 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8092
Ryan Hamiltonabad59e2019-06-06 04:02:598093 MockQuicData socket_data(version_);
jri5b785512016-09-13 04:29:118094 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:028095 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi4ac9e1f2018-06-21 05:21:478096 socket_data.AddWrite(write_error_mode, ERR_FAILED); // Write error.
Zhongyi Shi5f587cc2017-11-21 23:24:178097 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri5b785512016-09-13 04:29:118098
8099 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:458100 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338101 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:038102 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:528103 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
8104 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:038105 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8106 failed_on_default_network_callback_, callback_.callback()));
jri5b785512016-09-13 04:29:118107 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:248108 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri5b785512016-09-13 04:29:118109 EXPECT_TRUE(stream.get());
8110
8111 // Cause QUIC stream to be created.
8112 HttpRequestInfo request_info;
8113 request_info.method = "GET";
8114 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:398115 request_info.traffic_annotation =
8116 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:278117 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:398118 net_log_, CompletionOnceCallback()));
jri5b785512016-09-13 04:29:118119
8120 // Ensure that session is alive and active.
8121 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
8122 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8123 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8124
8125 // Send GET request on stream. This should cause a write error, which triggers
8126 // a connection migration attempt.
8127 HttpResponseInfo response;
8128 HttpRequestHeaders request_headers;
8129 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
8130 callback_.callback()));
Zhongyi Shi4ac9e1f2018-06-21 05:21:478131 // Run the message loop so that posted task to migrate to socket will be
8132 // executed. A new task will be posted to wait for a new network.
jri5b785512016-09-13 04:29:118133 base::RunLoop().RunUntilIdle();
8134
8135 // In this particular code path, the network will not yet be marked
8136 // as going away and the session will still be alive.
8137 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8138 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8139 EXPECT_EQ(1u, session->GetNumActiveStreams());
8140 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
8141
8142 // Set up second socket data provider that is used after
8143 // migration. The request is rewritten to this new socket, and the
8144 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:598145 MockQuicData socket_data1(version_);
Fan Yang32c5a112018-12-10 20:06:338146 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:028147 SYNCHRONOUS,
8148 ConstructGetRequestPacket(
8149 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Ryan Hamilton9f2eac32019-06-27 03:15:548150 client_maker_.set_coalesce_http_frames(true);
Zhongyi Shi32f2fd02018-04-16 18:23:438151 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:338152 ASYNC,
8153 ConstructOkResponsePacket(
8154 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
jri5b785512016-09-13 04:29:118155 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:338156 socket_data1.AddWrite(
8157 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
8158 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
8159 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:178160 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri5b785512016-09-13 04:29:118161
8162 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8163 ->SetConnectedNetworksList(
8164 {kDefaultNetworkForTests, kNewNetworkForTests});
Zhongyi Shi4ac9e1f2018-06-21 05:21:478165 if (disconnect_before_connect) {
8166 // Now deliver a DISCONNECT notification.
jri5b785512016-09-13 04:29:118167 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8168 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
Zhongyi Shi4ac9e1f2018-06-21 05:21:478169
8170 // Now deliver a CONNECTED notification and completes migration.
jri5b785512016-09-13 04:29:118171 scoped_mock_network_change_notifier_->mock_network_change_notifier()
Zhongyi Shi4ac9e1f2018-06-21 05:21:478172 ->NotifyNetworkConnected(kNewNetworkForTests);
8173 } else {
8174 // Now deliver a CONNECTED notification and completes migration.
8175 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8176 ->NotifyNetworkConnected(kNewNetworkForTests);
8177
8178 // Now deliver a DISCONNECT notification.
8179 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8180 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
jri5b785512016-09-13 04:29:118181 }
jri5b785512016-09-13 04:29:118182 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shi329f5cbd2018-06-22 23:51:188183 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:118184 EXPECT_EQ(1u, session->GetNumActiveStreams());
8185
8186 // This is the callback for the response headers that returned
8187 // pending previously, because no result was available. Check that
8188 // the result is now available due to the successful migration.
8189 EXPECT_THAT(callback_.WaitForResult(), IsOk());
8190 EXPECT_EQ(200, response.headers->response_code());
8191
Zhongyi Shi4ac9e1f2018-06-21 05:21:478192 // Deliver a MADEDEFAULT notification.
jri5b785512016-09-13 04:29:118193 scoped_mock_network_change_notifier_->mock_network_change_notifier()
Zhongyi Shi4ac9e1f2018-06-21 05:21:478194 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri5b785512016-09-13 04:29:118195
zhongyi98d6a9262017-05-19 02:47:458196 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:518197 EXPECT_EQ(OK,
8198 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:528199 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
8200 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:518201 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8202 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:248203 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
jri5b785512016-09-13 04:29:118204 EXPECT_TRUE(stream2.get());
8205
8206 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi329f5cbd2018-06-22 23:51:188207 EXPECT_EQ(session, GetActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:118208
8209 stream.reset();
8210 stream2.reset();
8211
8212 EXPECT_TRUE(socket_data.AllReadDataConsumed());
8213 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
8214 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
8215 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
jri5b785512016-09-13 04:29:118216}
8217
Zhongyi Shic16b4102019-02-12 00:37:408218// This test verifies after session migrates off the default network, it keeps
8219// retrying migrate back to the default network until successfully gets on the
8220// default network or the idle migration period threshold is exceeded.
8221// The default threshold is 30s.
8222TEST_P(QuicStreamFactoryTest, DefaultIdleMigrationPeriod) {
Nick Harper72ade192019-07-17 03:30:428223 test_params_.quic_params.migrate_idle_sessions = true;
Zhongyi Shic16b4102019-02-12 00:37:408224 InitializeConnectionMigrationV2Test(
8225 {kDefaultNetworkForTests, kNewNetworkForTests});
8226 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8227 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8228
8229 // Using a testing task runner and a test tick tock.
8230 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
8231 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
8232 QuicStreamFactoryPeer::SetTickClock(factory_.get(),
8233 task_runner->GetMockTickClock());
8234
Ryan Hamiltonabad59e2019-06-06 04:02:598235 MockQuicData default_socket_data(version_);
Zhongyi Shic16b4102019-02-12 00:37:408236 default_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
8237 default_socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
8238 default_socket_data.AddSocketDataToFactory(socket_factory_.get());
8239
8240 // Set up second socket data provider that is used after migration.
Ryan Hamiltonabad59e2019-06-06 04:02:598241 MockQuicData alternate_socket_data(version_);
Zhongyi Shic16b4102019-02-12 00:37:408242 alternate_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8243 // Ping packet to send after migration.
8244 alternate_socket_data.AddWrite(
8245 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
8246 alternate_socket_data.AddSocketDataToFactory(socket_factory_.get());
8247
8248 // Set up probing socket for migrating back to the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:598249 MockQuicData quic_data(version_); // retry count: 0.
Zhongyi Shic16b4102019-02-12 00:37:408250 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8251 quic_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8252 quic_data.AddSocketDataToFactory(socket_factory_.get());
8253
Ryan Hamiltonabad59e2019-06-06 04:02:598254 MockQuicData quic_data1(version_); // retry count: 1
Zhongyi Shic16b4102019-02-12 00:37:408255 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8256 quic_data1.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8257 quic_data1.AddSocketDataToFactory(socket_factory_.get());
8258
Ryan Hamilton0d65a8c2019-06-07 00:46:028259 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:598260 MockQuicData quic_data2(version_); // retry count: 2
Zhongyi Shic16b4102019-02-12 00:37:408261 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8262 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8263 quic_data2.AddSocketDataToFactory(socket_factory_.get());
8264
Ryan Hamilton0d65a8c2019-06-07 00:46:028265 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:598266 MockQuicData quic_data3(version_); // retry count: 3
Zhongyi Shic16b4102019-02-12 00:37:408267 quic_data3.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8268 quic_data3.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8269 quic_data3.AddSocketDataToFactory(socket_factory_.get());
8270
Ryan Hamilton0d65a8c2019-06-07 00:46:028271 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:598272 MockQuicData quic_data4(version_); // retry count: 4
Zhongyi Shic16b4102019-02-12 00:37:408273 quic_data4.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8274 quic_data4.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8275 quic_data4.AddSocketDataToFactory(socket_factory_.get());
8276
Ryan Hamilton0d65a8c2019-06-07 00:46:028277 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:598278 MockQuicData quic_data5(version_); // retry count: 5
Zhongyi Shic16b4102019-02-12 00:37:408279 quic_data5.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8280 quic_data5.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8281 quic_data5.AddSocketDataToFactory(socket_factory_.get());
8282
8283 // Create request and QuicHttpStream.
8284 QuicStreamRequest request(factory_.get());
8285 EXPECT_EQ(ERR_IO_PENDING,
8286 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:528287 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
8288 SocketTag(), NetworkIsolationKey(),
Zhongyi Shic16b4102019-02-12 00:37:408289 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8290 failed_on_default_network_callback_, callback_.callback()));
8291 EXPECT_THAT(callback_.WaitForResult(), IsOk());
8292 std::unique_ptr<HttpStream> stream = CreateStream(&request);
8293 EXPECT_TRUE(stream.get());
8294
8295 // Ensure that session is active.
8296 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8297
8298 // Trigger connection migration. Since there are no active streams,
8299 // the session will be closed.
8300 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8301 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
8302
8303 // The nearest task will complete migration.
8304 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
8305 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
8306 task_runner->FastForwardBy(base::TimeDelta());
8307
8308 // The migrate back timer will fire. Due to default network
8309 // being disconnected, no attempt will be exercised to migrate back.
8310 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
8311 EXPECT_EQ(base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs),
8312 task_runner->NextPendingTaskDelay());
8313 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
8314 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
8315
8316 // Deliver the signal that the old default network now backs up.
8317 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8318 ->NotifyNetworkMadeDefault(kDefaultNetworkForTests);
8319
8320 // A task is posted to migrate back to the default network immediately.
8321 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
8322 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
8323 task_runner->FastForwardBy(base::TimeDelta());
8324
8325 // Retry migrate back in 1, 2, 4, 8, 16s.
8326 // Session will be closed due to idle migration timeout.
8327 for (int i = 0; i < 5; i++) {
8328 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8329 // A task is posted to migrate back to the default network in 2^i seconds.
8330 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
8331 EXPECT_EQ(base::TimeDelta::FromSeconds(UINT64_C(1) << i),
8332 task_runner->NextPendingTaskDelay());
8333 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
8334 }
8335
8336 EXPECT_TRUE(default_socket_data.AllReadDataConsumed());
8337 EXPECT_TRUE(default_socket_data.AllWriteDataConsumed());
8338 EXPECT_TRUE(alternate_socket_data.AllReadDataConsumed());
8339 EXPECT_TRUE(alternate_socket_data.AllWriteDataConsumed());
8340}
8341
8342TEST_P(QuicStreamFactoryTest, CustomIdleMigrationPeriod) {
8343 // The customized threshold is 15s.
Nick Harper72ade192019-07-17 03:30:428344 test_params_.quic_params.migrate_idle_sessions = true;
8345 test_params_.quic_params.idle_session_migration_period =
Zhongyi Shic16b4102019-02-12 00:37:408346 base::TimeDelta::FromSeconds(15);
8347 InitializeConnectionMigrationV2Test(
8348 {kDefaultNetworkForTests, kNewNetworkForTests});
8349 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8350 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8351
8352 // Using a testing task runner and a test tick tock.
8353 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
8354 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
8355 QuicStreamFactoryPeer::SetTickClock(factory_.get(),
8356 task_runner->GetMockTickClock());
8357
Ryan Hamiltonabad59e2019-06-06 04:02:598358 MockQuicData default_socket_data(version_);
Zhongyi Shic16b4102019-02-12 00:37:408359 default_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
8360 default_socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
8361 default_socket_data.AddSocketDataToFactory(socket_factory_.get());
8362
8363 // Set up second socket data provider that is used after migration.
Ryan Hamiltonabad59e2019-06-06 04:02:598364 MockQuicData alternate_socket_data(version_);
Zhongyi Shic16b4102019-02-12 00:37:408365 alternate_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8366 // Ping packet to send after migration.
8367 alternate_socket_data.AddWrite(
8368 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
8369 alternate_socket_data.AddSocketDataToFactory(socket_factory_.get());
8370
8371 // Set up probing socket for migrating back to the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:598372 MockQuicData quic_data(version_); // retry count: 0.
Zhongyi Shic16b4102019-02-12 00:37:408373 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8374 quic_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8375 quic_data.AddSocketDataToFactory(socket_factory_.get());
8376
Ryan Hamilton0d65a8c2019-06-07 00:46:028377 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:598378 MockQuicData quic_data1(version_); // retry count: 1
Zhongyi Shic16b4102019-02-12 00:37:408379 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8380 quic_data1.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8381 quic_data1.AddSocketDataToFactory(socket_factory_.get());
8382
Ryan Hamilton0d65a8c2019-06-07 00:46:028383 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:598384 MockQuicData quic_data2(version_); // retry count: 2
Zhongyi Shic16b4102019-02-12 00:37:408385 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8386 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8387 quic_data2.AddSocketDataToFactory(socket_factory_.get());
8388
Ryan Hamilton0d65a8c2019-06-07 00:46:028389 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:598390 MockQuicData quic_data3(version_); // retry count: 3
Zhongyi Shic16b4102019-02-12 00:37:408391 quic_data3.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8392 quic_data3.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8393 quic_data3.AddSocketDataToFactory(socket_factory_.get());
8394
Ryan Hamilton0d65a8c2019-06-07 00:46:028395 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:598396 MockQuicData quic_data4(version_); // retry count: 4
Zhongyi Shic16b4102019-02-12 00:37:408397 quic_data4.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8398 quic_data4.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8399 quic_data4.AddSocketDataToFactory(socket_factory_.get());
8400
8401 // Create request and QuicHttpStream.
8402 QuicStreamRequest request(factory_.get());
8403 EXPECT_EQ(ERR_IO_PENDING,
8404 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:528405 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
8406 SocketTag(), NetworkIsolationKey(),
Zhongyi Shic16b4102019-02-12 00:37:408407 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8408 failed_on_default_network_callback_, callback_.callback()));
8409 EXPECT_THAT(callback_.WaitForResult(), IsOk());
8410 std::unique_ptr<HttpStream> stream = CreateStream(&request);
8411 EXPECT_TRUE(stream.get());
8412
8413 // Ensure that session is active.
8414 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8415
8416 // Trigger connection migration. Since there are no active streams,
8417 // the session will be closed.
8418 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8419 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
8420
8421 // The nearest task will complete migration.
8422 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
8423 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
8424 task_runner->FastForwardBy(base::TimeDelta());
8425
8426 // The migrate back timer will fire. Due to default network
8427 // being disconnected, no attempt will be exercised to migrate back.
8428 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
8429 EXPECT_EQ(base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs),
8430 task_runner->NextPendingTaskDelay());
8431 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
8432 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
8433
8434 // Deliver the signal that the old default network now backs up.
8435 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8436 ->NotifyNetworkMadeDefault(kDefaultNetworkForTests);
8437
8438 // A task is posted to migrate back to the default network immediately.
8439 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
8440 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
8441 task_runner->FastForwardBy(base::TimeDelta());
8442
8443 // Retry migrate back in 1, 2, 4, 8s.
8444 // Session will be closed due to idle migration timeout.
8445 for (int i = 0; i < 4; i++) {
8446 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8447 // A task is posted to migrate back to the default network in 2^i seconds.
8448 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
8449 EXPECT_EQ(base::TimeDelta::FromSeconds(UINT64_C(1) << i),
8450 task_runner->NextPendingTaskDelay());
8451 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
8452 }
8453
8454 EXPECT_TRUE(default_socket_data.AllReadDataConsumed());
8455 EXPECT_TRUE(default_socket_data.AllWriteDataConsumed());
8456 EXPECT_TRUE(alternate_socket_data.AllReadDataConsumed());
8457 EXPECT_TRUE(alternate_socket_data.AllWriteDataConsumed());
8458}
8459
jri217455a12016-07-13 20:15:098460TEST_P(QuicStreamFactoryTest, ServerMigration) {
Nick Harper72ade192019-07-17 03:30:428461 test_params_.quic_params.allow_server_migration = true;
jri217455a12016-07-13 20:15:098462 Initialize();
8463
8464 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8465 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8466 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8467
Ryan Hamiltonabad59e2019-06-06 04:02:598468 MockQuicData socket_data1(version_);
rcha00569732016-08-27 11:09:368469 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:028470 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
rch5cb522462017-04-25 20:18:368471 socket_data1.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:028472 SYNCHRONOUS,
8473 ConstructGetRequestPacket(
8474 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true));
Zhongyi Shi5f587cc2017-11-21 23:24:178475 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri217455a12016-07-13 20:15:098476
8477 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:458478 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338479 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:038480 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:528481 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
8482 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:038483 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8484 failed_on_default_network_callback_, callback_.callback()));
jri217455a12016-07-13 20:15:098485 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:248486 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri217455a12016-07-13 20:15:098487 EXPECT_TRUE(stream.get());
8488
8489 // Cause QUIC stream to be created.
8490 HttpRequestInfo request_info;
8491 request_info.method = "GET";
8492 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:398493 request_info.traffic_annotation =
8494 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:278495 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:398496 net_log_, CompletionOnceCallback()));
jri217455a12016-07-13 20:15:098497
8498 // Ensure that session is alive and active.
8499 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
8500 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8501 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8502
8503 // Send GET request on stream.
8504 HttpResponseInfo response;
8505 HttpRequestHeaders request_headers;
8506 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
8507 callback_.callback()));
8508
8509 IPEndPoint ip;
8510 session->GetDefaultSocket()->GetPeerAddress(&ip);
8511 DVLOG(1) << "Socket connected to: " << ip.address().ToString() << " "
8512 << ip.port();
8513
8514 // Set up second socket data provider that is used after
8515 // migration. The request is rewritten to this new socket, and the
8516 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:598517 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:368518 socket_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438519 SYNCHRONOUS, client_maker_.MakePingPacket(3, /*include_version=*/true));
8520 socket_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:338521 ASYNC,
8522 ConstructOkResponsePacket(
8523 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
rcha00569732016-08-27 11:09:368524 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:338525 socket_data2.AddWrite(
8526 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
8527 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
8528 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:178529 socket_data2.AddSocketDataToFactory(socket_factory_.get());
jri217455a12016-07-13 20:15:098530
8531 const uint8_t kTestIpAddress[] = {1, 2, 3, 4};
8532 const uint16_t kTestPort = 123;
Zhongyi Shif124a582017-11-02 00:15:048533 session->Migrate(NetworkChangeNotifier::kInvalidNetworkHandle,
8534 IPEndPoint(IPAddress(kTestIpAddress), kTestPort), true,
8535 net_log_);
jri217455a12016-07-13 20:15:098536
8537 session->GetDefaultSocket()->GetPeerAddress(&ip);
8538 DVLOG(1) << "Socket migrated to: " << ip.address().ToString() << " "
8539 << ip.port();
8540
8541 // The session should be alive and active.
8542 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8543 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8544 EXPECT_EQ(1u, session->GetNumActiveStreams());
8545
8546 // Run the message loop so that data queued in the new socket is read by the
8547 // packet reader.
8548 base::RunLoop().RunUntilIdle();
8549
8550 // Verify that response headers on the migrated socket were delivered to the
8551 // stream.
8552 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
8553 EXPECT_EQ(200, response.headers->response_code());
8554
8555 stream.reset();
8556
8557 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
8558 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
8559 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
8560 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
8561}
8562
jri053fdbd2016-08-19 02:33:058563TEST_P(QuicStreamFactoryTest, ServerMigrationIPv4ToIPv4) {
8564 // Add alternate IPv4 server address to config.
8565 IPEndPoint alt_address = IPEndPoint(IPAddress(1, 2, 3, 4), 123);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528566 quic::QuicConfig config;
Victor Vasiliev4f6fb892019-05-31 16:58:318567 config.SetAlternateServerAddressToSend(ToQuicSocketAddress(alt_address));
jri053fdbd2016-08-19 02:33:058568 VerifyServerMigration(config, alt_address);
8569}
8570
8571TEST_P(QuicStreamFactoryTest, ServerMigrationIPv6ToIPv6) {
8572 // Add a resolver rule to make initial connection to an IPv6 address.
Renjiea0cb4a2c2018-09-26 23:37:308573 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
8574 "fe80::aebc:32ff:febb:1e33", "");
jri053fdbd2016-08-19 02:33:058575 // Add alternate IPv6 server address to config.
8576 IPEndPoint alt_address = IPEndPoint(
8577 IPAddress(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), 123);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528578 quic::QuicConfig config;
Victor Vasiliev4f6fb892019-05-31 16:58:318579 config.SetAlternateServerAddressToSend(ToQuicSocketAddress(alt_address));
jri053fdbd2016-08-19 02:33:058580 VerifyServerMigration(config, alt_address);
8581}
8582
8583TEST_P(QuicStreamFactoryTest, ServerMigrationIPv6ToIPv4) {
8584 // Add a resolver rule to make initial connection to an IPv6 address.
Renjiea0cb4a2c2018-09-26 23:37:308585 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
8586 "fe80::aebc:32ff:febb:1e33", "");
jri053fdbd2016-08-19 02:33:058587 // Add alternate IPv4 server address to config.
8588 IPEndPoint alt_address = IPEndPoint(IPAddress(1, 2, 3, 4), 123);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528589 quic::QuicConfig config;
Victor Vasiliev4f6fb892019-05-31 16:58:318590 config.SetAlternateServerAddressToSend(ToQuicSocketAddress(alt_address));
jri053fdbd2016-08-19 02:33:058591 IPEndPoint expected_address(
8592 ConvertIPv4ToIPv4MappedIPv6(alt_address.address()), alt_address.port());
8593 VerifyServerMigration(config, expected_address);
8594}
8595
8596TEST_P(QuicStreamFactoryTest, ServerMigrationIPv4ToIPv6Fails) {
Nick Harper72ade192019-07-17 03:30:428597 test_params_.quic_params.allow_server_migration = true;
jri053fdbd2016-08-19 02:33:058598 Initialize();
8599
8600 // Add a resolver rule to make initial connection to an IPv4 address.
Renjiea0cb4a2c2018-09-26 23:37:308601 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), "1.2.3.4",
8602 "");
jri053fdbd2016-08-19 02:33:058603 // Add alternate IPv6 server address to config.
8604 IPEndPoint alt_address = IPEndPoint(
8605 IPAddress(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), 123);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528606 quic::QuicConfig config;
Victor Vasiliev4f6fb892019-05-31 16:58:318607 config.SetAlternateServerAddressToSend(ToQuicSocketAddress(alt_address));
jri053fdbd2016-08-19 02:33:058608
8609 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8610 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8611 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8612
8613 crypto_client_stream_factory_.SetConfig(config);
8614
8615 // Set up only socket data provider.
Ryan Hamiltonabad59e2019-06-06 04:02:598616 MockQuicData socket_data1(version_);
rcha00569732016-08-27 11:09:368617 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:438618 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
8619 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338620 SYNCHRONOUS, client_maker_.MakeRstPacket(
8621 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
8622 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:178623 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri053fdbd2016-08-19 02:33:058624
8625 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:458626 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338627 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:038628 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:528629 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
8630 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:038631 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8632 failed_on_default_network_callback_, callback_.callback()));
jri053fdbd2016-08-19 02:33:058633 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:248634 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri053fdbd2016-08-19 02:33:058635 EXPECT_TRUE(stream.get());
8636
8637 // Cause QUIC stream to be created.
8638 HttpRequestInfo request_info;
8639 request_info.method = "GET";
8640 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:398641 request_info.traffic_annotation =
8642 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:278643 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:398644 net_log_, CompletionOnceCallback()));
jri053fdbd2016-08-19 02:33:058645
8646 // Ensure that session is alive and active.
8647 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
8648 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8649 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8650
8651 IPEndPoint actual_address;
8652 session->GetDefaultSocket()->GetPeerAddress(&actual_address);
8653 // No migration should have happened.
8654 IPEndPoint expected_address =
8655 IPEndPoint(IPAddress(1, 2, 3, 4), kDefaultServerPort);
8656 EXPECT_EQ(actual_address, expected_address);
8657 DVLOG(1) << "Socket connected to: " << actual_address.address().ToString()
8658 << " " << actual_address.port();
8659 DVLOG(1) << "Expected address: " << expected_address.address().ToString()
8660 << " " << expected_address.port();
8661
8662 stream.reset();
8663 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
8664 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
8665}
8666
rsleevi17784692016-10-12 01:36:208667TEST_P(QuicStreamFactoryTest, OnCertDBChanged) {
jri7046038f2015-10-22 00:29:268668 Initialize();
rch6faa4d42016-01-05 20:48:438669 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8670 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8671 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8672
Ryan Hamiltonabad59e2019-06-06 04:02:598673 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:368674 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:438675 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:178676 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]d7d1e50b2013-11-25 22:08:098677
Ryan Hamilton0d65a8c2019-06-07 00:46:028678 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:598679 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:368680 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:028681 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:178682 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]d7d1e50b2013-11-25 22:08:098683
zhongyi98d6a9262017-05-19 02:47:458684 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338685 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:038686 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:528687 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
8688 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:038689 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8690 failed_on_default_network_callback_, callback_.callback()));
[email protected]d7d1e50b2013-11-25 22:08:098691
robpercival214763f2016-07-01 23:27:018692 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:248693 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Charles 'Buck' Krasic71763c9f2018-02-16 02:37:288694 EXPECT_TRUE(stream);
8695 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
[email protected]d7d1e50b2013-11-25 22:08:098696
8697 // Change the CA cert and verify that stream saw the event.
mattmfd05a1f2017-02-18 06:18:448698 factory_->OnCertDBChanged();
Charles 'Buck' Krasic71763c9f2018-02-16 02:37:288699
jri7046038f2015-10-22 00:29:268700 EXPECT_FALSE(factory_->require_confirmation());
Charles 'Buck' Krasic71763c9f2018-02-16 02:37:288701 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8702 EXPECT_FALSE(HasActiveSession(host_port_pair_));
[email protected]d7d1e50b2013-11-25 22:08:098703
8704 // Now attempting to request a stream to the same origin should create
8705 // a new session.
8706
zhongyi98d6a9262017-05-19 02:47:458707 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338708 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:038709 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:528710 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
8711 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:038712 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8713 failed_on_default_network_callback_, callback_.callback()));
[email protected]d7d1e50b2013-11-25 22:08:098714
robpercival214763f2016-07-01 23:27:018715 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Charles 'Buck' Krasic71763c9f2018-02-16 02:37:288716 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
8717 EXPECT_TRUE(stream2);
8718 QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
8719 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8720 EXPECT_NE(session, session2);
8721 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8722 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
8723
8724 stream2.reset();
8725 stream.reset();
[email protected]d7d1e50b2013-11-25 22:08:098726
rch37de576c2015-05-17 20:28:178727 EXPECT_TRUE(socket_data.AllReadDataConsumed());
8728 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
8729 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
8730 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]d7d1e50b2013-11-25 22:08:098731}
8732
[email protected]1e960032013-12-20 19:00:208733TEST_P(QuicStreamFactoryTest, SharedCryptoConfig) {
jri7046038f2015-10-22 00:29:268734 Initialize();
rch6faa4d42016-01-05 20:48:438735
rch872e00e2016-12-02 02:48:188736 std::vector<string> cannoncial_suffixes;
[email protected]6e12d702013-11-13 00:17:178737 cannoncial_suffixes.push_back(string(".c.youtube.com"));
8738 cannoncial_suffixes.push_back(string(".googlevideo.com"));
[email protected]c49ff182013-09-28 08:33:268739
[email protected]6e12d702013-11-13 00:17:178740 for (unsigned i = 0; i < cannoncial_suffixes.size(); ++i) {
8741 string r1_host_name("r1");
8742 string r2_host_name("r2");
8743 r1_host_name.append(cannoncial_suffixes[i]);
8744 r2_host_name.append(cannoncial_suffixes[i]);
[email protected]b70fdb792013-10-25 19:04:148745
[email protected]bf4ea2f2014-03-10 22:57:538746 HostPortPair host_port_pair1(r1_host_name, 80);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528747 quic::QuicCryptoClientConfig* crypto_config =
jri7046038f2015-10-22 00:29:268748 QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
Ryan Hamilton4f0b26e2018-06-27 23:52:328749 quic::QuicServerId server_id1(host_port_pair1.host(),
8750 host_port_pair1.port(), privacy_mode_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528751 quic::QuicCryptoClientConfig::CachedState* cached1 =
[email protected]257f24f2014-04-01 09:15:378752 crypto_config->LookupOrCreate(server_id1);
[email protected]6e12d702013-11-13 00:17:178753 EXPECT_FALSE(cached1->proof_valid());
8754 EXPECT_TRUE(cached1->source_address_token().empty());
8755
8756 // Mutate the cached1 to have different data.
8757 // TODO(rtenneti): mutate other members of CachedState.
8758 cached1->set_source_address_token(r1_host_name);
8759 cached1->SetProofValid();
8760
[email protected]bf4ea2f2014-03-10 22:57:538761 HostPortPair host_port_pair2(r2_host_name, 80);
Ryan Hamilton4f0b26e2018-06-27 23:52:328762 quic::QuicServerId server_id2(host_port_pair2.host(),
8763 host_port_pair2.port(), privacy_mode_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528764 quic::QuicCryptoClientConfig::CachedState* cached2 =
[email protected]257f24f2014-04-01 09:15:378765 crypto_config->LookupOrCreate(server_id2);
[email protected]6e12d702013-11-13 00:17:178766 EXPECT_EQ(cached1->source_address_token(), cached2->source_address_token());
8767 EXPECT_TRUE(cached2->proof_valid());
8768 }
[email protected]b70fdb792013-10-25 19:04:148769}
8770
[email protected]1e960032013-12-20 19:00:208771TEST_P(QuicStreamFactoryTest, CryptoConfigWhenProofIsInvalid) {
jri7046038f2015-10-22 00:29:268772 Initialize();
rch872e00e2016-12-02 02:48:188773 std::vector<string> cannoncial_suffixes;
[email protected]6e12d702013-11-13 00:17:178774 cannoncial_suffixes.push_back(string(".c.youtube.com"));
8775 cannoncial_suffixes.push_back(string(".googlevideo.com"));
[email protected]b70fdb792013-10-25 19:04:148776
[email protected]6e12d702013-11-13 00:17:178777 for (unsigned i = 0; i < cannoncial_suffixes.size(); ++i) {
8778 string r3_host_name("r3");
8779 string r4_host_name("r4");
8780 r3_host_name.append(cannoncial_suffixes[i]);
8781 r4_host_name.append(cannoncial_suffixes[i]);
[email protected]b70fdb792013-10-25 19:04:148782
[email protected]bf4ea2f2014-03-10 22:57:538783 HostPortPair host_port_pair1(r3_host_name, 80);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528784 quic::QuicCryptoClientConfig* crypto_config =
jri7046038f2015-10-22 00:29:268785 QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
Ryan Hamilton4f0b26e2018-06-27 23:52:328786 quic::QuicServerId server_id1(host_port_pair1.host(),
8787 host_port_pair1.port(), privacy_mode_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528788 quic::QuicCryptoClientConfig::CachedState* cached1 =
[email protected]257f24f2014-04-01 09:15:378789 crypto_config->LookupOrCreate(server_id1);
[email protected]6e12d702013-11-13 00:17:178790 EXPECT_FALSE(cached1->proof_valid());
8791 EXPECT_TRUE(cached1->source_address_token().empty());
8792
8793 // Mutate the cached1 to have different data.
8794 // TODO(rtenneti): mutate other members of CachedState.
8795 cached1->set_source_address_token(r3_host_name);
8796 cached1->SetProofInvalid();
8797
[email protected]bf4ea2f2014-03-10 22:57:538798 HostPortPair host_port_pair2(r4_host_name, 80);
Ryan Hamilton4f0b26e2018-06-27 23:52:328799 quic::QuicServerId server_id2(host_port_pair2.host(),
8800 host_port_pair2.port(), privacy_mode_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528801 quic::QuicCryptoClientConfig::CachedState* cached2 =
[email protected]257f24f2014-04-01 09:15:378802 crypto_config->LookupOrCreate(server_id2);
[email protected]6e12d702013-11-13 00:17:178803 EXPECT_NE(cached1->source_address_token(), cached2->source_address_token());
8804 EXPECT_TRUE(cached2->source_address_token().empty());
8805 EXPECT_FALSE(cached2->proof_valid());
8806 }
[email protected]c49ff182013-09-28 08:33:268807}
8808
rtenneti34dffe752015-02-24 23:27:328809TEST_P(QuicStreamFactoryTest, EnableNotLoadFromDiskCache) {
jri7046038f2015-10-22 00:29:268810 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:208811 factory_->set_require_confirmation(false);
rch6faa4d42016-01-05 20:48:438812 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8813 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8814
jri7046038f2015-10-22 00:29:268815 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
rtenneti34dffe752015-02-24 23:27:328816
Ryan Hamiltonabad59e2019-06-06 04:02:598817 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:368818 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:178819 socket_data.AddSocketDataToFactory(socket_factory_.get());
rtenneti34dffe752015-02-24 23:27:328820
8821 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:278822 MockCryptoClientStream::ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:308823 host_resolver_->set_synchronous_mode(true);
8824 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
8825 "192.168.0.1", "");
rtenneti34dffe752015-02-24 23:27:328826
zhongyi98d6a9262017-05-19 02:47:458827 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:518828 EXPECT_EQ(OK,
8829 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:528830 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
8831 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:518832 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8833 failed_on_default_network_callback_, callback_.callback()));
rtenneti34dffe752015-02-24 23:27:328834
8835 // If we are waiting for disk cache, we would have posted a task. Verify that
8836 // the CancelWaitForDataReady task hasn't been posted.
8837 ASSERT_EQ(0u, runner_->GetPostedTasks().size());
8838
Yixin Wang7891a39d2017-11-08 20:59:248839 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rtenneti34dffe752015-02-24 23:27:328840 EXPECT_TRUE(stream.get());
rch37de576c2015-05-17 20:28:178841 EXPECT_TRUE(socket_data.AllReadDataConsumed());
8842 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
rtenneti34dffe752015-02-24 23:27:328843}
8844
dmurph44ca4f42016-09-09 20:39:098845TEST_P(QuicStreamFactoryTest, ReducePingTimeoutOnConnectionTimeOutOpenStreams) {
Nick Harper72ade192019-07-17 03:30:428846 test_params_.quic_params.reduced_ping_timeout_seconds = 10;
dmurph44ca4f42016-09-09 20:39:098847 Initialize();
8848 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8849 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8850 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8851
8852 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
zhongyidd1439f62016-09-02 02:02:268853
Ryan Hamiltonabad59e2019-06-06 04:02:598854 MockQuicData socket_data(version_);
zhongyidd1439f62016-09-02 02:02:268855 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:438856 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:178857 socket_data.AddSocketDataToFactory(socket_factory_.get());
zhongyidd1439f62016-09-02 02:02:268858
Ryan Hamilton0d65a8c2019-06-07 00:46:028859 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:598860 MockQuicData socket_data2(version_);
zhongyidd1439f62016-09-02 02:02:268861 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton0d65a8c2019-06-07 00:46:028862 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:178863 socket_data2.AddSocketDataToFactory(socket_factory_.get());
zhongyidd1439f62016-09-02 02:02:268864
8865 HostPortPair server2(kServer2HostName, kDefaultServerPort);
8866
8867 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:278868 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Renjiea0cb4a2c2018-09-26 23:37:308869 host_resolver_->set_synchronous_mode(true);
8870 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
8871 "192.168.0.1", "");
8872 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
zhongyidd1439f62016-09-02 02:02:268873
8874 // Quic should use default PING timeout when no previous connection times out
8875 // with open stream.
Ryan Hamilton8d9ee76e2018-05-29 23:52:528876 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(quic::kPingTimeoutSecs),
zhongyidd1439f62016-09-02 02:02:268877 QuicStreamFactoryPeer::GetPingTimeout(factory_.get()));
zhongyi98d6a9262017-05-19 02:47:458878 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:518879 EXPECT_EQ(OK,
8880 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:528881 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
8882 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:518883 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8884 failed_on_default_network_callback_, callback_.callback()));
zhongyidd1439f62016-09-02 02:02:268885
8886 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528887 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(quic::kPingTimeoutSecs),
zhongyidd1439f62016-09-02 02:02:268888 session->connection()->ping_timeout());
8889
Yixin Wang7891a39d2017-11-08 20:59:248890 std::unique_ptr<HttpStream> stream = CreateStream(&request);
zhongyidd1439f62016-09-02 02:02:268891 EXPECT_TRUE(stream.get());
8892 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:398893 request_info.traffic_annotation =
8894 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:278895 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:398896 net_log_, CompletionOnceCallback()));
zhongyidd1439f62016-09-02 02:02:268897
8898 DVLOG(1)
8899 << "Created 1st session and initialized a stream. Now trigger timeout";
Ryan Hamilton8d9ee76e2018-05-29 23:52:528900 session->connection()->CloseConnection(
8901 quic::QUIC_NETWORK_IDLE_TIMEOUT, "test",
8902 quic::ConnectionCloseBehavior::SILENT_CLOSE);
zhongyidd1439f62016-09-02 02:02:268903 // Need to spin the loop now to ensure that
8904 // QuicStreamFactory::OnSessionClosed() runs.
8905 base::RunLoop run_loop;
8906 run_loop.RunUntilIdle();
8907
zhongyidd1439f62016-09-02 02:02:268908 // The first connection times out with open stream, QUIC should reduce initial
8909 // PING time for subsequent connections.
Ryan Hamilton8d9ee76e2018-05-29 23:52:528910 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(10),
zhongyidd1439f62016-09-02 02:02:268911 QuicStreamFactoryPeer::GetPingTimeout(factory_.get()));
8912
8913 // Test two-in-a-row timeouts with open streams.
8914 DVLOG(1) << "Create 2nd session and timeout with open stream";
8915 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:458916 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:518917 EXPECT_EQ(OK,
8918 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:528919 server2, version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
8920 NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:518921 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
8922 failed_on_default_network_callback_, callback2.callback()));
zhongyidd1439f62016-09-02 02:02:268923 QuicChromiumClientSession* session2 = GetActiveSession(server2);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528924 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(10),
zhongyidd1439f62016-09-02 02:02:268925 session2->connection()->ping_timeout());
8926
Yixin Wang7891a39d2017-11-08 20:59:248927 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
zhongyidd1439f62016-09-02 02:02:268928 EXPECT_TRUE(stream2.get());
Steven Valdezb4ff0412018-01-18 22:39:278929 EXPECT_EQ(OK,
8930 stream2->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:398931 net_log_, CompletionOnceCallback()));
zhongyidd1439f62016-09-02 02:02:268932 session2->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:528933 quic::QUIC_NETWORK_IDLE_TIMEOUT, "test",
8934 quic::ConnectionCloseBehavior::SILENT_CLOSE);
zhongyidd1439f62016-09-02 02:02:268935 // Need to spin the loop now to ensure that
8936 // QuicStreamFactory::OnSessionClosed() runs.
8937 base::RunLoop run_loop2;
8938 run_loop2.RunUntilIdle();
zhongyidd1439f62016-09-02 02:02:268939
8940 EXPECT_TRUE(socket_data.AllReadDataConsumed());
8941 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
8942 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
8943 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
8944}
8945
tbansal3b966952016-10-25 23:25:148946// Verifies that the QUIC stream factory is initialized correctly.
rtenneticd2aaa15b2015-10-10 20:29:338947TEST_P(QuicStreamFactoryTest, MaybeInitialize) {
tbansal9b1cdf32017-05-10 17:28:398948 VerifyInitialization();
rtenneti8a80a6dc2015-09-21 19:51:138949}
8950
rtennetid073dd22016-08-04 01:58:338951TEST_P(QuicStreamFactoryTest, StartCertVerifyJob) {
8952 Initialize();
8953
Ryan Hamiltonabad59e2019-06-06 04:02:598954 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:368955 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:438956 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:178957 socket_data.AddSocketDataToFactory(socket_factory_.get());
rtennetid073dd22016-08-04 01:58:338958
8959 // Save current state of |race_cert_verification|.
8960 bool race_cert_verification =
8961 QuicStreamFactoryPeer::GetRaceCertVerification(factory_.get());
8962
8963 // Load server config.
8964 HostPortPair host_port_pair(kDefaultServerHostName, kDefaultServerPort);
Ryan Hamilton4f0b26e2018-06-27 23:52:328965 quic::QuicServerId quic_server_id(host_port_pair_.host(),
8966 host_port_pair_.port(),
8967 privacy_mode_ == PRIVACY_MODE_ENABLED);
rtennetid073dd22016-08-04 01:58:338968 QuicStreamFactoryPeer::CacheDummyServerConfig(factory_.get(), quic_server_id);
8969
8970 QuicStreamFactoryPeer::SetRaceCertVerification(factory_.get(), true);
8971 EXPECT_FALSE(HasActiveCertVerifierJob(quic_server_id));
8972
8973 // Start CertVerifyJob.
Ryan Hamilton8d9ee76e2018-05-29 23:52:528974 quic::QuicAsyncStatus status = QuicStreamFactoryPeer::StartCertVerifyJob(
rtennetid073dd22016-08-04 01:58:338975 factory_.get(), quic_server_id, /*cert_verify_flags=*/0, net_log_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528976 if (status == quic::QUIC_PENDING) {
rtennetid073dd22016-08-04 01:58:338977 // Verify CertVerifierJob has started.
8978 EXPECT_TRUE(HasActiveCertVerifierJob(quic_server_id));
8979
8980 while (HasActiveCertVerifierJob(quic_server_id)) {
8981 base::RunLoop().RunUntilIdle();
8982 }
8983 }
8984 // Verify CertVerifierJob has finished.
8985 EXPECT_FALSE(HasActiveCertVerifierJob(quic_server_id));
8986
8987 // Start a QUIC request.
zhongyi98d6a9262017-05-19 02:47:458988 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338989 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:038990 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:528991 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
8992 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:038993 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8994 failed_on_default_network_callback_, callback_.callback()));
rtennetid073dd22016-08-04 01:58:338995
8996 EXPECT_EQ(OK, callback_.WaitForResult());
8997
Yixin Wang7891a39d2017-11-08 20:59:248998 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rtennetid073dd22016-08-04 01:58:338999 EXPECT_TRUE(stream.get());
9000
9001 // Restore |race_cert_verification|.
9002 QuicStreamFactoryPeer::SetRaceCertVerification(factory_.get(),
9003 race_cert_verification);
9004
9005 EXPECT_TRUE(socket_data.AllReadDataConsumed());
9006 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
9007
9008 // Verify there are no outstanding CertVerifierJobs after request has
9009 // finished.
9010 EXPECT_FALSE(HasActiveCertVerifierJob(quic_server_id));
9011}
9012
rtenneti1cd3b162015-09-29 02:58:289013TEST_P(QuicStreamFactoryTest, YieldAfterPackets) {
jri7046038f2015-10-22 00:29:269014 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:209015 factory_->set_require_confirmation(false);
rch6faa4d42016-01-05 20:48:439016 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9017 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:269018 QuicStreamFactoryPeer::SetYieldAfterPackets(factory_.get(), 0);
rtenneti1cd3b162015-09-29 02:58:289019
Ryan Hamiltonabad59e2019-06-06 04:02:599020 MockQuicData socket_data(version_);
Fan Yangac867502019-01-28 21:10:239021 socket_data.AddRead(SYNCHRONOUS, ConstructClientConnectionClosePacket(1));
rcha00569732016-08-27 11:09:369022 socket_data.AddRead(ASYNC, OK);
Zhongyi Shi5f587cc2017-11-21 23:24:179023 socket_data.AddSocketDataToFactory(socket_factory_.get());
rtenneti1cd3b162015-09-29 02:58:289024
9025 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:279026 MockCryptoClientStream::ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:309027 host_resolver_->set_synchronous_mode(true);
9028 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
9029 "192.168.0.1", "");
rtenneti1cd3b162015-09-29 02:58:289030
rcha02807b42016-01-29 21:56:159031 // Set up the TaskObserver to verify QuicChromiumPacketReader::StartReading
9032 // posts a task.
rtenneti1cd3b162015-09-29 02:58:289033 // TODO(rtenneti): Change SpdySessionTestTaskObserver to NetTestTaskObserver??
rcha02807b42016-01-29 21:56:159034 SpdySessionTestTaskObserver observer("quic_chromium_packet_reader.cc",
9035 "StartReading");
rtenneti1cd3b162015-09-29 02:58:289036
zhongyi98d6a9262017-05-19 02:47:459037 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:519038 EXPECT_EQ(OK,
9039 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529040 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
9041 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:519042 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9043 failed_on_default_network_callback_, callback_.callback()));
rtenneti1cd3b162015-09-29 02:58:289044
rcha02807b42016-01-29 21:56:159045 // Call run_loop so that QuicChromiumPacketReader::OnReadComplete() gets
9046 // called.
rtenneti1cd3b162015-09-29 02:58:289047 base::RunLoop run_loop;
9048 run_loop.RunUntilIdle();
9049
9050 // Verify task that the observer's executed_count is 1, which indicates
rcha02807b42016-01-29 21:56:159051 // QuicChromiumPacketReader::StartReading() has posted only one task and
9052 // yielded the read.
rtenneti1cd3b162015-09-29 02:58:289053 EXPECT_EQ(1u, observer.executed_count());
9054
Yixin Wang7891a39d2017-11-08 20:59:249055 std::unique_ptr<HttpStream> stream = CreateStream(&request);
xunjieli2608f9b2016-03-14 13:39:239056 EXPECT_FALSE(stream.get()); // Session is already closed.
rtenneti1cd3b162015-09-29 02:58:289057 EXPECT_TRUE(socket_data.AllReadDataConsumed());
9058 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
9059}
9060
9061TEST_P(QuicStreamFactoryTest, YieldAfterDuration) {
jri7046038f2015-10-22 00:29:269062 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:209063 factory_->set_require_confirmation(false);
rch6faa4d42016-01-05 20:48:439064 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9065 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rtenneti1cd3b162015-09-29 02:58:289066 QuicStreamFactoryPeer::SetYieldAfterDuration(
Ryan Hamilton8d9ee76e2018-05-29 23:52:529067 factory_.get(), quic::QuicTime::Delta::FromMilliseconds(-1));
rtenneti1cd3b162015-09-29 02:58:289068
Ryan Hamiltonabad59e2019-06-06 04:02:599069 MockQuicData socket_data(version_);
Fan Yangac867502019-01-28 21:10:239070 socket_data.AddRead(SYNCHRONOUS, ConstructClientConnectionClosePacket(1));
rcha00569732016-08-27 11:09:369071 socket_data.AddRead(ASYNC, OK);
Zhongyi Shi5f587cc2017-11-21 23:24:179072 socket_data.AddSocketDataToFactory(socket_factory_.get());
rtenneti1cd3b162015-09-29 02:58:289073
9074 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:279075 MockCryptoClientStream::ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:309076 host_resolver_->set_synchronous_mode(true);
9077 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
9078 "192.168.0.1", "");
rtenneti1cd3b162015-09-29 02:58:289079
rcha02807b42016-01-29 21:56:159080 // Set up the TaskObserver to verify QuicChromiumPacketReader::StartReading
9081 // posts a task.
rtenneti1cd3b162015-09-29 02:58:289082 // TODO(rtenneti): Change SpdySessionTestTaskObserver to NetTestTaskObserver??
rcha02807b42016-01-29 21:56:159083 SpdySessionTestTaskObserver observer("quic_chromium_packet_reader.cc",
9084 "StartReading");
rtenneti1cd3b162015-09-29 02:58:289085
zhongyi98d6a9262017-05-19 02:47:459086 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:519087 EXPECT_EQ(OK,
9088 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529089 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
9090 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:519091 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9092 failed_on_default_network_callback_, callback_.callback()));
rtenneti1cd3b162015-09-29 02:58:289093
rcha02807b42016-01-29 21:56:159094 // Call run_loop so that QuicChromiumPacketReader::OnReadComplete() gets
9095 // called.
rtenneti1cd3b162015-09-29 02:58:289096 base::RunLoop run_loop;
9097 run_loop.RunUntilIdle();
9098
9099 // Verify task that the observer's executed_count is 1, which indicates
rcha02807b42016-01-29 21:56:159100 // QuicChromiumPacketReader::StartReading() has posted only one task and
9101 // yielded the read.
rtenneti1cd3b162015-09-29 02:58:289102 EXPECT_EQ(1u, observer.executed_count());
9103
Yixin Wang7891a39d2017-11-08 20:59:249104 std::unique_ptr<HttpStream> stream = CreateStream(&request);
xunjieli2608f9b2016-03-14 13:39:239105 EXPECT_FALSE(stream.get()); // Session is already closed.
rtenneti1cd3b162015-09-29 02:58:289106 EXPECT_TRUE(socket_data.AllReadDataConsumed());
9107 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
9108}
9109
ckrasic3865ee0f2016-02-29 22:04:569110TEST_P(QuicStreamFactoryTest, ServerPushSessionAffinity) {
9111 Initialize();
9112 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9113 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9114
Ryan Hamiltonabad59e2019-06-06 04:02:599115 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:369116 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:439117 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:179118 socket_data.AddSocketDataToFactory(socket_factory_.get());
ckrasic3865ee0f2016-02-29 22:04:569119
zhongyi98d6a9262017-05-19 02:47:459120 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339121 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039122 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529123 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
9124 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039125 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9126 failed_on_default_network_callback_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:569127
robpercival214763f2016-07-01 23:27:019128 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:249129 std::unique_ptr<HttpStream> stream = CreateStream(&request);
ckrasic3865ee0f2016-02-29 22:04:569130 EXPECT_TRUE(stream.get());
9131
9132 EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumPushStreamsCreated(factory_.get()));
9133
bnc5fdc07162016-05-23 17:36:039134 string url = "https://www.example.org/";
ckrasic3865ee0f2016-02-29 22:04:569135
bnc912a04b2016-04-20 14:19:509136 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
ckrasic3865ee0f2016-02-29 22:04:569137
Ryan Hamilton8d9ee76e2018-05-29 23:52:529138 quic::QuicClientPromisedInfo promised(
Fan Yang32c5a112018-12-10 20:06:339139 session, GetNthServerInitiatedUnidirectionalStreamId(0), kDefaultUrl);
ckrasic3865ee0f2016-02-29 22:04:569140 (*QuicStreamFactoryPeer::GetPushPromiseIndex(factory_.get())
bnc3d9035b32016-06-30 18:18:489141 ->promised_by_url())[kDefaultUrl] = &promised;
ckrasic3865ee0f2016-02-29 22:04:569142
zhongyi98d6a9262017-05-19 02:47:459143 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:519144 EXPECT_EQ(OK,
9145 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529146 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
9147 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:519148 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9149 failed_on_default_network_callback_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:569150
9151 EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumPushStreamsCreated(factory_.get()));
9152}
9153
9154TEST_P(QuicStreamFactoryTest, ServerPushPrivacyModeMismatch) {
9155 Initialize();
9156 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9157 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9158 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9159
Ryan Hamiltonabad59e2019-06-06 04:02:599160 MockQuicData socket_data1(version_);
rcha00569732016-08-27 11:09:369161 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:439162 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
9163 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:339164 SYNCHRONOUS, client_maker_.MakeRstPacket(
9165 2, true, GetNthServerInitiatedUnidirectionalStreamId(0),
9166 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:179167 socket_data1.AddSocketDataToFactory(socket_factory_.get());
ckrasic3865ee0f2016-02-29 22:04:569168
Ryan Hamilton0d65a8c2019-06-07 00:46:029169 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:599170 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:369171 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:439172 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:179173 socket_data2.AddSocketDataToFactory(socket_factory_.get());
ckrasic3865ee0f2016-02-29 22:04:569174
zhongyi98d6a9262017-05-19 02:47:459175 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339176 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039177 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529178 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
9179 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039180 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9181 failed_on_default_network_callback_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:569182
robpercival214763f2016-07-01 23:27:019183 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:249184 std::unique_ptr<HttpStream> stream = CreateStream(&request);
ckrasic3865ee0f2016-02-29 22:04:569185 EXPECT_TRUE(stream.get());
9186
9187 EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumPushStreamsCreated(factory_.get()));
9188
bnc5fdc07162016-05-23 17:36:039189 string url = "https://www.example.org/";
bnc912a04b2016-04-20 14:19:509190 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
ckrasic3865ee0f2016-02-29 22:04:569191
Ryan Hamilton8d9ee76e2018-05-29 23:52:529192 quic::QuicClientPromisedInfo promised(
Fan Yang32c5a112018-12-10 20:06:339193 session, GetNthServerInitiatedUnidirectionalStreamId(0), kDefaultUrl);
ckrasic3865ee0f2016-02-29 22:04:569194
Ryan Hamilton8d9ee76e2018-05-29 23:52:529195 quic::QuicClientPushPromiseIndex* index =
ckrasic3865ee0f2016-02-29 22:04:569196 QuicStreamFactoryPeer::GetPushPromiseIndex(factory_.get());
9197
bnc3d9035b32016-06-30 18:18:489198 (*index->promised_by_url())[kDefaultUrl] = &promised;
9199 EXPECT_EQ(index->GetPromised(kDefaultUrl), &promised);
ckrasic3865ee0f2016-02-29 22:04:569200
9201 // Doing the request should not use the push stream, but rather
9202 // cancel it because the privacy modes do not match.
zhongyi98d6a9262017-05-19 02:47:459203 QuicStreamRequest request2(factory_.get());
Ryan Hamilton9ef8c102019-06-28 03:58:529204 EXPECT_EQ(ERR_IO_PENDING,
9205 request2.Request(
9206 host_port_pair_, version_, PRIVACY_MODE_ENABLED,
9207 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
9208 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9209 failed_on_default_network_callback_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:569210
9211 EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumPushStreamsCreated(factory_.get()));
bnc3d9035b32016-06-30 18:18:489212 EXPECT_EQ(index->GetPromised(kDefaultUrl), nullptr);
ckrasic3865ee0f2016-02-29 22:04:569213
robpercival214763f2016-07-01 23:27:019214 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:249215 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
ckrasic3865ee0f2016-02-29 22:04:569216 EXPECT_TRUE(stream2.get());
9217
9218 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
9219 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
9220 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
9221 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
9222}
9223
Ryan Hamilton8d9ee76e2018-05-29 23:52:529224// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:459225// even if destination is different.
9226TEST_P(QuicStreamFactoryTest, PoolByOrigin) {
9227 Initialize();
9228
9229 HostPortPair destination1("first.example.com", 443);
9230 HostPortPair destination2("second.example.com", 443);
9231
9232 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9233 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9234
Ryan Hamiltonabad59e2019-06-06 04:02:599235 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:369236 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:439237 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:179238 socket_data.AddSocketDataToFactory(socket_factory_.get());
bnc359ed2a2016-04-29 20:43:459239
zhongyi98d6a9262017-05-19 02:47:459240 QuicStreamRequest request1(factory_.get());
Nick Harper23290b82019-05-02 00:02:569241 EXPECT_EQ(ERR_IO_PENDING,
9242 request1.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529243 destination1, version_, privacy_mode_, DEFAULT_PRIORITY,
9244 SocketTag(), NetworkIsolationKey(),
Nick Harper23290b82019-05-02 00:02:569245 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9246 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:019247 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:249248 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
bnc359ed2a2016-04-29 20:43:459249 EXPECT_TRUE(stream1.get());
9250 EXPECT_TRUE(HasActiveSession(host_port_pair_));
9251
9252 // Second request returns synchronously because it pools to existing session.
9253 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:459254 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:519255 EXPECT_EQ(OK,
9256 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529257 destination2, version_, privacy_mode_, DEFAULT_PRIORITY,
9258 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:519259 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9260 failed_on_default_network_callback_, callback2.callback()));
Yixin Wang7891a39d2017-11-08 20:59:249261 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
bnc359ed2a2016-04-29 20:43:459262 EXPECT_TRUE(stream2.get());
9263
rchf0b18c8a2017-05-05 19:31:579264 QuicChromiumClientSession::Handle* session1 =
9265 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
9266 QuicChromiumClientSession::Handle* session2 =
9267 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
9268 EXPECT_TRUE(session1->SharesSameSession(*session2));
Ryan Hamilton4f0b26e2018-06-27 23:52:329269 EXPECT_EQ(quic::QuicServerId(host_port_pair_.host(), host_port_pair_.port(),
9270 privacy_mode_ == PRIVACY_MODE_ENABLED),
bnc359ed2a2016-04-29 20:43:459271 session1->server_id());
9272
9273 EXPECT_TRUE(socket_data.AllReadDataConsumed());
9274 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
9275}
9276
9277class QuicStreamFactoryWithDestinationTest
9278 : public QuicStreamFactoryTestBase,
9279 public ::testing::TestWithParam<PoolingTestParams> {
9280 protected:
9281 QuicStreamFactoryWithDestinationTest()
Yixin Wang079ad542018-01-11 04:06:059282 : QuicStreamFactoryTestBase(
9283 GetParam().version,
9284 GetParam().client_headers_include_h2_stream_dependency),
bnc359ed2a2016-04-29 20:43:459285 destination_type_(GetParam().destination_type),
9286 hanging_read_(SYNCHRONOUS, ERR_IO_PENDING, 0) {}
9287
9288 HostPortPair GetDestination() {
9289 switch (destination_type_) {
9290 case SAME_AS_FIRST:
9291 return origin1_;
9292 case SAME_AS_SECOND:
9293 return origin2_;
9294 case DIFFERENT:
9295 return HostPortPair(kDifferentHostname, 443);
9296 default:
9297 NOTREACHED();
9298 return HostPortPair();
9299 }
9300 }
9301
9302 void AddHangingSocketData() {
9303 std::unique_ptr<SequencedSocketData> sequenced_socket_data(
Ryan Sleevib8d7ea02018-05-07 20:01:019304 new SequencedSocketData(base::make_span(&hanging_read_, 1),
9305 base::span<MockWrite>()));
Zhongyi Shi5f587cc2017-11-21 23:24:179306 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
bnc359ed2a2016-04-29 20:43:459307 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
9308 }
9309
9310 bool AllDataConsumed() {
9311 for (const auto& socket_data_ptr : sequenced_socket_data_vector_) {
9312 if (!socket_data_ptr->AllReadDataConsumed() ||
9313 !socket_data_ptr->AllWriteDataConsumed()) {
9314 return false;
9315 }
9316 }
9317 return true;
9318 }
9319
9320 DestinationType destination_type_;
9321 HostPortPair origin1_;
9322 HostPortPair origin2_;
9323 MockRead hanging_read_;
rch872e00e2016-12-02 02:48:189324 std::vector<std::unique_ptr<SequencedSocketData>>
9325 sequenced_socket_data_vector_;
bnc359ed2a2016-04-29 20:43:459326};
9327
Victor Costane635086f2019-01-27 05:20:309328INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
9329 QuicStreamFactoryWithDestinationTest,
9330 ::testing::ValuesIn(GetPoolingTestParams()));
bnc359ed2a2016-04-29 20:43:459331
9332// A single QUIC request fails because the certificate does not match the origin
9333// hostname, regardless of whether it matches the alternative service hostname.
9334TEST_P(QuicStreamFactoryWithDestinationTest, InvalidCertificate) {
9335 if (destination_type_ == DIFFERENT)
9336 return;
9337
9338 Initialize();
9339
9340 GURL url("https://mail.example.com/");
9341 origin1_ = HostPortPair::FromURL(url);
9342
9343 // Not used for requests, but this provides a test case where the certificate
9344 // is valid for the hostname of the alternative service.
9345 origin2_ = HostPortPair("mail.example.org", 433);
9346
9347 HostPortPair destination = GetDestination();
9348
9349 scoped_refptr<X509Certificate> cert(
9350 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:249351 ASSERT_FALSE(cert->VerifyNameMatch(origin1_.host()));
9352 ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host()));
bnc359ed2a2016-04-29 20:43:459353
9354 ProofVerifyDetailsChromium verify_details;
9355 verify_details.cert_verify_result.verified_cert = cert;
9356 verify_details.cert_verify_result.is_issued_by_known_root = true;
9357 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9358
9359 AddHangingSocketData();
9360
zhongyi98d6a9262017-05-19 02:47:459361 QuicStreamRequest request(factory_.get());
Nick Harper23290b82019-05-02 00:02:569362 EXPECT_EQ(ERR_IO_PENDING,
9363 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529364 destination, version_, privacy_mode_, DEFAULT_PRIORITY,
9365 SocketTag(), NetworkIsolationKey(),
Nick Harper23290b82019-05-02 00:02:569366 /*cert_verify_flags=*/0, url, net_log_, &net_error_details_,
9367 failed_on_default_network_callback_, callback_.callback()));
bnc359ed2a2016-04-29 20:43:459368
robpercival214763f2016-07-01 23:27:019369 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_QUIC_HANDSHAKE_FAILED));
bnc359ed2a2016-04-29 20:43:459370
9371 EXPECT_TRUE(AllDataConsumed());
9372}
9373
9374// QuicStreamRequest is pooled based on |destination| if certificate matches.
9375TEST_P(QuicStreamFactoryWithDestinationTest, SharedCertificate) {
9376 Initialize();
9377
9378 GURL url1("https://www.example.org/");
9379 GURL url2("https://mail.example.org/");
9380 origin1_ = HostPortPair::FromURL(url1);
9381 origin2_ = HostPortPair::FromURL(url2);
9382
9383 HostPortPair destination = GetDestination();
9384
9385 scoped_refptr<X509Certificate> cert(
9386 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:249387 ASSERT_TRUE(cert->VerifyNameMatch(origin1_.host()));
9388 ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host()));
9389 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:459390
9391 ProofVerifyDetailsChromium verify_details;
9392 verify_details.cert_verify_result.verified_cert = cert;
9393 verify_details.cert_verify_result.is_issued_by_known_root = true;
9394 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9395
fayang3bcb8b502016-12-07 21:44:379396 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:529397 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Ryan Hamilton0d65a8c2019-06-07 00:46:029398 client_maker_.MakeInitialSettingsPacket(1));
bnceb9aa7112017-01-05 01:03:469399 MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(),
9400 settings_packet->length(), 1)};
fayang3bcb8b502016-12-07 21:44:379401 std::unique_ptr<SequencedSocketData> sequenced_socket_data(
Ryan Sleevib8d7ea02018-05-07 20:01:019402 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:179403 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
fayang3bcb8b502016-12-07 21:44:379404 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
bnc359ed2a2016-04-29 20:43:459405
zhongyi98d6a9262017-05-19 02:47:459406 QuicStreamRequest request1(factory_.get());
Nick Harper23290b82019-05-02 00:02:569407 EXPECT_EQ(ERR_IO_PENDING,
9408 request1.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529409 destination, version_, privacy_mode_, DEFAULT_PRIORITY,
9410 SocketTag(), NetworkIsolationKey(),
Nick Harper23290b82019-05-02 00:02:569411 /*cert_verify_flags=*/0, url1, net_log_, &net_error_details_,
9412 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:019413 EXPECT_THAT(callback_.WaitForResult(), IsOk());
fayang3bcb8b502016-12-07 21:44:379414
Yixin Wang7891a39d2017-11-08 20:59:249415 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
bnc359ed2a2016-04-29 20:43:459416 EXPECT_TRUE(stream1.get());
9417 EXPECT_TRUE(HasActiveSession(origin1_));
9418
9419 // Second request returns synchronously because it pools to existing session.
9420 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:459421 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:519422 EXPECT_EQ(OK,
9423 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529424 destination, version_, privacy_mode_, DEFAULT_PRIORITY,
9425 SocketTag(), NetworkIsolationKey(),
Matt Menke26e41542019-06-05 01:09:519426 /*cert_verify_flags=*/0, url2, net_log_, &net_error_details_,
9427 failed_on_default_network_callback_, callback2.callback()));
Yixin Wang7891a39d2017-11-08 20:59:249428 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
bnc359ed2a2016-04-29 20:43:459429 EXPECT_TRUE(stream2.get());
9430
rchf0b18c8a2017-05-05 19:31:579431 QuicChromiumClientSession::Handle* session1 =
9432 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
9433 QuicChromiumClientSession::Handle* session2 =
9434 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
9435 EXPECT_TRUE(session1->SharesSameSession(*session2));
bnc359ed2a2016-04-29 20:43:459436
Ryan Hamilton4f0b26e2018-06-27 23:52:329437 EXPECT_EQ(quic::QuicServerId(origin1_.host(), origin1_.port(),
9438 privacy_mode_ == PRIVACY_MODE_ENABLED),
9439 session1->server_id());
bnc359ed2a2016-04-29 20:43:459440
9441 EXPECT_TRUE(AllDataConsumed());
9442}
9443
bnc47eba7d2016-07-01 00:43:389444// QuicStreamRequest is not pooled if PrivacyMode differs.
9445TEST_P(QuicStreamFactoryWithDestinationTest, DifferentPrivacyMode) {
9446 Initialize();
9447
9448 GURL url1("https://www.example.org/");
9449 GURL url2("https://mail.example.org/");
9450 origin1_ = HostPortPair::FromURL(url1);
9451 origin2_ = HostPortPair::FromURL(url2);
9452
9453 HostPortPair destination = GetDestination();
9454
9455 scoped_refptr<X509Certificate> cert(
9456 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:249457 ASSERT_TRUE(cert->VerifyNameMatch(origin1_.host()));
9458 ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host()));
9459 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc47eba7d2016-07-01 00:43:389460
9461 ProofVerifyDetailsChromium verify_details1;
9462 verify_details1.cert_verify_result.verified_cert = cert;
9463 verify_details1.cert_verify_result.is_issued_by_known_root = true;
9464 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
9465
9466 ProofVerifyDetailsChromium verify_details2;
9467 verify_details2.cert_verify_result.verified_cert = cert;
9468 verify_details2.cert_verify_result.is_issued_by_known_root = true;
9469 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
9470
fayang3bcb8b502016-12-07 21:44:379471 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:529472 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Ryan Hamilton0d65a8c2019-06-07 00:46:029473 client_maker_.MakeInitialSettingsPacket(1));
bnceb9aa7112017-01-05 01:03:469474 MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(),
9475 settings_packet->length(), 1)};
fayang3bcb8b502016-12-07 21:44:379476 std::unique_ptr<SequencedSocketData> sequenced_socket_data(
Ryan Sleevib8d7ea02018-05-07 20:01:019477 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:179478 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
fayang3bcb8b502016-12-07 21:44:379479 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
9480 std::unique_ptr<SequencedSocketData> sequenced_socket_data1(
Ryan Sleevib8d7ea02018-05-07 20:01:019481 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:179482 socket_factory_->AddSocketDataProvider(sequenced_socket_data1.get());
fayang3bcb8b502016-12-07 21:44:379483 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data1));
bnc47eba7d2016-07-01 00:43:389484
zhongyi98d6a9262017-05-19 02:47:459485 QuicStreamRequest request1(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339486 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039487 request1.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529488 destination, version_, PRIVACY_MODE_DISABLED, DEFAULT_PRIORITY,
9489 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039490 /*cert_verify_flags=*/0, url1, net_log_, &net_error_details_,
9491 failed_on_default_network_callback_, callback_.callback()));
bnc47eba7d2016-07-01 00:43:389492 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:249493 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
bnc47eba7d2016-07-01 00:43:389494 EXPECT_TRUE(stream1.get());
9495 EXPECT_TRUE(HasActiveSession(origin1_));
9496
9497 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:459498 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339499 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039500 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529501 destination, version_, PRIVACY_MODE_ENABLED, DEFAULT_PRIORITY,
9502 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039503 /*cert_verify_flags=*/0, url2, net_log_, &net_error_details_,
9504 failed_on_default_network_callback_, callback2.callback()));
bnc47eba7d2016-07-01 00:43:389505 EXPECT_EQ(OK, callback2.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:249506 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
bnc47eba7d2016-07-01 00:43:389507 EXPECT_TRUE(stream2.get());
9508
9509 // |request2| does not pool to the first session, because PrivacyMode does not
9510 // match. Instead, another session is opened to the same destination, but
Ryan Hamilton8d9ee76e2018-05-29 23:52:529511 // with a different quic::QuicServerId.
rchf0b18c8a2017-05-05 19:31:579512 QuicChromiumClientSession::Handle* session1 =
9513 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
9514 QuicChromiumClientSession::Handle* session2 =
9515 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
9516 EXPECT_FALSE(session1->SharesSameSession(*session2));
bnc47eba7d2016-07-01 00:43:389517
Ryan Hamilton4f0b26e2018-06-27 23:52:329518 EXPECT_EQ(quic::QuicServerId(origin1_.host(), origin1_.port(), false),
bnc47eba7d2016-07-01 00:43:389519 session1->server_id());
Ryan Hamilton4f0b26e2018-06-27 23:52:329520 EXPECT_EQ(quic::QuicServerId(origin2_.host(), origin2_.port(), true),
bnc47eba7d2016-07-01 00:43:389521 session2->server_id());
9522
9523 EXPECT_TRUE(AllDataConsumed());
9524}
9525
bnc359ed2a2016-04-29 20:43:459526// QuicStreamRequest is not pooled if certificate does not match its origin.
9527TEST_P(QuicStreamFactoryWithDestinationTest, DisjointCertificate) {
9528 Initialize();
9529
9530 GURL url1("https://news.example.org/");
9531 GURL url2("https://mail.example.com/");
9532 origin1_ = HostPortPair::FromURL(url1);
9533 origin2_ = HostPortPair::FromURL(url2);
9534
9535 HostPortPair destination = GetDestination();
9536
9537 scoped_refptr<X509Certificate> cert1(
9538 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:249539 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_.host()));
9540 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_.host()));
9541 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:459542
9543 ProofVerifyDetailsChromium verify_details1;
9544 verify_details1.cert_verify_result.verified_cert = cert1;
9545 verify_details1.cert_verify_result.is_issued_by_known_root = true;
9546 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
9547
9548 scoped_refptr<X509Certificate> cert2(
9549 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:249550 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_.host()));
9551 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:459552
9553 ProofVerifyDetailsChromium verify_details2;
9554 verify_details2.cert_verify_result.verified_cert = cert2;
9555 verify_details2.cert_verify_result.is_issued_by_known_root = true;
9556 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
9557
fayang3bcb8b502016-12-07 21:44:379558 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:529559 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
Ryan Hamilton0d65a8c2019-06-07 00:46:029560 client_maker_.MakeInitialSettingsPacket(1));
bnceb9aa7112017-01-05 01:03:469561 MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(),
9562 settings_packet->length(), 1)};
fayang3bcb8b502016-12-07 21:44:379563 std::unique_ptr<SequencedSocketData> sequenced_socket_data(
Ryan Sleevib8d7ea02018-05-07 20:01:019564 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:179565 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
fayang3bcb8b502016-12-07 21:44:379566 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
9567 std::unique_ptr<SequencedSocketData> sequenced_socket_data1(
Ryan Sleevib8d7ea02018-05-07 20:01:019568 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:179569 socket_factory_->AddSocketDataProvider(sequenced_socket_data1.get());
fayang3bcb8b502016-12-07 21:44:379570 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data1));
bnc359ed2a2016-04-29 20:43:459571
zhongyi98d6a9262017-05-19 02:47:459572 QuicStreamRequest request1(factory_.get());
Nick Harper23290b82019-05-02 00:02:569573 EXPECT_EQ(ERR_IO_PENDING,
9574 request1.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529575 destination, version_, privacy_mode_, DEFAULT_PRIORITY,
9576 SocketTag(), NetworkIsolationKey(),
Nick Harper23290b82019-05-02 00:02:569577 /*cert_verify_flags=*/0, url1, net_log_, &net_error_details_,
9578 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:019579 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:249580 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
bnc359ed2a2016-04-29 20:43:459581 EXPECT_TRUE(stream1.get());
9582 EXPECT_TRUE(HasActiveSession(origin1_));
9583
9584 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:459585 QuicStreamRequest request2(factory_.get());
Nick Harper23290b82019-05-02 00:02:569586 EXPECT_EQ(ERR_IO_PENDING,
9587 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529588 destination, version_, privacy_mode_, DEFAULT_PRIORITY,
9589 SocketTag(), NetworkIsolationKey(),
Nick Harper23290b82019-05-02 00:02:569590 /*cert_verify_flags=*/0, url2, net_log_, &net_error_details_,
9591 failed_on_default_network_callback_, callback2.callback()));
robpercival214763f2016-07-01 23:27:019592 EXPECT_THAT(callback2.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:249593 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
bnc359ed2a2016-04-29 20:43:459594 EXPECT_TRUE(stream2.get());
9595
9596 // |request2| does not pool to the first session, because the certificate does
9597 // not match. Instead, another session is opened to the same destination, but
Ryan Hamilton8d9ee76e2018-05-29 23:52:529598 // with a different quic::QuicServerId.
rchf0b18c8a2017-05-05 19:31:579599 QuicChromiumClientSession::Handle* session1 =
9600 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
9601 QuicChromiumClientSession::Handle* session2 =
9602 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
9603 EXPECT_FALSE(session1->SharesSameSession(*session2));
bnc359ed2a2016-04-29 20:43:459604
Ryan Hamilton4f0b26e2018-06-27 23:52:329605 EXPECT_EQ(quic::QuicServerId(origin1_.host(), origin1_.port(),
9606 privacy_mode_ == PRIVACY_MODE_ENABLED),
9607 session1->server_id());
9608 EXPECT_EQ(quic::QuicServerId(origin2_.host(), origin2_.port(),
9609 privacy_mode_ == PRIVACY_MODE_ENABLED),
9610 session2->server_id());
bnc359ed2a2016-04-29 20:43:459611
9612 EXPECT_TRUE(AllDataConsumed());
9613}
9614
msramek992625ec2016-08-04 18:33:589615// This test verifies that QuicStreamFactory::ClearCachedStatesInCryptoConfig
9616// correctly transform an origin filter to a ServerIdFilter. Whether the
9617// deletion itself works correctly is tested in QuicCryptoClientConfigTest.
9618TEST_P(QuicStreamFactoryTest, ClearCachedStatesInCryptoConfig) {
9619 Initialize();
Ryan Hamilton8d9ee76e2018-05-29 23:52:529620 quic::QuicCryptoClientConfig* crypto_config =
msramek992625ec2016-08-04 18:33:589621 QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
9622
9623 struct TestCase {
9624 TestCase(const std::string& host,
9625 int port,
9626 PrivacyMode privacy_mode,
Ryan Hamilton8d9ee76e2018-05-29 23:52:529627 quic::QuicCryptoClientConfig* crypto_config)
msramek992625ec2016-08-04 18:33:589628 : server_id(host, port, privacy_mode),
9629 state(crypto_config->LookupOrCreate(server_id)) {
rch872e00e2016-12-02 02:48:189630 std::vector<string> certs(1);
msramek992625ec2016-08-04 18:33:589631 certs[0] = "cert";
9632 state->SetProof(certs, "cert_sct", "chlo_hash", "signature");
9633 state->set_source_address_token("TOKEN");
9634 state->SetProofValid();
9635
9636 EXPECT_FALSE(state->certs().empty());
9637 }
9638
Ryan Hamilton8d9ee76e2018-05-29 23:52:529639 quic::QuicServerId server_id;
9640 quic::QuicCryptoClientConfig::CachedState* state;
msramek992625ec2016-08-04 18:33:589641 } test_cases[] = {
9642 TestCase("www.google.com", 443, privacy_mode_, crypto_config),
9643 TestCase("www.example.com", 443, privacy_mode_, crypto_config),
9644 TestCase("www.example.com", 4433, privacy_mode_, crypto_config)};
9645
9646 // Clear cached states for the origin https://www.example.com:4433.
9647 GURL origin("https://www.example.com:4433");
csharrisonebeca8e2016-10-18 02:35:369648 factory_->ClearCachedStatesInCryptoConfig(base::Bind(
9649 static_cast<bool (*)(const GURL&, const GURL&)>(::operator==), origin));
msramek992625ec2016-08-04 18:33:589650 EXPECT_FALSE(test_cases[0].state->certs().empty());
9651 EXPECT_FALSE(test_cases[1].state->certs().empty());
9652 EXPECT_TRUE(test_cases[2].state->certs().empty());
9653
9654 // Clear all cached states.
9655 factory_->ClearCachedStatesInCryptoConfig(
9656 base::Callback<bool(const GURL&)>());
9657 EXPECT_TRUE(test_cases[0].state->certs().empty());
9658 EXPECT_TRUE(test_cases[1].state->certs().empty());
9659 EXPECT_TRUE(test_cases[2].state->certs().empty());
9660}
9661
Yixin Wang46a425f2017-08-10 23:02:209662// Passes connection options and client connection options to QuicStreamFactory,
Ryan Hamilton8d9ee76e2018-05-29 23:52:529663// then checks that its internal quic::QuicConfig is correct.
Yixin Wang46a425f2017-08-10 23:02:209664TEST_P(QuicStreamFactoryTest, ConfigConnectionOptions) {
Nick Harper72ade192019-07-17 03:30:429665 test_params_.quic_params.connection_options.push_back(quic::kTIME);
9666 test_params_.quic_params.connection_options.push_back(quic::kTBBR);
9667 test_params_.quic_params.connection_options.push_back(quic::kREJ);
Yixin Wang46a425f2017-08-10 23:02:209668
Nick Harper72ade192019-07-17 03:30:429669 test_params_.quic_params.client_connection_options.push_back(quic::kTBBR);
9670 test_params_.quic_params.client_connection_options.push_back(quic::k1RTT);
Yixin Wang46a425f2017-08-10 23:02:209671
9672 Initialize();
9673
Ryan Hamilton8d9ee76e2018-05-29 23:52:529674 const quic::QuicConfig* config =
9675 QuicStreamFactoryPeer::GetConfig(factory_.get());
Nick Harper72ade192019-07-17 03:30:429676 EXPECT_EQ(test_params_.quic_params.connection_options,
Zhongyi Shi967d2f12019-02-08 20:58:539677 config->SendConnectionOptions());
Yixin Wang46a425f2017-08-10 23:02:209678 EXPECT_TRUE(config->HasClientRequestedIndependentOption(
Ryan Hamilton8d9ee76e2018-05-29 23:52:529679 quic::kTBBR, quic::Perspective::IS_CLIENT));
Yixin Wang46a425f2017-08-10 23:02:209680 EXPECT_TRUE(config->HasClientRequestedIndependentOption(
Ryan Hamilton8d9ee76e2018-05-29 23:52:529681 quic::k1RTT, quic::Perspective::IS_CLIENT));
Yixin Wang46a425f2017-08-10 23:02:209682}
9683
Yixin Wang247ea642017-11-15 01:15:509684// Verifies that the host resolver uses the request priority passed to
9685// QuicStreamRequest::Request().
9686TEST_P(QuicStreamFactoryTest, HostResolverUsesRequestPriority) {
9687 Initialize();
9688 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9689 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9690
Ryan Hamiltonabad59e2019-06-06 04:02:599691 MockQuicData socket_data(version_);
Yixin Wang247ea642017-11-15 01:15:509692 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:439693 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:179694 socket_data.AddSocketDataToFactory(socket_factory_.get());
Yixin Wang247ea642017-11-15 01:15:509695
9696 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339697 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039698 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529699 host_port_pair_, version_, privacy_mode_, MAXIMUM_PRIORITY,
9700 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039701 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9702 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang247ea642017-11-15 01:15:509703
9704 EXPECT_THAT(callback_.WaitForResult(), IsOk());
9705 std::unique_ptr<HttpStream> stream = CreateStream(&request);
9706 EXPECT_TRUE(stream.get());
9707
Renjiea0cb4a2c2018-09-26 23:37:309708 EXPECT_EQ(MAXIMUM_PRIORITY, host_resolver_->last_request_priority());
Yixin Wang247ea642017-11-15 01:15:509709
9710 EXPECT_TRUE(socket_data.AllReadDataConsumed());
9711 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
9712}
9713
Lily Chenf11e1292018-11-29 16:42:099714TEST_P(QuicStreamFactoryTest, HostResolverRequestReprioritizedOnSetPriority) {
9715 Initialize();
9716 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9717 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9718
Ryan Hamiltonabad59e2019-06-06 04:02:599719 MockQuicData socket_data(version_);
Lily Chenf11e1292018-11-29 16:42:099720 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9721 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
9722 socket_data.AddSocketDataToFactory(socket_factory_.get());
9723
9724 QuicStreamRequest request(factory_.get());
9725 EXPECT_EQ(ERR_IO_PENDING,
9726 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529727 host_port_pair_, version_, privacy_mode_, MAXIMUM_PRIORITY,
9728 SocketTag(), NetworkIsolationKey(),
Lily Chenf11e1292018-11-29 16:42:099729 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9730 failed_on_default_network_callback_, callback_.callback()));
9731
9732 EXPECT_EQ(MAXIMUM_PRIORITY, host_resolver_->last_request_priority());
9733 EXPECT_EQ(MAXIMUM_PRIORITY, host_resolver_->request_priority(1));
9734
9735 QuicStreamRequest request2(factory_.get());
9736 EXPECT_EQ(ERR_IO_PENDING,
9737 request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529738 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
9739 SocketTag(), NetworkIsolationKey(),
Lily Chenf11e1292018-11-29 16:42:099740 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
9741 failed_on_default_network_callback_, callback_.callback()));
9742 EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_->last_request_priority());
9743 EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_->request_priority(2));
9744
9745 request.SetPriority(LOWEST);
9746 EXPECT_EQ(LOWEST, host_resolver_->request_priority(1));
9747 EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_->request_priority(2));
9748}
9749
Zhongyi Shi967d2f12019-02-08 20:58:539750// Passes |quic_max_time_before_crypto_handshake_seconds| and
9751// |quic_max_idle_time_before_crypto_handshake_seconds| to QuicStreamFactory,
Ryan Hamilton8d9ee76e2018-05-29 23:52:529752// checks that its internal quic::QuicConfig is correct.
Yixin Wang469da562017-11-15 21:34:589753TEST_P(QuicStreamFactoryTest, ConfigMaxTimeBeforeCryptoHandshake) {
Nick Harper72ade192019-07-17 03:30:429754 test_params_.quic_params.max_time_before_crypto_handshake_seconds = 11;
9755 test_params_.quic_params.max_idle_time_before_crypto_handshake_seconds = 13;
Yixin Wang469da562017-11-15 21:34:589756 Initialize();
9757
Ryan Hamilton8d9ee76e2018-05-29 23:52:529758 const quic::QuicConfig* config =
9759 QuicStreamFactoryPeer::GetConfig(factory_.get());
9760 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(11),
Yixin Wang469da562017-11-15 21:34:589761 config->max_time_before_crypto_handshake());
Ryan Hamilton8d9ee76e2018-05-29 23:52:529762 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(13),
Yixin Wang469da562017-11-15 21:34:589763 config->max_idle_time_before_crypto_handshake());
9764}
9765
Yixin Wang7c5d11a82017-12-21 02:40:009766// Verify ResultAfterHostResolutionCallback behavior when host resolution
9767// succeeds asynchronously, then crypto handshake fails synchronously.
9768TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackAsyncSync) {
9769 Initialize();
9770 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9771 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9772
Renjiea0cb4a2c2018-09-26 23:37:309773 host_resolver_->set_ondemand_mode(true);
Yixin Wang7c5d11a82017-12-21 02:40:009774
Ryan Hamiltonabad59e2019-06-06 04:02:599775 MockQuicData socket_data(version_);
Yixin Wang7c5d11a82017-12-21 02:40:009776 socket_data.AddRead(SYNCHRONOUS, ERR_FAILED);
9777 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
9778 socket_data.AddSocketDataToFactory(socket_factory_.get());
9779
9780 QuicStreamRequest request(factory_.get());
9781 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039782 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529783 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
9784 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039785 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9786 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:009787
9788 TestCompletionCallback host_resolution_callback;
9789 EXPECT_TRUE(
9790 request.WaitForHostResolution(host_resolution_callback.callback()));
9791
9792 // |host_resolver_| has not finished host resolution at this point, so
9793 // |host_resolution_callback| should not have a result.
9794 base::RunLoop().RunUntilIdle();
9795 EXPECT_FALSE(host_resolution_callback.have_result());
9796
9797 // Allow |host_resolver_| to finish host resolution.
9798 // Since the request fails immediately after host resolution (getting
9799 // ERR_FAILED from socket reads/writes), |host_resolution_callback| should be
9800 // called with ERR_QUIC_PROTOCOL_ERROR since that's the next result in
9801 // forming the connection.
Renjiea0cb4a2c2018-09-26 23:37:309802 host_resolver_->ResolveAllPending();
Yixin Wang7c5d11a82017-12-21 02:40:009803 base::RunLoop().RunUntilIdle();
9804 EXPECT_TRUE(host_resolution_callback.have_result());
9805 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, host_resolution_callback.WaitForResult());
9806
9807 // Calling WaitForHostResolution() a second time should return
9808 // false since host resolution has finished already.
9809 EXPECT_FALSE(
9810 request.WaitForHostResolution(host_resolution_callback.callback()));
9811
9812 EXPECT_TRUE(callback_.have_result());
9813 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
9814}
9815
9816// Verify ResultAfterHostResolutionCallback behavior when host resolution
9817// succeeds asynchronously, then crypto handshake fails asynchronously.
9818TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackAsyncAsync) {
9819 Initialize();
9820 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9821 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9822
Renjiea0cb4a2c2018-09-26 23:37:309823 host_resolver_->set_ondemand_mode(true);
Yixin Wang7c5d11a82017-12-21 02:40:009824 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:279825 MockCryptoClientStream::ZERO_RTT);
Yixin Wang7c5d11a82017-12-21 02:40:009826 factory_->set_require_confirmation(true);
9827
Ryan Hamiltonabad59e2019-06-06 04:02:599828 MockQuicData socket_data(version_);
Yixin Wang7c5d11a82017-12-21 02:40:009829 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
9830 socket_data.AddRead(ASYNC, ERR_FAILED);
9831 socket_data.AddWrite(ASYNC, ERR_FAILED);
9832 socket_data.AddSocketDataToFactory(socket_factory_.get());
9833
9834 QuicStreamRequest request(factory_.get());
9835 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039836 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529837 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
9838 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039839 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9840 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:009841
9842 TestCompletionCallback host_resolution_callback;
9843 EXPECT_TRUE(
9844 request.WaitForHostResolution(host_resolution_callback.callback()));
9845
9846 // |host_resolver_| has not finished host resolution at this point, so
9847 // |host_resolution_callback| should not have a result.
9848 base::RunLoop().RunUntilIdle();
9849 EXPECT_FALSE(host_resolution_callback.have_result());
9850
9851 // Allow |host_resolver_| to finish host resolution. Since crypto handshake
9852 // will hang after host resolution, |host_resolution_callback| should run with
9853 // ERR_IO_PENDING since that's the next result in forming the connection.
Renjiea0cb4a2c2018-09-26 23:37:309854 host_resolver_->ResolveAllPending();
Yixin Wang7c5d11a82017-12-21 02:40:009855 base::RunLoop().RunUntilIdle();
9856 EXPECT_TRUE(host_resolution_callback.have_result());
9857 EXPECT_EQ(ERR_IO_PENDING, host_resolution_callback.WaitForResult());
9858
9859 // Calling WaitForHostResolution() a second time should return
9860 // false since host resolution has finished already.
9861 EXPECT_FALSE(
9862 request.WaitForHostResolution(host_resolution_callback.callback()));
9863
9864 EXPECT_FALSE(callback_.have_result());
9865 socket_data.GetSequencedSocketData()->Resume();
9866 base::RunLoop().RunUntilIdle();
9867 EXPECT_TRUE(callback_.have_result());
9868 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
9869}
9870
9871// Verify ResultAfterHostResolutionCallback behavior when host resolution
9872// succeeds synchronously, then crypto handshake fails synchronously.
9873TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackSyncSync) {
9874 Initialize();
9875 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9876 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9877
Renjiea0cb4a2c2018-09-26 23:37:309878 host_resolver_->set_synchronous_mode(true);
Yixin Wang7c5d11a82017-12-21 02:40:009879
Ryan Hamiltonabad59e2019-06-06 04:02:599880 MockQuicData socket_data(version_);
Yixin Wang7c5d11a82017-12-21 02:40:009881 socket_data.AddRead(SYNCHRONOUS, ERR_FAILED);
9882 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
9883 socket_data.AddSocketDataToFactory(socket_factory_.get());
9884
9885 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339886 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR,
Zhongyi Shia6b68d112018-09-24 07:49:039887 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529888 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
9889 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039890 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9891 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:009892
9893 // WaitForHostResolution() should return false since host
9894 // resolution has finished already.
9895 TestCompletionCallback host_resolution_callback;
9896 EXPECT_FALSE(
9897 request.WaitForHostResolution(host_resolution_callback.callback()));
9898 base::RunLoop().RunUntilIdle();
9899 EXPECT_FALSE(host_resolution_callback.have_result());
9900 EXPECT_FALSE(callback_.have_result());
9901}
9902
9903// Verify ResultAfterHostResolutionCallback behavior when host resolution
9904// succeeds synchronously, then crypto handshake fails asynchronously.
9905TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackSyncAsync) {
9906 Initialize();
9907 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9908 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9909
9910 // Host resolution will succeed synchronously, but Request() as a whole
9911 // will fail asynchronously.
Renjiea0cb4a2c2018-09-26 23:37:309912 host_resolver_->set_synchronous_mode(true);
Yixin Wang7c5d11a82017-12-21 02:40:009913 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:279914 MockCryptoClientStream::ZERO_RTT);
Yixin Wang7c5d11a82017-12-21 02:40:009915 factory_->set_require_confirmation(true);
9916
Ryan Hamiltonabad59e2019-06-06 04:02:599917 MockQuicData socket_data(version_);
Yixin Wang7c5d11a82017-12-21 02:40:009918 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
9919 socket_data.AddRead(ASYNC, ERR_FAILED);
9920 socket_data.AddWrite(ASYNC, ERR_FAILED);
9921 socket_data.AddSocketDataToFactory(socket_factory_.get());
9922
9923 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339924 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039925 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529926 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
9927 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039928 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9929 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:009930
9931 // WaitForHostResolution() should return false since host
9932 // resolution has finished already.
9933 TestCompletionCallback host_resolution_callback;
9934 EXPECT_FALSE(
9935 request.WaitForHostResolution(host_resolution_callback.callback()));
9936 base::RunLoop().RunUntilIdle();
9937 EXPECT_FALSE(host_resolution_callback.have_result());
9938
9939 EXPECT_FALSE(callback_.have_result());
9940 socket_data.GetSequencedSocketData()->Resume();
9941 base::RunLoop().RunUntilIdle();
9942 EXPECT_TRUE(callback_.have_result());
9943 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
9944}
9945
9946// Verify ResultAfterHostResolutionCallback behavior when host resolution fails
9947// synchronously.
9948TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackFailSync) {
9949 Initialize();
9950 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9951 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9952
9953 // Host resolution will fail synchronously.
Renjiea0cb4a2c2018-09-26 23:37:309954 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
9955 host_resolver_->set_synchronous_mode(true);
Yixin Wang7c5d11a82017-12-21 02:40:009956
9957 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339958 EXPECT_EQ(ERR_NAME_NOT_RESOLVED,
Zhongyi Shia6b68d112018-09-24 07:49:039959 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529960 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
9961 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039962 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9963 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:009964
9965 // WaitForHostResolution() should return false since host
9966 // resolution has failed already.
9967 TestCompletionCallback host_resolution_callback;
9968 EXPECT_FALSE(
9969 request.WaitForHostResolution(host_resolution_callback.callback()));
9970 base::RunLoop().RunUntilIdle();
9971 EXPECT_FALSE(host_resolution_callback.have_result());
9972}
9973
9974// Verify ResultAfterHostResolutionCallback behavior when host resolution fails
9975// asynchronously.
9976TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackFailAsync) {
9977 Initialize();
9978 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9979 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9980
Renjiea0cb4a2c2018-09-26 23:37:309981 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
Yixin Wang7c5d11a82017-12-21 02:40:009982
9983 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339984 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039985 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:529986 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
9987 SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039988 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9989 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:009990
9991 TestCompletionCallback host_resolution_callback;
9992 EXPECT_TRUE(
9993 request.WaitForHostResolution(host_resolution_callback.callback()));
9994
9995 // Allow |host_resolver_| to fail host resolution. |host_resolution_callback|
9996 // Should run with ERR_NAME_NOT_RESOLVED since that's the error host
9997 // resolution failed with.
9998 base::RunLoop().RunUntilIdle();
9999 EXPECT_TRUE(host_resolution_callback.have_result());
10000 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, host_resolution_callback.WaitForResult());
10001
10002 EXPECT_TRUE(callback_.have_result());
10003 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, callback_.WaitForResult());
10004}
10005
Renjiea0cb4a2c2018-09-26 23:37:3010006// With dns race experiment turned on, and DNS resolve succeeds synchronously,
10007// the final connection is established through the resolved DNS. No racing
10008// connection.
10009TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceAndHostResolutionSync) {
Nick Harper72ade192019-07-17 03:30:4210010 test_params_.quic_params.race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010011 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10012 Initialize();
10013 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10014 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10015
10016 // Set an address in resolver for synchronous return.
10017 host_resolver_->set_synchronous_mode(true);
10018 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10019 kNonCachedIPAddress, "");
10020
10021 // Set up a different address in stale resolver cache.
10022 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10023 HostCache::Entry entry(OK,
10024 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10025 HostCache::Entry::SOURCE_DNS);
10026 base::TimeDelta zero;
10027 HostCache* cache = host_resolver_->GetHostCache();
10028 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10029 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810030 cache->Invalidate();
Renjie8d2d8d91b2018-09-29 00:29:0310031
Ryan Hamiltonabad59e2019-06-06 04:02:5910032 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010033 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10034 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10035 quic_data.AddSocketDataToFactory(socket_factory_.get());
10036
10037 QuicStreamRequest request(factory_.get());
10038 EXPECT_THAT(request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210039 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10040 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010041 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10042 failed_on_default_network_callback_, callback_.callback()),
10043 IsOk());
10044 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10045 EXPECT_TRUE(stream.get());
10046 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Victor Vasilievbee79ea2019-05-15 01:25:4810047 EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress);
Renjiea0cb4a2c2018-09-26 23:37:3010048
10049 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10050 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10051}
10052
10053// With dns race experiment on, DNS resolve returns async, no matching cache in
10054// host resolver, connection should be successful and through resolved DNS. No
10055// racing connection.
10056TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceAndHostResolutionAsync) {
Renjiea0cb4a2c2018-09-26 23:37:3010057 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10058 Initialize();
10059 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10060 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10061
10062 // Set an address in resolver for asynchronous return.
10063 host_resolver_->set_ondemand_mode(true);
10064 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10065 kNonCachedIPAddress, "");
10066
Ryan Hamiltonabad59e2019-06-06 04:02:5910067 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010068 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10069 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10070 quic_data.AddSocketDataToFactory(socket_factory_.get());
10071
10072 QuicStreamRequest request(factory_.get());
10073 EXPECT_EQ(ERR_IO_PENDING,
10074 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210075 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10076 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010077 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10078 failed_on_default_network_callback_, callback_.callback()));
10079 TestCompletionCallback host_resolution_callback;
10080 EXPECT_TRUE(
10081 request.WaitForHostResolution(host_resolution_callback.callback()));
10082 base::RunLoop().RunUntilIdle();
10083 EXPECT_FALSE(host_resolution_callback.have_result());
10084
10085 // Cause the host resolution to return.
10086 host_resolver_->ResolveAllPending();
10087 EXPECT_THAT(host_resolution_callback.WaitForResult(), IsOk());
10088 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10089
10090 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10091 EXPECT_TRUE(stream.get());
10092 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
10093
Victor Vasilievbee79ea2019-05-15 01:25:4810094 EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress);
Renjiea0cb4a2c2018-09-26 23:37:3010095
10096 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10097 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10098}
10099
10100// With dns race experiment on, DNS resolve returns async, stale dns used,
10101// connects synchrounously, and then the resolved DNS matches.
10102TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveAsyncStaleMatch) {
Nick Harper72ade192019-07-17 03:30:4210103 test_params_.quic_params.race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010104 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10105 Initialize();
10106 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10107 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10108
10109 // Set an address in resolver for asynchronous return.
10110 host_resolver_->set_ondemand_mode(true);
10111 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10112 kCachedIPAddress.ToString(), "");
10113
10114 // Set up the same address in the stale resolver cache.
10115 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10116 HostCache::Entry entry(OK,
10117 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10118 HostCache::Entry::SOURCE_DNS);
10119 base::TimeDelta zero;
10120 HostCache* cache = host_resolver_->GetHostCache();
10121 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10122 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810123 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010124
Ryan Hamiltonabad59e2019-06-06 04:02:5910125 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010126 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10127 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10128 quic_data.AddSocketDataToFactory(socket_factory_.get());
10129
10130 QuicStreamRequest request(factory_.get());
10131 EXPECT_EQ(ERR_IO_PENDING,
10132 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210133 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10134 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010135 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10136 failed_on_default_network_callback_, callback_.callback()));
10137
10138 // Check that the racing job is running.
10139 EXPECT_TRUE(HasLiveSession(host_port_pair_));
10140 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10141
10142 // Resolve dns and return.
10143 host_resolver_->ResolveAllPending();
10144 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10145 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10146 EXPECT_TRUE(stream.get());
10147
10148 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
10149
Victor Vasilievbee79ea2019-05-15 01:25:4810150 EXPECT_EQ(session->peer_address().host().ToString(),
10151 kCachedIPAddress.ToString());
Renjiea0cb4a2c2018-09-26 23:37:3010152
10153 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10154 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10155}
10156
10157// With dns race experiment on, dns resolve async, stale dns used, connect
10158// async, and then the result matches.
10159TEST_P(QuicStreamFactoryTest,
10160 ResultAfterDNSRaceHostResolveAsyncConnectAsyncStaleMatch) {
Nick Harper72ade192019-07-17 03:30:4210161 test_params_.quic_params.race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010162 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10163 Initialize();
10164 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10165 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10166
10167 // Set an address in resolver for asynchronous return.
10168 host_resolver_->set_ondemand_mode(true);
10169 factory_->set_require_confirmation(true);
10170 crypto_client_stream_factory_.set_handshake_mode(
10171 MockCryptoClientStream::ZERO_RTT);
10172 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10173 kCachedIPAddress.ToString(), "");
10174
10175 // Set up the same address in the stale resolver cache.
10176 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10177 HostCache::Entry entry(OK,
10178 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10179 HostCache::Entry::SOURCE_DNS);
10180 base::TimeDelta zero;
10181 HostCache* cache = host_resolver_->GetHostCache();
10182 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10183 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810184 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010185
Ryan Hamiltonabad59e2019-06-06 04:02:5910186 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010187 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10188 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10189 quic_data.AddSocketDataToFactory(socket_factory_.get());
10190
10191 QuicStreamRequest request(factory_.get());
10192 EXPECT_EQ(ERR_IO_PENDING,
10193 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210194 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10195 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010196 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10197 failed_on_default_network_callback_, callback_.callback()));
10198
10199 // Send Crypto handshake so connect will call back.
10200 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
10201 quic::QuicSession::HANDSHAKE_CONFIRMED);
10202 base::RunLoop().RunUntilIdle();
10203
10204 // Check that the racing job is running.
10205 EXPECT_TRUE(HasLiveSession(host_port_pair_));
10206 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10207
10208 // Resolve dns and call back, make sure job finishes.
10209 host_resolver_->ResolveAllPending();
10210 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10211
10212 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10213 EXPECT_TRUE(stream.get());
10214
10215 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
10216
Victor Vasilievbee79ea2019-05-15 01:25:4810217 EXPECT_EQ(session->peer_address().host().ToString(),
10218 kCachedIPAddress.ToString());
Renjiea0cb4a2c2018-09-26 23:37:3010219
10220 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10221 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10222}
10223
10224// With dns race experiment on, dns resolve async, stale dns used, dns resolve
10225// return, then connection finishes and matches with the result.
10226TEST_P(QuicStreamFactoryTest,
10227 ResultAfterDNSRaceHostResolveAsyncStaleMatchConnectAsync) {
Nick Harper72ade192019-07-17 03:30:4210228 test_params_.quic_params.race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010229 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10230 Initialize();
10231 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10232 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10233
10234 // Set an address in resolver for asynchronous return.
10235 host_resolver_->set_ondemand_mode(true);
10236 factory_->set_require_confirmation(true);
10237 crypto_client_stream_factory_.set_handshake_mode(
10238 MockCryptoClientStream::ZERO_RTT);
10239 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10240 kCachedIPAddress.ToString(), "");
10241
10242 // Set up the same address in the stale resolver cache.
10243 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10244 HostCache::Entry entry(OK,
10245 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10246 HostCache::Entry::SOURCE_DNS);
10247 base::TimeDelta zero;
10248 HostCache* cache = host_resolver_->GetHostCache();
10249 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10250 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810251 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010252
Ryan Hamiltonabad59e2019-06-06 04:02:5910253 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010254 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10255 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10256 quic_data.AddSocketDataToFactory(socket_factory_.get());
10257
10258 QuicStreamRequest request(factory_.get());
10259 EXPECT_EQ(ERR_IO_PENDING,
10260 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210261 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10262 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010263 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10264 failed_on_default_network_callback_, callback_.callback()));
10265
10266 // Finish dns async, check we still need to wait for stale connection async.
10267 host_resolver_->ResolveAllPending();
10268 base::RunLoop().RunUntilIdle();
10269 EXPECT_FALSE(callback_.have_result());
10270
10271 // Finish stale connection async, and the stale connection should pass dns
10272 // validation.
10273 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
10274 quic::QuicSession::HANDSHAKE_CONFIRMED);
10275 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10276 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10277 EXPECT_TRUE(stream.get());
10278
10279 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Victor Vasilievbee79ea2019-05-15 01:25:4810280 EXPECT_EQ(session->peer_address().host().ToString(),
10281 kCachedIPAddress.ToString());
Renjiea0cb4a2c2018-09-26 23:37:3010282
10283 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10284 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10285}
10286
10287// With dns race experiment on, dns resolve async, stale used and connects
10288// sync, but dns no match
10289TEST_P(QuicStreamFactoryTest,
10290 ResultAfterDNSRaceHostResolveAsyncStaleSyncNoMatch) {
Nick Harper72ade192019-07-17 03:30:4210291 test_params_.quic_params.race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010292 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10293 Initialize();
10294 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10295 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10296
10297 // Set an address in resolver for asynchronous return.
10298 host_resolver_->set_ondemand_mode(true);
10299 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10300 kNonCachedIPAddress, "");
10301
10302 // Set up a different address in the stale resolver cache.
10303 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10304 HostCache::Entry entry(OK,
10305 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10306 HostCache::Entry::SOURCE_DNS);
10307 base::TimeDelta zero;
10308 HostCache* cache = host_resolver_->GetHostCache();
10309 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10310 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810311 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010312
10313 // Socket for the stale connection which will invoke connection closure.
Ryan Hamiltonabad59e2019-06-06 04:02:5910314 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010315 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10316 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10317 quic_data.AddWrite(
Renjief5fcb172019-02-05 01:59:3310318 SYNCHRONOUS,
10319 client_maker_.MakeConnectionClosePacket(
10320 2, true, quic::QUIC_STALE_CONNECTION_CANCELLED, "net error"));
Renjiea0cb4a2c2018-09-26 23:37:3010321 quic_data.AddSocketDataToFactory(socket_factory_.get());
10322
10323 // Socket for the new connection.
Ryan Hamilton0d65a8c2019-06-07 00:46:0210324 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:5910325 MockQuicData quic_data2(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010326 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10327 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10328 quic_data2.AddSocketDataToFactory(socket_factory_.get());
10329
10330 QuicStreamRequest request(factory_.get());
10331 EXPECT_EQ(ERR_IO_PENDING,
10332 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210333 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10334 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010335 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10336 failed_on_default_network_callback_, callback_.callback()));
10337
10338 // Check the stale connection is running.
10339 EXPECT_TRUE(HasLiveSession(host_port_pair_));
10340 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10341
10342 // Finish dns resolution and check the job has finished.
10343 host_resolver_->ResolveAllPending();
10344 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10345
10346 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10347 EXPECT_TRUE(stream.get());
10348
10349 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
10350
Victor Vasilievbee79ea2019-05-15 01:25:4810351 EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress);
Renjiea0cb4a2c2018-09-26 23:37:3010352
10353 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10354 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10355 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
10356 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
10357}
10358
10359// With dns race experiment on, dns resolve async, stale used and connects
10360// async, finishes before dns, but no match
10361TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleAsyncResolveAsyncNoMatch) {
Nick Harper72ade192019-07-17 03:30:4210362 test_params_.quic_params.race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010363 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10364 Initialize();
10365 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10366 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10367
10368 // Set an address in resolver for asynchronous return.
10369 host_resolver_->set_ondemand_mode(true);
10370 factory_->set_require_confirmation(true);
10371 crypto_client_stream_factory_.set_handshake_mode(
10372 MockCryptoClientStream::ZERO_RTT);
10373 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10374 kNonCachedIPAddress, "");
10375
10376 // Set up a different address in the stale resolvercache.
10377 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10378 HostCache::Entry entry(OK,
10379 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10380 HostCache::Entry::SOURCE_DNS);
10381 base::TimeDelta zero;
10382 HostCache* cache = host_resolver_->GetHostCache();
10383 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10384 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810385 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010386
Ryan Hamiltonabad59e2019-06-06 04:02:5910387 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010388 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10389 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10390 quic_data.AddWrite(
Renjief5fcb172019-02-05 01:59:3310391 SYNCHRONOUS,
10392 client_maker_.MakeConnectionClosePacket(
10393 2, true, quic::QUIC_STALE_CONNECTION_CANCELLED, "net error"));
Renjiea0cb4a2c2018-09-26 23:37:3010394 quic_data.AddSocketDataToFactory(socket_factory_.get());
10395
Ryan Hamilton0d65a8c2019-06-07 00:46:0210396 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:5910397 MockQuicData quic_data2(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010398 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10399 quic_data2.AddSocketDataToFactory(socket_factory_.get());
10400
10401 QuicStreamRequest request(factory_.get());
10402 EXPECT_EQ(ERR_IO_PENDING,
10403 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210404 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10405 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010406 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10407 failed_on_default_network_callback_, callback_.callback()));
10408
10409 // Finish the stale connection.
10410 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
10411 quic::QuicSession::HANDSHAKE_CONFIRMED);
10412 base::RunLoop().RunUntilIdle();
10413 EXPECT_TRUE(HasLiveSession(host_port_pair_));
10414 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10415
10416 // Finish host resolution and check the job is done.
10417 host_resolver_->ResolveAllPending();
10418 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10419
10420 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10421 EXPECT_TRUE(stream.get());
10422
10423 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Victor Vasilievbee79ea2019-05-15 01:25:4810424 EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress);
Renjiea0cb4a2c2018-09-26 23:37:3010425
10426 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10427 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10428 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
10429 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
10430}
10431
10432// With dns race experiment on, dns resolve async, stale used and connects
10433// async, dns finishes first, but no match
10434TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceResolveAsyncStaleAsyncNoMatch) {
Nick Harper72ade192019-07-17 03:30:4210435 test_params_.quic_params.race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010436 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10437 Initialize();
10438 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10439 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10440
10441 // Set an address in resolver for asynchronous return.
10442 host_resolver_->set_ondemand_mode(true);
10443 factory_->set_require_confirmation(true);
10444 crypto_client_stream_factory_.set_handshake_mode(
10445 MockCryptoClientStream::ZERO_RTT);
10446 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10447 kNonCachedIPAddress, "");
10448
10449 // Set up a different address in the stale resolver cache.
10450 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10451 HostCache::Entry entry(OK,
10452 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10453 HostCache::Entry::SOURCE_DNS);
10454 base::TimeDelta zero;
10455 HostCache* cache = host_resolver_->GetHostCache();
10456 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10457 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810458 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010459
Ryan Hamiltonabad59e2019-06-06 04:02:5910460 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010461 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Michael Warres167db3e2019-03-01 21:38:0310462 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:3010463 quic_data.AddWrite(
Renjief5fcb172019-02-05 01:59:3310464 SYNCHRONOUS,
10465 client_maker_.MakeConnectionClosePacket(
10466 1, true, quic::QUIC_STALE_CONNECTION_CANCELLED, "net error"));
Renjiea0cb4a2c2018-09-26 23:37:3010467 quic_data.AddSocketDataToFactory(socket_factory_.get());
10468
Ryan Hamilton0d65a8c2019-06-07 00:46:0210469 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:5910470 MockQuicData quic_data2(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010471 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie8d2d8d91b2018-09-29 00:29:0310472 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
10473 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Renjiea0cb4a2c2018-09-26 23:37:3010474 quic_data2.AddSocketDataToFactory(socket_factory_.get());
10475
10476 QuicStreamRequest request(factory_.get());
10477 EXPECT_EQ(ERR_IO_PENDING,
10478 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210479 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10480 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010481 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10482 failed_on_default_network_callback_, callback_.callback()));
10483 // Finish dns resolution, but need to wait for stale connection.
10484 host_resolver_->ResolveAllPending();
Renjie8d2d8d91b2018-09-29 00:29:0310485 base::RunLoop().RunUntilIdle();
Renjiea0cb4a2c2018-09-26 23:37:3010486 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
10487 quic::QuicSession::HANDSHAKE_CONFIRMED);
10488 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10489
10490 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10491 EXPECT_TRUE(stream.get());
10492
10493 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Victor Vasilievbee79ea2019-05-15 01:25:4810494 EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress);
Renjiea0cb4a2c2018-09-26 23:37:3010495
10496 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10497 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10498 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
10499 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
10500}
10501
10502// With dns race experiment on, dns resolve returns error sync, same behavior
10503// as experiment is not on
10504TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveError) {
Nick Harper72ade192019-07-17 03:30:4210505 test_params_.quic_params.race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010506 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10507 Initialize();
10508 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10509 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10510
10511 // Set synchronous failure in resolver.
10512 host_resolver_->set_synchronous_mode(true);
10513 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
10514
Ryan Hamiltonabad59e2019-06-06 04:02:5910515 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010516 quic_data.AddSocketDataToFactory(socket_factory_.get());
10517 QuicStreamRequest request(factory_.get());
10518
10519 EXPECT_EQ(ERR_NAME_NOT_RESOLVED,
10520 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210521 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10522 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010523 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10524 failed_on_default_network_callback_, callback_.callback()));
10525}
10526
10527// With dns race experiment on, no cache available, dns resolve returns error
10528// async
10529TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveAsyncError) {
Nick Harper72ade192019-07-17 03:30:4210530 test_params_.quic_params.race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010531 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10532 Initialize();
10533 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10534 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10535
10536 // Set asynchronous failure in resolver.
10537 host_resolver_->set_ondemand_mode(true);
10538 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
10539
Ryan Hamiltonabad59e2019-06-06 04:02:5910540 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010541 quic_data.AddSocketDataToFactory(socket_factory_.get());
10542 QuicStreamRequest request(factory_.get());
10543
10544 EXPECT_EQ(ERR_IO_PENDING,
10545 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210546 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10547 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010548 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10549 failed_on_default_network_callback_, callback_.callback()));
10550
10551 // Resolve and expect result that shows the resolution error.
10552 host_resolver_->ResolveAllPending();
10553 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
10554}
10555
10556// With dns race experiment on, dns resolve async, staled used and connects
10557// sync, dns returns error and no connection is established.
10558TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleSyncHostResolveError) {
Nick Harper72ade192019-07-17 03:30:4210559 test_params_.quic_params.race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010560 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10561 Initialize();
10562 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10563 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10564
10565 // Set asynchronous failure in resolver.
10566 host_resolver_->set_ondemand_mode(true);
10567 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
10568
10569 // Set up an address in the stale cache.
10570 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10571 HostCache::Entry entry(OK,
10572 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10573 HostCache::Entry::SOURCE_DNS);
10574 base::TimeDelta zero;
10575 HostCache* cache = host_resolver_->GetHostCache();
10576 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10577 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810578 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010579
10580 // Socket for the stale connection which is supposed to disconnect.
Ryan Hamiltonabad59e2019-06-06 04:02:5910581 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010582 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10583 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10584 quic_data.AddWrite(
Renjief5fcb172019-02-05 01:59:3310585 SYNCHRONOUS,
10586 client_maker_.MakeConnectionClosePacket(
10587 2, true, quic::QUIC_STALE_CONNECTION_CANCELLED, "net error"));
Renjiea0cb4a2c2018-09-26 23:37:3010588 quic_data.AddSocketDataToFactory(socket_factory_.get());
10589
10590 QuicStreamRequest request(factory_.get());
10591 EXPECT_EQ(ERR_IO_PENDING,
10592 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210593 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10594 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010595 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10596 failed_on_default_network_callback_, callback_.callback()));
10597
10598 // Check that the stale connection is running.
10599 EXPECT_TRUE(HasLiveSession(host_port_pair_));
10600 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10601
10602 // Finish host resolution.
10603 host_resolver_->ResolveAllPending();
10604 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
10605
Renjiea0cb4a2c2018-09-26 23:37:3010606 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10607 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10608}
10609
10610// With dns race experiment on, dns resolve async, stale used and connection
Renjie99ec24b2019-04-26 17:44:3410611// return error, then dns matches.
10612// This serves as a regression test for crbug.com/956374.
Renjiea0cb4a2c2018-09-26 23:37:3010613TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleErrorDNSMatches) {
Nick Harper72ade192019-07-17 03:30:4210614 test_params_.quic_params.race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010615 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10616 Initialize();
10617 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10618 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10619
10620 // Set an address in host resolver for asynchronous return.
10621 host_resolver_->set_ondemand_mode(true);
10622 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10623 kCachedIPAddress.ToString(), "");
10624
10625 // Set up the same address in the stale resolver cache.
10626 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10627 HostCache::Entry entry(OK,
10628 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10629 HostCache::Entry::SOURCE_DNS);
10630 base::TimeDelta zero;
10631 HostCache* cache = host_resolver_->GetHostCache();
10632 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10633 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810634 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010635
10636 // Simulate synchronous connect failure.
Ryan Hamiltonabad59e2019-06-06 04:02:5910637 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010638 quic_data.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
10639 quic_data.AddSocketDataToFactory(socket_factory_.get());
10640
Ryan Hamilton0d65a8c2019-06-07 00:46:0210641 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:5910642 MockQuicData quic_data2(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010643 quic_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
10644 quic_data2.AddSocketDataToFactory(socket_factory_.get());
10645
10646 QuicStreamRequest request(factory_.get());
10647 EXPECT_EQ(ERR_IO_PENDING,
10648 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210649 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10650 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010651 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10652 failed_on_default_network_callback_, callback_.callback()));
10653 EXPECT_FALSE(HasLiveSession(host_port_pair_));
10654 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10655
10656 host_resolver_->ResolveAllPending();
10657 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_ADDRESS_IN_USE));
10658}
10659
10660// With dns race experiment on, dns resolve async, stale used and connection
10661// returns error, dns no match, new connection is established
10662TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleErrorDNSNoMatch) {
Nick Harper72ade192019-07-17 03:30:4210663 test_params_.quic_params.race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010664 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10665 Initialize();
10666 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10667 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10668
10669 // Set an address in host resolver.
10670 host_resolver_->set_ondemand_mode(true);
10671 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10672 kNonCachedIPAddress, "");
10673
10674 // Set up a different address in stale resolver cache.
10675 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10676 HostCache::Entry entry(OK,
10677 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10678 HostCache::Entry::SOURCE_DNS);
10679 base::TimeDelta zero;
10680 HostCache* cache = host_resolver_->GetHostCache();
10681 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10682 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810683 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010684
10685 // Add failure for the stale connection.
Ryan Hamiltonabad59e2019-06-06 04:02:5910686 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010687 quic_data.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
10688 quic_data.AddSocketDataToFactory(socket_factory_.get());
10689
Ryan Hamilton0d65a8c2019-06-07 00:46:0210690 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:5910691 MockQuicData quic_data2(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010692 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10693 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10694 quic_data2.AddSocketDataToFactory(socket_factory_.get());
10695
10696 QuicStreamRequest request(factory_.get());
10697 EXPECT_EQ(ERR_IO_PENDING,
10698 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210699 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10700 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010701 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10702 failed_on_default_network_callback_, callback_.callback()));
10703
10704 // Check that the stale connection fails.
10705 EXPECT_FALSE(HasLiveSession(host_port_pair_));
10706 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10707
10708 // Finish host resolution and check the job finishes ok.
10709 host_resolver_->ResolveAllPending();
10710 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10711
10712 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10713 EXPECT_TRUE(stream.get());
10714
10715 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
10716
Victor Vasilievbee79ea2019-05-15 01:25:4810717 EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress);
Renjiea0cb4a2c2018-09-26 23:37:3010718
10719 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
10720 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
10721}
10722
10723// With dns race experiment on, dns resolve async, stale used and connection
10724// returns error, dns no match, new connection error
10725TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleErrorDNSNoMatchError) {
Nick Harper72ade192019-07-17 03:30:4210726 test_params_.quic_params.race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010727 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10728 Initialize();
10729 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10730 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10731
10732 // Set an address in host resolver asynchronously.
10733 host_resolver_->set_ondemand_mode(true);
10734 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10735 kNonCachedIPAddress, "");
10736
10737 // Set up a different address in the stale cache.
10738 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10739 HostCache::Entry entry(OK,
10740 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10741 HostCache::Entry::SOURCE_DNS);
10742 base::TimeDelta zero;
10743 HostCache* cache = host_resolver_->GetHostCache();
10744 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10745 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810746 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010747
10748 // Add failure for stale connection.
Ryan Hamiltonabad59e2019-06-06 04:02:5910749 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010750 quic_data.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
10751 quic_data.AddSocketDataToFactory(socket_factory_.get());
10752
10753 // Add failure for resolved dns connection.
Ryan Hamilton0d65a8c2019-06-07 00:46:0210754 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:5910755 MockQuicData quic_data2(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010756 quic_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
10757 quic_data2.AddSocketDataToFactory(socket_factory_.get());
10758
10759 QuicStreamRequest request(factory_.get());
10760 EXPECT_EQ(ERR_IO_PENDING,
10761 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210762 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10763 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010764 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10765 failed_on_default_network_callback_, callback_.callback()));
10766
10767 // Check the stale connection fails.
10768 EXPECT_FALSE(HasLiveSession(host_port_pair_));
10769 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10770
10771 // Check the resolved dns connection fails.
10772 host_resolver_->ResolveAllPending();
10773 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_ADDRESS_IN_USE));
10774}
10775
10776// With dns race experiment on, dns resolve async and stale connect async, dns
10777// resolve returns error and then preconnect finishes
10778TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceResolveAsyncErrorStaleAsync) {
Nick Harper72ade192019-07-17 03:30:4210779 test_params_.quic_params.race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010780 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10781 Initialize();
10782 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10783 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10784
10785 // Add asynchronous failure in host resolver.
10786 host_resolver_->set_ondemand_mode(true);
10787 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
10788 factory_->set_require_confirmation(true);
10789 crypto_client_stream_factory_.set_handshake_mode(
10790 MockCryptoClientStream::ZERO_RTT);
10791
10792 // Set up an address in stale resolver cache.
10793 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10794 HostCache::Entry entry(OK,
10795 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10796 HostCache::Entry::SOURCE_DNS);
10797 base::TimeDelta zero;
10798 HostCache* cache = host_resolver_->GetHostCache();
10799 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10800 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810801 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010802
10803 // Socket data for stale connection which is supposed to disconnect.
Ryan Hamiltonabad59e2019-06-06 04:02:5910804 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010805 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Michael Warres167db3e2019-03-01 21:38:0310806 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:3010807 quic_data.AddWrite(
Renjief5fcb172019-02-05 01:59:3310808 SYNCHRONOUS,
10809 client_maker_.MakeConnectionClosePacket(
10810 1, true, quic::QUIC_STALE_CONNECTION_CANCELLED, "net error"));
Renjiea0cb4a2c2018-09-26 23:37:3010811 quic_data.AddSocketDataToFactory(socket_factory_.get());
10812
10813 QuicStreamRequest request(factory_.get());
10814 EXPECT_EQ(ERR_IO_PENDING,
10815 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210816 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10817 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010818 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10819 failed_on_default_network_callback_, callback_.callback()));
10820
10821 // host resolution returned but stale connection hasn't finished yet.
10822 host_resolver_->ResolveAllPending();
10823 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
10824
10825 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10826 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10827}
10828
10829// With dns race experiment on, dns resolve async and stale connect async, dns
Renjiea0cb4a2c2018-09-26 23:37:3010830// resolve returns error and then preconnect fails.
10831TEST_P(QuicStreamFactoryTest,
10832 ResultAfterDNSRaceResolveAsyncErrorStaleAsyncError) {
Nick Harper72ade192019-07-17 03:30:4210833 test_params_.quic_params.race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010834 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10835 Initialize();
10836 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10837 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10838
10839 // Add asynchronous failure to host resolver.
10840 host_resolver_->set_ondemand_mode(true);
10841 factory_->set_require_confirmation(true);
10842 crypto_client_stream_factory_.set_handshake_mode(
10843 MockCryptoClientStream::ZERO_RTT);
10844 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
10845
10846 // Set up an address in stale resolver cache.
10847 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10848 HostCache::Entry entry(OK,
10849 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10850 HostCache::Entry::SOURCE_DNS);
10851 base::TimeDelta zero;
10852 HostCache* cache = host_resolver_->GetHostCache();
10853 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10854 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810855 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010856
Ryan Hamiltonabad59e2019-06-06 04:02:5910857 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010858 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Michael Warres167db3e2019-03-01 21:38:0310859 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:3010860 quic_data.AddWrite(
Renjief5fcb172019-02-05 01:59:3310861 SYNCHRONOUS,
10862 client_maker_.MakeConnectionClosePacket(
10863 1, true, quic::QUIC_STALE_CONNECTION_CANCELLED, "net error"));
Renjiea0cb4a2c2018-09-26 23:37:3010864 quic_data.AddSocketDataToFactory(socket_factory_.get());
10865
10866 QuicStreamRequest request(factory_.get());
10867 EXPECT_EQ(ERR_IO_PENDING,
10868 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210869 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10870 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010871 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10872 failed_on_default_network_callback_, callback_.callback()));
10873
10874 // Host Resolution returns failure but stale connection hasn't finished.
10875 host_resolver_->ResolveAllPending();
10876
10877 // Check that the final error is on resolution failure.
10878 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
10879
10880 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10881}
10882
10883// With dns race experiment on, test that host resolution callback behaves
10884// normal as experiment is not on
10885TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveAsync) {
Nick Harper72ade192019-07-17 03:30:4210886 test_params_.quic_params.race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010887 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10888 Initialize();
10889 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10890 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10891
10892 host_resolver_->set_ondemand_mode(true);
10893 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10894 kNonCachedIPAddress, "");
10895
Ryan Hamiltonabad59e2019-06-06 04:02:5910896 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010897 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10898 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10899 quic_data.AddSocketDataToFactory(socket_factory_.get());
10900
10901 QuicStreamRequest request(factory_.get());
10902 EXPECT_EQ(ERR_IO_PENDING,
10903 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5210904 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10905 SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010906 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10907 failed_on_default_network_callback_, callback_.callback()));
10908
10909 // Check that expect_on_host_resolution_ is properlly set.
10910 TestCompletionCallback host_resolution_callback;
10911 EXPECT_TRUE(
10912 request.WaitForHostResolution(host_resolution_callback.callback()));
10913 base::RunLoop().RunUntilIdle();
10914 EXPECT_FALSE(host_resolution_callback.have_result());
10915
10916 host_resolver_->ResolveAllPending();
10917 EXPECT_THAT(host_resolution_callback.WaitForResult(), IsOk());
10918
10919 // Check that expect_on_host_resolution_ is flipped back.
10920 EXPECT_FALSE(
10921 request.WaitForHostResolution(host_resolution_callback.callback()));
10922
10923 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10924 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10925}
10926
Renjiec5e9a8a32019-07-04 01:17:0910927// With stale dns and migration before handshake experiment on, migration failed
10928// after handshake confirmed, and then fresh resolve returns.
10929TEST_P(QuicStreamFactoryTest, StaleNetworkFailedAfterHandshake) {
Nick Harper72ade192019-07-17 03:30:4210930 test_params_.quic_params.race_stale_dns_on_connection = true;
Renjiec5e9a8a32019-07-04 01:17:0910931 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10932
10933 InitializeConnectionMigrationV2Test(
10934 {kDefaultNetworkForTests, kNewNetworkForTests});
10935 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10936 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10937
10938 // Set an address in resolver for asynchronous return.
10939 host_resolver_->set_ondemand_mode(true);
10940 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10941 kNonCachedIPAddress, "");
10942
10943 // Set up the same address in the stale resolver cache.
10944 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10945 HostCache::Entry entry(OK,
10946 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10947 HostCache::Entry::SOURCE_DNS);
10948 base::TimeDelta zero;
10949 HostCache* cache = host_resolver_->GetHostCache();
10950 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10951 // Expire the cache
10952 cache->Invalidate();
10953
10954 MockQuicData quic_data(version_);
10955 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10956 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10957 quic_data.AddSocketDataToFactory(socket_factory_.get());
10958
10959 // Socket for the new connection.
10960 client_maker_.Reset();
10961 MockQuicData quic_data2(version_);
10962 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10963 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10964 quic_data2.AddSocketDataToFactory(socket_factory_.get());
10965
10966 QuicStreamRequest request(factory_.get());
10967 EXPECT_EQ(ERR_IO_PENDING,
10968 request.Request(
10969 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
10970 SocketTag(), NetworkIsolationKey(),
10971 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10972 failed_on_default_network_callback_, callback_.callback()));
10973
10974 // Check that the racing job is running.
10975 EXPECT_TRUE(HasLiveSession(host_port_pair_));
10976 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10977
10978 // By disconnecting the network, the stale session will be killed.
10979 scoped_mock_network_change_notifier_->mock_network_change_notifier()
10980 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
10981
10982 host_resolver_->ResolveAllPending();
10983 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10984
10985 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10986 EXPECT_TRUE(stream.get());
10987
10988 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
10989
10990 EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress);
10991
10992 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10993 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10994 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
10995 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
10996}
10997
10998// With stale dns experiment on, the stale session is killed while waiting for
10999// handshake
11000TEST_P(QuicStreamFactoryTest, StaleNetworkFailedBeforeHandshake) {
Nick Harper72ade192019-07-17 03:30:4211001 test_params_.quic_params.race_stale_dns_on_connection = true;
Renjiec5e9a8a32019-07-04 01:17:0911002 host_resolver_ = std::make_unique<MockCachingHostResolver>();
11003 InitializeConnectionMigrationV2Test(
11004 {kDefaultNetworkForTests, kNewNetworkForTests});
11005 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
11006 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
11007
11008 // Set an address in resolver for asynchronous return.
11009 host_resolver_->set_ondemand_mode(true);
11010 factory_->set_require_confirmation(true);
11011 crypto_client_stream_factory_.set_handshake_mode(
11012 MockCryptoClientStream::ZERO_RTT);
11013 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
11014 kNonCachedIPAddress, "");
11015
11016 // Set up a different address in the stale resolvercache.
11017 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
11018 HostCache::Entry entry(OK,
11019 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
11020 HostCache::Entry::SOURCE_DNS);
11021 base::TimeDelta zero;
11022 HostCache* cache = host_resolver_->GetHostCache();
11023 cache->Set(key, entry, base::TimeTicks::Now(), zero);
11024 // Expire the cache
11025 cache->Invalidate();
11026
11027 MockQuicData quic_data(version_);
11028 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
11029 quic_data.AddSocketDataToFactory(socket_factory_.get());
11030
11031 client_maker_.Reset();
11032 MockQuicData quic_data2(version_);
11033 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
11034 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
11035 quic_data2.AddSocketDataToFactory(socket_factory_.get());
11036
11037 QuicStreamRequest request(factory_.get());
11038 EXPECT_EQ(ERR_IO_PENDING,
11039 request.Request(
11040 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
11041 SocketTag(), NetworkIsolationKey(),
11042 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
11043 failed_on_default_network_callback_, callback_.callback()));
11044
11045 // Check that the racing job is running.
11046 EXPECT_TRUE(HasLiveSession(host_port_pair_));
11047 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
11048
11049 // By disconnecting the network, the stale session will be killed.
11050 scoped_mock_network_change_notifier_->mock_network_change_notifier()
11051 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
11052
11053 host_resolver_->ResolveAllPending();
11054 base::RunLoop().RunUntilIdle();
11055 // Make sure the fresh session is established.
11056 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
11057 quic::QuicSession::HANDSHAKE_CONFIRMED);
11058 EXPECT_THAT(callback_.WaitForResult(), IsOk());
11059
11060 std::unique_ptr<HttpStream> stream = CreateStream(&request);
11061 EXPECT_TRUE(stream.get());
11062
11063 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
11064 EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress);
11065
11066 EXPECT_TRUE(quic_data.AllReadDataConsumed());
11067 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
11068 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
11069 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
11070}
11071
Renjiea0522f062019-04-29 18:52:2111072TEST_P(QuicStreamFactoryTest, ConfigInitialRttForHandshake) {
11073 int kInitialRtt = 400;
Nick Harper72ade192019-07-17 03:30:4211074 test_params_.quic_params.initial_rtt_for_handshake_milliseconds = kInitialRtt;
Renjiea0522f062019-04-29 18:52:2111075 crypto_client_stream_factory_.set_handshake_mode(
11076 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
11077 Initialize();
11078 factory_->set_require_confirmation(true);
11079 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
11080 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
11081
11082 // Using a testing task runner so that we can control time.
11083 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
11084
11085 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
11086 QuicStreamFactoryPeer::SetAlarmFactory(
11087 factory_.get(),
11088 std::make_unique<QuicChromiumAlarmFactory>(task_runner.get(), &clock_));
11089
Ryan Hamiltonabad59e2019-06-06 04:02:5911090 MockQuicData socket_data(version_);
Renjiea0522f062019-04-29 18:52:2111091 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
11092 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
11093 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(2));
11094 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamilton0d65a8c2019-06-07 00:46:0211095 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(3));
11096
Renjiea0522f062019-04-29 18:52:2111097 socket_data.AddSocketDataToFactory(socket_factory_.get());
11098
11099 QuicStreamRequest request(factory_.get());
11100 EXPECT_EQ(ERR_IO_PENDING,
11101 request.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5211102 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY,
11103 SocketTag(), NetworkIsolationKey(),
Renjiea0522f062019-04-29 18:52:2111104 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
11105 failed_on_default_network_callback_, callback_.callback()));
11106 base::RunLoop().RunUntilIdle();
11107
11108 EXPECT_FALSE(HasActiveSession(host_port_pair_));
11109 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
11110
11111 // The pending task is scheduled for handshake timeout retransmission,
David Schinazi3f7465c2019-07-12 01:57:0511112 // which is 2 * 400ms with crypto frames and 1.5 * 400ms otherwise.
11113 int handshake_timeout =
11114 QuicVersionUsesCryptoFrames(version_.transport_version)
11115 ? 2 * kInitialRtt
11116 : 1.5 * kInitialRtt;
Renjiea0522f062019-04-29 18:52:2111117 EXPECT_EQ(base::TimeDelta::FromMilliseconds(handshake_timeout),
11118 task_runner->NextPendingTaskDelay());
11119
11120 // The alarm factory dependes on |clock_|, so clock is advanced to trigger
11121 // retransmission alarm.
11122 clock_.AdvanceTime(
11123 quic::QuicTime::Delta::FromMilliseconds(handshake_timeout));
11124 task_runner->FastForwardBy(
11125 base::TimeDelta::FromMilliseconds(handshake_timeout));
11126
11127 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
11128 quic::QuicSession::HANDSHAKE_CONFIRMED);
11129
11130 EXPECT_THAT(callback_.WaitForResult(), IsOk());
11131
11132 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
11133 EXPECT_EQ(400000u, session->config()->GetInitialRoundTripTimeUsToSend());
11134 EXPECT_TRUE(socket_data.AllReadDataConsumed());
11135 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
11136}
11137
Paul Jensen8e3c5d32018-02-19 17:06:3311138// Test that QuicStreamRequests with similar and different tags results in
11139// reused and unique QUIC streams using appropriately tagged sockets.
11140TEST_P(QuicStreamFactoryTest, Tag) {
11141 MockTaggingClientSocketFactory* socket_factory =
11142 new MockTaggingClientSocketFactory();
11143 socket_factory_.reset(socket_factory);
11144 Initialize();
11145 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
11146 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
11147
11148 // Prepare to establish two QUIC sessions.
Ryan Hamiltonabad59e2019-06-06 04:02:5911149 MockQuicData socket_data(version_);
Paul Jensen8e3c5d32018-02-19 17:06:3311150 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:4311151 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Paul Jensen8e3c5d32018-02-19 17:06:3311152 socket_data.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamilton0d65a8c2019-06-07 00:46:0211153 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:5911154 MockQuicData socket_data2(version_);
Paul Jensen8e3c5d32018-02-19 17:06:3311155 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:4311156 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Paul Jensen8e3c5d32018-02-19 17:06:3311157 socket_data2.AddSocketDataToFactory(socket_factory_.get());
11158
11159#if defined(OS_ANDROID)
11160 SocketTag tag1(SocketTag::UNSET_UID, 0x12345678);
11161 SocketTag tag2(getuid(), 0x87654321);
11162#else
11163 // On non-Android platforms we can only use the default constructor.
11164 SocketTag tag1, tag2;
11165#endif
11166
11167 // Request a stream with |tag1|.
11168 QuicStreamRequest request1(factory_.get());
Zhongyi Shia6b68d112018-09-24 07:49:0311169 int rv = request1.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5211170 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY, tag1,
11171 NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:0311172 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
11173 failed_on_default_network_callback_, callback_.callback());
Paul Jensen8e3c5d32018-02-19 17:06:3311174 EXPECT_THAT(callback_.GetResult(rv), IsOk());
11175 EXPECT_EQ(socket_factory->GetLastProducedUDPSocket()->tag(), tag1);
11176 EXPECT_TRUE(socket_factory->GetLastProducedUDPSocket()
11177 ->tagged_before_data_transferred());
11178 std::unique_ptr<QuicChromiumClientSession::Handle> stream1 =
11179 request1.ReleaseSessionHandle();
11180 EXPECT_TRUE(stream1);
11181 EXPECT_TRUE(stream1->IsConnected());
11182
11183 // Request a stream with |tag1| and verify underlying session is reused.
11184 QuicStreamRequest request2(factory_.get());
Zhongyi Shia6b68d112018-09-24 07:49:0311185 rv = request2.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5211186 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY, tag1,
11187 NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:0311188 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
11189 failed_on_default_network_callback_, callback_.callback());
Paul Jensen8e3c5d32018-02-19 17:06:3311190 EXPECT_THAT(callback_.GetResult(rv), IsOk());
11191 std::unique_ptr<QuicChromiumClientSession::Handle> stream2 =
11192 request2.ReleaseSessionHandle();
11193 EXPECT_TRUE(stream2);
11194 EXPECT_TRUE(stream2->IsConnected());
11195 EXPECT_TRUE(stream2->SharesSameSession(*stream1));
11196
11197 // Request a stream with |tag2| and verify a new session is created.
11198 QuicStreamRequest request3(factory_.get());
Zhongyi Shia6b68d112018-09-24 07:49:0311199 rv = request3.Request(
Ryan Hamilton9ef8c102019-06-28 03:58:5211200 host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY, tag2,
11201 NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:0311202 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
11203 failed_on_default_network_callback_, callback_.callback());
Paul Jensen8e3c5d32018-02-19 17:06:3311204 EXPECT_THAT(callback_.GetResult(rv), IsOk());
11205 EXPECT_EQ(socket_factory->GetLastProducedUDPSocket()->tag(), tag2);
11206 EXPECT_TRUE(socket_factory->GetLastProducedUDPSocket()
11207 ->tagged_before_data_transferred());
11208 std::unique_ptr<QuicChromiumClientSession::Handle> stream3 =
11209 request3.ReleaseSessionHandle();
11210 EXPECT_TRUE(stream3);
11211 EXPECT_TRUE(stream3->IsConnected());
11212#if defined(OS_ANDROID)
11213 EXPECT_FALSE(stream3->SharesSameSession(*stream1));
11214#else
11215 // Same tag should reuse session.
11216 EXPECT_TRUE(stream3->SharesSameSession(*stream1));
11217#endif
11218}
11219
[email protected]e13201d82012-12-12 05:00:3211220} // namespace test
[email protected]e13201d82012-12-12 05:00:3211221} // namespace net