blob: 15849cd75a8d6447d7729f548f895ccc284c48e2 [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 Shic4823bd2018-04-27 00:49:1916#include "base/test/test_mock_time_task_runner.h"
Paul Jensen8e3c5d32018-02-19 17:06:3317#include "build/build_config.h"
mgershaf9a9232017-04-13 20:19:0318#include "net/base/mock_network_change_notifier.h"
rsleevid6de8302016-06-21 01:33:2019#include "net/cert/ct_policy_enforcer.h"
Ryan Sleevi987d2d92017-12-19 19:22:1420#include "net/cert/do_nothing_ct_verifier.h"
21#include "net/cert/mock_cert_verifier.h"
[email protected]f2cb3cf2013-03-21 01:40:5322#include "net/dns/mock_host_resolver.h"
[email protected]e13201d82012-12-12 05:00:3223#include "net/http/http_response_headers.h"
24#include "net/http/http_response_info.h"
rtenneti8332ba52015-09-17 19:33:4125#include "net/http/http_server_properties_impl.h"
[email protected]e13201d82012-12-12 05:00:3226#include "net/http/http_util.h"
[email protected]080b77932014-08-04 01:22:4627#include "net/http/transport_security_state.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0828#include "net/quic/crypto/proof_verifier_chromium.h"
29#include "net/quic/mock_crypto_client_stream_factory.h"
30#include "net/quic/mock_quic_data.h"
31#include "net/quic/properties_based_quic_server_info.h"
32#include "net/quic/quic_http_stream.h"
33#include "net/quic/quic_http_utils.h"
34#include "net/quic/quic_server_info.h"
35#include "net/quic/quic_stream_factory_peer.h"
36#include "net/quic/quic_test_packet_maker.h"
37#include "net/quic/test_task_runner.h"
bnc3472afd2016-11-17 15:27:2138#include "net/socket/next_proto.h"
[email protected]e13201d82012-12-12 05:00:3239#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5840#include "net/spdy/spdy_session_test_util.h"
41#include "net/spdy/spdy_test_util_common.h"
[email protected]6b8a3c742014-07-25 00:25:3542#include "net/ssl/channel_id_service.h"
43#include "net/ssl/default_channel_id_store.h"
[email protected]eed749f92013-12-23 18:57:3844#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0145#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4346#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:0147#include "net/test/test_with_scoped_task_environment.h"
Ryan Hamilton56b10c5d2018-05-11 13:40:1648#include "net/third_party/quic/core/crypto/crypto_handshake.h"
49#include "net/third_party/quic/core/crypto/quic_crypto_client_config.h"
50#include "net/third_party/quic/core/crypto/quic_decrypter.h"
51#include "net/third_party/quic/core/crypto/quic_encrypter.h"
Victor Vasilievc5b409c22018-07-24 12:23:4652#include "net/third_party/quic/core/http/quic_client_promised_info.h"
Ryan Hamilton56b10c5d2018-05-11 13:40:1653#include "net/third_party/quic/platform/api/quic_test.h"
54#include "net/third_party/quic/test_tools/mock_clock.h"
55#include "net/third_party/quic/test_tools/mock_random.h"
56#include "net/third_party/quic/test_tools/quic_config_peer.h"
57#include "net/third_party/quic/test_tools/quic_spdy_session_peer.h"
58#include "net/third_party/quic/test_tools/quic_test_utils.h"
Ryan Hamilton2e003eea2018-05-02 00:24:2959#include "net/third_party/spdy/core/spdy_test_utils.h"
Ramin Halavati683bcaa92018-02-14 08:42:3960#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
robpercival214763f2016-07-01 23:27:0161#include "testing/gmock/include/gmock/gmock.h"
[email protected]e13201d82012-12-12 05:00:3262#include "testing/gtest/include/gtest/gtest.h"
msramek992625ec2016-08-04 18:33:5863#include "url/gurl.h"
[email protected]e13201d82012-12-12 05:00:3264
[email protected]6e12d702013-11-13 00:17:1765using std::string;
[email protected]6e12d702013-11-13 00:17:1766
[email protected]e13201d82012-12-12 05:00:3267namespace net {
jri7e636642016-01-14 06:57:0868
nharper642ae4b2016-06-30 00:40:3669namespace {
70
71class MockSSLConfigService : public SSLConfigService {
72 public:
73 MockSSLConfigService() {}
Ryan Sleevib8449e02018-07-15 04:31:0774 ~MockSSLConfigService() override {}
nharper642ae4b2016-06-30 00:40:3675
76 void GetSSLConfig(SSLConfig* config) override { *config = config_; }
77
Nick Harper89bc7212018-07-31 19:07:5778 bool CanShareConnectionWithClientCerts(
79 const std::string& hostname) const override {
80 return false;
81 }
82
nharper642ae4b2016-06-30 00:40:3683 private:
nharper642ae4b2016-06-30 00:40:3684 SSLConfig config_;
85};
86
87} // namespace
88
[email protected]e13201d82012-12-12 05:00:3289namespace test {
90
[email protected]3c772402013-12-18 21:38:1191namespace {
bnc359ed2a2016-04-29 20:43:4592
93enum DestinationType {
94 // In pooling tests with two requests for different origins to the same
95 // destination, the destination should be
96 SAME_AS_FIRST, // the same as the first origin,
97 SAME_AS_SECOND, // the same as the second origin, or
98 DIFFERENT, // different from both.
99};
100
rch6faa4d42016-01-05 20:48:43101const char kDefaultServerHostName[] = "www.example.org";
102const char kServer2HostName[] = "mail.example.org";
bnc359ed2a2016-04-29 20:43:45103const char kDifferentHostname[] = "different.example.com";
[email protected]3c772402013-12-18 21:38:11104const int kDefaultServerPort = 443;
ckrasic3865ee0f2016-02-29 22:04:56105const char kDefaultUrl[] = "https://www.example.org/";
106const char kServer2Url[] = "https://mail.example.org/";
107const char kServer3Url[] = "https://docs.example.org/";
108const char kServer4Url[] = "https://images.example.org/";
Zhongyi Shic4823bd2018-04-27 00:49:19109const int kDefaultRTTMilliSecs = 300;
110const size_t kMinRetryTimeForDefaultNetworkSecs = 1;
Zhongyi Shib1b1fa42018-06-19 23:13:47111const size_t kWaitTimeForNewNetworkSecs = 10;
rtenneti14abd312015-02-06 21:56:01112
bnc359ed2a2016-04-29 20:43:45113// Run QuicStreamFactoryTest instances with all value combinations of version
114// and enable_connection_racting.
rtenneti14abd312015-02-06 21:56:01115struct TestParams {
bnc359ed2a2016-04-29 20:43:45116 friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
Yixin Wang079ad542018-01-11 04:06:05117 os << "{ version: " << QuicVersionToString(p.version)
118 << ", client_headers_include_h2_stream_dependency: "
119 << p.client_headers_include_h2_stream_dependency << " }";
rtenneti14abd312015-02-06 21:56:01120 return os;
121 }
122
Ryan Hamilton8d9ee76e2018-05-29 23:52:52123 quic::QuicTransportVersion version;
Yixin Wang079ad542018-01-11 04:06:05124 bool client_headers_include_h2_stream_dependency;
rtenneti14abd312015-02-06 21:56:01125};
126
rch872e00e2016-12-02 02:48:18127std::vector<TestParams> GetTestParams() {
128 std::vector<TestParams> params;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52129 quic::QuicTransportVersionVector all_supported_versions =
130 quic::AllSupportedTransportVersions();
Yixin Wang079ad542018-01-11 04:06:05131 for (const auto& version : all_supported_versions) {
132 params.push_back(TestParams{version, false});
133 params.push_back(TestParams{version, true});
134 }
bnc359ed2a2016-04-29 20:43:45135 return params;
136}
137
138// Run QuicStreamFactoryWithDestinationTest instances with all value
139// combinations of version, enable_connection_racting, and destination_type.
140struct PoolingTestParams {
141 friend std::ostream& operator<<(std::ostream& os,
142 const PoolingTestParams& p) {
143 os << "{ version: " << QuicVersionToString(p.version)
bnc359ed2a2016-04-29 20:43:45144 << ", destination_type: ";
145 switch (p.destination_type) {
146 case SAME_AS_FIRST:
147 os << "SAME_AS_FIRST";
148 break;
149 case SAME_AS_SECOND:
150 os << "SAME_AS_SECOND";
151 break;
152 case DIFFERENT:
153 os << "DIFFERENT";
154 break;
155 }
Yixin Wang079ad542018-01-11 04:06:05156 os << ", client_headers_include_h2_stream_dependency: "
157 << p.client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45158 os << " }";
159 return os;
160 }
161
Ryan Hamilton8d9ee76e2018-05-29 23:52:52162 quic::QuicTransportVersion version;
bnc359ed2a2016-04-29 20:43:45163 DestinationType destination_type;
Yixin Wang079ad542018-01-11 04:06:05164 bool client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45165};
166
rch872e00e2016-12-02 02:48:18167std::vector<PoolingTestParams> GetPoolingTestParams() {
168 std::vector<PoolingTestParams> params;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52169 quic::QuicTransportVersionVector all_supported_versions =
170 quic::AllSupportedTransportVersions();
171 for (const quic::QuicTransportVersion version : all_supported_versions) {
Yixin Wang079ad542018-01-11 04:06:05172 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, false});
173 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, true});
174 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, false});
175 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, true});
176 params.push_back(PoolingTestParams{version, DIFFERENT, false});
177 params.push_back(PoolingTestParams{version, DIFFERENT, true});
rtenneti14abd312015-02-06 21:56:01178 }
179 return params;
180}
181
bnc912a04b2016-04-20 14:19:50182} // namespace
[email protected]3c772402013-12-18 21:38:11183
bnc359ed2a2016-04-29 20:43:45184class QuicHttpStreamPeer {
185 public:
rchf0b18c8a2017-05-05 19:31:57186 static QuicChromiumClientSession::Handle* GetSessionHandle(
187 HttpStream* stream) {
188 return static_cast<QuicHttpStream*>(stream)->quic_session();
bnc359ed2a2016-04-29 20:43:45189 }
190};
191
Zhongyi Shi5f587cc2017-11-21 23:24:17192// TestConnectionMigrationSocketFactory will vend sockets with incremental port
193// number.
194class TestConnectionMigrationSocketFactory : public MockClientSocketFactory {
195 public:
196 TestConnectionMigrationSocketFactory() : next_source_port_num_(1u) {}
197 ~TestConnectionMigrationSocketFactory() override {}
198
199 std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
200 DatagramSocket::BindType bind_type,
Zhongyi Shi5f587cc2017-11-21 23:24:17201 NetLog* net_log,
202 const NetLogSource& source) override {
203 SocketDataProvider* data_provider = mock_data().GetNext();
204 std::unique_ptr<MockUDPClientSocket> socket(
205 new MockUDPClientSocket(data_provider, net_log));
206 socket->set_source_port(next_source_port_num_++);
207 return std::move(socket);
208 }
209
210 private:
211 uint16_t next_source_port_num_;
212
213 DISALLOW_COPY_AND_ASSIGN(TestConnectionMigrationSocketFactory);
214};
215
Bence Béky98447b12018-05-08 03:14:01216class QuicStreamFactoryTestBase : public WithScopedTaskEnvironment {
[email protected]e13201d82012-12-12 05:00:32217 protected:
Ryan Hamilton8d9ee76e2018-05-29 23:52:52218 QuicStreamFactoryTestBase(quic::QuicTransportVersion version,
Yixin Wang079ad542018-01-11 04:06:05219 bool client_headers_include_h2_stream_dependency)
nharper642ae4b2016-06-30 00:40:36220 : ssl_config_service_(new MockSSLConfigService),
Zhongyi Shi5f587cc2017-11-21 23:24:17221 socket_factory_(new MockClientSocketFactory),
nharper642ae4b2016-06-30 00:40:36222 random_generator_(0),
rchbf4c26d2017-04-16 23:17:55223 runner_(new TestTaskRunner(&clock_)),
bnc359ed2a2016-04-29 20:43:45224 version_(version),
Yixin Wang079ad542018-01-11 04:06:05225 client_headers_include_h2_stream_dependency_(
226 client_headers_include_h2_stream_dependency),
alyssar2adf3ac2016-05-03 17:12:58227 client_maker_(version_,
228 0,
rchbf4c26d2017-04-16 23:17:55229 &clock_,
alyssar2adf3ac2016-05-03 17:12:58230 kDefaultServerHostName,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52231 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:05232 client_headers_include_h2_stream_dependency_),
alyssar2adf3ac2016-05-03 17:12:58233 server_maker_(version_,
234 0,
rchbf4c26d2017-04-16 23:17:55235 &clock_,
alyssar2adf3ac2016-05-03 17:12:58236 kDefaultServerHostName,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52237 quic::Perspective::IS_SERVER,
Yixin Wang079ad542018-01-11 04:06:05238 false),
Ryan Sleevi987d2d92017-12-19 19:22:14239 cert_verifier_(std::make_unique<MockCertVerifier>()),
jri2b966f22014-09-02 22:25:36240 channel_id_service_(
fdoraya89e673c2017-01-31 21:44:21241 new ChannelIDService(new DefaultChannelIDStore(nullptr))),
Ryan Sleevi987d2d92017-12-19 19:22:14242 cert_transparency_verifier_(std::make_unique<DoNothingCTVerifier>()),
jri7e636642016-01-14 06:57:08243 scoped_mock_network_change_notifier_(nullptr),
jri7046038f2015-10-22 00:29:26244 factory_(nullptr),
[email protected]bf4ea2f2014-03-10 22:57:53245 host_port_pair_(kDefaultServerHostName, kDefaultServerPort),
ckrasic3865ee0f2016-02-29 22:04:56246 url_(kDefaultUrl),
247 url2_(kServer2Url),
248 url3_(kServer3Url),
249 url4_(kServer4Url),
jri7046038f2015-10-22 00:29:26250 privacy_mode_(PRIVACY_MODE_DISABLED),
rch431dd4452017-04-19 15:22:35251 store_server_configs_in_properties_(false),
Jana Iyengar903dec22017-11-28 00:44:23252 close_sessions_on_ip_change_(false),
Zhongyi Shi63574b72018-06-01 20:22:25253 goaway_sessions_on_ip_change_(false),
jri7e636642016-01-14 06:57:08254 idle_connection_timeout_seconds_(kIdleConnectionTimeoutSeconds),
Ryan Hamilton8d9ee76e2018-05-29 23:52:52255 reduced_ping_timeout_seconds_(quic::kPingTimeoutSecs),
Yixin Wang469da562017-11-15 21:34:58256 max_time_before_crypto_handshake_seconds_(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52257 quic::kMaxTimeForCryptoHandshakeSecs),
258 max_idle_time_before_crypto_handshake_seconds_(
259 quic::kInitialIdleTimeoutSecs),
Zhongyi Shif4683a32017-12-01 00:03:28260 migrate_sessions_on_network_change_v2_(false),
261 migrate_sessions_early_v2_(false),
Zhongyi Shi8de43832018-08-15 23:40:00262 retry_on_alternate_network_before_handshake_(false),
Renjiea5722ccf2018-08-10 00:18:49263 go_away_on_path_degrading_(false),
jri217455a12016-07-13 20:15:09264 allow_server_migration_(false),
rchd6163f32017-01-30 23:50:38265 race_cert_verification_(false),
266 estimate_initial_rtt_(false) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:52267 clock_.AdvanceTime(quic::QuicTime::Delta::FromSeconds(1));
bnc359ed2a2016-04-29 20:43:45268 }
269
jri7046038f2015-10-22 00:29:26270 void Initialize() {
bnc359ed2a2016-04-29 20:43:45271 DCHECK(!factory_);
jri7046038f2015-10-22 00:29:26272 factory_.reset(new QuicStreamFactory(
nharper642ae4b2016-06-30 00:40:36273 net_log_.net_log(), &host_resolver_, ssl_config_service_.get(),
Zhongyi Shi5f587cc2017-11-21 23:24:17274 socket_factory_.get(), &http_server_properties_, cert_verifier_.get(),
tbansal9b1cdf32017-05-10 17:28:39275 &ct_policy_enforcer_, channel_id_service_.get(),
nharper642ae4b2016-06-30 00:40:36276 &transport_security_state_, cert_transparency_verifier_.get(),
jri7046038f2015-10-22 00:29:26277 /*SocketPerformanceWatcherFactory*/ nullptr,
rchbf4c26d2017-04-16 23:17:55278 &crypto_client_stream_factory_, &random_generator_, &clock_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52279 quic::kDefaultMaxPacketSize, string(),
280 store_server_configs_in_properties_, close_sessions_on_ip_change_,
Zhongyi Shi63574b72018-06-01 20:22:25281 goaway_sessions_on_ip_change_,
rch9ecde09b2017-04-08 00:18:23282 /*mark_quic_broken_when_network_blackholes*/ false,
zhongyidd1439f62016-09-02 02:02:26283 idle_connection_timeout_seconds_, reduced_ping_timeout_seconds_,
Yixin Wang469da562017-11-15 21:34:58284 max_time_before_crypto_handshake_seconds_,
285 max_idle_time_before_crypto_handshake_seconds_,
Zhongyi Shif4683a32017-12-01 00:03:28286 migrate_sessions_on_network_change_v2_, migrate_sessions_early_v2_,
Zhongyi Shi8de43832018-08-15 23:40:00287 retry_on_alternate_network_before_handshake_,
Renjiea5722ccf2018-08-10 00:18:49288 go_away_on_path_degrading_,
Zhongyi Shi73f23ca872017-12-13 18:37:13289 base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs),
Zhongyi Shiee760762018-08-01 00:54:29290 kMaxMigrationsToNonDefaultNetworkOnWriteError,
Zhongyi Shi8b1e43f2017-12-13 20:46:30291 kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
Charles 'Buck' Krasic0c346c92017-09-14 18:17:37292 allow_server_migration_, race_cert_verification_, estimate_initial_rtt_,
Yixin Wang079ad542018-01-11 04:06:05293 client_headers_include_h2_stream_dependency_, connection_options_,
kapishnikov7f8dd1e2018-01-24 06:10:49294 client_connection_options_, /*enable_token_binding*/ false,
Nick Harper1e5757d42018-05-02 23:08:57295 /*enable_channel_id*/ false,
kapishnikov7f8dd1e2018-01-24 06:10:49296 /*enable_socket_recv_optimization*/ false));
[email protected]e13201d82012-12-12 05:00:32297 }
298
Zhongyi Shi5f587cc2017-11-21 23:24:17299 void InitializeConnectionMigrationV2Test(
300 NetworkChangeNotifier::NetworkList connected_networks) {
301 scoped_mock_network_change_notifier_.reset(
302 new ScopedMockNetworkChangeNotifier());
303 MockNetworkChangeNotifier* mock_ncn =
304 scoped_mock_network_change_notifier_->mock_network_change_notifier();
305 mock_ncn->ForceNetworkHandlesSupported();
306 mock_ncn->SetConnectedNetworksList(connected_networks);
307 migrate_sessions_on_network_change_v2_ = true;
Zhongyi Shif4683a32017-12-01 00:03:28308 migrate_sessions_early_v2_ = true;
Zhongyi Shi8de43832018-08-15 23:40:00309 retry_on_alternate_network_before_handshake_ = true;
Zhongyi Shi5f587cc2017-11-21 23:24:17310 socket_factory_.reset(new TestConnectionMigrationSocketFactory);
311 Initialize();
312 }
313
Yixin Wang7891a39d2017-11-08 20:59:24314 std::unique_ptr<HttpStream> CreateStream(QuicStreamRequest* request) {
315 std::unique_ptr<QuicChromiumClientSession::Handle> session =
316 request->ReleaseSessionHandle();
317 if (!session || !session->IsConnected())
318 return nullptr;
319
320 return std::make_unique<QuicHttpStream>(std::move(session));
321 }
322
bnccb7ff3c2015-05-21 20:51:55323 bool HasActiveSession(const HostPortPair& host_port_pair) {
Ryan Hamilton4f0b26e2018-06-27 23:52:32324 quic::QuicServerId server_id(host_port_pair.host(), host_port_pair.port(),
325 false);
bnc5fdc07162016-05-23 17:36:03326 return QuicStreamFactoryPeer::HasActiveSession(factory_.get(), server_id);
bnccb7ff3c2015-05-21 20:51:55327 }
328
zhongyi363c91c2017-03-23 23:16:08329 bool HasActiveJob(const HostPortPair& host_port_pair,
330 const PrivacyMode privacy_mode) {
Ryan Hamilton4f0b26e2018-06-27 23:52:32331 quic::QuicServerId server_id(host_port_pair.host(), host_port_pair.port(),
332 privacy_mode == PRIVACY_MODE_ENABLED);
zhongyi363c91c2017-03-23 23:16:08333 return QuicStreamFactoryPeer::HasActiveJob(factory_.get(), server_id);
334 }
335
Ryan Hamilton8d9ee76e2018-05-29 23:52:52336 bool HasActiveCertVerifierJob(const quic::QuicServerId& server_id) {
rtennetid073dd22016-08-04 01:58:33337 return QuicStreamFactoryPeer::HasActiveCertVerifierJob(factory_.get(),
338 server_id);
339 }
340
Zhongyi Shic1449372018-08-09 09:58:58341 // Get the pending, not activated session, if there is only one session alive.
342 QuicChromiumClientSession* GetPendingSession(
343 const HostPortPair& host_port_pair) {
344 quic::QuicServerId server_id(host_port_pair.host(), host_port_pair.port(),
345 false);
346 return QuicStreamFactoryPeer::GetPendingSession(factory_.get(), server_id,
347 host_port_pair);
348 }
349
bnc912a04b2016-04-20 14:19:50350 QuicChromiumClientSession* GetActiveSession(
351 const HostPortPair& host_port_pair) {
Ryan Hamilton4f0b26e2018-06-27 23:52:32352 quic::QuicServerId server_id(host_port_pair.host(), host_port_pair.port(),
353 false);
bnc5fdc07162016-05-23 17:36:03354 return QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server_id);
bnc912a04b2016-04-20 14:19:50355 }
356
[email protected]bf4ea2f2014-03-10 22:57:53357 int GetSourcePortForNewSession(const HostPortPair& destination) {
[email protected]d8e2abf82014-03-06 10:30:10358 return GetSourcePortForNewSessionInner(destination, false);
359 }
360
rjshaded5ced072015-12-18 19:26:02361 int GetSourcePortForNewSessionAndGoAway(const HostPortPair& destination) {
[email protected]d8e2abf82014-03-06 10:30:10362 return GetSourcePortForNewSessionInner(destination, true);
363 }
364
[email protected]bf4ea2f2014-03-10 22:57:53365 int GetSourcePortForNewSessionInner(const HostPortPair& destination,
[email protected]d8e2abf82014-03-06 10:30:10366 bool goaway_received) {
[email protected]3c772402013-12-18 21:38:11367 // Should only be called if there is no active session for this destination.
bnccb7ff3c2015-05-21 20:51:55368 EXPECT_FALSE(HasActiveSession(destination));
Zhongyi Shi5f587cc2017-11-21 23:24:17369 size_t socket_count = socket_factory_->udp_client_socket_ports().size();
[email protected]3c772402013-12-18 21:38:11370
rcha00569732016-08-27 11:09:36371 MockQuicData socket_data;
372 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:43373 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:17374 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]3c772402013-12-18 21:38:11375
zhongyi98d6a9262017-05-19 02:47:45376 QuicStreamRequest request(factory_.get());
ckrasic3865ee0f2016-02-29 22:04:56377 GURL url("https://" + destination.host() + "/");
Paul Jensen8e3c5d32018-02-19 17:06:33378 EXPECT_EQ(ERR_IO_PENDING,
379 request.Request(destination, version_, privacy_mode_,
380 DEFAULT_PRIORITY, SocketTag(),
381 /*cert_verify_flags=*/0, url, net_log_,
382 &net_error_details_, callback_.callback()));
[email protected]3c772402013-12-18 21:38:11383
robpercival214763f2016-07-01 23:27:01384 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:24385 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]3c772402013-12-18 21:38:11386 EXPECT_TRUE(stream.get());
387 stream.reset();
388
bnc912a04b2016-04-20 14:19:50389 QuicChromiumClientSession* session = GetActiveSession(destination);
[email protected]3c772402013-12-18 21:38:11390
Zhongyi Shi5f587cc2017-11-21 23:24:17391 if (socket_count + 1 != socket_factory_->udp_client_socket_ports().size()) {
mmenke651bae7f2015-12-18 21:26:45392 ADD_FAILURE();
[email protected]3c772402013-12-18 21:38:11393 return 0;
394 }
395
[email protected]d8e2abf82014-03-06 10:30:10396 if (goaway_received) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:52397 quic::QuicGoAwayFrame goaway(quic::kInvalidControlFrameId,
398 quic::QUIC_NO_ERROR, 1, "");
rtenneti9bd5d4b2015-08-21 05:44:52399 session->connection()->OnGoAwayFrame(goaway);
[email protected]d8e2abf82014-03-06 10:30:10400 }
[email protected]3c772402013-12-18 21:38:11401
jri7046038f2015-10-22 00:29:26402 factory_->OnSessionClosed(session);
bnccb7ff3c2015-05-21 20:51:55403 EXPECT_FALSE(HasActiveSession(destination));
rch37de576c2015-05-17 20:28:17404 EXPECT_TRUE(socket_data.AllReadDataConsumed());
405 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
Zhongyi Shi5f587cc2017-11-21 23:24:17406 return socket_factory_->udp_client_socket_ports()[socket_count];
[email protected]3c772402013-12-18 21:38:11407 }
408
Ryan Hamilton8d9ee76e2018-05-29 23:52:52409 std::unique_ptr<quic::QuicEncryptedPacket>
410 ConstructClientConnectionClosePacket(quic::QuicPacketNumber num) {
Bin Wu5311aca2018-01-22 01:19:03411 return client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52412 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
rtenneti1cd3b162015-09-29 02:58:28413 }
414
Ryan Hamilton8d9ee76e2018-05-29 23:52:52415 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
416 quic::QuicPacketNumber packet_number,
417 quic::QuicRstStreamErrorCode error_code) {
418 quic::QuicStreamId stream_id = GetNthClientInitiatedStreamId(0);
fayang3bcb8b502016-12-07 21:44:37419 return client_maker_.MakeRstPacket(packet_number, true, stream_id,
Jana Iyengarba355772017-09-21 22:03:21420 error_code);
fayang3bcb8b502016-12-07 21:44:37421 }
422
bncf8bf0722015-05-19 20:04:13423 static ProofVerifyDetailsChromium DefaultProofVerifyDetails() {
rch6faa4d42016-01-05 20:48:43424 // Load a certificate that is valid for *.example.org
bncf8bf0722015-05-19 20:04:13425 scoped_refptr<X509Certificate> test_cert(
rch6faa4d42016-01-05 20:48:43426 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bncf8bf0722015-05-19 20:04:13427 EXPECT_TRUE(test_cert.get());
428 ProofVerifyDetailsChromium verify_details;
429 verify_details.cert_verify_result.verified_cert = test_cert;
430 verify_details.cert_verify_result.is_issued_by_known_root = true;
431 return verify_details;
432 }
433
jri8c44d692015-10-23 23:53:41434 void NotifyIPAddressChanged() {
435 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
jri7e636642016-01-14 06:57:08436 // Spin the message loop so the notification is delivered.
fdoray92e35a72016-06-10 15:54:55437 base::RunLoop().RunUntilIdle();
jri8c44d692015-10-23 23:53:41438 }
439
Ryan Hamilton8d9ee76e2018-05-29 23:52:52440 std::unique_ptr<quic::QuicEncryptedPacket> ConstructGetRequestPacket(
441 quic::QuicPacketNumber packet_number,
442 quic::QuicStreamId stream_id,
jri7e636642016-01-14 06:57:08443 bool should_include_version,
444 bool fin) {
Ryan Hamilton0239aac2018-05-19 00:03:13445 spdy::SpdyHeaderBlock headers =
alyssar2adf3ac2016-05-03 17:12:58446 client_maker_.GetRequestHeaders("GET", "https", "/");
Ryan Hamilton0239aac2018-05-19 00:03:13447 spdy::SpdyPriority priority =
jri7e636642016-01-14 06:57:08448 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
449 size_t spdy_headers_frame_len;
alyssar2adf3ac2016-05-03 17:12:58450 return client_maker_.MakeRequestHeadersPacket(
jri7e636642016-01-14 06:57:08451 packet_number, stream_id, should_include_version, fin, priority,
Yixin Wang7a3f1b8d2018-01-17 21:40:48452 std::move(headers), 0, &spdy_headers_frame_len);
jri7e636642016-01-14 06:57:08453 }
454
Ryan Hamilton8d9ee76e2018-05-29 23:52:52455 std::unique_ptr<quic::QuicEncryptedPacket> ConstructGetRequestPacket(
456 quic::QuicPacketNumber packet_number,
457 quic::QuicStreamId stream_id,
Zhongyi Shi3c4c9e92018-07-02 23:16:23458 quic::QuicStreamId parent_stream_id,
fayang3bcb8b502016-12-07 21:44:37459 bool should_include_version,
460 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52461 quic::QuicStreamOffset* offset) {
Ryan Hamilton0239aac2018-05-19 00:03:13462 spdy::SpdyHeaderBlock headers =
fayang3bcb8b502016-12-07 21:44:37463 client_maker_.GetRequestHeaders("GET", "https", "/");
Ryan Hamilton0239aac2018-05-19 00:03:13464 spdy::SpdyPriority priority =
fayang3bcb8b502016-12-07 21:44:37465 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
466 size_t spdy_headers_frame_len;
467 return client_maker_.MakeRequestHeadersPacket(
468 packet_number, stream_id, should_include_version, fin, priority,
Zhongyi Shi3c4c9e92018-07-02 23:16:23469 std::move(headers), parent_stream_id, &spdy_headers_frame_len, offset);
470 }
471
472 std::unique_ptr<quic::QuicEncryptedPacket> ConstructGetRequestPacket(
473 quic::QuicPacketNumber packet_number,
474 quic::QuicStreamId stream_id,
475 bool should_include_version,
476 bool fin,
477 quic::QuicStreamOffset* offset) {
478 return ConstructGetRequestPacket(packet_number, stream_id,
479 /*parent_stream_id=*/0,
480 should_include_version, fin, offset);
fayang3bcb8b502016-12-07 21:44:37481 }
482
Ryan Hamilton8d9ee76e2018-05-29 23:52:52483 std::unique_ptr<quic::QuicEncryptedPacket> ConstructOkResponsePacket(
484 quic::QuicPacketNumber packet_number,
485 quic::QuicStreamId stream_id,
jri7e636642016-01-14 06:57:08486 bool should_include_version,
487 bool fin) {
Ryan Hamilton0239aac2018-05-19 00:03:13488 spdy::SpdyHeaderBlock headers = server_maker_.GetResponseHeaders("200 OK");
jri7e636642016-01-14 06:57:08489 size_t spdy_headers_frame_len;
alyssar2adf3ac2016-05-03 17:12:58490 return server_maker_.MakeResponseHeadersPacket(
bnc086b39e12016-06-24 13:05:26491 packet_number, stream_id, should_include_version, fin,
492 std::move(headers), &spdy_headers_frame_len);
jri7e636642016-01-14 06:57:08493 }
494
Ryan Hamilton8d9ee76e2018-05-29 23:52:52495 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket() {
rch5cb522462017-04-25 20:18:36496 return client_maker_.MakeInitialSettingsPacket(1, nullptr);
497 }
498
Ryan Hamilton8d9ee76e2018-05-29 23:52:52499 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
500 quic::QuicPacketNumber packet_number,
501 quic::QuicStreamOffset* offset) {
rch5cb522462017-04-25 20:18:36502 return client_maker_.MakeInitialSettingsPacket(packet_number, offset);
fayang3bcb8b502016-12-07 21:44:37503 }
504
jri053fdbd2016-08-19 02:33:05505 // Helper method for server migration tests.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52506 void VerifyServerMigration(const quic::QuicConfig& config,
bnc6a0348c2017-05-22 18:56:19507 IPEndPoint expected_address) {
jri053fdbd2016-08-19 02:33:05508 allow_server_migration_ = true;
509 Initialize();
510
511 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
512 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri053fdbd2016-08-19 02:33:05513 crypto_client_stream_factory_.SetConfig(config);
514
515 // Set up first socket data provider.
rcha00569732016-08-27 11:09:36516 MockQuicData socket_data1;
517 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:17518 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri053fdbd2016-08-19 02:33:05519
rcha00569732016-08-27 11:09:36520 // Set up second socket data provider that is used after
521 // migration.
522 MockQuicData socket_data2;
523 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:43524 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
fayang3bcb8b502016-12-07 21:44:37525 socket_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:43526 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
527 socket_data2.AddWrite(
528 SYNCHRONOUS,
529 client_maker_.MakeRstPacket(3, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:52530 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:17531 socket_data2.AddSocketDataToFactory(socket_factory_.get());
jri053fdbd2016-08-19 02:33:05532
533 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:45534 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:33535 EXPECT_EQ(ERR_IO_PENDING,
536 request.Request(host_port_pair_, version_, privacy_mode_,
537 DEFAULT_PRIORITY, SocketTag(),
538 /*cert_verify_flags=*/0, url_, net_log_,
539 &net_error_details_, callback_.callback()));
jri053fdbd2016-08-19 02:33:05540 EXPECT_EQ(OK, callback_.WaitForResult());
bnceb9aa7112017-01-05 01:03:46541
542 // Run QuicChromiumClientSession::WriteToNewSocket()
543 // posted by QuicChromiumClientSession::MigrateToSocket().
544 base::RunLoop().RunUntilIdle();
545
Yixin Wang7891a39d2017-11-08 20:59:24546 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri053fdbd2016-08-19 02:33:05547 EXPECT_TRUE(stream.get());
548
549 // Cause QUIC stream to be created.
550 HttpRequestInfo request_info;
551 request_info.method = "GET";
552 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:39553 request_info.traffic_annotation =
554 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:27555 EXPECT_EQ(OK,
556 stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:39557 net_log_, CompletionOnceCallback()));
jri053fdbd2016-08-19 02:33:05558 // Ensure that session is alive and active.
559 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
560 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
561 EXPECT_TRUE(HasActiveSession(host_port_pair_));
562
563 IPEndPoint actual_address;
564 session->GetDefaultSocket()->GetPeerAddress(&actual_address);
565 EXPECT_EQ(actual_address, expected_address);
566 DVLOG(1) << "Socket connected to: " << actual_address.address().ToString()
567 << " " << actual_address.port();
568 DVLOG(1) << "Expected address: " << expected_address.address().ToString()
569 << " " << expected_address.port();
570
571 stream.reset();
572 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
573 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
574 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
575 }
576
tbansal3b966952016-10-25 23:25:14577 // Verifies that the QUIC stream factory is initialized correctly.
tbansal9b1cdf32017-05-10 17:28:39578 void VerifyInitialization() {
rch431dd4452017-04-19 15:22:35579 store_server_configs_in_properties_ = true;
tbansal3b966952016-10-25 23:25:14580 idle_connection_timeout_seconds_ = 500;
581 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:20582 factory_->set_require_confirmation(false);
tbansal3b966952016-10-25 23:25:14583 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
584 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rch431dd4452017-04-19 15:22:35585 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
586 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:27587 MockCryptoClientStream::ZERO_RTT);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52588 const quic::QuicConfig* config =
589 QuicStreamFactoryPeer::GetConfig(factory_.get());
ckrasic32b17dcd2016-10-31 06:15:35590 EXPECT_EQ(500, config->IdleNetworkTimeout().ToSeconds());
tbansal3b966952016-10-25 23:25:14591
592 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
593
bnc3472afd2016-11-17 15:27:21594 const AlternativeService alternative_service1(
595 kProtoQUIC, host_port_pair_.host(), host_port_pair_.port());
tbansal3b966952016-10-25 23:25:14596 AlternativeServiceInfoVector alternative_service_info_vector;
597 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
598 alternative_service_info_vector.push_back(
zhongyie537a002017-06-27 16:48:21599 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
600 alternative_service1, expiration, {version_}));
tbansal3b966952016-10-25 23:25:14601 http_server_properties_.SetAlternativeServices(
602 url::SchemeHostPort(url_), alternative_service_info_vector);
603
604 HostPortPair host_port_pair2(kServer2HostName, kDefaultServerPort);
605 url::SchemeHostPort server2("https", kServer2HostName, kDefaultServerPort);
bnc3472afd2016-11-17 15:27:21606 const AlternativeService alternative_service2(
607 kProtoQUIC, host_port_pair2.host(), host_port_pair2.port());
tbansal3b966952016-10-25 23:25:14608 AlternativeServiceInfoVector alternative_service_info_vector2;
609 alternative_service_info_vector2.push_back(
zhongyie537a002017-06-27 16:48:21610 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
611 alternative_service2, expiration, {version_}));
tbansal9b1cdf32017-05-10 17:28:39612
613 http_server_properties_.SetAlternativeServices(
614 server2, alternative_service_info_vector2);
615 // Verify that the properties of both QUIC servers are stored in the
616 // HTTP properties map.
617 EXPECT_EQ(2U, http_server_properties_.alternative_service_map().size());
tbansal3b966952016-10-25 23:25:14618
619 http_server_properties_.SetMaxServerConfigsStoredInProperties(
Yixin Wang4a227aa22017-11-30 21:33:01620 kDefaultMaxQuicServerEntries);
tbansal3b966952016-10-25 23:25:14621
Ryan Hamilton8d9ee76e2018-05-29 23:52:52622 quic::QuicServerId quic_server_id(kDefaultServerHostName, 443,
623 PRIVACY_MODE_DISABLED);
rch431dd4452017-04-19 15:22:35624 std::unique_ptr<QuicServerInfo> quic_server_info =
Jeremy Roman0579ed62017-08-29 15:56:19625 std::make_unique<PropertiesBasedQuicServerInfo>(
rch431dd4452017-04-19 15:22:35626 quic_server_id, &http_server_properties_);
tbansal3b966952016-10-25 23:25:14627
628 // Update quic_server_info's server_config and persist it.
629 QuicServerInfo::State* state = quic_server_info->mutable_state();
630 // Minimum SCFG that passes config validation checks.
631 const char scfg[] = {// SCFG
632 0x53, 0x43, 0x46, 0x47,
633 // num entries
634 0x01, 0x00,
635 // padding
636 0x00, 0x00,
637 // EXPY
638 0x45, 0x58, 0x50, 0x59,
639 // EXPY end offset
640 0x08, 0x00, 0x00, 0x00,
641 // Value
642 '1', '2', '3', '4', '5', '6', '7', '8'};
643
644 // Create temporary strings becasue Persist() clears string data in |state|.
645 string server_config(reinterpret_cast<const char*>(&scfg), sizeof(scfg));
646 string source_address_token("test_source_address_token");
647 string cert_sct("test_cert_sct");
648 string chlo_hash("test_chlo_hash");
649 string signature("test_signature");
650 string test_cert("test_cert");
rch872e00e2016-12-02 02:48:18651 std::vector<string> certs;
tbansal3b966952016-10-25 23:25:14652 certs.push_back(test_cert);
653 state->server_config = server_config;
654 state->source_address_token = source_address_token;
655 state->cert_sct = cert_sct;
656 state->chlo_hash = chlo_hash;
657 state->server_config_sig = signature;
658 state->certs = certs;
659
660 quic_server_info->Persist();
661
Ryan Hamilton8d9ee76e2018-05-29 23:52:52662 quic::QuicServerId quic_server_id2(kServer2HostName, 443,
663 PRIVACY_MODE_DISABLED);
rch431dd4452017-04-19 15:22:35664 std::unique_ptr<QuicServerInfo> quic_server_info2 =
Jeremy Roman0579ed62017-08-29 15:56:19665 std::make_unique<PropertiesBasedQuicServerInfo>(
rch431dd4452017-04-19 15:22:35666 quic_server_id2, &http_server_properties_);
tbansal3b966952016-10-25 23:25:14667 // Update quic_server_info2's server_config and persist it.
668 QuicServerInfo::State* state2 = quic_server_info2->mutable_state();
669
670 // Minimum SCFG that passes config validation checks.
671 const char scfg2[] = {// SCFG
672 0x53, 0x43, 0x46, 0x47,
673 // num entries
674 0x01, 0x00,
675 // padding
676 0x00, 0x00,
677 // EXPY
678 0x45, 0x58, 0x50, 0x59,
679 // EXPY end offset
680 0x08, 0x00, 0x00, 0x00,
681 // Value
682 '8', '7', '3', '4', '5', '6', '2', '1'};
683
684 // Create temporary strings becasue Persist() clears string data in
685 // |state2|.
686 string server_config2(reinterpret_cast<const char*>(&scfg2), sizeof(scfg2));
687 string source_address_token2("test_source_address_token2");
688 string cert_sct2("test_cert_sct2");
689 string chlo_hash2("test_chlo_hash2");
690 string signature2("test_signature2");
691 string test_cert2("test_cert2");
rch872e00e2016-12-02 02:48:18692 std::vector<string> certs2;
tbansal3b966952016-10-25 23:25:14693 certs2.push_back(test_cert2);
694 state2->server_config = server_config2;
695 state2->source_address_token = source_address_token2;
696 state2->cert_sct = cert_sct2;
697 state2->chlo_hash = chlo_hash2;
698 state2->server_config_sig = signature2;
699 state2->certs = certs2;
700
701 quic_server_info2->Persist();
702
tbansal3b966952016-10-25 23:25:14703 // Verify the MRU order is maintained.
704 const QuicServerInfoMap& quic_server_info_map =
705 http_server_properties_.quic_server_info_map();
706 EXPECT_EQ(2u, quic_server_info_map.size());
707 QuicServerInfoMap::const_iterator quic_server_info_map_it =
708 quic_server_info_map.begin();
709 EXPECT_EQ(quic_server_info_map_it->first, quic_server_id2);
710 ++quic_server_info_map_it;
711 EXPECT_EQ(quic_server_info_map_it->first, quic_server_id);
712
rch431dd4452017-04-19 15:22:35713 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
714 "192.168.0.1", "");
715
716 // Create a session and verify that the cached state is loaded.
717 MockQuicData socket_data;
718 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:17719 socket_data.AddSocketDataToFactory(socket_factory_.get());
rch431dd4452017-04-19 15:22:35720
zhongyi98d6a9262017-05-19 02:47:45721 QuicStreamRequest request(factory_.get());
Yixin Wang247ea642017-11-15 01:15:50722 EXPECT_EQ(ERR_IO_PENDING,
Ryan Hamilton4f0b26e2018-06-27 23:52:32723 request.Request(
724 HostPortPair(quic_server_id.host(), quic_server_id.port()),
725 version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
726 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
727 callback_.callback()));
rch431dd4452017-04-19 15:22:35728 EXPECT_THAT(callback_.WaitForResult(), IsOk());
729
tbansal3b966952016-10-25 23:25:14730 EXPECT_FALSE(QuicStreamFactoryPeer::CryptoConfigCacheIsEmpty(
731 factory_.get(), quic_server_id));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52732 quic::QuicCryptoClientConfig* crypto_config =
tbansal3b966952016-10-25 23:25:14733 QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
Ryan Hamilton8d9ee76e2018-05-29 23:52:52734 quic::QuicCryptoClientConfig::CachedState* cached =
tbansal3b966952016-10-25 23:25:14735 crypto_config->LookupOrCreate(quic_server_id);
736 EXPECT_FALSE(cached->server_config().empty());
737 EXPECT_TRUE(cached->GetServerConfig());
738 EXPECT_EQ(server_config, cached->server_config());
739 EXPECT_EQ(source_address_token, cached->source_address_token());
740 EXPECT_EQ(cert_sct, cached->cert_sct());
741 EXPECT_EQ(chlo_hash, cached->chlo_hash());
742 EXPECT_EQ(signature, cached->signature());
743 ASSERT_EQ(1U, cached->certs().size());
744 EXPECT_EQ(test_cert, cached->certs()[0]);
745
rch431dd4452017-04-19 15:22:35746 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
747
748 // Create a session and verify that the cached state is loaded.
749 MockQuicData socket_data2;
750 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:17751 socket_data2.AddSocketDataToFactory(socket_factory_.get());
rch431dd4452017-04-19 15:22:35752
753 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
754 "192.168.0.2", "");
755
zhongyi98d6a9262017-05-19 02:47:45756 QuicStreamRequest request2(factory_.get());
rch431dd4452017-04-19 15:22:35757 EXPECT_EQ(ERR_IO_PENDING,
Ryan Hamilton4f0b26e2018-06-27 23:52:32758 request2.Request(
759 HostPortPair(quic_server_id2.host(), quic_server_id2.port()),
760 version_, privacy_mode_, DEFAULT_PRIORITY, SocketTag(),
761 /*cert_verify_flags=*/0, GURL("https://mail.example.org/"),
762 net_log_, &net_error_details_, callback_.callback()));
rch431dd4452017-04-19 15:22:35763 EXPECT_THAT(callback_.WaitForResult(), IsOk());
764
tbansal3b966952016-10-25 23:25:14765 EXPECT_FALSE(QuicStreamFactoryPeer::CryptoConfigCacheIsEmpty(
766 factory_.get(), quic_server_id2));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52767 quic::QuicCryptoClientConfig::CachedState* cached2 =
tbansal3b966952016-10-25 23:25:14768 crypto_config->LookupOrCreate(quic_server_id2);
769 EXPECT_FALSE(cached2->server_config().empty());
770 EXPECT_TRUE(cached2->GetServerConfig());
771 EXPECT_EQ(server_config2, cached2->server_config());
772 EXPECT_EQ(source_address_token2, cached2->source_address_token());
773 EXPECT_EQ(cert_sct2, cached2->cert_sct());
774 EXPECT_EQ(chlo_hash2, cached2->chlo_hash());
775 EXPECT_EQ(signature2, cached2->signature());
776 ASSERT_EQ(1U, cached->certs().size());
777 EXPECT_EQ(test_cert2, cached2->certs()[0]);
778 }
779
jri5b785512016-09-13 04:29:11780 void RunTestLoopUntilIdle() {
781 while (!runner_->GetPostedTasks().empty())
782 runner_->RunNextTask();
783 }
784
Ryan Hamilton8d9ee76e2018-05-29 23:52:52785 quic::QuicStreamId GetNthClientInitiatedStreamId(int n) {
786 return quic::test::GetNthClientInitiatedStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36787 }
788
Ryan Hamilton8d9ee76e2018-05-29 23:52:52789 quic::QuicStreamId GetNthServerInitiatedStreamId(int n) {
790 return quic::test::GetNthServerInitiatedStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36791 }
792
jri9f303712016-09-13 01:10:22793 // Helper methods for tests of connection migration on write error.
794 void TestMigrationOnWriteErrorNonMigratableStream(IoMode write_error_mode);
Zhongyi Shi0439ecc72018-07-11 04:41:26795 // Migratable stream triggers write error.
796 void TestMigrationOnWriteErrorMixedStreams(IoMode write_error_mode);
797 // Non-migratable stream triggers write error.
798 void TestMigrationOnWriteErrorMixedStreams2(IoMode write_error_mode);
jri9f303712016-09-13 01:10:22799 void TestMigrationOnWriteErrorMigrationDisabled(IoMode write_error_mode);
800 void TestMigrationOnWriteError(IoMode write_error_mode);
Zhongyi Shi0439ecc72018-07-11 04:41:26801 void TestMigrationOnWriteErrorWithMultipleRequests(IoMode write_error_mode);
jri9f303712016-09-13 01:10:22802 void TestMigrationOnWriteErrorNoNewNetwork(IoMode write_error_mode);
Zhongyi Shi7f1d9212018-06-22 23:24:36803 void TestMigrationOnMultipleWriteErrors(
804 IoMode write_error_mode_on_old_network,
805 IoMode write_error_mode_on_new_network);
Zhongyi Shib24001c02018-06-18 20:01:52806 void TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
807 bool disconnected);
Zhongyi Shi1e2bc742018-06-16 02:06:07808 void TestMigrationOnWriteErrorWithNotificationQueuedLater(bool disconnected);
Zhongyi Shi9f316b262018-06-18 22:01:16809 void TestMigrationOnNetworkDisconnected(bool async_write_before);
Zhongyi Shia0644e32018-06-21 05:19:52810 void TestMigrationOnNetworkMadeDefault(IoMode write_mode);
Zhongyi Shi22fd5f52018-06-20 17:39:09811 void TestMigrationOnPathDegrading(bool async_write_before);
Zhongyi Shib3bc982c2018-07-10 19:59:24812 void TestMigrateSessionWithDrainingStream(
813 IoMode write_mode_for_queued_packet);
jri5b785512016-09-13 04:29:11814 void TestMigrationOnWriteErrorPauseBeforeConnected(IoMode write_error_mode);
Zhongyi Shi4ac9e1f2018-06-21 05:21:47815 void TestMigrationOnWriteErrorWithMultipleNotifications(
jri5b785512016-09-13 04:29:11816 IoMode write_error_mode,
Zhongyi Shi4ac9e1f2018-06-21 05:21:47817 bool disconnect_before_connect);
Zhongyi Shi634c1882018-08-16 04:05:59818 void TestNoAlternateNetworkBeforeHandshake(quic::QuicErrorCode error);
Zhongyi Shi8de43832018-08-15 23:40:00819 void TestNewConnectionOnAlternateNetworkBeforeHandshake(
820 quic::QuicErrorCode error);
jri9f303712016-09-13 01:10:22821
Jana Iyengarf6b13d82017-09-04 02:09:10822 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
[email protected]e13201d82012-12-12 05:00:32823 MockHostResolver host_resolver_;
Ryan Sleevib8449e02018-07-15 04:31:07824 std::unique_ptr<SSLConfigService> ssl_config_service_;
Zhongyi Shi5f587cc2017-11-21 23:24:17825 std::unique_ptr<MockClientSocketFactory> socket_factory_;
[email protected]e8ff26842013-03-22 21:02:05826 MockCryptoClientStreamFactory crypto_client_stream_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52827 quic::test::MockRandom random_generator_;
828 quic::MockClock clock_;
rtenneti38f5cd52014-10-28 20:28:28829 scoped_refptr<TestTaskRunner> runner_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52830 const quic::QuicTransportVersion version_;
Yixin Wang079ad542018-01-11 04:06:05831 const bool client_headers_include_h2_stream_dependency_;
alyssar2adf3ac2016-05-03 17:12:58832 QuicTestPacketMaker client_maker_;
833 QuicTestPacketMaker server_maker_;
rtenneticcab42b2015-10-09 06:38:16834 HttpServerPropertiesImpl http_server_properties_;
danakjad1777e2016-04-16 00:56:42835 std::unique_ptr<CertVerifier> cert_verifier_;
836 std::unique_ptr<ChannelIDService> channel_id_service_;
[email protected]080b77932014-08-04 01:22:46837 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42838 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:23839 DefaultCTPolicyEnforcer ct_policy_enforcer_;
danakjad1777e2016-04-16 00:56:42840 std::unique_ptr<ScopedMockNetworkChangeNotifier>
jri7e636642016-01-14 06:57:08841 scoped_mock_network_change_notifier_;
danakjad1777e2016-04-16 00:56:42842 std::unique_ptr<QuicStreamFactory> factory_;
[email protected]bf4ea2f2014-03-10 22:57:53843 HostPortPair host_port_pair_;
ckrasic3865ee0f2016-02-29 22:04:56844 GURL url_;
845 GURL url2_;
846 GURL url3_;
847 GURL url4_;
848
[email protected]9dd3ff0f2014-03-26 09:51:28849 PrivacyMode privacy_mode_;
tfarina42834112016-09-22 13:38:20850 NetLogWithSource net_log_;
[email protected]e13201d82012-12-12 05:00:32851 TestCompletionCallback callback_;
Ryan Hamilton75f197262017-08-17 14:00:07852 NetErrorDetails net_error_details_;
jri7046038f2015-10-22 00:29:26853
854 // Variables to configure QuicStreamFactory.
rch431dd4452017-04-19 15:22:35855 bool store_server_configs_in_properties_;
Jana Iyengar903dec22017-11-28 00:44:23856 bool close_sessions_on_ip_change_;
Zhongyi Shi63574b72018-06-01 20:22:25857 bool goaway_sessions_on_ip_change_;
rtenneti41c09992015-11-30 18:24:01858 int idle_connection_timeout_seconds_;
zhongyidd1439f62016-09-02 02:02:26859 int reduced_ping_timeout_seconds_;
Yixin Wang469da562017-11-15 21:34:58860 int max_time_before_crypto_handshake_seconds_;
861 int max_idle_time_before_crypto_handshake_seconds_;
Zhongyi Shif4683a32017-12-01 00:03:28862 bool migrate_sessions_on_network_change_v2_;
863 bool migrate_sessions_early_v2_;
Zhongyi Shi8de43832018-08-15 23:40:00864 bool retry_on_alternate_network_before_handshake_;
Renjiea5722ccf2018-08-10 00:18:49865 bool go_away_on_path_degrading_;
jri217455a12016-07-13 20:15:09866 bool allow_server_migration_;
rtennetid073dd22016-08-04 01:58:33867 bool race_cert_verification_;
rchd6163f32017-01-30 23:50:38868 bool estimate_initial_rtt_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52869 quic::QuicTagVector connection_options_;
870 quic::QuicTagVector client_connection_options_;
[email protected]e13201d82012-12-12 05:00:32871};
872
bnc359ed2a2016-04-29 20:43:45873class QuicStreamFactoryTest : public QuicStreamFactoryTestBase,
874 public ::testing::TestWithParam<TestParams> {
875 protected:
Yixin Wang079ad542018-01-11 04:06:05876 QuicStreamFactoryTest()
877 : QuicStreamFactoryTestBase(
878 GetParam().version,
879 GetParam().client_headers_include_h2_stream_dependency) {}
bnc359ed2a2016-04-29 20:43:45880};
881
Bence Békyce380cb2018-04-26 23:39:55882INSTANTIATE_TEST_CASE_P(VersionIncludeStreamDependencySequence,
rtenneti14abd312015-02-06 21:56:01883 QuicStreamFactoryTest,
884 ::testing::ValuesIn(GetTestParams()));
[email protected]1e960032013-12-20 19:00:20885
[email protected]1e960032013-12-20 19:00:20886TEST_P(QuicStreamFactoryTest, Create) {
jri7046038f2015-10-22 00:29:26887 Initialize();
rch6faa4d42016-01-05 20:48:43888 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
889 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:26890
rcha00569732016-08-27 11:09:36891 MockQuicData socket_data;
892 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:43893 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:17894 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]e13201d82012-12-12 05:00:32895
zhongyi98d6a9262017-05-19 02:47:45896 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:33897 EXPECT_EQ(ERR_IO_PENDING,
898 request.Request(host_port_pair_, version_, privacy_mode_,
899 DEFAULT_PRIORITY, SocketTag(),
900 /*cert_verify_flags=*/0, url_, net_log_,
901 &net_error_details_, 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
Yixin Wang247ea642017-11-15 01:15:50907 EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_.last_request_priority());
908
zhongyi98d6a9262017-05-19 02:47:45909 QuicStreamRequest request2(factory_.get());
zhongyia00ca012017-07-06 23:36:39910 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_, privacy_mode_,
Paul Jensen8e3c5d32018-02-19 17:06:33911 DEFAULT_PRIORITY, SocketTag(),
912 /*cert_verify_flags=*/0, url_, net_log_,
913 &net_error_details_, callback_.callback()));
rch68a80eb2017-04-25 05:24:24914 // Will reset stream 3.
Yixin Wang7891a39d2017-11-08 20:59:24915 stream = CreateStream(&request2);
rch68a80eb2017-04-25 05:24:24916
917 EXPECT_TRUE(stream.get());
918
919 // TODO(rtenneti): We should probably have a tests that HTTP and HTTPS result
920 // in streams on different sessions.
zhongyi98d6a9262017-05-19 02:47:45921 QuicStreamRequest request3(factory_.get());
zhongyia00ca012017-07-06 23:36:39922 EXPECT_EQ(OK, request3.Request(host_port_pair_, version_, privacy_mode_,
Paul Jensen8e3c5d32018-02-19 17:06:33923 DEFAULT_PRIORITY, SocketTag(),
924 /*cert_verify_flags=*/0, url_, net_log_,
925 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:24926 stream = CreateStream(&request3); // Will reset stream 5.
Ryan Hamiltona12722b2017-08-12 02:23:20927 stream.reset(); // Will reset stream 7.
[email protected]e13201d82012-12-12 05:00:32928
rch37de576c2015-05-17 20:28:17929 EXPECT_TRUE(socket_data.AllReadDataConsumed());
930 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]e13201d82012-12-12 05:00:32931}
932
[email protected]8bd2b812014-03-26 04:01:17933TEST_P(QuicStreamFactoryTest, CreateZeroRtt) {
jri7046038f2015-10-22 00:29:26934 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:20935 factory_->set_require_confirmation(false);
rch6faa4d42016-01-05 20:48:43936 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
937 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:26938
rcha00569732016-08-27 11:09:36939 MockQuicData socket_data;
940 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:17941 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]8bd2b812014-03-26 04:01:17942
943 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:27944 MockCryptoClientStream::ZERO_RTT);
[email protected]8bd2b812014-03-26 04:01:17945 host_resolver_.set_synchronous_mode(true);
946 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
947 "192.168.0.1", "");
948
zhongyi98d6a9262017-05-19 02:47:45949 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:33950 EXPECT_EQ(OK, request.Request(host_port_pair_, version_, privacy_mode_,
951 DEFAULT_PRIORITY, SocketTag(),
952 /*cert_verify_flags=*/0, url_, net_log_,
953 &net_error_details_, callback_.callback()));
[email protected]8bd2b812014-03-26 04:01:17954
Yixin Wang7891a39d2017-11-08 20:59:24955 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]8bd2b812014-03-26 04:01:17956 EXPECT_TRUE(stream.get());
rch37de576c2015-05-17 20:28:17957 EXPECT_TRUE(socket_data.AllReadDataConsumed());
958 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]8bd2b812014-03-26 04:01:17959}
960
rchd6163f32017-01-30 23:50:38961TEST_P(QuicStreamFactoryTest, DefaultInitialRtt) {
962 Initialize();
963 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
964 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
965
966 MockQuicData socket_data;
967 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:43968 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:17969 socket_data.AddSocketDataToFactory(socket_factory_.get());
rchd6163f32017-01-30 23:50:38970
zhongyi98d6a9262017-05-19 02:47:45971 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:33972 EXPECT_EQ(ERR_IO_PENDING,
973 request.Request(host_port_pair_, version_, privacy_mode_,
974 DEFAULT_PRIORITY, SocketTag(),
975 /*cert_verify_flags=*/0, url_, net_log_,
976 &net_error_details_, callback_.callback()));
rchd6163f32017-01-30 23:50:38977
978 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:24979 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rchd6163f32017-01-30 23:50:38980 EXPECT_TRUE(stream.get());
981
982 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Ryan Hamiltona12722b2017-08-12 02:23:20983 EXPECT_TRUE(session->require_confirmation());
rchd6163f32017-01-30 23:50:38984 EXPECT_EQ(100000u, session->connection()->GetStats().srtt_us);
985 ASSERT_FALSE(session->config()->HasInitialRoundTripTimeUsToSend());
986}
987
Helen Li0e823912017-09-25 19:48:30988TEST_P(QuicStreamFactoryTest, FactoryDestroyedWhenJobPending) {
989 Initialize();
990 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
991 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
992
993 MockQuicData socket_data;
994 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:43995 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:17996 socket_data.AddSocketDataToFactory(socket_factory_.get());
Helen Li0e823912017-09-25 19:48:30997
998 auto request = std::make_unique<QuicStreamRequest>(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:33999 EXPECT_EQ(ERR_IO_PENDING,
1000 request->Request(host_port_pair_, version_, privacy_mode_,
1001 DEFAULT_PRIORITY, SocketTag(),
1002 /*cert_verify_flags=*/0, url_, net_log_,
1003 &net_error_details_, callback_.callback()));
Helen Li0e823912017-09-25 19:48:301004 request.reset();
1005 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
1006 // Tearing down a QuicStreamFactory with a pending Job should not cause any
1007 // crash. crbug.com/768343.
1008 factory_.reset();
1009}
1010
Ryan Hamiltona12722b2017-08-12 02:23:201011TEST_P(QuicStreamFactoryTest, RequireConfirmation) {
1012 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271013 MockCryptoClientStream::ZERO_RTT);
Ryan Hamiltona12722b2017-08-12 02:23:201014 host_resolver_.set_synchronous_mode(true);
1015 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
1016 "192.168.0.1", "");
1017 Initialize();
1018 factory_->set_require_confirmation(true);
1019 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1020 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1021
1022 MockQuicData socket_data;
1023 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431024 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171025 socket_data.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamiltona12722b2017-08-12 02:23:201026
1027 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331028 EXPECT_EQ(ERR_IO_PENDING,
1029 request.Request(host_port_pair_, version_, privacy_mode_,
1030 DEFAULT_PRIORITY, SocketTag(),
1031 /*cert_verify_flags=*/0, url_, net_log_,
1032 &net_error_details_, callback_.callback()));
Ryan Hamiltona12722b2017-08-12 02:23:201033
Ryan Hamilton8e32a2b2017-08-28 20:06:521034 IPAddress last_address;
1035 EXPECT_FALSE(http_server_properties_.GetSupportsQuic(&last_address));
1036
Ryan Hamiltona12722b2017-08-12 02:23:201037 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521038 quic::QuicSession::HANDSHAKE_CONFIRMED);
Ryan Hamiltona12722b2017-08-12 02:23:201039
Ryan Hamilton8e32a2b2017-08-28 20:06:521040 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
1041
Ryan Hamiltona12722b2017-08-12 02:23:201042 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241043 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Ryan Hamiltona12722b2017-08-12 02:23:201044 EXPECT_TRUE(stream.get());
1045
1046 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1047 EXPECT_TRUE(session->require_confirmation());
1048}
1049
1050TEST_P(QuicStreamFactoryTest, DontRequireConfirmationFromSameIP) {
1051 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271052 MockCryptoClientStream::ZERO_RTT);
Ryan Hamiltona12722b2017-08-12 02:23:201053 host_resolver_.set_synchronous_mode(true);
1054 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
1055 "192.168.0.1", "");
1056 Initialize();
1057 factory_->set_require_confirmation(true);
1058 http_server_properties_.SetSupportsQuic(IPAddress(192, 0, 2, 33));
1059
1060 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1061 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1062
1063 MockQuicData socket_data;
1064 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431065 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171066 socket_data.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamiltona12722b2017-08-12 02:23:201067
1068 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331069 EXPECT_THAT(request.Request(host_port_pair_, version_, privacy_mode_,
1070 DEFAULT_PRIORITY, SocketTag(),
1071 /*cert_verify_flags=*/0, url_, net_log_,
1072 &net_error_details_, callback_.callback()),
1073 IsOk());
Ryan Hamiltona12722b2017-08-12 02:23:201074
Ryan Hamilton8e32a2b2017-08-28 20:06:521075 IPAddress last_address;
1076 EXPECT_FALSE(http_server_properties_.GetSupportsQuic(&last_address));
1077
Yixin Wang7891a39d2017-11-08 20:59:241078 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Ryan Hamiltona12722b2017-08-12 02:23:201079 EXPECT_TRUE(stream.get());
1080
1081 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1082 EXPECT_FALSE(session->require_confirmation());
Ryan Hamilton8e32a2b2017-08-28 20:06:521083
1084 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521085 quic::QuicSession::HANDSHAKE_CONFIRMED);
Ryan Hamilton8e32a2b2017-08-28 20:06:521086
1087 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
Ryan Hamiltona12722b2017-08-12 02:23:201088}
1089
rchd6163f32017-01-30 23:50:381090TEST_P(QuicStreamFactoryTest, CachedInitialRtt) {
1091 ServerNetworkStats stats;
1092 stats.srtt = base::TimeDelta::FromMilliseconds(10);
1093 http_server_properties_.SetServerNetworkStats(url::SchemeHostPort(url_),
1094 stats);
1095 estimate_initial_rtt_ = true;
1096
1097 Initialize();
1098 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1099 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1100
1101 MockQuicData socket_data;
1102 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431103 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171104 socket_data.AddSocketDataToFactory(socket_factory_.get());
rchd6163f32017-01-30 23:50:381105
zhongyi98d6a9262017-05-19 02:47:451106 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331107 EXPECT_EQ(ERR_IO_PENDING,
1108 request.Request(host_port_pair_, version_, privacy_mode_,
1109 DEFAULT_PRIORITY, SocketTag(),
1110 /*cert_verify_flags=*/0, url_, net_log_,
1111 &net_error_details_, callback_.callback()));
rchd6163f32017-01-30 23:50:381112
1113 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241114 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rchd6163f32017-01-30 23:50:381115 EXPECT_TRUE(stream.get());
1116
1117 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1118 EXPECT_EQ(10000u, session->connection()->GetStats().srtt_us);
1119 ASSERT_TRUE(session->config()->HasInitialRoundTripTimeUsToSend());
1120 EXPECT_EQ(10000u, session->config()->GetInitialRoundTripTimeUsToSend());
1121}
1122
1123TEST_P(QuicStreamFactoryTest, 2gInitialRtt) {
1124 ScopedMockNetworkChangeNotifier notifier;
1125 notifier.mock_network_change_notifier()->SetConnectionType(
1126 NetworkChangeNotifier::CONNECTION_2G);
1127 estimate_initial_rtt_ = true;
1128
1129 Initialize();
1130 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1131 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1132
1133 MockQuicData socket_data;
1134 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431135 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171136 socket_data.AddSocketDataToFactory(socket_factory_.get());
rchd6163f32017-01-30 23:50:381137
zhongyi98d6a9262017-05-19 02:47:451138 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331139 EXPECT_EQ(ERR_IO_PENDING,
1140 request.Request(host_port_pair_, version_, privacy_mode_,
1141 DEFAULT_PRIORITY, SocketTag(),
1142 /*cert_verify_flags=*/0, url_, net_log_,
1143 &net_error_details_, callback_.callback()));
rchd6163f32017-01-30 23:50:381144
1145 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241146 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rchd6163f32017-01-30 23:50:381147 EXPECT_TRUE(stream.get());
1148
1149 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1150 EXPECT_EQ(1200000u, session->connection()->GetStats().srtt_us);
1151 ASSERT_TRUE(session->config()->HasInitialRoundTripTimeUsToSend());
1152 EXPECT_EQ(1200000u, session->config()->GetInitialRoundTripTimeUsToSend());
1153}
1154
1155TEST_P(QuicStreamFactoryTest, 3gInitialRtt) {
1156 ScopedMockNetworkChangeNotifier notifier;
1157 notifier.mock_network_change_notifier()->SetConnectionType(
1158 NetworkChangeNotifier::CONNECTION_3G);
1159 estimate_initial_rtt_ = true;
1160
1161 Initialize();
1162 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1163 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1164
1165 MockQuicData socket_data;
1166 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431167 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171168 socket_data.AddSocketDataToFactory(socket_factory_.get());
rchd6163f32017-01-30 23:50:381169
zhongyi98d6a9262017-05-19 02:47:451170 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331171 EXPECT_EQ(ERR_IO_PENDING,
1172 request.Request(host_port_pair_, version_, privacy_mode_,
1173 DEFAULT_PRIORITY, SocketTag(),
1174 /*cert_verify_flags=*/0, url_, net_log_,
1175 &net_error_details_, callback_.callback()));
rchd6163f32017-01-30 23:50:381176
1177 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241178 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rchd6163f32017-01-30 23:50:381179 EXPECT_TRUE(stream.get());
1180
1181 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1182 EXPECT_EQ(400000u, session->connection()->GetStats().srtt_us);
1183 ASSERT_TRUE(session->config()->HasInitialRoundTripTimeUsToSend());
1184 EXPECT_EQ(400000u, session->config()->GetInitialRoundTripTimeUsToSend());
1185}
1186
rch68955482015-09-24 00:14:391187TEST_P(QuicStreamFactoryTest, GoAway) {
jri7046038f2015-10-22 00:29:261188 Initialize();
rch6faa4d42016-01-05 20:48:431189 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1190 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:261191
rcha00569732016-08-27 11:09:361192 MockQuicData socket_data;
1193 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431194 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171195 socket_data.AddSocketDataToFactory(socket_factory_.get());
rch68955482015-09-24 00:14:391196
zhongyi98d6a9262017-05-19 02:47:451197 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331198 EXPECT_EQ(ERR_IO_PENDING,
1199 request.Request(host_port_pair_, version_, privacy_mode_,
1200 DEFAULT_PRIORITY, SocketTag(),
1201 /*cert_verify_flags=*/0, url_, net_log_,
1202 &net_error_details_, callback_.callback()));
rch68955482015-09-24 00:14:391203
robpercival214763f2016-07-01 23:27:011204 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241205 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rch68955482015-09-24 00:14:391206 EXPECT_TRUE(stream.get());
1207
bnc912a04b2016-04-20 14:19:501208 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
rch68955482015-09-24 00:14:391209
Ryan Hamilton8d9ee76e2018-05-29 23:52:521210 session->OnGoAway(quic::QuicGoAwayFrame());
rch68955482015-09-24 00:14:391211
bnc912a04b2016-04-20 14:19:501212 EXPECT_FALSE(HasActiveSession(host_port_pair_));
rch68955482015-09-24 00:14:391213
1214 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1215 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1216}
1217
zhongyi6b5a3892016-03-12 04:46:201218TEST_P(QuicStreamFactoryTest, GoAwayForConnectionMigrationWithPortOnly) {
1219 Initialize();
1220 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1221 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1222
rcha00569732016-08-27 11:09:361223 MockQuicData socket_data;
1224 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431225 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171226 socket_data.AddSocketDataToFactory(socket_factory_.get());
zhongyi6b5a3892016-03-12 04:46:201227
zhongyi98d6a9262017-05-19 02:47:451228 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331229 EXPECT_EQ(ERR_IO_PENDING,
1230 request.Request(host_port_pair_, version_, privacy_mode_,
1231 DEFAULT_PRIORITY, SocketTag(),
1232 /*cert_verify_flags=*/0, url_, net_log_,
1233 &net_error_details_, callback_.callback()));
zhongyi6b5a3892016-03-12 04:46:201234
robpercival214763f2016-07-01 23:27:011235 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241236 std::unique_ptr<HttpStream> stream = CreateStream(&request);
zhongyi6b5a3892016-03-12 04:46:201237 EXPECT_TRUE(stream.get());
1238
bnc912a04b2016-04-20 14:19:501239 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
zhongyi6b5a3892016-03-12 04:46:201240
Ryan Hamilton8d9ee76e2018-05-29 23:52:521241 session->OnGoAway(quic::QuicGoAwayFrame(
1242 quic::kInvalidControlFrameId, quic::QUIC_ERROR_MIGRATING_PORT, 0,
1243 "peer connection migration due to port change only"));
zhongyi6b5a3892016-03-12 04:46:201244 NetErrorDetails details;
1245 EXPECT_FALSE(details.quic_port_migration_detected);
1246 session->PopulateNetErrorDetails(&details);
1247 EXPECT_TRUE(details.quic_port_migration_detected);
1248 details.quic_port_migration_detected = false;
1249 stream->PopulateNetErrorDetails(&details);
1250 EXPECT_TRUE(details.quic_port_migration_detected);
1251
bnc912a04b2016-04-20 14:19:501252 EXPECT_FALSE(HasActiveSession(host_port_pair_));
zhongyi6b5a3892016-03-12 04:46:201253
1254 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1255 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1256}
1257
[email protected]5db452202014-08-19 05:22:151258TEST_P(QuicStreamFactoryTest, Pooling) {
jri7046038f2015-10-22 00:29:261259 Initialize();
rch6faa4d42016-01-05 20:48:431260 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1261 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:261262
rcha00569732016-08-27 11:09:361263 MockQuicData socket_data;
1264 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431265 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171266 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]eed749f92013-12-23 18:57:381267
rch6faa4d42016-01-05 20:48:431268 HostPortPair server2(kServer2HostName, kDefaultServerPort);
[email protected]eed749f92013-12-23 18:57:381269 host_resolver_.set_synchronous_mode(true);
rch6faa4d42016-01-05 20:48:431270 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
rjshaded5ced072015-12-18 19:26:021271 "192.168.0.1", "");
rch6faa4d42016-01-05 20:48:431272 host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]eed749f92013-12-23 18:57:381273
zhongyi98d6a9262017-05-19 02:47:451274 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331275 EXPECT_EQ(OK, request.Request(host_port_pair_, version_, privacy_mode_,
1276 DEFAULT_PRIORITY, SocketTag(),
1277 /*cert_verify_flags=*/0, url_, net_log_,
1278 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241279 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]eed749f92013-12-23 18:57:381280 EXPECT_TRUE(stream.get());
1281
1282 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451283 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331284 EXPECT_EQ(OK, request2.Request(server2, version_, privacy_mode_,
1285 DEFAULT_PRIORITY, SocketTag(),
1286 /*cert_verify_flags=*/0, url2_, net_log_,
1287 &net_error_details_, callback.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241288 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]eed749f92013-12-23 18:57:381289 EXPECT_TRUE(stream2.get());
1290
bnc912a04b2016-04-20 14:19:501291 EXPECT_EQ(GetActiveSession(host_port_pair_), GetActiveSession(server2));
[email protected]eed749f92013-12-23 18:57:381292
rch37de576c2015-05-17 20:28:171293 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1294 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]eed749f92013-12-23 18:57:381295}
1296
jri94ddc3142016-08-26 01:32:431297TEST_P(QuicStreamFactoryTest, PoolingWithServerMigration) {
1298 // Set up session to migrate.
1299 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
1300 "192.168.0.1", "");
1301 IPEndPoint alt_address = IPEndPoint(IPAddress(1, 2, 3, 4), 443);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521302 quic::QuicConfig config;
fayang91ca2012016-11-22 07:42:461303 config.SetAlternateServerAddressToSend(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521304 quic::QuicSocketAddress(quic::QuicSocketAddressImpl(alt_address)));
jri94ddc3142016-08-26 01:32:431305
1306 VerifyServerMigration(config, alt_address);
1307
1308 // Close server-migrated session.
1309 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Renjieba55fae2018-09-20 03:05:161310 session->CloseSessionOnError(0u, quic::QUIC_NO_ERROR,
1311 quic::ConnectionCloseBehavior::SILENT_CLOSE);
jri94ddc3142016-08-26 01:32:431312
1313 // Set up server IP, socket, proof, and config for new session.
1314 HostPortPair server2(kServer2HostName, kDefaultServerPort);
1315 host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
1316
1317 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521318 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361319 client_maker_.MakeInitialSettingsPacket(1, nullptr));
bnceb9aa7112017-01-05 01:03:461320 MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(),
1321 settings_packet->length(), 1)};
fayang3bcb8b502016-12-07 21:44:371322
Ryan Sleevib8d7ea02018-05-07 20:01:011323 SequencedSocketData socket_data(reads, writes);
Zhongyi Shi5f587cc2017-11-21 23:24:171324 socket_factory_->AddSocketDataProvider(&socket_data);
jri94ddc3142016-08-26 01:32:431325
1326 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1327 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521328 quic::QuicConfig config2;
jri94ddc3142016-08-26 01:32:431329 crypto_client_stream_factory_.SetConfig(config2);
1330
1331 // Create new request to cause new session creation.
1332 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451333 QuicStreamRequest request2(factory_.get());
jri94ddc3142016-08-26 01:32:431334 EXPECT_EQ(ERR_IO_PENDING,
Yixin Wang247ea642017-11-15 01:15:501335 request2.Request(server2, version_, privacy_mode_, DEFAULT_PRIORITY,
Paul Jensen8e3c5d32018-02-19 17:06:331336 SocketTag(),
Yixin Wang7f3cdc3f2017-11-10 01:44:141337 /*cert_verify_flags=*/0, url2_, net_log_,
Ryan Hamilton75f197262017-08-17 14:00:071338 &net_error_details_, callback.callback()));
jri94ddc3142016-08-26 01:32:431339 EXPECT_EQ(OK, callback.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:241340 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
jri94ddc3142016-08-26 01:32:431341 EXPECT_TRUE(stream2.get());
1342
1343 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1344 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1345 // EXPECT_EQ(GetActiveSession(host_port_pair_), GetActiveSession(server2));
1346}
1347
[email protected]eed749f92013-12-23 18:57:381348TEST_P(QuicStreamFactoryTest, NoPoolingAfterGoAway) {
jri7046038f2015-10-22 00:29:261349 Initialize();
rch6faa4d42016-01-05 20:48:431350 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1351 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1352 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:261353
rcha00569732016-08-27 11:09:361354 MockQuicData socket_data1;
1355 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431356 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171357 socket_data1.AddSocketDataToFactory(socket_factory_.get());
rcha00569732016-08-27 11:09:361358 MockQuicData socket_data2;
1359 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431360 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171361 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]eed749f92013-12-23 18:57:381362
rch6faa4d42016-01-05 20:48:431363 HostPortPair server2(kServer2HostName, kDefaultServerPort);
[email protected]eed749f92013-12-23 18:57:381364 host_resolver_.set_synchronous_mode(true);
rch6faa4d42016-01-05 20:48:431365 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
rjshaded5ced072015-12-18 19:26:021366 "192.168.0.1", "");
rch6faa4d42016-01-05 20:48:431367 host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]eed749f92013-12-23 18:57:381368
zhongyi98d6a9262017-05-19 02:47:451369 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331370 EXPECT_EQ(OK, request.Request(host_port_pair_, version_, privacy_mode_,
1371 DEFAULT_PRIORITY, SocketTag(),
1372 /*cert_verify_flags=*/0, url_, net_log_,
1373 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241374 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]eed749f92013-12-23 18:57:381375 EXPECT_TRUE(stream.get());
1376
1377 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451378 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331379 EXPECT_EQ(OK, request2.Request(server2, version_, privacy_mode_,
1380 DEFAULT_PRIORITY, SocketTag(),
1381 /*cert_verify_flags=*/0, url2_, net_log_,
1382 &net_error_details_, callback.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241383 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]eed749f92013-12-23 18:57:381384 EXPECT_TRUE(stream2.get());
1385
bnc912a04b2016-04-20 14:19:501386 factory_->OnSessionGoingAway(GetActiveSession(host_port_pair_));
1387 EXPECT_FALSE(HasActiveSession(host_port_pair_));
1388 EXPECT_FALSE(HasActiveSession(server2));
[email protected]eed749f92013-12-23 18:57:381389
1390 TestCompletionCallback callback3;
zhongyi98d6a9262017-05-19 02:47:451391 QuicStreamRequest request3(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331392 EXPECT_EQ(OK, request3.Request(server2, version_, privacy_mode_,
1393 DEFAULT_PRIORITY, SocketTag(),
1394 /*cert_verify_flags=*/0, url2_, net_log_,
1395 &net_error_details_, callback3.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241396 std::unique_ptr<HttpStream> stream3 = CreateStream(&request3);
[email protected]eed749f92013-12-23 18:57:381397 EXPECT_TRUE(stream3.get());
1398
bnc912a04b2016-04-20 14:19:501399 EXPECT_TRUE(HasActiveSession(server2));
[email protected]eed749f92013-12-23 18:57:381400
rch37de576c2015-05-17 20:28:171401 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
1402 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
1403 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1404 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]eed749f92013-12-23 18:57:381405}
1406
[email protected]5db452202014-08-19 05:22:151407TEST_P(QuicStreamFactoryTest, HttpsPooling) {
jri7046038f2015-10-22 00:29:261408 Initialize();
rch6faa4d42016-01-05 20:48:431409
rcha00569732016-08-27 11:09:361410 MockQuicData socket_data;
1411 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431412 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171413 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]eed749f92013-12-23 18:57:381414
rch6faa4d42016-01-05 20:48:431415 HostPortPair server1(kDefaultServerHostName, 443);
1416 HostPortPair server2(kServer2HostName, 443);
[email protected]eed749f92013-12-23 18:57:381417
bncf8bf0722015-05-19 20:04:131418 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
bnc20daf9a2015-05-15 17:11:011419 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
[email protected]eed749f92013-12-23 18:57:381420
1421 host_resolver_.set_synchronous_mode(true);
[email protected]bf4ea2f2014-03-10 22:57:531422 host_resolver_.rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
1423 host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]eed749f92013-12-23 18:57:381424
zhongyi98d6a9262017-05-19 02:47:451425 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331426 EXPECT_EQ(OK, request.Request(server1, version_, privacy_mode_,
1427 DEFAULT_PRIORITY, SocketTag(),
1428 /*cert_verify_flags=*/0, url_, net_log_,
1429 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241430 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]eed749f92013-12-23 18:57:381431 EXPECT_TRUE(stream.get());
1432
1433 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451434 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331435 EXPECT_EQ(OK, request2.Request(server2, version_, privacy_mode_,
1436 DEFAULT_PRIORITY, SocketTag(),
1437 /*cert_verify_flags=*/0, url2_, net_log_,
1438 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241439 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]eed749f92013-12-23 18:57:381440 EXPECT_TRUE(stream2.get());
1441
bnc912a04b2016-04-20 14:19:501442 EXPECT_EQ(GetActiveSession(server1), GetActiveSession(server2));
[email protected]eed749f92013-12-23 18:57:381443
rch37de576c2015-05-17 20:28:171444 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1445 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]eed749f92013-12-23 18:57:381446}
1447
[email protected]5db452202014-08-19 05:22:151448TEST_P(QuicStreamFactoryTest, HttpsPoolingWithMatchingPins) {
jri7046038f2015-10-22 00:29:261449 Initialize();
rcha00569732016-08-27 11:09:361450 MockQuicData socket_data;
1451 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431452 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171453 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]5db452202014-08-19 05:22:151454
rch6faa4d42016-01-05 20:48:431455 HostPortPair server1(kDefaultServerHostName, 443);
1456 HostPortPair server2(kServer2HostName, 443);
Avi Drissman13fc8932015-12-20 04:40:461457 uint8_t primary_pin = 1;
1458 uint8_t backup_pin = 2;
rch6faa4d42016-01-05 20:48:431459 test::AddPin(&transport_security_state_, kServer2HostName, primary_pin,
[email protected]5db452202014-08-19 05:22:151460 backup_pin);
1461
bncf8bf0722015-05-19 20:04:131462 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
[email protected]5db452202014-08-19 05:22:151463 verify_details.cert_verify_result.public_key_hashes.push_back(
1464 test::GetTestHashValue(primary_pin));
bnc20daf9a2015-05-15 17:11:011465 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
[email protected]5db452202014-08-19 05:22:151466
1467 host_resolver_.set_synchronous_mode(true);
1468 host_resolver_.rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
1469 host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
1470
zhongyi98d6a9262017-05-19 02:47:451471 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331472 EXPECT_EQ(OK, request.Request(server1, version_, privacy_mode_,
1473 DEFAULT_PRIORITY, SocketTag(),
1474 /*cert_verify_flags=*/0, url_, net_log_,
1475 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241476 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]5db452202014-08-19 05:22:151477 EXPECT_TRUE(stream.get());
1478
1479 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451480 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331481 EXPECT_EQ(OK, request2.Request(server2, version_, privacy_mode_,
1482 DEFAULT_PRIORITY, SocketTag(),
1483 /*cert_verify_flags=*/0, url2_, net_log_,
1484 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241485 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]5db452202014-08-19 05:22:151486 EXPECT_TRUE(stream2.get());
1487
bnc912a04b2016-04-20 14:19:501488 EXPECT_EQ(GetActiveSession(server1), GetActiveSession(server2));
[email protected]5db452202014-08-19 05:22:151489
rch37de576c2015-05-17 20:28:171490 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1491 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]5db452202014-08-19 05:22:151492}
1493
1494TEST_P(QuicStreamFactoryTest, NoHttpsPoolingWithDifferentPins) {
jri7046038f2015-10-22 00:29:261495 Initialize();
rcha00569732016-08-27 11:09:361496
1497 MockQuicData socket_data1;
1498 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431499 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171500 socket_data1.AddSocketDataToFactory(socket_factory_.get());
rcha00569732016-08-27 11:09:361501 MockQuicData socket_data2;
1502 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431503 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171504 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]5db452202014-08-19 05:22:151505
rch6faa4d42016-01-05 20:48:431506 HostPortPair server1(kDefaultServerHostName, 443);
1507 HostPortPair server2(kServer2HostName, 443);
Avi Drissman13fc8932015-12-20 04:40:461508 uint8_t primary_pin = 1;
1509 uint8_t backup_pin = 2;
1510 uint8_t bad_pin = 3;
rch6faa4d42016-01-05 20:48:431511 test::AddPin(&transport_security_state_, kServer2HostName, primary_pin,
[email protected]5db452202014-08-19 05:22:151512 backup_pin);
1513
bncf8bf0722015-05-19 20:04:131514 ProofVerifyDetailsChromium verify_details1 = DefaultProofVerifyDetails();
bnc20daf9a2015-05-15 17:11:011515 verify_details1.cert_verify_result.public_key_hashes.push_back(
1516 test::GetTestHashValue(bad_pin));
1517 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
1518
bncf8bf0722015-05-19 20:04:131519 ProofVerifyDetailsChromium verify_details2 = DefaultProofVerifyDetails();
bnc20daf9a2015-05-15 17:11:011520 verify_details2.cert_verify_result.public_key_hashes.push_back(
1521 test::GetTestHashValue(primary_pin));
1522 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
[email protected]5db452202014-08-19 05:22:151523
1524 host_resolver_.set_synchronous_mode(true);
1525 host_resolver_.rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
1526 host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
1527
zhongyi98d6a9262017-05-19 02:47:451528 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331529 EXPECT_EQ(OK, request.Request(server1, version_, privacy_mode_,
1530 DEFAULT_PRIORITY, SocketTag(),
1531 /*cert_verify_flags=*/0, url_, net_log_,
1532 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241533 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]5db452202014-08-19 05:22:151534 EXPECT_TRUE(stream.get());
1535
1536 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451537 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331538 EXPECT_EQ(OK, request2.Request(server2, version_, privacy_mode_,
1539 DEFAULT_PRIORITY, SocketTag(),
1540 /*cert_verify_flags=*/0, url2_, net_log_,
1541 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241542 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]5db452202014-08-19 05:22:151543 EXPECT_TRUE(stream2.get());
1544
bnc912a04b2016-04-20 14:19:501545 EXPECT_NE(GetActiveSession(server1), GetActiveSession(server2));
[email protected]5db452202014-08-19 05:22:151546
rch37de576c2015-05-17 20:28:171547 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
1548 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
1549 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1550 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]5db452202014-08-19 05:22:151551}
1552
[email protected]1e960032013-12-20 19:00:201553TEST_P(QuicStreamFactoryTest, Goaway) {
jri7046038f2015-10-22 00:29:261554 Initialize();
rch6faa4d42016-01-05 20:48:431555 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1556 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1557 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1558
rcha00569732016-08-27 11:09:361559 MockQuicData socket_data;
1560 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431561 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171562 socket_data.AddSocketDataToFactory(socket_factory_.get());
rcha00569732016-08-27 11:09:361563 MockQuicData socket_data2;
1564 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431565 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171566 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]4d283b32013-10-17 12:57:271567
zhongyi98d6a9262017-05-19 02:47:451568 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331569 EXPECT_EQ(ERR_IO_PENDING,
1570 request.Request(host_port_pair_, version_, privacy_mode_,
1571 DEFAULT_PRIORITY, SocketTag(),
1572 /*cert_verify_flags=*/0, url_, net_log_,
1573 &net_error_details_, callback_.callback()));
[email protected]4d283b32013-10-17 12:57:271574
robpercival214763f2016-07-01 23:27:011575 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241576 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]4d283b32013-10-17 12:57:271577 EXPECT_TRUE(stream.get());
1578
1579 // Mark the session as going away. Ensure that while it is still alive
1580 // that it is no longer active.
bnc912a04b2016-04-20 14:19:501581 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri7046038f2015-10-22 00:29:261582 factory_->OnSessionGoingAway(session);
1583 EXPECT_EQ(true,
1584 QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
bnc912a04b2016-04-20 14:19:501585 EXPECT_FALSE(HasActiveSession(host_port_pair_));
[email protected]4d283b32013-10-17 12:57:271586
1587 // Create a new request for the same destination and verify that a
1588 // new session is created.
zhongyi98d6a9262017-05-19 02:47:451589 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331590 EXPECT_EQ(ERR_IO_PENDING,
1591 request2.Request(host_port_pair_, version_, privacy_mode_,
1592 DEFAULT_PRIORITY, SocketTag(),
1593 /*cert_verify_flags=*/0, url_, net_log_,
1594 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:011595 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241596 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]4d283b32013-10-17 12:57:271597 EXPECT_TRUE(stream2.get());
1598
bnc912a04b2016-04-20 14:19:501599 EXPECT_TRUE(HasActiveSession(host_port_pair_));
1600 EXPECT_NE(session, GetActiveSession(host_port_pair_));
jri7046038f2015-10-22 00:29:261601 EXPECT_EQ(true,
1602 QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
[email protected]4d283b32013-10-17 12:57:271603
1604 stream2.reset();
1605 stream.reset();
1606
rch37de576c2015-05-17 20:28:171607 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1608 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1609 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1610 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]4d283b32013-10-17 12:57:271611}
1612
[email protected]1e960032013-12-20 19:00:201613TEST_P(QuicStreamFactoryTest, MaxOpenStream) {
jri7046038f2015-10-22 00:29:261614 Initialize();
rch6faa4d42016-01-05 20:48:431615 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1616 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1617
Ryan Hamilton8d9ee76e2018-05-29 23:52:521618 quic::QuicStreamId stream_id = GetNthClientInitiatedStreamId(0);
rcha00569732016-08-27 11:09:361619 MockQuicData socket_data;
Zhongyi Shi32f2fd02018-04-16 18:23:431620 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
fayang3bcb8b502016-12-07 21:44:371621 socket_data.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521622 SYNCHRONOUS, client_maker_.MakeRstPacket(2, true, stream_id,
1623 quic::QUIC_STREAM_CANCELLED));
1624 socket_data.AddRead(ASYNC,
1625 server_maker_.MakeRstPacket(1, false, stream_id,
1626 quic::QUIC_STREAM_CANCELLED));
rcha00569732016-08-27 11:09:361627 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:171628 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]0b2294d32013-08-02 00:46:361629
1630 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:391631 request_info.traffic_annotation =
1632 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1633
xunjieli1d2b4272017-04-25 22:37:171634 std::vector<std::unique_ptr<HttpStream>> streams;
Ryan Hamilton9835e662018-08-02 05:36:271635 // The MockCryptoClientStream sets max_open_streams to be
Ryan Hamilton8d9ee76e2018-05-29 23:52:521636 // quic::kDefaultMaxStreamsPerConnection / 2.
1637 for (size_t i = 0; i < quic::kDefaultMaxStreamsPerConnection / 2; i++) {
zhongyi98d6a9262017-05-19 02:47:451638 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331639 int rv = request.Request(host_port_pair_, version_, privacy_mode_,
1640 DEFAULT_PRIORITY, SocketTag(),
1641 /*cert_verify_flags=*/0, url_, net_log_,
1642 &net_error_details_, callback_.callback());
[email protected]0b2294d32013-08-02 00:46:361643 if (i == 0) {
robpercival214763f2016-07-01 23:27:011644 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1645 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]0b2294d32013-08-02 00:46:361646 } else {
robpercival214763f2016-07-01 23:27:011647 EXPECT_THAT(rv, IsOk());
[email protected]0b2294d32013-08-02 00:46:361648 }
Yixin Wang7891a39d2017-11-08 20:59:241649 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0b2294d32013-08-02 00:46:361650 EXPECT_TRUE(stream);
Steven Valdezb4ff0412018-01-18 22:39:271651 EXPECT_EQ(OK,
1652 stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:391653 net_log_, CompletionOnceCallback()));
avib3635452016-10-21 18:33:531654 streams.push_back(std::move(stream));
[email protected]0b2294d32013-08-02 00:46:361655 }
1656
zhongyi98d6a9262017-05-19 02:47:451657 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331658 EXPECT_EQ(OK, request.Request(host_port_pair_, version_, privacy_mode_,
1659 DEFAULT_PRIORITY, SocketTag(),
1660 /*cert_verify_flags=*/0, url_, net_log_,
Bence Békyd8a21fc32018-06-27 18:29:581661 &net_error_details_, CompletionOnceCallback()));
Yixin Wang7891a39d2017-11-08 20:59:241662 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0b2294d32013-08-02 00:46:361663 EXPECT_TRUE(stream);
rjshaded5ced072015-12-18 19:26:021664 EXPECT_EQ(ERR_IO_PENDING,
Steven Valdezb4ff0412018-01-18 22:39:271665 stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
1666 net_log_, callback_.callback()));
[email protected]0b2294d32013-08-02 00:46:361667
1668 // Close the first stream.
1669 streams.front()->Close(false);
ckrasicea295fe2015-10-31 05:03:271670 // Trigger exchange of RSTs that in turn allow progress for the last
1671 // stream.
robpercival214763f2016-07-01 23:27:011672 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]0b2294d32013-08-02 00:46:361673
rch37de576c2015-05-17 20:28:171674 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1675 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
ckrasicea295fe2015-10-31 05:03:271676
1677 // Force close of the connection to suppress the generation of RST
1678 // packets when streams are torn down, which wouldn't be relevant to
1679 // this test anyway.
bnc912a04b2016-04-20 14:19:501680 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521681 session->connection()->CloseConnection(
1682 quic::QUIC_PUBLIC_RESET, "test",
1683 quic::ConnectionCloseBehavior::SILENT_CLOSE);
[email protected]0b2294d32013-08-02 00:46:361684}
1685
[email protected]1e960032013-12-20 19:00:201686TEST_P(QuicStreamFactoryTest, ResolutionErrorInCreate) {
jri7046038f2015-10-22 00:29:261687 Initialize();
rcha00569732016-08-27 11:09:361688 MockQuicData socket_data;
Zhongyi Shi5f587cc2017-11-21 23:24:171689 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]e13201d82012-12-12 05:00:321690
[email protected]3c772402013-12-18 21:38:111691 host_resolver_.rules()->AddSimulatedFailure(kDefaultServerHostName);
[email protected]e13201d82012-12-12 05:00:321692
zhongyi98d6a9262017-05-19 02:47:451693 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331694 EXPECT_EQ(ERR_IO_PENDING,
1695 request.Request(host_port_pair_, version_, privacy_mode_,
1696 DEFAULT_PRIORITY, SocketTag(),
1697 /*cert_verify_flags=*/0, url_, net_log_,
1698 &net_error_details_, callback_.callback()));
[email protected]e13201d82012-12-12 05:00:321699
robpercival214763f2016-07-01 23:27:011700 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
[email protected]e13201d82012-12-12 05:00:321701
rch37de576c2015-05-17 20:28:171702 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1703 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]e13201d82012-12-12 05:00:321704}
1705
[email protected]1e960032013-12-20 19:00:201706TEST_P(QuicStreamFactoryTest, ConnectErrorInCreate) {
jri7046038f2015-10-22 00:29:261707 Initialize();
rcha00569732016-08-27 11:09:361708
1709 MockQuicData socket_data;
1710 socket_data.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
Zhongyi Shi5f587cc2017-11-21 23:24:171711 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]3c772402013-12-18 21:38:111712
zhongyi98d6a9262017-05-19 02:47:451713 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331714 EXPECT_EQ(ERR_IO_PENDING,
1715 request.Request(host_port_pair_, version_, privacy_mode_,
1716 DEFAULT_PRIORITY, SocketTag(),
1717 /*cert_verify_flags=*/0, url_, net_log_,
1718 &net_error_details_, callback_.callback()));
[email protected]3c772402013-12-18 21:38:111719
robpercival214763f2016-07-01 23:27:011720 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_ADDRESS_IN_USE));
[email protected]3c772402013-12-18 21:38:111721
rch37de576c2015-05-17 20:28:171722 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1723 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]3c772402013-12-18 21:38:111724}
1725
[email protected]1e960032013-12-20 19:00:201726TEST_P(QuicStreamFactoryTest, CancelCreate) {
jri7046038f2015-10-22 00:29:261727 Initialize();
rcha00569732016-08-27 11:09:361728 MockQuicData socket_data;
1729 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431730 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171731 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]e13201d82012-12-12 05:00:321732 {
zhongyi98d6a9262017-05-19 02:47:451733 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331734 EXPECT_EQ(ERR_IO_PENDING,
1735 request.Request(host_port_pair_, version_, privacy_mode_,
1736 DEFAULT_PRIORITY, SocketTag(),
1737 /*cert_verify_flags=*/0, url_, net_log_,
1738 &net_error_details_, callback_.callback()));
[email protected]e13201d82012-12-12 05:00:321739 }
1740
mmenke651bae7f2015-12-18 21:26:451741 base::RunLoop().RunUntilIdle();
[email protected]e13201d82012-12-12 05:00:321742
zhongyi98d6a9262017-05-19 02:47:451743 QuicStreamRequest request2(factory_.get());
zhongyia00ca012017-07-06 23:36:391744 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_, privacy_mode_,
Paul Jensen8e3c5d32018-02-19 17:06:331745 DEFAULT_PRIORITY, SocketTag(),
1746 /*cert_verify_flags=*/0, url_, net_log_,
1747 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241748 std::unique_ptr<HttpStream> stream = CreateStream(&request2);
rch68a80eb2017-04-25 05:24:241749
[email protected]e13201d82012-12-12 05:00:321750 EXPECT_TRUE(stream.get());
1751 stream.reset();
1752
rch37de576c2015-05-17 20:28:171753 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1754 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]e13201d82012-12-12 05:00:321755}
1756
[email protected]1e960032013-12-20 19:00:201757TEST_P(QuicStreamFactoryTest, CloseAllSessions) {
jri7046038f2015-10-22 00:29:261758 Initialize();
rch6faa4d42016-01-05 20:48:431759 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1760 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1761 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1762
rcha00569732016-08-27 11:09:361763 MockQuicData socket_data;
1764 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431765 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Ryan Hamilton8d9ee76e2018-05-29 23:52:521766 socket_data.AddWrite(
1767 SYNCHRONOUS, ConstructClientRstPacket(2, quic::QUIC_RST_ACKNOWLEDGEMENT));
Renjieba55fae2018-09-20 03:05:161768 socket_data.AddWrite(SYNCHRONOUS,
1769 client_maker_.MakeConnectionClosePacket(
1770 3, true, quic::QUIC_INTERNAL_ERROR, "net error"));
Zhongyi Shi5f587cc2017-11-21 23:24:171771 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]56dfb902013-01-03 23:17:551772
rcha00569732016-08-27 11:09:361773 MockQuicData socket_data2;
1774 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431775 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171776 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]56dfb902013-01-03 23:17:551777
zhongyi98d6a9262017-05-19 02:47:451778 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331779 EXPECT_EQ(ERR_IO_PENDING,
1780 request.Request(host_port_pair_, version_, privacy_mode_,
1781 DEFAULT_PRIORITY, SocketTag(),
1782 /*cert_verify_flags=*/0, url_, net_log_,
1783 &net_error_details_, callback_.callback()));
[email protected]56dfb902013-01-03 23:17:551784
robpercival214763f2016-07-01 23:27:011785 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241786 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0b2294d32013-08-02 00:46:361787 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:391788 request_info.traffic_annotation =
1789 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:271790 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:391791 net_log_, CompletionOnceCallback()));
[email protected]56dfb902013-01-03 23:17:551792
1793 // Close the session and verify that stream saw the error.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521794 factory_->CloseAllSessions(ERR_INTERNET_DISCONNECTED,
1795 quic::QUIC_INTERNAL_ERROR);
[email protected]56dfb902013-01-03 23:17:551796 EXPECT_EQ(ERR_INTERNET_DISCONNECTED,
1797 stream->ReadResponseHeaders(callback_.callback()));
1798
1799 // Now attempting to request a stream to the same origin should create
1800 // a new session.
1801
zhongyi98d6a9262017-05-19 02:47:451802 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331803 EXPECT_EQ(ERR_IO_PENDING,
1804 request2.Request(host_port_pair_, version_, privacy_mode_,
1805 DEFAULT_PRIORITY, SocketTag(),
1806 /*cert_verify_flags=*/0, url_, net_log_,
1807 &net_error_details_, callback_.callback()));
[email protected]56dfb902013-01-03 23:17:551808
robpercival214763f2016-07-01 23:27:011809 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241810 stream = CreateStream(&request2);
[email protected]56dfb902013-01-03 23:17:551811 stream.reset(); // Will reset stream 3.
1812
rch37de576c2015-05-17 20:28:171813 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1814 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1815 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1816 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]56dfb902013-01-03 23:17:551817}
1818
zhongyi363c91c2017-03-23 23:16:081819// Regression test for crbug.com/700617. Test a write error during the
1820// crypto handshake will not hang QuicStreamFactory::Job and should
1821// report QUIC_HANDSHAKE_FAILED to upper layers. Subsequent
1822// QuicStreamRequest should succeed without hanging.
1823TEST_P(QuicStreamFactoryTest,
1824 WriteErrorInCryptoConnectWithAsyncHostResolution) {
1825 Initialize();
1826 // Use unmocked crypto stream to do crypto connect.
1827 crypto_client_stream_factory_.set_handshake_mode(
Zhongyi Shi879659422018-08-02 17:58:251828 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
zhongyi363c91c2017-03-23 23:16:081829
1830 MockQuicData socket_data;
1831 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1832 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
1833 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:171834 socket_data.AddSocketDataToFactory(socket_factory_.get());
zhongyi363c91c2017-03-23 23:16:081835
1836 // Create request, should fail after the write of the CHLO fails.
zhongyi98d6a9262017-05-19 02:47:451837 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331838 EXPECT_EQ(ERR_IO_PENDING,
1839 request.Request(host_port_pair_, version_, privacy_mode_,
1840 DEFAULT_PRIORITY, SocketTag(),
1841 /*cert_verify_flags=*/0, url_, net_log_,
1842 &net_error_details_, callback_.callback()));
zhongyi363c91c2017-03-23 23:16:081843 EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED, callback_.WaitForResult());
1844 EXPECT_FALSE(HasActiveSession(host_port_pair_));
1845 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
1846
1847 // Verify new requests can be sent normally without hanging.
1848 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271849 MockCryptoClientStream::COLD_START);
zhongyi363c91c2017-03-23 23:16:081850 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1851 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1852 MockQuicData socket_data2;
1853 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431854 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171855 socket_data2.AddSocketDataToFactory(socket_factory_.get());
zhongyi363c91c2017-03-23 23:16:081856
zhongyi98d6a9262017-05-19 02:47:451857 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331858 EXPECT_EQ(ERR_IO_PENDING,
1859 request2.Request(host_port_pair_, version_, privacy_mode_,
1860 DEFAULT_PRIORITY, SocketTag(),
1861 /*cert_verify_flags=*/0, url_, net_log_,
1862 &net_error_details_, callback_.callback()));
zhongyi363c91c2017-03-23 23:16:081863 EXPECT_FALSE(HasActiveSession(host_port_pair_));
1864 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
1865 // Run the message loop to complete host resolution.
1866 base::RunLoop().RunUntilIdle();
1867
1868 // Complete handshake. QuicStreamFactory::Job should complete and succeed.
1869 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521870 quic::QuicSession::HANDSHAKE_CONFIRMED);
zhongyi363c91c2017-03-23 23:16:081871 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1872 EXPECT_TRUE(HasActiveSession(host_port_pair_));
1873 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
1874
1875 // Create QuicHttpStream.
Yixin Wang7891a39d2017-11-08 20:59:241876 std::unique_ptr<HttpStream> stream = CreateStream(&request2);
zhongyi363c91c2017-03-23 23:16:081877 EXPECT_TRUE(stream.get());
1878 stream.reset();
1879 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1880 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1881 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1882 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
1883}
1884
1885TEST_P(QuicStreamFactoryTest, WriteErrorInCryptoConnectWithSyncHostResolution) {
1886 Initialize();
1887 // Use unmocked crypto stream to do crypto connect.
1888 crypto_client_stream_factory_.set_handshake_mode(
Zhongyi Shi879659422018-08-02 17:58:251889 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
zhongyi363c91c2017-03-23 23:16:081890 host_resolver_.set_synchronous_mode(true);
1891 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
1892 "192.168.0.1", "");
1893
1894 MockQuicData socket_data;
1895 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1896 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
1897 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:171898 socket_data.AddSocketDataToFactory(socket_factory_.get());
zhongyi363c91c2017-03-23 23:16:081899
1900 // Create request, should fail immediately.
zhongyi98d6a9262017-05-19 02:47:451901 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331902 EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED,
1903 request.Request(host_port_pair_, version_, privacy_mode_,
1904 DEFAULT_PRIORITY, SocketTag(),
1905 /*cert_verify_flags=*/0, url_, net_log_,
1906 &net_error_details_, callback_.callback()));
zhongyi363c91c2017-03-23 23:16:081907 // Check no active session, or active jobs left for this server.
1908 EXPECT_FALSE(HasActiveSession(host_port_pair_));
1909 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
1910
1911 // Verify new requests can be sent normally without hanging.
1912 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271913 MockCryptoClientStream::COLD_START);
zhongyi363c91c2017-03-23 23:16:081914 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1915 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1916 MockQuicData socket_data2;
1917 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431918 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171919 socket_data2.AddSocketDataToFactory(socket_factory_.get());
zhongyi363c91c2017-03-23 23:16:081920
zhongyi98d6a9262017-05-19 02:47:451921 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331922 EXPECT_EQ(ERR_IO_PENDING,
1923 request2.Request(host_port_pair_, version_, privacy_mode_,
1924 DEFAULT_PRIORITY, SocketTag(),
1925 /*cert_verify_flags=*/0, url_, net_log_,
1926 &net_error_details_, callback_.callback()));
zhongyi363c91c2017-03-23 23:16:081927 EXPECT_FALSE(HasActiveSession(host_port_pair_));
1928 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
1929
1930 // Complete handshake.
1931 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521932 quic::QuicSession::HANDSHAKE_CONFIRMED);
zhongyi363c91c2017-03-23 23:16:081933 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1934 EXPECT_TRUE(HasActiveSession(host_port_pair_));
1935 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
1936
1937 // Create QuicHttpStream.
Yixin Wang7891a39d2017-11-08 20:59:241938 std::unique_ptr<HttpStream> stream = CreateStream(&request2);
zhongyi363c91c2017-03-23 23:16:081939 EXPECT_TRUE(stream.get());
1940 stream.reset();
1941 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1942 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1943 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1944 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
1945}
1946
Zhongyi Shi63574b72018-06-01 20:22:251947TEST_P(QuicStreamFactoryTest, CloseSessionsOnIPAddressChanged) {
Jana Iyengar903dec22017-11-28 00:44:231948 close_sessions_on_ip_change_ = true;
jri7046038f2015-10-22 00:29:261949 Initialize();
rch6faa4d42016-01-05 20:48:431950 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1951 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1952 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri8c44d692015-10-23 23:53:411953
rcha00569732016-08-27 11:09:361954 MockQuicData socket_data;
1955 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431956 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Ryan Hamilton8d9ee76e2018-05-29 23:52:521957 socket_data.AddWrite(
1958 SYNCHRONOUS, ConstructClientRstPacket(2, quic::QUIC_RST_ACKNOWLEDGEMENT));
Renjieba55fae2018-09-20 03:05:161959 socket_data.AddWrite(
1960 SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
1961 3, true, quic::QUIC_IP_ADDRESS_CHANGED, "net error"));
Zhongyi Shi5f587cc2017-11-21 23:24:171962 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]f698a012013-05-06 20:18:591963
rcha00569732016-08-27 11:09:361964 MockQuicData socket_data2;
1965 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431966 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171967 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]f698a012013-05-06 20:18:591968
zhongyi98d6a9262017-05-19 02:47:451969 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331970 EXPECT_EQ(ERR_IO_PENDING,
1971 request.Request(host_port_pair_, version_, privacy_mode_,
1972 DEFAULT_PRIORITY, SocketTag(),
1973 /*cert_verify_flags=*/0, url_, net_log_,
1974 &net_error_details_, callback_.callback()));
[email protected]f698a012013-05-06 20:18:591975
robpercival214763f2016-07-01 23:27:011976 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241977 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0b2294d32013-08-02 00:46:361978 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:391979 request_info.traffic_annotation =
1980 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:271981 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:391982 net_log_, CompletionOnceCallback()));
[email protected]f698a012013-05-06 20:18:591983
Zhongyi Shi63574b72018-06-01 20:22:251984 // Check an active session exisits for the destination.
1985 EXPECT_TRUE(HasActiveSession(host_port_pair_));
1986 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1987 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
1988
Ryan Hamilton8e32a2b2017-08-28 20:06:521989 IPAddress last_address;
1990 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
Zhongyi Shi63574b72018-06-01 20:22:251991 // Change the IP address and verify that stream saw the error and the active
1992 // session is closed.
jri8c44d692015-10-23 23:53:411993 NotifyIPAddressChanged();
[email protected]f698a012013-05-06 20:18:591994 EXPECT_EQ(ERR_NETWORK_CHANGED,
1995 stream->ReadResponseHeaders(callback_.callback()));
jri7046038f2015-10-22 00:29:261996 EXPECT_TRUE(factory_->require_confirmation());
Ryan Hamilton8e32a2b2017-08-28 20:06:521997 EXPECT_FALSE(http_server_properties_.GetSupportsQuic(&last_address));
Zhongyi Shi63574b72018-06-01 20:22:251998 // Check no active session exists for the destination.
1999 EXPECT_FALSE(HasActiveSession(host_port_pair_));
[email protected]f698a012013-05-06 20:18:592000
2001 // Now attempting to request a stream to the same origin should create
2002 // a new session.
zhongyi98d6a9262017-05-19 02:47:452003 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332004 EXPECT_EQ(ERR_IO_PENDING,
2005 request2.Request(host_port_pair_, version_, privacy_mode_,
2006 DEFAULT_PRIORITY, SocketTag(),
2007 /*cert_verify_flags=*/0, url_, net_log_,
2008 &net_error_details_, callback_.callback()));
[email protected]f698a012013-05-06 20:18:592009
robpercival214763f2016-07-01 23:27:012010 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242011 stream = CreateStream(&request2);
[email protected]f698a012013-05-06 20:18:592012
Zhongyi Shi63574b72018-06-01 20:22:252013 // Check a new active session exisits for the destination and the old session
2014 // is no longer live.
2015 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2016 QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
2017 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
2018
2019 stream.reset(); // Will reset stream 3.
rch37de576c2015-05-17 20:28:172020 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2021 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2022 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
2023 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]f698a012013-05-06 20:18:592024}
2025
Zhongyi Shi63574b72018-06-01 20:22:252026// Test that if goaway_session_on_ip_change is set, old sessions will be marked
2027// as going away on IP address change instead of being closed. New requests will
2028// go to a new connection.
2029TEST_P(QuicStreamFactoryTest, GoAwaySessionsOnIPAddressChanged) {
2030 goaway_sessions_on_ip_change_ = true;
2031 Initialize();
2032 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2033 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2034 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2035
2036 MockQuicData quic_data1;
2037 quic::QuicStreamOffset header_stream_offset = 0;
2038 quic_data1.AddWrite(SYNCHRONOUS,
2039 ConstructInitialSettingsPacket(1, &header_stream_offset));
2040 quic_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
2041 2, GetNthClientInitiatedStreamId(0),
2042 true, true, &header_stream_offset));
2043 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
2044 quic_data1.AddRead(
2045 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
2046 false, true));
2047 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
2048 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2049
2050 MockQuicData quic_data2;
2051 quic::QuicStreamOffset header_stream_offset2 = 0;
2052 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
2053 quic_data2.AddWrite(
2054 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset2));
2055 quic_data2.AddSocketDataToFactory(socket_factory_.get());
2056
2057 // Create request and QuicHttpStream.
2058 QuicStreamRequest request(factory_.get());
2059 EXPECT_EQ(ERR_IO_PENDING,
2060 request.Request(host_port_pair_, version_, privacy_mode_,
2061 DEFAULT_PRIORITY, SocketTag(),
2062 /*cert_verify_flags=*/0, url_, net_log_,
2063 &net_error_details_, callback_.callback()));
2064 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2065 std::unique_ptr<HttpStream> stream = CreateStream(&request);
2066 EXPECT_TRUE(stream.get());
2067
2068 // Cause QUIC stream to be created.
2069 HttpRequestInfo request_info;
2070 request_info.method = "GET";
2071 request_info.url = url_;
2072 request_info.traffic_annotation =
2073 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2074 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
2075 net_log_, CompletionOnceCallback()));
2076
2077 // Ensure that session is alive and active.
2078 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
2079 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2080 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2081
2082 // Send GET request on stream.
2083 HttpResponseInfo response;
2084 HttpRequestHeaders request_headers;
2085 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
2086 callback_.callback()));
2087
2088 // Receive an IP address change notification.
2089 NotifyIPAddressChanged();
2090
2091 // The connection should still be alive, but marked as going away.
2092 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2093 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2094 EXPECT_EQ(1u, session->GetNumActiveStreams());
2095
2096 // Resume the data, response should be read from the original connection.
2097 quic_data1.Resume();
2098 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
2099 EXPECT_EQ(200, response.headers->response_code());
2100 EXPECT_EQ(0u, session->GetNumActiveStreams());
2101
2102 // Second request should be sent on a new connection.
2103 QuicStreamRequest request2(factory_.get());
2104 EXPECT_EQ(ERR_IO_PENDING,
2105 request2.Request(host_port_pair_, version_, privacy_mode_,
2106 DEFAULT_PRIORITY, SocketTag(),
2107 /*cert_verify_flags=*/0, url_, net_log_,
2108 &net_error_details_, callback_.callback()));
2109 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2110 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
2111 EXPECT_TRUE(stream2.get());
2112
2113 // Check an active session exisits for the destination.
2114 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2115 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2116 QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
2117 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
2118
2119 stream.reset();
2120 stream2.reset();
2121 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
2122 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
2123 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
2124 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
2125}
2126
Jana Iyengarba355772017-09-21 22:03:212127TEST_P(QuicStreamFactoryTest, OnIPAddressChangedWithConnectionMigration) {
Zhongyi Shi1a054612018-06-14 04:59:082128 InitializeConnectionMigrationV2Test(
Jana Iyengarba355772017-09-21 22:03:212129 {kDefaultNetworkForTests, kNewNetworkForTests});
2130 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2131 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2132 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2133
2134 MockQuicData socket_data;
2135 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432136 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Ryan Hamilton8d9ee76e2018-05-29 23:52:522137 socket_data.AddWrite(
2138 SYNCHRONOUS, ConstructClientRstPacket(2, quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:172139 socket_data.AddSocketDataToFactory(socket_factory_.get());
Jana Iyengarba355772017-09-21 22:03:212140
2141 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332142 EXPECT_EQ(ERR_IO_PENDING,
2143 request.Request(host_port_pair_, version_, privacy_mode_,
2144 DEFAULT_PRIORITY, SocketTag(),
2145 /*cert_verify_flags=*/0, url_, net_log_,
2146 &net_error_details_, callback_.callback()));
Jana Iyengarba355772017-09-21 22:03:212147
2148 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242149 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Jana Iyengarba355772017-09-21 22:03:212150 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392151 request_info.traffic_annotation =
2152 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272153 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392154 net_log_, CompletionOnceCallback()));
Jana Iyengarba355772017-09-21 22:03:212155
2156 IPAddress last_address;
2157 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
2158
2159 // Change the IP address and verify that the connection is unaffected.
2160 NotifyIPAddressChanged();
2161 EXPECT_FALSE(factory_->require_confirmation());
2162 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
2163
2164 // Attempting a new request to the same origin uses the same connection.
2165 QuicStreamRequest request2(factory_.get());
2166 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_, privacy_mode_,
Paul Jensen8e3c5d32018-02-19 17:06:332167 DEFAULT_PRIORITY, SocketTag(),
2168 /*cert_verify_flags=*/0, url_, net_log_,
2169 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:242170 stream = CreateStream(&request2);
Jana Iyengarba355772017-09-21 22:03:212171
2172 stream.reset();
2173 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2174 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2175}
2176
Zhongyi Shia0644e32018-06-21 05:19:522177TEST_P(QuicStreamFactoryTest, MigrateOnNetworkMadeDefaultWithSynchronousWrite) {
2178 TestMigrationOnNetworkMadeDefault(SYNCHRONOUS);
jri9f303712016-09-13 01:10:222179}
2180
Zhongyi Shia0644e32018-06-21 05:19:522181TEST_P(QuicStreamFactoryTest, MigrateOnNetworkMadeDefaultWithAsyncWrite) {
2182 TestMigrationOnNetworkMadeDefault(ASYNC);
jri9f303712016-09-13 01:10:222183}
2184
Zhongyi Shia0644e32018-06-21 05:19:522185// Sets up a test which attempts connection migration successfully after probing
2186// when a new network is made as default and the old default is still available.
2187// |write_mode| specifies the write mode for the last write before
2188// OnNetworkMadeDefault is delivered to session.
2189void QuicStreamFactoryTestBase::TestMigrationOnNetworkMadeDefault(
2190 IoMode write_mode) {
2191 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri7e636642016-01-14 06:57:082192 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2193 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2194 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2195
Zhongyi Shia0644e32018-06-21 05:19:522196 // Using a testing task runner so that we can control time.
2197 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
2198 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
2199
2200 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2201 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
2202
2203 MockQuicData quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522204 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shia0644e32018-06-21 05:19:522205 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
2206 quic_data1.AddWrite(SYNCHRONOUS,
2207 ConstructInitialSettingsPacket(1, &header_stream_offset));
2208 quic_data1.AddWrite(
2209 write_mode, ConstructGetRequestPacket(2, GetNthClientInitiatedStreamId(0),
2210 true, true, &header_stream_offset));
2211 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2212
2213 // Set up the second socket data provider that is used after migration.
2214 // The response to the earlier request is read on the new socket.
2215 MockQuicData quic_data2;
2216 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:252217 quic_data2.AddWrite(SYNCHRONOUS,
2218 client_maker_.MakeConnectivityProbingPacket(3, true));
Zhongyi Shia0644e32018-06-21 05:19:522219 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
2220 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:252221 quic_data2.AddRead(ASYNC,
2222 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shia0644e32018-06-21 05:19:522223 // Ping packet to send after migration is completed.
2224 quic_data2.AddWrite(ASYNC,
2225 client_maker_.MakeAckAndPingPacket(4, false, 1, 1, 1));
2226 quic_data2.AddRead(
2227 ASYNC, ConstructOkResponsePacket(2, GetNthClientInitiatedStreamId(0),
2228 false, false));
2229 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2230 quic_data2.AddWrite(SYNCHRONOUS,
2231 client_maker_.MakeAckAndRstPacket(
2232 5, false, GetNthClientInitiatedStreamId(0),
2233 quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true));
2234 quic_data2.AddSocketDataToFactory(socket_factory_.get());
jri7e636642016-01-14 06:57:082235
2236 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452237 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332238 EXPECT_EQ(ERR_IO_PENDING,
2239 request.Request(host_port_pair_, version_, privacy_mode_,
2240 DEFAULT_PRIORITY, SocketTag(),
2241 /*cert_verify_flags=*/0, url_, net_log_,
2242 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012243 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242244 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri7e636642016-01-14 06:57:082245 EXPECT_TRUE(stream.get());
2246
2247 // Cause QUIC stream to be created.
2248 HttpRequestInfo request_info;
2249 request_info.method = "GET";
bnc3d9035b32016-06-30 18:18:482250 request_info.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:392251 request_info.traffic_annotation =
2252 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272253 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392254 net_log_, CompletionOnceCallback()));
jri7e636642016-01-14 06:57:082255
2256 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502257 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri7e636642016-01-14 06:57:082258 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2259 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2260
2261 // Send GET request on stream.
2262 HttpResponseInfo response;
2263 HttpRequestHeaders request_headers;
2264 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
2265 callback_.callback()));
2266
Zhongyi Shia0644e32018-06-21 05:19:522267 // Deliver a signal that a alternate network is connected now, this should
2268 // cause the connection to start early migration on path degrading.
2269 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2270 ->SetConnectedNetworksList(
2271 {kDefaultNetworkForTests, kNewNetworkForTests});
2272 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2273 ->NotifyNetworkConnected(kNewNetworkForTests);
jri9f303712016-09-13 01:10:222274
Zhongyi Shia0644e32018-06-21 05:19:522275 // Cause the connection to report path degrading to the session.
2276 // Due to lack of alternate network, session will not mgirate connection.
2277 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
jri7e636642016-01-14 06:57:082278 scoped_mock_network_change_notifier_->mock_network_change_notifier()
jrie2661982016-08-20 08:24:342279 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri7e636642016-01-14 06:57:082280
Zhongyi Shia0644e32018-06-21 05:19:522281 // A task will be posted to migrate to the new default network.
2282 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2283 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
2284
2285 // Execute the posted task to migrate back to the default network.
2286 task_runner->RunUntilIdle();
2287 // Another task to try send a new connectivity probe is posted. And a task to
2288 // retry migrate back to default network is scheduled.
2289 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
2290 // Next connectivity probe is scheduled to be sent in 2 *
2291 // kDefaultRTTMilliSecs.
2292 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
2293 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
2294 next_task_delay);
2295
2296 // The connection should still be alive, and not marked as going away.
jri7e636642016-01-14 06:57:082297 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia0644e32018-06-21 05:19:522298 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2299 EXPECT_EQ(1u, session->GetNumActiveStreams());
2300 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
2301
2302 // Resume quic data and a connectivity probe response will be read on the new
2303 // socket, declare probing as successful. And a new task to WriteToNewSocket
2304 // will be posted to complete migration.
2305 quic_data2.Resume();
2306
2307 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2308 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri7e636642016-01-14 06:57:082309 EXPECT_EQ(1u, session->GetNumActiveStreams());
2310
Zhongyi Shia0644e32018-06-21 05:19:522311 // There should be three pending tasks, the nearest one will complete
2312 // migration to the new network.
2313 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
2314 next_task_delay = task_runner->NextPendingTaskDelay();
2315 EXPECT_EQ(base::TimeDelta(), next_task_delay);
2316 task_runner->FastForwardBy(next_task_delay);
2317
2318 // Response headers are received over the new network.
2319 EXPECT_THAT(callback_.WaitForResult(), IsOk());
jri7e636642016-01-14 06:57:082320 EXPECT_EQ(200, response.headers->response_code());
2321
Zhongyi Shia0644e32018-06-21 05:19:522322 // Now there are two pending tasks, the nearest one was to send connectivity
2323 // probe and has been cancelled due to successful migration.
2324 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
2325 next_task_delay = task_runner->NextPendingTaskDelay();
2326 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
2327 next_task_delay);
2328 task_runner->FastForwardBy(next_task_delay);
jri7e636642016-01-14 06:57:082329
Zhongyi Shia0644e32018-06-21 05:19:522330 // There's one more task to mgirate back to the default network in 0.4s, which
2331 // is also cancelled due to the success migration on the previous trial.
2332 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2333 next_task_delay = task_runner->NextPendingTaskDelay();
2334 base::TimeDelta expected_delay =
2335 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
2336 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
2337 EXPECT_EQ(expected_delay, next_task_delay);
2338 task_runner->FastForwardBy(next_task_delay);
2339 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
jri7e636642016-01-14 06:57:082340
Zhongyi Shia0644e32018-06-21 05:19:522341 // Verify that the session is still alive.
jri7e636642016-01-14 06:57:082342 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia0644e32018-06-21 05:19:522343 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri7e636642016-01-14 06:57:082344
Zhongyi Shia0644e32018-06-21 05:19:522345 stream.reset();
2346 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
2347 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
2348 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
2349 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
jri7e636642016-01-14 06:57:082350}
2351
Zhongyi Shib3bc982c2018-07-10 19:59:242352// Regression test for http://859674.
2353// This test veries that a writer will not attempt to write packets until being
2354// unblocked on both socket level and network level. In this test, a probing
2355// writer is used to send two connectivity probes to the peer: where the first
2356// one completes successfully, while a connectivity response is received before
2357// completes sending the second one. The connection migration attempt will
2358// proceed while the probing writer is blocked at the socket level, which will
2359// block the writer on the network level. Once connection migration completes
2360// successfully, the probing writer will be unblocked on the network level, it
2361// will not attempt to write new packets until the socket level is unblocked.
2362TEST_P(QuicStreamFactoryTest, MigratedToBlockedSocketAfterProbing) {
2363 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
2364 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2365 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2366 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2367
2368 // Using a testing task runner so that we can control time.
2369 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
2370 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
2371
2372 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2373 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
2374
2375 MockQuicData quic_data1;
2376 quic::QuicStreamOffset header_stream_offset = 0;
2377 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
2378 quic_data1.AddWrite(SYNCHRONOUS,
2379 ConstructInitialSettingsPacket(1, &header_stream_offset));
2380 quic_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
2381 2, GetNthClientInitiatedStreamId(0),
2382 true, true, &header_stream_offset));
2383 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2384
2385 // Set up the second socket data provider that is used after migration.
2386 // The response to the earlier request is read on the new socket.
2387 MockQuicData quic_data2;
2388 // First connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:252389 quic_data2.AddWrite(SYNCHRONOUS,
2390 client_maker_.MakeConnectivityProbingPacket(3, true));
Zhongyi Shib3bc982c2018-07-10 19:59:242391 quic_data2.AddRead(ASYNC,
2392 ERR_IO_PENDING); // Pause so that we can control time.
2393 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:252394 quic_data2.AddRead(ASYNC,
2395 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shib3bc982c2018-07-10 19:59:242396 // Second connectivity probe which will complete asynchronously.
Zhongyi Shi879659422018-08-02 17:58:252397 quic_data2.AddWrite(ASYNC,
2398 client_maker_.MakeConnectivityProbingPacket(4, true));
Zhongyi Shib3bc982c2018-07-10 19:59:242399 quic_data2.AddRead(
2400 ASYNC, ConstructOkResponsePacket(2, GetNthClientInitiatedStreamId(0),
2401 false, false));
2402 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2403 quic_data2.AddWrite(ASYNC,
2404 client_maker_.MakeAckAndPingPacket(5, false, 1, 1, 1));
2405 quic_data2.AddWrite(SYNCHRONOUS,
2406 client_maker_.MakeAckAndRstPacket(
2407 6, false, GetNthClientInitiatedStreamId(0),
2408 quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true));
2409
2410 quic_data2.AddSocketDataToFactory(socket_factory_.get());
2411
2412 // Create request and QuicHttpStream.
2413 QuicStreamRequest request(factory_.get());
2414 EXPECT_EQ(ERR_IO_PENDING,
2415 request.Request(host_port_pair_, version_, privacy_mode_,
2416 DEFAULT_PRIORITY, SocketTag(),
2417 /*cert_verify_flags=*/0, url_, net_log_,
2418 &net_error_details_, callback_.callback()));
2419 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2420 std::unique_ptr<HttpStream> stream = CreateStream(&request);
2421 EXPECT_TRUE(stream.get());
2422
2423 // Cause QUIC stream to be created.
2424 HttpRequestInfo request_info;
2425 request_info.method = "GET";
2426 request_info.url = url_;
2427 request_info.traffic_annotation =
2428 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2429 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
2430 net_log_, CompletionOnceCallback()));
2431
2432 // Ensure that session is alive and active.
2433 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
2434 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2435 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2436
2437 // Send GET request on stream.
2438 HttpResponseInfo response;
2439 HttpRequestHeaders request_headers;
2440 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
2441 callback_.callback()));
2442
2443 // Deliver a signal that a alternate network is connected now, this should
2444 // cause the connection to start early migration on path degrading.
2445 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2446 ->SetConnectedNetworksList(
2447 {kDefaultNetworkForTests, kNewNetworkForTests});
2448 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2449 ->NotifyNetworkConnected(kNewNetworkForTests);
2450
2451 // Cause the connection to report path degrading to the session.
2452 // Due to lack of alternate network, session will not mgirate connection.
2453 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
2454 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2455 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2456
2457 // A task will be posted to migrate to the new default network.
2458 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2459 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
2460
2461 // Execute the posted task to migrate back to the default network.
2462 task_runner->RunUntilIdle();
2463 // Another task to resend a new connectivity probe is posted. And a task to
2464 // retry migrate back to default network is scheduled.
2465 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
2466 // Next connectivity probe is scheduled to be sent in 2 *
2467 // kDefaultRTTMilliSecs.
2468 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
2469 base::TimeDelta expected_delay =
2470 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
2471 EXPECT_EQ(expected_delay, next_task_delay);
2472
2473 // Fast forward to send the second connectivity probe. The write will be
2474 // asynchronous and complete after the read completes.
2475 task_runner->FastForwardBy(next_task_delay);
2476
2477 // Resume quic data and a connectivity probe response will be read on the new
2478 // socket, declare probing as successful.
2479 quic_data2.Resume();
2480
2481 // The connection should still be alive, and not marked as going away.
2482 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2483 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2484 EXPECT_EQ(1u, session->GetNumActiveStreams());
2485 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
2486
2487 // There should be three pending tasks, the nearest one will complete
2488 // migration to the new network. Second task will retry migrate back to
2489 // default but cancelled, and the third task will retry send connectivity
2490 // probe but also cancelled.
2491 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
2492 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
2493 task_runner->RunUntilIdle();
2494
2495 // Response headers are received over the new network.
2496 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2497 EXPECT_EQ(200, response.headers->response_code());
2498
2499 // Run the message loop to complete the asynchronous write of ack and ping.
2500 base::RunLoop().RunUntilIdle();
2501
2502 // Now there are two pending tasks, the nearest one was to retry migrate back
2503 // to default network and has been cancelled due to successful migration.
2504 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
2505 expected_delay =
2506 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
2507 expected_delay;
2508 next_task_delay = task_runner->NextPendingTaskDelay();
2509 EXPECT_EQ(expected_delay, next_task_delay);
2510 task_runner->FastForwardBy(next_task_delay);
2511
2512 // There's one more task to retry sending connectivity probe in 0.4s and has
2513 // also been cancelled due to the successful probing.
2514 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2515 next_task_delay = task_runner->NextPendingTaskDelay();
2516 expected_delay =
2517 base::TimeDelta::FromMilliseconds(3 * 2 * kDefaultRTTMilliSecs) -
2518 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs);
2519 EXPECT_EQ(expected_delay, next_task_delay);
2520 task_runner->FastForwardBy(next_task_delay);
2521 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
2522
2523 // Verify that the session is still alive.
2524 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2525 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2526
2527 stream.reset();
2528 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
2529 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
2530 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
2531 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
2532}
2533
Zhongyi Shib1b1fa42018-06-19 23:13:472534// This test verifies that session times out connection migration attempt
2535// with signals delivered in the following order (no alternate network is
2536// available):
2537// - default network disconnected is delivered: session attempts connection
2538// migration but found not alternate network. Session waits for a new network
2539// comes up in the next kWaitTimeForNewNetworkSecs seonds.
2540// - no new network is connected, migration times out. Session is closed.
2541TEST_P(QuicStreamFactoryTest, MigrationTimeoutWithNoNewNetwork) {
2542 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri7e636642016-01-14 06:57:082543 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2544 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2545
Zhongyi Shib1b1fa42018-06-19 23:13:472546 // Using a testing task runner so that we can control time.
2547 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
2548 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
jri5b785512016-09-13 04:29:112549
rcha00569732016-08-27 11:09:362550 MockQuicData socket_data;
2551 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432552 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:172553 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri7e636642016-01-14 06:57:082554
2555 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452556 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332557 EXPECT_EQ(ERR_IO_PENDING,
2558 request.Request(host_port_pair_, version_, privacy_mode_,
2559 DEFAULT_PRIORITY, SocketTag(),
2560 /*cert_verify_flags=*/0, url_, net_log_,
2561 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012562 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242563 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri7e636642016-01-14 06:57:082564 EXPECT_TRUE(stream.get());
2565
2566 // Cause QUIC stream to be created.
2567 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392568 request_info.traffic_annotation =
2569 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272570 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392571 net_log_, CompletionOnceCallback()));
jri7e636642016-01-14 06:57:082572
2573 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502574 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri7e636642016-01-14 06:57:082575 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2576 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2577
2578 // Trigger connection migration. Since there are no networks
jri5b785512016-09-13 04:29:112579 // to migrate to, this should cause the session to wait for a new network.
jri7e636642016-01-14 06:57:082580 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2581 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
2582
jri5b785512016-09-13 04:29:112583 // The migration will not fail until the migration alarm timeout.
2584 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shib1b1fa42018-06-19 23:13:472585 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:112586 EXPECT_EQ(1u, session->GetNumActiveStreams());
2587 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
2588 EXPECT_EQ(true, session->connection()->writer()->IsWriteBlocked());
2589
Zhongyi Shib1b1fa42018-06-19 23:13:472590 // Migration will be timed out after kWaitTimeForNewNetwokSecs.
2591 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2592 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
2593 EXPECT_EQ(base::TimeDelta::FromSeconds(kWaitTimeForNewNetworkSecs),
2594 next_task_delay);
2595 task_runner->FastForwardBy(next_task_delay);
jri5b785512016-09-13 04:29:112596
2597 // The connection should now be closed. A request for response
2598 // headers should fail.
jri7e636642016-01-14 06:57:082599 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2600 EXPECT_FALSE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:112601 EXPECT_EQ(ERR_NETWORK_CHANGED, callback_.WaitForResult());
jri7e636642016-01-14 06:57:082602
2603 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2604 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2605}
2606
Zhongyi Shi21e99532018-07-17 22:23:072607// This test verifies that connectivity probes will be sent even if there is
2608// a non-migratable stream. However, when connection migrates to the
2609// successfully probed path, any non-migratable stream will be reset. And if
2610// the connection becomes idle then, close the connection.
jri9f303712016-09-13 01:10:222611TEST_P(QuicStreamFactoryTest, OnNetworkMadeDefaultNonMigratableStream) {
Zhongyi Shi5f587cc2017-11-21 23:24:172612 InitializeConnectionMigrationV2Test(
2613 {kDefaultNetworkForTests, kNewNetworkForTests});
2614 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2615 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2616
2617 MockQuicData socket_data;
2618 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432619 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Renjieba55fae2018-09-20 03:05:162620 socket_data.AddWrite(
2621 SYNCHRONOUS,
2622 client_maker_.MakeRstAckAndConnectionClosePacket(
2623 3, false, 5, quic::QUIC_STREAM_CANCELLED,
2624 quic::QuicTime::Delta::FromMilliseconds(0), 1, 1, 1,
2625 quic::QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS, "net error"));
2626
Zhongyi Shi5f587cc2017-11-21 23:24:172627 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri231c2972016-03-08 19:50:112628
Zhongyi Shi21e99532018-07-17 22:23:072629 // Set up the second socket data provider that is used for probing.
2630 MockQuicData quic_data1;
2631 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:252632 quic_data1.AddWrite(SYNCHRONOUS,
2633 client_maker_.MakeConnectivityProbingPacket(2, true));
Zhongyi Shi21e99532018-07-17 22:23:072634 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
2635 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:252636 quic_data1.AddRead(ASYNC,
2637 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shi21e99532018-07-17 22:23:072638 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2639
jri231c2972016-03-08 19:50:112640 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452641 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332642 EXPECT_EQ(ERR_IO_PENDING,
2643 request.Request(host_port_pair_, version_, privacy_mode_,
2644 DEFAULT_PRIORITY, SocketTag(),
2645 /*cert_verify_flags=*/0, url_, net_log_,
2646 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012647 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242648 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri231c2972016-03-08 19:50:112649 EXPECT_TRUE(stream.get());
2650
2651 // Cause QUIC stream to be created, but marked as non-migratable.
2652 HttpRequestInfo request_info;
Zhongyi Shibb28b1f2018-07-18 02:41:262653 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Ramin Halavati683bcaa92018-02-14 08:42:392654 request_info.traffic_annotation =
2655 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272656 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392657 net_log_, CompletionOnceCallback()));
jri231c2972016-03-08 19:50:112658
2659 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502660 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri231c2972016-03-08 19:50:112661 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2662 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2663
Zhongyi Shi21e99532018-07-17 22:23:072664 // Trigger connection migration. Session will start to probe the alternative
2665 // network. Although there is a non-migratable stream, session will still be
2666 // active until probing is declared as successful.
jri231c2972016-03-08 19:50:112667 scoped_mock_network_change_notifier_->mock_network_change_notifier()
jrie2661982016-08-20 08:24:342668 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri231c2972016-03-08 19:50:112669
2670 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shi21e99532018-07-17 22:23:072671 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri231c2972016-03-08 19:50:112672 EXPECT_EQ(1u, session->GetNumActiveStreams());
2673
Zhongyi Shi21e99532018-07-17 22:23:072674 // Resume data to read a connectivity probing response, which will cause
2675 // non-migtable streams to be closed. As session becomes idle, connection will
2676 // be closed.
2677 quic_data1.Resume();
2678 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2679 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2680 EXPECT_EQ(0u, session->GetNumActiveStreams());
jri231c2972016-03-08 19:50:112681
Zhongyi Shi21e99532018-07-17 22:23:072682 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
2683 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
jri231c2972016-03-08 19:50:112684 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2685 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2686}
2687
jri9f303712016-09-13 01:10:222688TEST_P(QuicStreamFactoryTest, OnNetworkMadeDefaultConnectionMigrationDisabled) {
Zhongyi Shi5f587cc2017-11-21 23:24:172689 InitializeConnectionMigrationV2Test(
2690 {kDefaultNetworkForTests, kNewNetworkForTests});
2691 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2692 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2693
2694 MockQuicData socket_data;
2695 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432696 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
2697 socket_data.AddWrite(
2698 SYNCHRONOUS,
2699 client_maker_.MakeRstPacket(2, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:522700 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:172701 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9c541572016-03-29 17:51:482702
2703 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452704 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332705 EXPECT_EQ(ERR_IO_PENDING,
2706 request.Request(host_port_pair_, version_, privacy_mode_,
2707 DEFAULT_PRIORITY, SocketTag(),
2708 /*cert_verify_flags=*/0, url_, net_log_,
2709 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012710 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242711 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9c541572016-03-29 17:51:482712 EXPECT_TRUE(stream.get());
2713
2714 // Cause QUIC stream to be created.
2715 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392716 request_info.traffic_annotation =
2717 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272718 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392719 net_log_, CompletionOnceCallback()));
jri9c541572016-03-29 17:51:482720
2721 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502722 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri9c541572016-03-29 17:51:482723 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2724 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2725
2726 // Set session config to have connection migration disabled.
Ryan Hamilton8d9ee76e2018-05-29 23:52:522727 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
2728 session->config());
jri9c541572016-03-29 17:51:482729 EXPECT_TRUE(session->config()->DisableConnectionMigration());
2730
2731 // Trigger connection migration. Since there is a non-migratable stream,
2732 // this should cause session to continue but be marked as going away.
2733 scoped_mock_network_change_notifier_->mock_network_change_notifier()
jrie2661982016-08-20 08:24:342734 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri9c541572016-03-29 17:51:482735
2736 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2737 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2738 EXPECT_EQ(1u, session->GetNumActiveStreams());
2739
2740 stream.reset();
2741
2742 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2743 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2744}
2745
jri9f303712016-09-13 01:10:222746TEST_P(QuicStreamFactoryTest, OnNetworkDisconnectedNonMigratableStream) {
Zhongyi Shi5f587cc2017-11-21 23:24:172747 InitializeConnectionMigrationV2Test(
2748 {kDefaultNetworkForTests, kNewNetworkForTests});
2749 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2750 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2751
2752 MockQuicData socket_data;
2753 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432754 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
2755 socket_data.AddWrite(
2756 SYNCHRONOUS,
2757 client_maker_.MakeRstPacket(2, true, GetNthClientInitiatedStreamId(0),
Zhongyi Shi0439ecc72018-07-11 04:41:262758 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:172759 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri231c2972016-03-08 19:50:112760
2761 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452762 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332763 EXPECT_EQ(ERR_IO_PENDING,
2764 request.Request(host_port_pair_, version_, privacy_mode_,
2765 DEFAULT_PRIORITY, SocketTag(),
2766 /*cert_verify_flags=*/0, url_, net_log_,
2767 &net_error_details_, 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
2785 // Trigger connection migration. Since there is a non-migratable stream,
2786 // this should cause a RST_STREAM frame to be emitted with
Zhongyi Shi0439ecc72018-07-11 04:41:262787 // quic::QUIC_STREAM_CANCELLED error code, and the session will be closed.
jri231c2972016-03-08 19:50:112788 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2789 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
2790
2791 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2792 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2793
2794 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2795 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2796}
2797
jri9c541572016-03-29 17:51:482798TEST_P(QuicStreamFactoryTest,
jri9f303712016-09-13 01:10:222799 OnNetworkDisconnectedConnectionMigrationDisabled) {
Zhongyi Shi5f587cc2017-11-21 23:24:172800 InitializeConnectionMigrationV2Test(
2801 {kDefaultNetworkForTests, kNewNetworkForTests});
2802 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2803 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2804
2805 MockQuicData socket_data;
2806 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432807 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
2808 socket_data.AddWrite(
2809 SYNCHRONOUS,
2810 client_maker_.MakeRstPacket(2, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:522811 quic::QUIC_RST_ACKNOWLEDGEMENT));
Zhongyi Shi5f587cc2017-11-21 23:24:172812 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9c541572016-03-29 17:51:482813
2814 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452815 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332816 EXPECT_EQ(ERR_IO_PENDING,
2817 request.Request(host_port_pair_, version_, privacy_mode_,
2818 DEFAULT_PRIORITY, SocketTag(),
2819 /*cert_verify_flags=*/0, url_, net_log_,
2820 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012821 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242822 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9c541572016-03-29 17:51:482823 EXPECT_TRUE(stream.get());
2824
2825 // Cause QUIC stream to be created.
2826 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392827 request_info.traffic_annotation =
2828 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272829 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392830 net_log_, CompletionOnceCallback()));
jri9c541572016-03-29 17:51:482831
2832 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502833 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri9c541572016-03-29 17:51:482834 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2835 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2836
2837 // Set session config to have connection migration disabled.
Ryan Hamilton8d9ee76e2018-05-29 23:52:522838 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
2839 session->config());
jri9c541572016-03-29 17:51:482840 EXPECT_TRUE(session->config()->DisableConnectionMigration());
2841
2842 // Trigger connection migration. Since there is a non-migratable stream,
2843 // this should cause a RST_STREAM frame to be emitted with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522844 // quic::QUIC_RST_ACKNOWLEDGEMENT error code, and the session will be closed.
jri9c541572016-03-29 17:51:482845 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2846 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
2847
2848 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2849 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2850
2851 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2852 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2853}
2854
jri9f303712016-09-13 01:10:222855TEST_P(QuicStreamFactoryTest, OnNetworkMadeDefaultNoOpenStreams) {
Zhongyi Shi5f587cc2017-11-21 23:24:172856 InitializeConnectionMigrationV2Test(
2857 {kDefaultNetworkForTests, kNewNetworkForTests});
2858 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2859 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2860
2861 MockQuicData socket_data;
2862 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432863 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Renjieba55fae2018-09-20 03:05:162864 socket_data.AddWrite(
2865 SYNCHRONOUS,
2866 client_maker_.MakeConnectionClosePacket(
2867 2, true, quic::QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS,
2868 "net error"));
Zhongyi Shi5f587cc2017-11-21 23:24:172869 socket_data.AddSocketDataToFactory(socket_factory_.get());
2870
2871 // Create request and QuicHttpStream.
2872 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332873 EXPECT_EQ(ERR_IO_PENDING,
2874 request.Request(host_port_pair_, version_, privacy_mode_,
2875 DEFAULT_PRIORITY, SocketTag(),
2876 /*cert_verify_flags=*/0, url_, net_log_,
2877 &net_error_details_, callback_.callback()));
Zhongyi Shi5f587cc2017-11-21 23:24:172878 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2879 std::unique_ptr<HttpStream> stream = CreateStream(&request);
2880 EXPECT_TRUE(stream.get());
2881
2882 // Ensure that session is alive and active.
2883 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
2884 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2885 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2886
2887 // Trigger connection migration.
2888 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2889 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2890
2891 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2892 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2893
2894 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2895 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2896}
2897
jri9f303712016-09-13 01:10:222898TEST_P(QuicStreamFactoryTest, OnNetworkDisconnectedNoOpenStreams) {
Zhongyi Shi5f587cc2017-11-21 23:24:172899 InitializeConnectionMigrationV2Test(
2900 {kDefaultNetworkForTests, kNewNetworkForTests});
2901 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2902 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2903
2904 MockQuicData socket_data;
2905 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432906 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:172907 socket_data.AddSocketDataToFactory(socket_factory_.get());
2908
2909 // Create request and QuicHttpStream.
2910 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332911 EXPECT_EQ(ERR_IO_PENDING,
2912 request.Request(host_port_pair_, version_, privacy_mode_,
2913 DEFAULT_PRIORITY, SocketTag(),
2914 /*cert_verify_flags=*/0, url_, net_log_,
2915 &net_error_details_, callback_.callback()));
Zhongyi Shi5f587cc2017-11-21 23:24:172916 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2917 std::unique_ptr<HttpStream> stream = CreateStream(&request);
2918 EXPECT_TRUE(stream.get());
2919
2920 // Ensure that session is alive and active.
2921 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
2922 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2923 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2924
2925 // Trigger connection migration. Since there are no active streams,
2926 // the session will be closed.
2927 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2928 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
2929
2930 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2931 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2932
2933 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2934 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2935}
2936
Zhongyi Shi9f316b262018-06-18 22:01:162937// This test verifies session migrates to the alternate network immediately when
2938// default network disconnects with a synchronous write before migration.
2939TEST_P(QuicStreamFactoryTest, MigrateOnDefaultNetworkDisconnectedSync) {
2940 TestMigrationOnNetworkDisconnected(/*async_write_before*/ false);
2941}
2942
2943// This test verifies session migrates to the alternate network immediately when
2944// default network disconnects with an asynchronously write before migration.
2945TEST_P(QuicStreamFactoryTest, MigrateOnDefaultNetworkDisconnectedAsync) {
2946 TestMigrationOnNetworkDisconnected(/*async_write_before*/ true);
2947}
2948
2949void QuicStreamFactoryTestBase::TestMigrationOnNetworkDisconnected(
2950 bool async_write_before) {
2951 InitializeConnectionMigrationV2Test(
2952 {kDefaultNetworkForTests, kNewNetworkForTests});
2953 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2954 ->NotifyNetworkMadeDefault(kDefaultNetworkForTests);
2955 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2956 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2957 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2958
2959 // Use the test task runner.
2960 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
2961
2962 int packet_number = 1;
2963 MockQuicData socket_data;
2964 quic::QuicStreamOffset header_stream_offset = 0;
2965 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2966 socket_data.AddWrite(
2967 SYNCHRONOUS,
2968 ConstructInitialSettingsPacket(packet_number++, &header_stream_offset));
2969 socket_data.AddWrite(
2970 SYNCHRONOUS, ConstructGetRequestPacket(
2971 packet_number++, GetNthClientInitiatedStreamId(0), true,
2972 true, &header_stream_offset));
2973 if (async_write_before) {
2974 socket_data.AddWrite(ASYNC, OK);
2975 packet_number++;
2976 }
2977 socket_data.AddSocketDataToFactory(socket_factory_.get());
2978
2979 // Create request and QuicHttpStream.
2980 QuicStreamRequest request(factory_.get());
2981 EXPECT_EQ(ERR_IO_PENDING,
2982 request.Request(host_port_pair_, version_, privacy_mode_,
2983 DEFAULT_PRIORITY, SocketTag(),
2984 /*cert_verify_flags=*/0, url_, net_log_,
2985 &net_error_details_, callback_.callback()));
2986 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2987 std::unique_ptr<HttpStream> stream = CreateStream(&request);
2988 EXPECT_TRUE(stream.get());
2989
2990 // Cause QUIC stream to be created.
2991 HttpRequestInfo request_info;
2992 request_info.method = "GET";
2993 request_info.url = url_;
2994 request_info.traffic_annotation =
2995 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2996 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
2997 net_log_, CompletionOnceCallback()));
2998
2999 // Ensure that session is alive and active.
3000 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3001 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3002 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3003
3004 // Send GET request on stream.
3005 HttpResponseInfo response;
3006 HttpRequestHeaders request_headers;
3007 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3008 callback_.callback()));
3009
Zhongyi Shi22fd5f52018-06-20 17:39:093010 if (async_write_before)
Zhongyi Shi9f316b262018-06-18 22:01:163011 session->SendPing();
Zhongyi Shi9f316b262018-06-18 22:01:163012
3013 // Set up second socket data provider that is used after migration.
3014 // The response to the earlier request is read on this new socket.
3015 MockQuicData socket_data1;
3016 socket_data1.AddWrite(
3017 SYNCHRONOUS,
3018 client_maker_.MakePingPacket(packet_number++, /*include_version=*/true));
3019 socket_data1.AddRead(
3020 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
3021 false, false));
3022 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3023 socket_data1.AddWrite(
3024 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
3025 packet_number++, false, GetNthClientInitiatedStreamId(0),
3026 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
3027 socket_data1.AddSocketDataToFactory(socket_factory_.get());
3028
3029 // Trigger connection migration.
3030 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3031 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
3032
3033 // The connection should still be alive, not marked as going away.
3034 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3035 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3036 EXPECT_EQ(1u, session->GetNumActiveStreams());
3037 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3038
3039 // Ensure that the session is still alive.
3040 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3041 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3042 EXPECT_EQ(1u, session->GetNumActiveStreams());
3043
3044 // Run the message loop so that data queued in the new socket is read by the
3045 // packet reader.
3046 runner_->RunNextTask();
3047
3048 // Response headers are received over the new network.
3049 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3050 EXPECT_EQ(200, response.headers->response_code());
3051
3052 // Check that the session is still alive.
3053 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3054 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3055
3056 // There should be posted tasks not executed, which is to migrate back to
3057 // default network.
3058 EXPECT_FALSE(runner_->GetPostedTasks().empty());
3059
3060 // Receive signal to mark new network as default.
3061 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3062 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3063
3064 stream.reset();
3065 EXPECT_TRUE(socket_data.AllReadDataConsumed());
3066 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
3067 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
3068 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
3069}
3070
Zhongyi Shi5f587cc2017-11-21 23:24:173071// This test receives NCN signals in the following order:
3072// - default network disconnected
3073// - after a pause, new network is connected.
3074// - new network is made default.
3075TEST_P(QuicStreamFactoryTest, NewNetworkConnectedAfterNoNetwork) {
3076 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
3077 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3078 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3079 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3080
3081 // Use the test task runner.
3082 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
3083
3084 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523085 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shi5f587cc2017-11-21 23:24:173086 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3087 socket_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433088 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
3089 socket_data.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
3090 2, GetNthClientInitiatedStreamId(0),
3091 true, true, &header_stream_offset));
Zhongyi Shi5f587cc2017-11-21 23:24:173092 socket_data.AddSocketDataToFactory(socket_factory_.get());
3093
3094 // Create request and QuicHttpStream.
3095 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:333096 EXPECT_EQ(ERR_IO_PENDING,
3097 request.Request(host_port_pair_, version_, privacy_mode_,
3098 DEFAULT_PRIORITY, SocketTag(),
3099 /*cert_verify_flags=*/0, url_, net_log_,
3100 &net_error_details_, callback_.callback()));
Zhongyi Shi5f587cc2017-11-21 23:24:173101 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3102 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3103 EXPECT_TRUE(stream.get());
3104
3105 // Cause QUIC stream to be created.
3106 HttpRequestInfo request_info;
3107 request_info.method = "GET";
3108 request_info.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:393109 request_info.traffic_annotation =
3110 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:273111 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:393112 net_log_, CompletionOnceCallback()));
Zhongyi Shi5f587cc2017-11-21 23:24:173113
3114 // Ensure that session is alive and active.
3115 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3116 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3117 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3118
3119 // Send GET request on stream.
3120 HttpResponseInfo response;
3121 HttpRequestHeaders request_headers;
3122 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3123 callback_.callback()));
3124
3125 // Trigger connection migration. Since there are no networks
3126 // to migrate to, this should cause the session to wait for a new network.
3127 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3128 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
3129
3130 // The connection should still be alive, not marked as going away.
3131 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3132 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3133 EXPECT_EQ(1u, session->GetNumActiveStreams());
3134 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3135
3136 // Set up second socket data provider that is used after migration.
3137 // The response to the earlier request is read on this new socket.
3138 MockQuicData socket_data1;
3139 socket_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433140 SYNCHRONOUS, client_maker_.MakePingPacket(3, /*include_version=*/true));
3141 socket_data1.AddRead(
3142 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
3143 false, false));
Zhongyi Shi5f587cc2017-11-21 23:24:173144 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:433145 socket_data1.AddWrite(SYNCHRONOUS,
3146 client_maker_.MakeAckAndRstPacket(
3147 4, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:523148 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:173149 socket_data1.AddSocketDataToFactory(socket_factory_.get());
3150
3151 // Add a new network and notify the stream factory of a new connected network.
3152 // This causes a PING packet to be sent over the new network.
3153 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3154 ->SetConnectedNetworksList({kNewNetworkForTests});
3155 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3156 ->NotifyNetworkConnected(kNewNetworkForTests);
3157
3158 // Ensure that the session is still alive.
3159 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3160 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3161 EXPECT_EQ(1u, session->GetNumActiveStreams());
3162
3163 // Run the message loop so that data queued in the new socket is read by the
3164 // packet reader.
3165 runner_->RunNextTask();
3166
3167 // Response headers are received over the new network.
3168 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3169 EXPECT_EQ(200, response.headers->response_code());
3170
3171 // Check that the session is still alive.
3172 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3173 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3174
3175 // There should posted tasks not executed, which is to migrate back to default
3176 // network.
3177 EXPECT_FALSE(runner_->GetPostedTasks().empty());
3178
3179 // Receive signal to mark new network as default.
3180 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3181 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3182
3183 stream.reset();
3184 EXPECT_TRUE(socket_data.AllReadDataConsumed());
3185 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
3186 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
3187 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
3188}
3189
Zhongyi Shid3d5f502018-08-10 00:22:223190// Regression test for http://crbug.com/872011.
3191// This test verifies that migrate to the probing socket will not trigger
3192// new packets being read synchronously and generate ACK frame while
3193// processing the initial connectivity probe response, which may cause a
3194// connection being closed with INTERNAL_ERROR as pending ACK frame is not
3195// allowed when processing a new packet.
3196TEST_P(QuicStreamFactoryTest, MigrateToProbingSocket) {
3197 InitializeConnectionMigrationV2Test(
3198 {kDefaultNetworkForTests, kNewNetworkForTests});
3199 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3200 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3201 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3202
3203 // Using a testing task runner so that we can control time.
3204 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3205 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
3206
3207 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3208 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3209
3210 int packet_number = 1;
3211 MockQuicData quic_data1;
3212 quic::QuicStreamOffset header_stream_offset = 0;
3213 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
3214 quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
3215 packet_number++, &header_stream_offset));
3216 quic_data1.AddWrite(
3217 SYNCHRONOUS, ConstructGetRequestPacket(
3218 packet_number++, GetNthClientInitiatedStreamId(0), true,
3219 true, &header_stream_offset));
3220 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3221
3222 // Set up the second socket data provider that is used for probing on the
3223 // alternate network.
3224 MockQuicData quic_data2;
3225 // Connectivity probe to be sent on the new path.
3226 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(
3227 packet_number++, true));
3228 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3229 // First connectivity probe to receive from the server, which will complete
3230 // connection migraiton on path degrading.
3231 quic_data2.AddRead(ASYNC,
3232 server_maker_.MakeConnectivityProbingPacket(1, false));
3233 // Read multiple connectivity probes synchronously.
3234 quic_data2.AddRead(SYNCHRONOUS,
3235 server_maker_.MakeConnectivityProbingPacket(2, false));
3236 quic_data2.AddRead(SYNCHRONOUS,
3237 server_maker_.MakeConnectivityProbingPacket(3, false));
3238 quic_data2.AddRead(SYNCHRONOUS,
3239 server_maker_.MakeConnectivityProbingPacket(4, false));
3240 quic_data2.AddWrite(
3241 ASYNC, client_maker_.MakeAckPacket(packet_number++, 1, 4, 1, 1, true));
3242 quic_data2.AddRead(
3243 ASYNC, ConstructOkResponsePacket(5, GetNthClientInitiatedStreamId(0),
3244 false, false));
3245 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3246 quic_data2.AddWrite(
3247 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
3248 packet_number++, false, GetNthClientInitiatedStreamId(0),
3249 quic::QUIC_STREAM_CANCELLED, 5, 1, 1, true));
3250 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3251
3252 // Create request and QuicHttpStream.
3253 QuicStreamRequest request(factory_.get());
3254 EXPECT_EQ(ERR_IO_PENDING,
3255 request.Request(host_port_pair_, version_, privacy_mode_,
3256 DEFAULT_PRIORITY, SocketTag(),
3257 /*cert_verify_flags=*/0, url_, net_log_,
3258 &net_error_details_, callback_.callback()));
3259 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3260 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3261 EXPECT_TRUE(stream.get());
3262
3263 // Cause QUIC stream to be created.
3264 HttpRequestInfo request_info;
3265 request_info.method = "GET";
3266 request_info.url = url_;
3267 request_info.traffic_annotation =
3268 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3269 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3270 net_log_, CompletionOnceCallback()));
3271
3272 // Ensure that session is alive and active.
3273 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3274 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3275 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3276
3277 // Send GET request on stream.
3278 HttpResponseInfo response;
3279 HttpRequestHeaders request_headers;
3280 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3281 callback_.callback()));
3282
3283 // Cause the connection to report path degrading to the session.
3284 // Session will start to probe the alternate network.
3285 session->connection()->OnPathDegradingTimeout();
3286
3287 // Next connectivity probe is scheduled to be sent in 2 *
3288 // kDefaultRTTMilliSecs.
3289 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3290 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
3291 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3292 next_task_delay);
3293
3294 // The connection should still be alive, and not marked as going away.
3295 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3296 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3297 EXPECT_EQ(1u, session->GetNumActiveStreams());
3298 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3299
3300 // Resume quic data and a connectivity probe response will be read on the new
3301 // socket.
3302 quic_data2.Resume();
3303
3304 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3305 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3306 EXPECT_EQ(1u, session->GetNumActiveStreams());
3307
3308 // There should be three pending tasks, the nearest one will complete
3309 // migration to the new network.
3310 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
3311 next_task_delay = task_runner->NextPendingTaskDelay();
3312 EXPECT_EQ(base::TimeDelta(), next_task_delay);
3313 task_runner->FastForwardBy(next_task_delay);
3314
3315 // Response headers are received over the new network.
3316 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3317 EXPECT_EQ(200, response.headers->response_code());
3318
3319 // Now there are two pending tasks, the nearest one was to send connectivity
3320 // probe and has been cancelled due to successful migration.
3321 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
3322 next_task_delay = task_runner->NextPendingTaskDelay();
3323 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3324 next_task_delay);
3325 task_runner->FastForwardBy(next_task_delay);
3326
3327 // There's one more task to mgirate back to the default network in 0.4s.
3328 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3329 next_task_delay = task_runner->NextPendingTaskDelay();
3330 base::TimeDelta expected_delay =
3331 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
3332 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
3333 EXPECT_EQ(expected_delay, next_task_delay);
3334
3335 // Deliver a signal that the alternate network now becomes default to session,
3336 // this will cancel mgirate back to default network timer.
3337 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3338 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3339
3340 task_runner->FastForwardBy(next_task_delay);
3341 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
3342
3343 // Verify that the session is still alive.
3344 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3345 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3346
3347 stream.reset();
3348 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
3349 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
3350 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
3351 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
3352}
3353
Zhongyi Shic4823bd2018-04-27 00:49:193354// This test verifies that the connection migrates to the alternate network
Zhongyi Shi22fd5f52018-06-20 17:39:093355// early when path degrading is detected with an ASYNCHRONOUS write before
3356// migration.
3357TEST_P(QuicStreamFactoryTest, MigrateEarlyOnPathDegradingAysnc) {
3358 TestMigrationOnPathDegrading(/*async_write_before_migration*/ true);
3359}
3360
3361// This test verifies that the connection migrates to the alternate network
3362// early when path degrading is detected with a SYNCHRONOUS write before
3363// migration.
3364TEST_P(QuicStreamFactoryTest, MigrateEarlyOnPathDegradingSync) {
3365 TestMigrationOnPathDegrading(/*async_write_before_migration*/ false);
3366}
3367
3368void QuicStreamFactoryTestBase::TestMigrationOnPathDegrading(
3369 bool async_write_before) {
Zhongyi Shic4823bd2018-04-27 00:49:193370 InitializeConnectionMigrationV2Test(
3371 {kDefaultNetworkForTests, kNewNetworkForTests});
3372 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3373 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3374 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3375
3376 // Using a testing task runner so that we can control time.
3377 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3378 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
3379
3380 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3381 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3382
Zhongyi Shi22fd5f52018-06-20 17:39:093383 int packet_number = 1;
Zhongyi Shic4823bd2018-04-27 00:49:193384 MockQuicData quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523385 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shic4823bd2018-04-27 00:49:193386 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
Zhongyi Shi22fd5f52018-06-20 17:39:093387 quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
3388 packet_number++, &header_stream_offset));
3389 quic_data1.AddWrite(
3390 SYNCHRONOUS, ConstructGetRequestPacket(
3391 packet_number++, GetNthClientInitiatedStreamId(0), true,
3392 true, &header_stream_offset));
3393 if (async_write_before) {
3394 quic_data1.AddWrite(ASYNC, OK);
3395 packet_number++;
3396 }
Zhongyi Shic4823bd2018-04-27 00:49:193397 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3398
3399 // Set up the second socket data provider that is used after migration.
3400 // The response to the earlier request is read on the new socket.
3401 MockQuicData quic_data2;
3402 // Connectivity probe to be sent on the new path.
Zhongyi Shi22fd5f52018-06-20 17:39:093403 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(
Zhongyi Shi879659422018-08-02 17:58:253404 packet_number++, true));
Zhongyi Shic4823bd2018-04-27 00:49:193405 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3406 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:253407 quic_data2.AddRead(ASYNC,
3408 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shic4823bd2018-04-27 00:49:193409 // Ping packet to send after migration is completed.
Zhongyi Shi22fd5f52018-06-20 17:39:093410 quic_data2.AddWrite(ASYNC, client_maker_.MakeAckAndPingPacket(
3411 packet_number++, false, 1, 1, 1));
Ryan Hamiltona3ee93a72018-08-01 22:03:083412 quic_data2.AddRead(
3413 ASYNC, ConstructOkResponsePacket(2, GetNthClientInitiatedStreamId(0),
3414 false, false));
Zhongyi Shic4823bd2018-04-27 00:49:193415 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi22fd5f52018-06-20 17:39:093416 quic_data2.AddWrite(
3417 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
3418 packet_number++, false, GetNthClientInitiatedStreamId(0),
3419 quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true));
Zhongyi Shic4823bd2018-04-27 00:49:193420 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3421
3422 // Create request and QuicHttpStream.
3423 QuicStreamRequest request(factory_.get());
3424 EXPECT_EQ(ERR_IO_PENDING,
3425 request.Request(host_port_pair_, version_, privacy_mode_,
3426 DEFAULT_PRIORITY, SocketTag(),
3427 /*cert_verify_flags=*/0, url_, net_log_,
3428 &net_error_details_, callback_.callback()));
3429 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3430 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3431 EXPECT_TRUE(stream.get());
3432
3433 // Cause QUIC stream to be created.
3434 HttpRequestInfo request_info;
3435 request_info.method = "GET";
3436 request_info.url = url_;
3437 request_info.traffic_annotation =
3438 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3439 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3440 net_log_, CompletionOnceCallback()));
3441
3442 // Ensure that session is alive and active.
3443 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3444 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3445 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3446
3447 // Send GET request on stream.
3448 HttpResponseInfo response;
3449 HttpRequestHeaders request_headers;
3450 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3451 callback_.callback()));
3452
Zhongyi Shi22fd5f52018-06-20 17:39:093453 if (async_write_before)
3454 session->SendPing();
3455
Zhongyi Shiaba4a832018-04-30 20:29:083456 // Cause the connection to report path degrading to the session.
3457 // Session will start to probe the alternate network.
3458 session->connection()->OnPathDegradingTimeout();
3459
3460 // Next connectivity probe is scheduled to be sent in 2 *
3461 // kDefaultRTTMilliSecs.
3462 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3463 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
3464 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3465 next_task_delay);
3466
3467 // The connection should still be alive, and not marked as going away.
3468 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3469 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3470 EXPECT_EQ(1u, session->GetNumActiveStreams());
3471 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3472
3473 // Resume quic data and a connectivity probe response will be read on the new
3474 // socket.
3475 quic_data2.Resume();
3476
3477 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3478 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3479 EXPECT_EQ(1u, session->GetNumActiveStreams());
3480
3481 // There should be three pending tasks, the nearest one will complete
3482 // migration to the new network.
3483 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
3484 next_task_delay = task_runner->NextPendingTaskDelay();
3485 EXPECT_EQ(base::TimeDelta(), next_task_delay);
3486 task_runner->FastForwardBy(next_task_delay);
3487
3488 // Response headers are received over the new network.
3489 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3490 EXPECT_EQ(200, response.headers->response_code());
3491
3492 // Now there are two pending tasks, the nearest one was to send connectivity
3493 // probe and has been cancelled due to successful migration.
3494 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
3495 next_task_delay = task_runner->NextPendingTaskDelay();
3496 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3497 next_task_delay);
3498 task_runner->FastForwardBy(next_task_delay);
3499
3500 // There's one more task to mgirate back to the default network in 0.4s.
3501 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3502 next_task_delay = task_runner->NextPendingTaskDelay();
3503 base::TimeDelta expected_delay =
3504 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
3505 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
3506 EXPECT_EQ(expected_delay, next_task_delay);
3507
3508 // Deliver a signal that the alternate network now becomes default to session,
3509 // this will cancel mgirate back to default network timer.
3510 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3511 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3512
3513 task_runner->FastForwardBy(next_task_delay);
3514 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
3515
3516 // Verify that the session is still alive.
3517 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3518 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3519
3520 stream.reset();
3521 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
3522 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
3523 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
3524 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
3525}
3526
Renjiea5722ccf2018-08-10 00:18:493527// This test verifies that the session marks itself GOAWAY on path degrading
3528// and it does not receive any new request
3529TEST_P(QuicStreamFactoryTest, GoawayOnPathDegrading) {
3530 go_away_on_path_degrading_ = true;
3531 Initialize();
3532 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3533 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3534 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3535
3536 MockQuicData quic_data1;
3537 quic::QuicStreamOffset header_stream_offset = 0;
3538 quic_data1.AddWrite(SYNCHRONOUS,
3539 ConstructInitialSettingsPacket(1, &header_stream_offset));
3540 quic_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
3541 2, GetNthClientInitiatedStreamId(0),
3542 true, true, &header_stream_offset));
3543 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3544 quic_data1.AddRead(
3545 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
3546 false, true));
3547 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
3548 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3549
3550 MockQuicData quic_data2;
3551 quic::QuicStreamOffset header_stream_offset2 = 0;
3552 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
3553 quic_data2.AddWrite(
3554 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset2));
3555 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3556
3557 // Creat request and QuicHttpStream.
3558 QuicStreamRequest request(factory_.get());
3559 EXPECT_EQ(ERR_IO_PENDING,
3560 request.Request(host_port_pair_, version_, privacy_mode_,
3561 DEFAULT_PRIORITY, SocketTag(),
3562 /*cerf_verify_flags=*/0, url_, net_log_,
3563 &net_error_details_, callback_.callback()));
3564 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3565 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3566 EXPECT_TRUE(stream.get());
3567
3568 // Cause QUIC stream to be created.
3569 HttpRequestInfo request_info;
3570 request_info.method = "GET";
3571 request_info.url = url_;
3572 request_info.traffic_annotation =
3573 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3574 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3575 net_log_, CompletionOnceCallback()));
3576
3577 // Ensure that session is alive and active.
3578 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3579 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3580 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3581
3582 // Send GET request on stream.
3583 HttpResponseInfo response;
3584 HttpRequestHeaders request_headers;
3585 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3586 callback_.callback()));
3587
3588 // Trigger the connection to report path degrading to the session.
3589 // Session will mark itself GOAWAY.
3590 session->connection()->OnPathDegradingTimeout();
3591
3592 // The connection should still be alive, but marked as going away.
3593 EXPECT_FALSE(HasActiveSession(host_port_pair_));
3594 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3595 EXPECT_EQ(1u, session->GetNumActiveStreams());
3596
3597 // Second request should be sent on a new connection.
3598 QuicStreamRequest request2(factory_.get());
3599 EXPECT_EQ(ERR_IO_PENDING,
3600 request2.Request(host_port_pair_, version_, privacy_mode_,
3601 DEFAULT_PRIORITY, SocketTag(),
3602 /*cert_verify_flags=*/0, url_, net_log_,
3603 &net_error_details_, callback_.callback()));
3604 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3605 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
3606 EXPECT_TRUE(stream2.get());
3607
3608 // Resume the data, verify old request can read response on the old session
3609 // successfully.
3610 quic_data1.Resume();
3611 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
3612 EXPECT_EQ(200, response.headers->response_code());
3613 EXPECT_EQ(0U, session->GetNumActiveStreams());
3614
3615 // Check an active session exists for the destination.
3616 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3617 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3618 QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
3619 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
3620 EXPECT_NE(session, session2);
3621
3622 stream.reset();
3623 stream2.reset();
3624 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
3625 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
3626 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
3627 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
3628}
3629
Zhongyi Shibb770d92018-06-16 02:07:003630// This test verifies that the connection will not migrate to a bad socket
3631// when path degrading is detected.
3632TEST_P(QuicStreamFactoryTest, DoNotMigrateToBadSocketOnPathDegrading) {
3633 InitializeConnectionMigrationV2Test(
3634 {kDefaultNetworkForTests, kNewNetworkForTests});
3635 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3636 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3637 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3638
3639 // Using a testing task runner so that we can control time.
3640 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3641 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
3642
3643 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3644 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3645
3646 MockQuicData quic_data;
3647 quic::QuicStreamOffset header_stream_offset = 0;
3648 quic_data.AddWrite(SYNCHRONOUS,
3649 ConstructInitialSettingsPacket(1, &header_stream_offset));
3650 quic_data.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
3651 2, GetNthClientInitiatedStreamId(0), true,
3652 true, &header_stream_offset));
3653 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3654 quic_data.AddRead(
3655 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
3656 false, false));
3657 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3658 quic_data.AddWrite(SYNCHRONOUS,
3659 client_maker_.MakeAckAndRstPacket(
3660 3, false, GetNthClientInitiatedStreamId(0),
3661 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
3662 quic_data.AddSocketDataToFactory(socket_factory_.get());
3663
3664 // Set up second socket that will immediately return disconnected.
3665 // The stream factory will abort probe the alternate network.
3666 MockConnect bad_connect = MockConnect(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
3667 SequencedSocketData socket_data(bad_connect, base::span<MockRead>(),
3668 base::span<MockWrite>());
3669 socket_factory_->AddSocketDataProvider(&socket_data);
3670
3671 // Create request and QuicHttpStream.
3672 QuicStreamRequest request(factory_.get());
3673 EXPECT_EQ(ERR_IO_PENDING,
3674 request.Request(host_port_pair_, version_, privacy_mode_,
3675 DEFAULT_PRIORITY, SocketTag(),
3676 /*cert_verify_flags=*/0, url_, net_log_,
3677 &net_error_details_, callback_.callback()));
3678 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3679 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3680 EXPECT_TRUE(stream.get());
3681
3682 // Cause QUIC stream to be created.
3683 HttpRequestInfo request_info;
3684 request_info.method = "GET";
3685 request_info.url = url_;
3686 request_info.traffic_annotation =
3687 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3688 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3689 net_log_, CompletionOnceCallback()));
3690
3691 // Ensure that session is alive and active.
3692 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3693 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3694 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3695
3696 // Send GET request on stream.
3697 HttpResponseInfo response;
3698 HttpRequestHeaders request_headers;
3699 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3700 callback_.callback()));
3701
3702 // Cause the connection to report path degrading to the session.
3703 // Session will start to probe the alternate network.
3704 session->connection()->OnPathDegradingTimeout();
3705
3706 // The connection should still be alive, and not marked as going away.
3707 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3708 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3709 EXPECT_EQ(1u, session->GetNumActiveStreams());
3710 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3711
3712 // Resume the data, and response header is received over the original network.
3713 quic_data.Resume();
3714 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3715 EXPECT_EQ(200, response.headers->response_code());
3716
3717 // Verify there is no pending task as probing alternate network is halted.
3718 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
3719
3720 // Verify that the session is still alive.
3721 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3722 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3723
3724 stream.reset();
3725 EXPECT_TRUE(quic_data.AllReadDataConsumed());
3726 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
3727}
3728
Zhongyi Shif5cc30392018-05-30 18:25:153729// Regression test for http://crbug.com/847569.
3730// This test verifies that the connection migrates to the alternate network
3731// early when there is no active stream but a draining stream.
Zhongyi Shib3bc982c2018-07-10 19:59:243732// The first packet being written after migration is a synchrnous write, which
3733// will cause a PING packet being sent.
3734TEST_P(QuicStreamFactoryTest, MigrateSessionWithDrainingStreamSync) {
3735 TestMigrateSessionWithDrainingStream(SYNCHRONOUS);
3736}
3737
3738// Regression test for http://crbug.com/847569.
3739// This test verifies that the connection migrates to the alternate network
3740// early when there is no active stream but a draining stream.
3741// The first packet being written after migration is an asynchronous write, no
3742// PING packet will be sent.
3743TEST_P(QuicStreamFactoryTest, MigrateSessionWithDrainingStreamAsync) {
3744 TestMigrateSessionWithDrainingStream(ASYNC);
3745}
3746
3747void QuicStreamFactoryTestBase::TestMigrateSessionWithDrainingStream(
3748 IoMode write_mode_for_queued_packet) {
Zhongyi Shif5cc30392018-05-30 18:25:153749 InitializeConnectionMigrationV2Test(
3750 {kDefaultNetworkForTests, kNewNetworkForTests});
3751 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3752 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3753 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3754
3755 // Using a testing task runner so that we can control time.
3756 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3757 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
3758
3759 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3760 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3761
Zhongyi Shib3bc982c2018-07-10 19:59:243762 int packet_number = 1;
Zhongyi Shif5cc30392018-05-30 18:25:153763 MockQuicData quic_data1;
3764 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shib3bc982c2018-07-10 19:59:243765 quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
3766 packet_number++, &header_stream_offset));
3767 quic_data1.AddWrite(
3768 SYNCHRONOUS, ConstructGetRequestPacket(
3769 packet_number++, GetNthClientInitiatedStreamId(0), true,
3770 true, &header_stream_offset));
Zhongyi Shif5cc30392018-05-30 18:25:153771 // Read an out of order packet with FIN to drain the stream.
3772 quic_data1.AddRead(
3773 ASYNC, ConstructOkResponsePacket(2, GetNthClientInitiatedStreamId(0),
3774 false, true)); // keep sending version.
Zhongyi Shib3bc982c2018-07-10 19:59:243775 quic_data1.AddWrite(SYNCHRONOUS, client_maker_.MakeAckPacket(
3776 packet_number++, 2, 2, 2, 1, true));
Zhongyi Shif5cc30392018-05-30 18:25:153777 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3778 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3779
3780 // Set up the second socket data provider that is used after migration.
3781 MockQuicData quic_data2;
3782 // Connectivity probe to be sent on the new path.
Zhongyi Shib3bc982c2018-07-10 19:59:243783 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(
Zhongyi Shi879659422018-08-02 17:58:253784 packet_number++, false));
Zhongyi Shif5cc30392018-05-30 18:25:153785 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3786 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:253787 quic_data2.AddRead(ASYNC,
3788 server_maker_.MakeConnectivityProbingPacket(3, false));
Zhongyi Shif5cc30392018-05-30 18:25:153789 // Ping packet to send after migration is completed.
Zhongyi Shib3bc982c2018-07-10 19:59:243790 quic_data2.AddWrite(
3791 write_mode_for_queued_packet,
3792 client_maker_.MakeAckPacket(packet_number++, 2, 3, 3, 1, true));
3793 if (write_mode_for_queued_packet == SYNCHRONOUS) {
3794 quic_data2.AddWrite(ASYNC,
3795 client_maker_.MakePingPacket(packet_number++, false));
3796 }
Zhongyi Shif5cc30392018-05-30 18:25:153797 quic_data2.AddRead(
3798 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
3799 false, false));
Zhongyi Shib3bc982c2018-07-10 19:59:243800 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeAckPacket(
3801 packet_number++, 1, 3, 1, 1, true));
Zhongyi Shif5cc30392018-05-30 18:25:153802 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3803 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3804
3805 // Create request and QuicHttpStream.
3806 QuicStreamRequest request(factory_.get());
3807 EXPECT_EQ(ERR_IO_PENDING,
3808 request.Request(host_port_pair_, version_, privacy_mode_,
3809 DEFAULT_PRIORITY, SocketTag(),
3810 /*cert_verify_flags=*/0, url_, net_log_,
3811 &net_error_details_, callback_.callback()));
3812 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3813 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3814 EXPECT_TRUE(stream.get());
3815
3816 // Cause QUIC stream to be created.
3817 HttpRequestInfo request_info;
3818 request_info.method = "GET";
3819 request_info.url = url_;
3820 request_info.traffic_annotation =
3821 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3822 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3823 net_log_, CompletionOnceCallback()));
3824
3825 // Ensure that session is alive and active.
3826 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3827 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3828 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3829
3830 // Send GET request on stream.
3831 HttpResponseInfo response;
3832 HttpRequestHeaders request_headers;
3833 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3834 callback_.callback()));
3835
3836 // Run the message loop to receive the out of order packet which contains a
3837 // FIN and drains the stream.
3838 base::RunLoop().RunUntilIdle();
3839 EXPECT_EQ(0u, session->GetNumActiveStreams());
3840
3841 // Cause the connection to report path degrading to the session.
3842 // Session should still start to probe the alternate network.
3843 session->connection()->OnPathDegradingTimeout();
3844 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3845
3846 // Next connectivity probe is scheduled to be sent in 2 *
3847 // kDefaultRTTMilliSecs.
3848 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3849 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
3850 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3851 next_task_delay);
3852
3853 // The connection should still be alive, and not marked as going away.
3854 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shif5cc30392018-05-30 18:25:153855
3856 // Resume quic data and a connectivity probe response will be read on the new
3857 // socket.
3858 quic_data2.Resume();
3859
3860 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3861 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:263862 EXPECT_EQ(0u, session->GetNumActiveStreams());
3863 EXPECT_EQ(1u, session->GetNumDrainingStreams());
Zhongyi Shif5cc30392018-05-30 18:25:153864
3865 // There should be three pending tasks, the nearest one will complete
3866 // migration to the new network.
3867 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
3868 next_task_delay = task_runner->NextPendingTaskDelay();
3869 EXPECT_EQ(base::TimeDelta(), next_task_delay);
3870 task_runner->FastForwardBy(next_task_delay);
3871
3872 // Now there are two pending tasks, the nearest one was to send connectivity
3873 // probe and has been cancelled due to successful migration.
3874 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
3875 next_task_delay = task_runner->NextPendingTaskDelay();
3876 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3877 next_task_delay);
3878 task_runner->FastForwardBy(next_task_delay);
3879
3880 // There's one more task to mgirate back to the default network in 0.4s.
3881 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3882 next_task_delay = task_runner->NextPendingTaskDelay();
3883 base::TimeDelta expected_delay =
3884 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
3885 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
3886 EXPECT_EQ(expected_delay, next_task_delay);
3887
Zhongyi Shib3bc982c2018-07-10 19:59:243888 base::RunLoop().RunUntilIdle();
3889
Zhongyi Shif5cc30392018-05-30 18:25:153890 // Deliver a signal that the alternate network now becomes default to session,
3891 // this will cancel mgirate back to default network timer.
3892 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3893 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3894
3895 task_runner->FastForwardBy(next_task_delay);
3896 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
3897
3898 // Verify that the session is still alive.
3899 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3900 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:263901 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
Zhongyi Shif5cc30392018-05-30 18:25:153902
3903 stream.reset();
3904 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
3905 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
3906 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
3907 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
3908}
3909
Zhongyi Shiaba4a832018-04-30 20:29:083910// Regression test for http://crbug.com/835444.
3911// This test verifies that the connection migrates to the alternate network
3912// when the alternate network is connected after path has been degrading.
3913TEST_P(QuicStreamFactoryTest, MigrateOnNewNetworkConnectAfterPathDegrading) {
3914 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
3915 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3916 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3917 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3918
3919 // Using a testing task runner so that we can control time.
3920 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3921 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
3922
3923 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3924 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3925
3926 MockQuicData quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523927 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shiaba4a832018-04-30 20:29:083928 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
3929 quic_data1.AddWrite(SYNCHRONOUS,
3930 ConstructInitialSettingsPacket(1, &header_stream_offset));
3931 quic_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
3932 2, GetNthClientInitiatedStreamId(0),
3933 true, true, &header_stream_offset));
3934 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3935
3936 // Set up the second socket data provider that is used after migration.
3937 // The response to the earlier request is read on the new socket.
3938 MockQuicData quic_data2;
3939 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:253940 quic_data2.AddWrite(SYNCHRONOUS,
3941 client_maker_.MakeConnectivityProbingPacket(3, true));
Zhongyi Shiaba4a832018-04-30 20:29:083942 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3943 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:253944 quic_data2.AddRead(ASYNC,
3945 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shiaba4a832018-04-30 20:29:083946 // Ping packet to send after migration is completed.
3947 quic_data2.AddWrite(ASYNC,
3948 client_maker_.MakeAckAndPingPacket(4, false, 1, 1, 1));
3949 quic_data2.AddRead(
3950 ASYNC, ConstructOkResponsePacket(2, GetNthClientInitiatedStreamId(0),
3951 false, false));
3952 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3953 quic_data2.AddWrite(SYNCHRONOUS,
3954 client_maker_.MakeAckAndRstPacket(
3955 5, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:523956 quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true));
Zhongyi Shiaba4a832018-04-30 20:29:083957 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3958
3959 // Create request and QuicHttpStream.
3960 QuicStreamRequest request(factory_.get());
3961 EXPECT_EQ(ERR_IO_PENDING,
3962 request.Request(host_port_pair_, version_, privacy_mode_,
3963 DEFAULT_PRIORITY, SocketTag(),
3964 /*cert_verify_flags=*/0, url_, net_log_,
3965 &net_error_details_, callback_.callback()));
3966 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3967 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3968 EXPECT_TRUE(stream.get());
3969
3970 // Cause QUIC stream to be created.
3971 HttpRequestInfo request_info;
3972 request_info.method = "GET";
3973 request_info.url = url_;
3974 request_info.traffic_annotation =
3975 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3976 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3977 net_log_, CompletionOnceCallback()));
3978
3979 // Ensure that session is alive and active.
3980 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3981 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3982 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3983
3984 // Send GET request on stream.
3985 HttpResponseInfo response;
3986 HttpRequestHeaders request_headers;
3987 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3988 callback_.callback()));
3989
3990 // Cause the connection to report path degrading to the session.
3991 // Due to lack of alternate network, session will not mgirate connection.
3992 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
3993 session->connection()->OnPathDegradingTimeout();
3994 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
3995
3996 // Deliver a signal that a alternate network is connected now, this should
3997 // cause the connection to start early migration on path degrading.
3998 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3999 ->SetConnectedNetworksList(
4000 {kDefaultNetworkForTests, kNewNetworkForTests});
4001 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4002 ->NotifyNetworkConnected(kNewNetworkForTests);
Zhongyi Shic4823bd2018-04-27 00:49:194003
4004 // Next connectivity probe is scheduled to be sent in 2 *
4005 // kDefaultRTTMilliSecs.
4006 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4007 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
4008 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
4009 next_task_delay);
4010
4011 // The connection should still be alive, and not marked as going away.
4012 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4013 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4014 EXPECT_EQ(1u, session->GetNumActiveStreams());
4015 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
4016
4017 // Resume quic data and a connectivity probe response will be read on the new
4018 // socket.
4019 quic_data2.Resume();
4020
4021 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4022 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4023 EXPECT_EQ(1u, session->GetNumActiveStreams());
4024
4025 // There should be three pending tasks, the nearest one will complete
4026 // migration to the new network.
4027 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
4028 next_task_delay = task_runner->NextPendingTaskDelay();
4029 EXPECT_EQ(base::TimeDelta(), next_task_delay);
4030 task_runner->FastForwardBy(next_task_delay);
4031
4032 // Response headers are received over the new network.
4033 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4034 EXPECT_EQ(200, response.headers->response_code());
4035
4036 // Now there are two pending tasks, the nearest one was to send connectivity
4037 // probe and has been cancelled due to successful migration.
4038 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
4039 next_task_delay = task_runner->NextPendingTaskDelay();
4040 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
4041 next_task_delay);
4042 task_runner->FastForwardBy(next_task_delay);
4043
4044 // There's one more task to mgirate back to the default network in 0.4s.
4045 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4046 next_task_delay = task_runner->NextPendingTaskDelay();
4047 base::TimeDelta expected_delay =
4048 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
4049 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
4050 EXPECT_EQ(expected_delay, next_task_delay);
4051
4052 // Deliver a signal that the alternate network now becomes default to session,
4053 // this will cancel mgirate back to default network timer.
4054 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4055 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
4056
4057 task_runner->FastForwardBy(next_task_delay);
4058 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4059
4060 // Verify that the session is still alive.
4061 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4062 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4063
4064 stream.reset();
4065 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
4066 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
4067 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
4068 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
4069}
4070
Zhongyi Shi28f6e352018-06-20 21:15:434071// This test verifies that multiple sessions are migrated on connection
4072// migration signal.
jrie3d187c2016-09-16 14:29:174073TEST_P(QuicStreamFactoryTest,
Zhongyi Shi28f6e352018-06-20 21:15:434074 MigrateMultipleSessionsToBadSocketsAfterDisconnected) {
4075 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jrie3d187c2016-09-16 14:29:174076
4077 MockQuicData socket_data1;
4078 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434079 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jrie3d187c2016-09-16 14:29:174080 socket_data1.AddWrite(ASYNC, OK);
Zhongyi Shi5f587cc2017-11-21 23:24:174081 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jrie3d187c2016-09-16 14:29:174082 MockQuicData socket_data2;
4083 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434084 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jrie3d187c2016-09-16 14:29:174085 socket_data2.AddWrite(ASYNC, OK);
Zhongyi Shi5f587cc2017-11-21 23:24:174086 socket_data2.AddSocketDataToFactory(socket_factory_.get());
jrie3d187c2016-09-16 14:29:174087
4088 HostPortPair server1(kDefaultServerHostName, 443);
4089 HostPortPair server2(kServer2HostName, 443);
4090
4091 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4092 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4093 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4094
4095 host_resolver_.set_synchronous_mode(true);
4096 host_resolver_.rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
4097 host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.2", "");
4098
4099 // Create request and QuicHttpStream to create session1.
zhongyi98d6a9262017-05-19 02:47:454100 QuicStreamRequest request1(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:334101 EXPECT_EQ(OK, request1.Request(server1, version_, privacy_mode_,
4102 DEFAULT_PRIORITY, SocketTag(),
4103 /*cert_verify_flags=*/0, url_, net_log_,
4104 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:244105 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
jrie3d187c2016-09-16 14:29:174106 EXPECT_TRUE(stream1.get());
4107
4108 // Create request and QuicHttpStream to create session2.
zhongyi98d6a9262017-05-19 02:47:454109 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:334110 EXPECT_EQ(OK, request2.Request(server2, version_, privacy_mode_,
4111 DEFAULT_PRIORITY, SocketTag(),
4112 /*cert_verify_flags=*/0, url2_, net_log_,
4113 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:244114 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
jrie3d187c2016-09-16 14:29:174115 EXPECT_TRUE(stream2.get());
4116
4117 QuicChromiumClientSession* session1 = GetActiveSession(server1);
4118 QuicChromiumClientSession* session2 = GetActiveSession(server2);
4119 EXPECT_NE(session1, session2);
4120
4121 // Cause QUIC stream to be created and send GET so session1 has an open
4122 // stream.
4123 HttpRequestInfo request_info1;
4124 request_info1.method = "GET";
4125 request_info1.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:394126 request_info1.traffic_annotation =
4127 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274128 EXPECT_EQ(OK,
4129 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394130 net_log_, CompletionOnceCallback()));
jrie3d187c2016-09-16 14:29:174131 HttpResponseInfo response1;
4132 HttpRequestHeaders request_headers1;
4133 EXPECT_EQ(OK, stream1->SendRequest(request_headers1, &response1,
4134 callback_.callback()));
4135
4136 // Cause QUIC stream to be created and send GET so session2 has an open
4137 // stream.
4138 HttpRequestInfo request_info2;
4139 request_info2.method = "GET";
4140 request_info2.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:394141 request_info2.traffic_annotation =
4142 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274143 EXPECT_EQ(OK,
4144 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394145 net_log_, CompletionOnceCallback()));
jrie3d187c2016-09-16 14:29:174146 HttpResponseInfo response2;
4147 HttpRequestHeaders request_headers2;
4148 EXPECT_EQ(OK, stream2->SendRequest(request_headers2, &response2,
4149 callback_.callback()));
4150
4151 // Cause both sessions to be paused due to DISCONNECTED.
4152 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4153 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
4154
4155 // Ensure that both sessions are paused but alive.
4156 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session1));
4157 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
4158
Zhongyi Shi28f6e352018-06-20 21:15:434159 // Add new sockets to use post migration. Those are bad sockets and will cause
4160 // migration to fail.
jrie3d187c2016-09-16 14:29:174161 MockConnect connect_result =
4162 MockConnect(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
Ryan Sleevib8d7ea02018-05-07 20:01:014163 SequencedSocketData socket_data3(connect_result, base::span<MockRead>(),
4164 base::span<MockWrite>());
Zhongyi Shi5f587cc2017-11-21 23:24:174165 socket_factory_->AddSocketDataProvider(&socket_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:014166 SequencedSocketData socket_data4(connect_result, base::span<MockRead>(),
4167 base::span<MockWrite>());
Zhongyi Shi5f587cc2017-11-21 23:24:174168 socket_factory_->AddSocketDataProvider(&socket_data4);
jrie3d187c2016-09-16 14:29:174169
Zhongyi Shi28f6e352018-06-20 21:15:434170 // Connect the new network and cause migration to bad sockets, causing
4171 // sessions to close.
jrie3d187c2016-09-16 14:29:174172 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4173 ->SetConnectedNetworksList({kNewNetworkForTests});
4174 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4175 ->NotifyNetworkConnected(kNewNetworkForTests);
4176
4177 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session1));
4178 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
4179
4180 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
4181 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
4182 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
4183 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
4184}
4185
Zhongyi Shi6ec9b36e2018-06-20 20:32:544186// This test verifies that session attempts connection migration with signals
4187// delivered in the following order (no alternate network is available):
4188// - path degrading is detected: session attempts connection migration but no
4189// alternate network is available, session caches path degrading signal in
4190// connection and stays on the original network.
4191// - original network backs up, request is served in the orignal network,
4192// session is not marked as going away.
4193TEST_P(QuicStreamFactoryTest, MigrateOnPathDegradingWithNoNewNetwork) {
4194 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jrid36ada62016-02-06 02:42:084195 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4196 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4197
Zhongyi Shi6ec9b36e2018-06-20 20:32:544198 MockQuicData quic_data;
4199 quic::QuicStreamOffset header_stream_offset = 0;
4200 quic_data.AddWrite(SYNCHRONOUS,
4201 ConstructInitialSettingsPacket(1, &header_stream_offset));
4202 quic_data.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
4203 2, GetNthClientInitiatedStreamId(0), true,
4204 true, &header_stream_offset));
4205 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause for path degrading signal.
4206
4207 // The rest of the data will still flow in the original socket as there is no
4208 // new network after path degrading.
4209 quic_data.AddRead(
4210 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
4211 false, false));
4212 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4213 quic_data.AddWrite(SYNCHRONOUS,
4214 client_maker_.MakeAckAndRstPacket(
4215 3, false, GetNthClientInitiatedStreamId(0),
4216 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
4217 quic_data.AddSocketDataToFactory(socket_factory_.get());
jrid36ada62016-02-06 02:42:084218
4219 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:454220 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:334221 EXPECT_EQ(ERR_IO_PENDING,
4222 request.Request(host_port_pair_, version_, privacy_mode_,
4223 DEFAULT_PRIORITY, SocketTag(),
4224 /*cert_verify_flags=*/0, url_, net_log_,
4225 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:014226 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:244227 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jrid36ada62016-02-06 02:42:084228 EXPECT_TRUE(stream.get());
4229
4230 // Cause QUIC stream to be created.
4231 HttpRequestInfo request_info;
Zhongyi Shi6ec9b36e2018-06-20 20:32:544232 request_info.method = "GET";
4233 request_info.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:394234 request_info.traffic_annotation =
4235 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Zhongyi Shi6ec9b36e2018-06-20 20:32:544236 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394237 net_log_, CompletionOnceCallback()));
jrid36ada62016-02-06 02:42:084238
4239 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:504240 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jrid36ada62016-02-06 02:42:084241 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4242 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4243
Zhongyi Shi6ec9b36e2018-06-20 20:32:544244 // Send GET request on stream.
4245 HttpResponseInfo response;
4246 HttpRequestHeaders request_headers;
4247 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
4248 callback_.callback()));
jrid36ada62016-02-06 02:42:084249
Zhongyi Shi6ec9b36e2018-06-20 20:32:544250 // Trigger connection migration on path degrading. Since there are no networks
4251 // to migrate to, the session will remain on the original network, not marked
4252 // as going away.
4253 session->connection()->OnPathDegradingTimeout();
4254 EXPECT_TRUE(session->connection()->IsPathDegrading());
4255
4256 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4257 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4258 EXPECT_EQ(1u, session->GetNumActiveStreams());
4259 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
4260
4261 // Resume so that rest of the data will flow in the original socket.
4262 quic_data.Resume();
jrid36ada62016-02-06 02:42:084263
4264 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4265 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4266 EXPECT_EQ(1u, session->GetNumActiveStreams());
4267
4268 stream.reset();
Zhongyi Shi6ec9b36e2018-06-20 20:32:544269 EXPECT_TRUE(quic_data.AllReadDataConsumed());
4270 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
jrid36ada62016-02-06 02:42:084271}
4272
Zhongyi Shi21e99532018-07-17 22:23:074273// This test verifies that session with non-migratable stream will probe the
4274// alternate network on path degrading, and close the non-migratable streams
4275// when probe is successful.
jri231c2972016-03-08 19:50:114276TEST_P(QuicStreamFactoryTest, MigrateSessionEarlyNonMigratableStream) {
Zhongyi Shi1a054612018-06-14 04:59:084277 InitializeConnectionMigrationV2Test(
jri231c2972016-03-08 19:50:114278 {kDefaultNetworkForTests, kNewNetworkForTests});
4279 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4280 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4281
rcha00569732016-08-27 11:09:364282 MockQuicData socket_data;
4283 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434284 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Renjieba55fae2018-09-20 03:05:164285 socket_data.AddWrite(
4286 SYNCHRONOUS,
4287 client_maker_.MakeRstAckAndConnectionClosePacket(
4288 3, false, 5, quic::QUIC_STREAM_CANCELLED,
4289 quic::QuicTime::Delta::FromMilliseconds(0), 1, 1, 1,
4290 quic::QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS, "net error"));
Zhongyi Shi5f587cc2017-11-21 23:24:174291 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri231c2972016-03-08 19:50:114292
Zhongyi Shi21e99532018-07-17 22:23:074293 // Set up the second socket data provider that is used for probing.
4294 MockQuicData quic_data1;
4295 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:254296 quic_data1.AddWrite(SYNCHRONOUS,
4297 client_maker_.MakeConnectivityProbingPacket(2, true));
Zhongyi Shi21e99532018-07-17 22:23:074298 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
4299 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:254300 quic_data1.AddRead(ASYNC,
4301 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shi21e99532018-07-17 22:23:074302 quic_data1.AddSocketDataToFactory(socket_factory_.get());
4303
jri231c2972016-03-08 19:50:114304 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:454305 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:334306 EXPECT_EQ(ERR_IO_PENDING,
4307 request.Request(host_port_pair_, version_, privacy_mode_,
4308 DEFAULT_PRIORITY, SocketTag(),
4309 /*cert_verify_flags=*/0, url_, net_log_,
4310 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:014311 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:244312 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri231c2972016-03-08 19:50:114313 EXPECT_TRUE(stream.get());
4314
4315 // Cause QUIC stream to be created, but marked as non-migratable.
4316 HttpRequestInfo request_info;
Zhongyi Shibb28b1f2018-07-18 02:41:264317 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Ramin Halavati683bcaa92018-02-14 08:42:394318 request_info.traffic_annotation =
4319 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274320 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394321 net_log_, CompletionOnceCallback()));
jri231c2972016-03-08 19:50:114322
4323 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:504324 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri231c2972016-03-08 19:50:114325 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4326 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4327
4328 // Trigger connection migration. Since there is a non-migratable stream,
4329 // this should cause session to be continue without migrating.
4330 session->OnPathDegrading();
4331
4332 // Run the message loop so that data queued in the new socket is read by the
4333 // packet reader.
4334 base::RunLoop().RunUntilIdle();
4335
4336 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4337 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4338 EXPECT_EQ(1u, session->GetNumActiveStreams());
4339
Zhongyi Shi21e99532018-07-17 22:23:074340 // Resume the data to read the connectivity probing response to declare probe
4341 // as successful. Non-migratable streams will be closed.
4342 quic_data1.Resume();
4343 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4344 EXPECT_FALSE(HasActiveSession(host_port_pair_));
4345 EXPECT_EQ(0u, session->GetNumActiveStreams());
jri231c2972016-03-08 19:50:114346
Zhongyi Shi21e99532018-07-17 22:23:074347 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
4348 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
jri231c2972016-03-08 19:50:114349 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4350 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4351}
4352
jri9c541572016-03-29 17:51:484353TEST_P(QuicStreamFactoryTest, MigrateSessionEarlyConnectionMigrationDisabled) {
Zhongyi Shi1a054612018-06-14 04:59:084354 InitializeConnectionMigrationV2Test(
jri9c541572016-03-29 17:51:484355 {kDefaultNetworkForTests, kNewNetworkForTests});
4356 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4357 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4358
rcha00569732016-08-27 11:09:364359 MockQuicData socket_data;
4360 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434361 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
4362 socket_data.AddWrite(
4363 SYNCHRONOUS,
4364 client_maker_.MakeRstPacket(2, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:524365 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:174366 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9c541572016-03-29 17:51:484367
4368 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:454369 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:334370 EXPECT_EQ(ERR_IO_PENDING,
4371 request.Request(host_port_pair_, version_, privacy_mode_,
4372 DEFAULT_PRIORITY, SocketTag(),
4373 /*cert_verify_flags=*/0, url_, net_log_,
4374 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:014375 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:244376 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9c541572016-03-29 17:51:484377 EXPECT_TRUE(stream.get());
4378
4379 // Cause QUIC stream to be created.
4380 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:394381 request_info.traffic_annotation =
4382 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274383 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394384 net_log_, CompletionOnceCallback()));
jri9c541572016-03-29 17:51:484385
4386 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:504387 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri9c541572016-03-29 17:51:484388 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4389 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4390
4391 // Set session config to have connection migration disabled.
Ryan Hamilton8d9ee76e2018-05-29 23:52:524392 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
4393 session->config());
jri9c541572016-03-29 17:51:484394 EXPECT_TRUE(session->config()->DisableConnectionMigration());
4395
4396 // Trigger connection migration. Since there is a non-migratable stream,
4397 // this should cause session to be continue without migrating.
4398 session->OnPathDegrading();
4399
4400 // Run the message loop so that data queued in the new socket is read by the
4401 // packet reader.
4402 base::RunLoop().RunUntilIdle();
4403
4404 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4405 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4406 EXPECT_EQ(1u, session->GetNumActiveStreams());
4407
4408 stream.reset();
4409
4410 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4411 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4412}
4413
Zhongyi Shi3c4c9e92018-07-02 23:16:234414// Regression test for http://crbug.com/791886.
4415// This test verifies that the old packet writer which encountered an
4416// asynchronous write error will be blocked during migration on write error. New
4417// packets would not be written until the one with write error is rewritten on
4418// the new network.
4419TEST_P(QuicStreamFactoryTest, MigrateSessionOnAysncWriteError) {
4420 InitializeConnectionMigrationV2Test(
4421 {kDefaultNetworkForTests, kNewNetworkForTests});
4422 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4423 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4424 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4425
4426 // Using a testing task runner so that we can control time.
4427 // base::RunLoop() controls mocked socket writes and reads.
4428 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4429 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4430
4431 MockQuicData socket_data;
4432 quic::QuicStreamOffset header_stream_offset = 0;
4433 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4434 socket_data.AddWrite(
4435 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4436 socket_data.AddWrite(ASYNC, ERR_ADDRESS_UNREACHABLE);
4437 socket_data.AddSocketDataToFactory(socket_factory_.get());
4438
4439 // Set up second socket data provider that is used after
4440 // migration. The request is rewritten to this new socket, and the
4441 // response to the request is read on this new socket.
4442 MockQuicData socket_data1;
4443 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
4444 2, GetNthClientInitiatedStreamId(0),
4445 true, true, &header_stream_offset));
4446 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
4447 3, GetNthClientInitiatedStreamId(1),
4448 GetNthClientInitiatedStreamId(0), true,
4449 true, &header_stream_offset));
4450 socket_data1.AddRead(
4451 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
4452 false, false));
4453 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4454 socket_data1.AddWrite(SYNCHRONOUS,
4455 client_maker_.MakeAckAndRstPacket(
4456 4, false, GetNthClientInitiatedStreamId(0),
4457 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
4458 socket_data1.AddWrite(
4459 SYNCHRONOUS,
4460 client_maker_.MakeRstPacket(5, false, GetNthClientInitiatedStreamId(1),
4461 quic::QUIC_STREAM_CANCELLED, 0));
4462
4463 socket_data1.AddSocketDataToFactory(socket_factory_.get());
4464
4465 // Create request #1 and QuicHttpStream.
4466 QuicStreamRequest request1(factory_.get());
4467 EXPECT_EQ(ERR_IO_PENDING,
4468 request1.Request(host_port_pair_, version_, privacy_mode_,
4469 DEFAULT_PRIORITY, SocketTag(),
4470 /*cert_verify_flags=*/0, url_, net_log_,
4471 &net_error_details_, callback_.callback()));
4472 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4473 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
4474 EXPECT_TRUE(stream1.get());
4475
4476 HttpRequestInfo request_info1;
4477 request_info1.method = "GET";
4478 request_info1.url = GURL("https://www.example.org/");
4479 request_info1.traffic_annotation =
4480 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4481 EXPECT_EQ(OK,
4482 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
4483 net_log_, CompletionOnceCallback()));
4484
4485 // Request #2 returns synchronously because it pools to existing session.
4486 TestCompletionCallback callback2;
4487 QuicStreamRequest request2(factory_.get());
4488 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_, privacy_mode_,
4489 DEFAULT_PRIORITY, SocketTag(),
4490 /*cert_verify_flags=*/0, url_, net_log_,
4491 &net_error_details_, callback2.callback()));
4492 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
4493 EXPECT_TRUE(stream2.get());
4494
4495 HttpRequestInfo request_info2;
4496 request_info2.method = "GET";
4497 request_info2.url = GURL("https://www.example.org/");
4498 request_info2.traffic_annotation =
4499 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4500 EXPECT_EQ(OK,
4501 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
4502 net_log_, CompletionOnceCallback()));
4503
4504 // Ensure that session is alive and active.
4505 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
4506 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4507 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4508 EXPECT_EQ(2u, session->GetNumActiveStreams());
4509
4510 // Send GET request on stream1. This should cause an async write error.
4511 HttpResponseInfo response;
4512 HttpRequestHeaders request_headers;
4513 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
4514 callback_.callback()));
4515 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4516
4517 // Run the message loop so that asynchronous write completes and a connection
4518 // migration on write error attempt is posted in QuicStreamFactory's task
4519 // runner.
4520 base::RunLoop().RunUntilIdle();
4521 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4522
4523 // Send GET request on stream. This will cause another write attempt before
4524 // migration on write error is exectued.
4525 HttpResponseInfo response2;
4526 HttpRequestHeaders request_headers2;
4527 EXPECT_EQ(OK, stream2->SendRequest(request_headers2, &response2,
4528 callback2.callback()));
4529
4530 // Run the task runner so that migration on write error is finally executed.
4531 task_runner->RunUntilIdle();
4532
Zhongyi Shia7dd46b2018-07-12 22:59:294533 // Verify the session is still alive and not marked as going away.
Zhongyi Shi3c4c9e92018-07-02 23:16:234534 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:294535 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi3c4c9e92018-07-02 23:16:234536 EXPECT_EQ(2u, session->GetNumActiveStreams());
Zhongyi Shia7dd46b2018-07-12 22:59:294537 // There should be one task posted to migrate back to the default network in
4538 // kMinRetryTimeForDefaultNetworkSecs.
4539 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4540 EXPECT_EQ(base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs),
4541 task_runner->NextPendingTaskDelay());
Zhongyi Shi3c4c9e92018-07-02 23:16:234542
4543 // Verify that response headers on the migrated socket were delivered to the
4544 // stream.
4545 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
4546 EXPECT_EQ(200, response.headers->response_code());
4547
4548 stream1.reset();
4549 stream2.reset();
4550
4551 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4552 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4553 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
4554 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
4555}
4556
Zhongyi Shia7dd46b2018-07-12 22:59:294557// Verify session is not marked as going away after connection migration on
4558// write error and migrate back to default network logic is applied to bring the
4559// migrated session back to the default network. Migration singals delivered
4560// in the following order (alternate network is always availabe):
4561// - session on the default network encountered a write error;
4562// - session successfully migrated to the non-default network;
4563// - session attempts to migrate back to default network post migration;
4564// - migration back to the default network is successful.
4565TEST_P(QuicStreamFactoryTest, MigrateBackToDefaultPostMigrationOnWriteError) {
4566 InitializeConnectionMigrationV2Test(
4567 {kDefaultNetworkForTests, kNewNetworkForTests});
4568 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4569 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4570 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4571
4572 // Using a testing task runner so that we can control time.
4573 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4574 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4575
4576 MockQuicData socket_data;
4577 quic::QuicStreamOffset header_stream_offset = 0;
4578 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4579 socket_data.AddWrite(
4580 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4581 socket_data.AddWrite(ASYNC, ERR_ADDRESS_UNREACHABLE);
4582 socket_data.AddSocketDataToFactory(socket_factory_.get());
4583
4584 // Set up second socket data provider that is used after
4585 // migration. The request is rewritten to this new socket, and the
4586 // response to the request is read on this new socket.
4587 MockQuicData quic_data2;
4588 quic_data2.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
4589 2, GetNthClientInitiatedStreamId(0),
4590 true, true, &header_stream_offset));
4591 quic_data2.AddRead(
4592 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
4593 false, false));
4594 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4595 quic_data2.AddSocketDataToFactory(socket_factory_.get());
4596
4597 // Create request QuicHttpStream.
4598 QuicStreamRequest request1(factory_.get());
4599 EXPECT_EQ(ERR_IO_PENDING,
4600 request1.Request(host_port_pair_, version_, privacy_mode_,
4601 DEFAULT_PRIORITY, SocketTag(),
4602 /*cert_verify_flags=*/0, url_, net_log_,
4603 &net_error_details_, callback_.callback()));
4604 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4605 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
4606 EXPECT_TRUE(stream1.get());
4607
4608 HttpRequestInfo request_info1;
4609 request_info1.method = "GET";
4610 request_info1.url = GURL("https://www.example.org/");
4611 request_info1.traffic_annotation =
4612 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4613 EXPECT_EQ(OK,
4614 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
4615 net_log_, CompletionOnceCallback()));
4616
4617 // Ensure that session is alive and active.
4618 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
4619 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4620 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4621 EXPECT_EQ(1u, session->GetNumActiveStreams());
4622
4623 // Send GET request. This should cause an async write error.
4624 HttpResponseInfo response;
4625 HttpRequestHeaders request_headers;
4626 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
4627 callback_.callback()));
4628 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4629
4630 // Run the message loop so that asynchronous write completes and a connection
4631 // migration on write error attempt is posted in QuicStreamFactory's task
4632 // runner.
4633 base::RunLoop().RunUntilIdle();
4634 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4635
4636 // Run the task runner so that migration on write error is finally executed.
4637 task_runner->RunUntilIdle();
4638
4639 // Verify the session is still alive and not marked as going away.
4640 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4641 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4642 EXPECT_EQ(1u, session->GetNumActiveStreams());
4643 // There should be one task posted to migrate back to the default network in
4644 // kMinRetryTimeForDefaultNetworkSecs.
4645 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4646 base::TimeDelta expected_delay =
4647 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs);
4648 EXPECT_EQ(expected_delay, task_runner->NextPendingTaskDelay());
4649
4650 // Verify that response headers on the migrated socket were delivered to the
4651 // stream.
4652 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
4653 EXPECT_EQ(200, response.headers->response_code());
4654
4655 // Set up the third socket data provider for migrate back to default network.
4656 MockQuicData quic_data3;
4657 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:254658 quic_data3.AddWrite(SYNCHRONOUS,
4659 client_maker_.MakeConnectivityProbingPacket(3, false));
Zhongyi Shia7dd46b2018-07-12 22:59:294660 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:254661 quic_data3.AddRead(ASYNC,
4662 server_maker_.MakeConnectivityProbingPacket(2, false));
Zhongyi Shia7dd46b2018-07-12 22:59:294663 quic_data3.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4664 quic_data3.AddWrite(ASYNC, client_maker_.MakeAckPacket(4, 1, 2, 1, 1, true));
4665 quic_data3.AddWrite(
4666 SYNCHRONOUS,
4667 client_maker_.MakeRstPacket(5, false, GetNthClientInitiatedStreamId(0),
4668 quic::QUIC_STREAM_CANCELLED, 0));
4669 quic_data3.AddSocketDataToFactory(socket_factory_.get());
4670
4671 // Fast forward to fire the migrate back timer and verify the session
4672 // successfully migrates back to the default network.
4673 task_runner->FastForwardBy(expected_delay);
4674
4675 // Verify the session is still alive and not marked as going away.
4676 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4677 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4678 EXPECT_EQ(1u, session->GetNumActiveStreams());
4679
4680 // There should be one task posted to one will resend a connectivity probe and
4681 // the other will retry migrate back, both are cancelled.
4682 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
4683 task_runner->FastForwardBy(
4684 base::TimeDelta::FromSeconds(2 * kMinRetryTimeForDefaultNetworkSecs));
4685 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4686
4687 stream1.reset();
4688 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4689 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4690 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
4691 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
4692 EXPECT_TRUE(quic_data3.AllReadDataConsumed());
4693 EXPECT_TRUE(quic_data3.AllWriteDataConsumed());
4694}
4695
Zhongyi Shic1449372018-08-09 09:58:584696// This test verifies that the connection will not attempt connection migration
4697// (send connectivity probes on alternate path) when path degrading is detected
4698// and handshake is not confirmed.
4699TEST_P(QuicStreamFactoryTest,
4700 NoMigrationOnPathDegradingBeforeHandshakeConfirmed) {
4701 InitializeConnectionMigrationV2Test(
4702 {kDefaultNetworkForTests, kNewNetworkForTests});
4703
4704 // Using a testing task runner.
4705 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4706 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4707
4708 // Use cold start mode to send crypto message for handshake.
4709 crypto_client_stream_factory_.set_handshake_mode(
4710 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
4711
4712 MockQuicData socket_data;
4713 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4714 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
4715 socket_data.AddSocketDataToFactory(socket_factory_.get());
4716
4717 // Create request and QuicHttpStream.
4718 QuicStreamRequest request(factory_.get());
4719 EXPECT_EQ(ERR_IO_PENDING,
4720 request.Request(host_port_pair_, version_, privacy_mode_,
4721 DEFAULT_PRIORITY, SocketTag(),
4722 /*cert_verify_flags=*/0, url_, net_log_,
4723 &net_error_details_, callback_.callback()));
4724
4725 base::RunLoop().RunUntilIdle();
4726
4727 // Ensure that session is alive but not active.
4728 EXPECT_FALSE(HasActiveSession(host_port_pair_));
4729 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
4730 QuicChromiumClientSession* session = GetPendingSession(host_port_pair_);
4731 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4732 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4733
4734 // Cause the connection to report path degrading to the session.
4735 // Session will ignore the signal as handshake is not completed.
4736 session->connection()->OnPathDegradingTimeout();
4737 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4738
4739 EXPECT_FALSE(HasActiveSession(host_port_pair_));
Zhongyi Shi8de43832018-08-15 23:40:004740 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
Zhongyi Shic1449372018-08-09 09:58:584741 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4742 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4743}
4744
Zhongyi Shi634c1882018-08-16 04:05:594745// This test verifies that if a connection is closed with
4746// QUIC_NETWORK_IDLE_TIMEOUT before handshake is completed and there is no
4747// alternate network, no new connection will be created.
4748TEST_P(QuicStreamFactoryTest, NoAlternateNetworkBeforeHandshakeOnIdleTimeout) {
4749 TestNoAlternateNetworkBeforeHandshake(quic::QUIC_NETWORK_IDLE_TIMEOUT);
4750}
4751
4752// This test verifies that if a connection is closed with QUIC_HANDSHAKE_TIMEOUT
4753// and there is no alternate network, no new connection will be created.
4754TEST_P(QuicStreamFactoryTest, NoAlternateNetworkOnHandshakeTimeout) {
4755 TestNoAlternateNetworkBeforeHandshake(quic::QUIC_HANDSHAKE_TIMEOUT);
4756}
4757
4758void QuicStreamFactoryTestBase::TestNoAlternateNetworkBeforeHandshake(
4759 quic::QuicErrorCode quic_error) {
4760 DCHECK(quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT ||
4761 quic_error == quic::QUIC_HANDSHAKE_TIMEOUT);
4762 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
4763
4764 // Using a testing task runner.
4765 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4766 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4767
4768 // Use cold start mode to send crypto message for handshake.
4769 crypto_client_stream_factory_.set_handshake_mode(
4770 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
4771
4772 MockQuicData socket_data;
4773 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4774 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
4775 socket_data.AddSocketDataToFactory(socket_factory_.get());
4776
4777 // Create request.
4778 QuicStreamRequest request(factory_.get());
4779 EXPECT_EQ(ERR_IO_PENDING,
4780 request.Request(host_port_pair_, version_, privacy_mode_,
4781 DEFAULT_PRIORITY, SocketTag(),
4782 /*cert_verify_flags=*/0, url_, net_log_,
4783 &net_error_details_, callback_.callback()));
4784
4785 base::RunLoop().RunUntilIdle();
4786
4787 // Ensure that session is alive but not active.
4788 EXPECT_FALSE(HasActiveSession(host_port_pair_));
4789 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
4790 QuicChromiumClientSession* session = GetPendingSession(host_port_pair_);
4791 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4792 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4793
4794 // Cause the connection to report path degrading to the session.
4795 // Session will ignore the signal as handshake is not completed.
4796 session->connection()->OnPathDegradingTimeout();
4797 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4798 EXPECT_FALSE(HasActiveSession(host_port_pair_));
4799 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
4800
4801 // Cause the connection to close due to |quic_error| before handshake.
4802 quic::QuicString error_details;
4803 if (quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT) {
4804 error_details = "No recent network activity.";
4805 } else {
4806 error_details = "Handshake timeout expired.";
4807 }
4808 session->connection()->CloseConnection(
4809 quic_error, error_details, quic::ConnectionCloseBehavior::SILENT_CLOSE);
4810
4811 // A task will be posted to clean up the session in the factory.
4812 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4813 task_runner->FastForwardUntilNoTasksRemain();
4814
4815 // No new session should be created as there is no alternate network.
4816 EXPECT_FALSE(HasActiveSession(host_port_pair_));
4817 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
4818 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4819 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4820}
4821
Zhongyi Shi8de43832018-08-15 23:40:004822TEST_P(QuicStreamFactoryTest, NewConnectionBeforeHandshakeAfterIdleTimeout) {
4823 TestNewConnectionOnAlternateNetworkBeforeHandshake(
4824 quic::QUIC_NETWORK_IDLE_TIMEOUT);
4825}
4826
4827TEST_P(QuicStreamFactoryTest, NewConnectionAfterHandshakeTimeout) {
4828 TestNewConnectionOnAlternateNetworkBeforeHandshake(
4829 quic::QUIC_HANDSHAKE_TIMEOUT);
4830}
4831
Zhongyi Shif3fcbbe62018-08-16 22:52:084832// Sets up a test to verify that a new connection will be created on the
4833// alternate network after the initial connection fails before handshake with
4834// signals delivered in the following order (alternate network is available):
4835// - the default network is not able to complete crypto handshake;
4836// - the original connection is closed with |quic_error|;
4837// - a new connection is created on the alternate network and is able to finish
4838// crypto handshake;
4839// - the new session on the alternate network attempts to migrate back to the
4840// default network by sending probes;
4841// - default network being disconnected is delivered: session will stop probing
4842// the original network.
4843// - alternate network is made by default.
Zhongyi Shi8de43832018-08-15 23:40:004844void QuicStreamFactoryTestBase::
4845 TestNewConnectionOnAlternateNetworkBeforeHandshake(
4846 quic::QuicErrorCode quic_error) {
4847 DCHECK(quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT ||
4848 quic_error == quic::QUIC_HANDSHAKE_TIMEOUT);
4849 InitializeConnectionMigrationV2Test(
4850 {kDefaultNetworkForTests, kNewNetworkForTests});
4851
4852 // Using a testing task runner.
4853 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4854 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4855
4856 // Use cold start mode to send crypto message for handshake.
4857 crypto_client_stream_factory_.set_handshake_mode(
4858 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
4859
4860 // Socket data for connection on the default network.
4861 MockQuicData socket_data;
4862 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4863 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
4864 socket_data.AddSocketDataToFactory(socket_factory_.get());
4865
4866 // Socket data for connection on the alternate network.
4867 MockQuicData socket_data2;
4868 quic::QuicStreamOffset header_stream_offset = 0;
4869 socket_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
4870 socket_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
4871 // Change the encryption level after handshake is confirmed.
4872 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
4873 socket_data2.AddWrite(
4874 ASYNC, ConstructInitialSettingsPacket(2, &header_stream_offset));
4875 socket_data2.AddWrite(
4876 ASYNC, ConstructGetRequestPacket(3, GetNthClientInitiatedStreamId(0),
4877 true, true, &header_stream_offset));
4878 socket_data2.AddRead(
4879 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
4880 false, false));
4881 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4882 socket_data2.AddWrite(SYNCHRONOUS,
4883 client_maker_.MakeAckAndRstPacket(
Zhongyi Shif3fcbbe62018-08-16 22:52:084884 5, false, GetNthClientInitiatedStreamId(0),
Zhongyi Shi8de43832018-08-15 23:40:004885 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
4886 socket_data2.AddSocketDataToFactory(socket_factory_.get());
4887
Zhongyi Shif3fcbbe62018-08-16 22:52:084888 // Socket data for probing on the default network.
4889 MockQuicData probing_data;
4890 probing_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
4891 probing_data.AddWrite(SYNCHRONOUS,
4892 client_maker_.MakeConnectivityProbingPacket(4, false));
4893 probing_data.AddSocketDataToFactory(socket_factory_.get());
4894
Zhongyi Shi8de43832018-08-15 23:40:004895 // Create request and QuicHttpStream.
4896 QuicStreamRequest request(factory_.get());
4897 EXPECT_EQ(ERR_IO_PENDING,
4898 request.Request(host_port_pair_, version_, privacy_mode_,
4899 DEFAULT_PRIORITY, SocketTag(),
4900 /*cert_verify_flags=*/0, url_, net_log_,
4901 &net_error_details_, callback_.callback()));
4902
4903 base::RunLoop().RunUntilIdle();
4904
4905 // Ensure that session is alive but not active.
4906 EXPECT_FALSE(HasActiveSession(host_port_pair_));
4907 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
4908 QuicChromiumClientSession* session = GetPendingSession(host_port_pair_);
4909 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4910 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4911
4912 quic::QuicString error_details;
4913 if (quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT) {
4914 error_details = "No recent network activity.";
4915 } else {
4916 error_details = "Handshake timeout expired.";
4917 }
4918 session->connection()->CloseConnection(
4919 quic_error, error_details, quic::ConnectionCloseBehavior::SILENT_CLOSE);
4920
4921 // A task will be posted to clean up the session in the factory.
4922 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4923 task_runner->FastForwardUntilNoTasksRemain();
4924
4925 // Verify a new session is created on the alternate network.
4926 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
4927 EXPECT_FALSE(HasActiveSession(host_port_pair_));
4928 QuicChromiumClientSession* session2 = GetPendingSession(host_port_pair_);
4929 EXPECT_NE(session, session2);
4930
4931 // Confirm the handshake on the alternate network.
4932 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
4933 quic::QuicSession::HANDSHAKE_CONFIRMED);
4934 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4935 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4936 // Resume the data now so that data can be sent and read.
4937 socket_data2.Resume();
4938
4939 // Create the stream.
4940 std::unique_ptr<HttpStream> stream = CreateStream(&request);
4941 EXPECT_TRUE(stream.get());
4942 HttpRequestInfo request_info;
4943 request_info.method = "GET";
4944 request_info.url = GURL("https://www.example.org/");
4945 request_info.traffic_annotation =
4946 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4947 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
4948 net_log_, CompletionOnceCallback()));
4949 // Send the request.
4950 HttpResponseInfo response;
4951 HttpRequestHeaders request_headers;
4952 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
4953 callback_.callback()));
4954 // Run the message loop to finish asynchronous mock write.
4955 base::RunLoop().RunUntilIdle();
4956 // Read the response.
4957 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
4958 EXPECT_EQ(200, response.headers->response_code());
4959
Zhongyi Shif3fcbbe62018-08-16 22:52:084960 // There should be a new task posted to migrate back to the default network.
4961 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4962 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
4963 EXPECT_EQ(base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs),
4964 next_task_delay);
4965 task_runner->FastForwardBy(next_task_delay);
4966
4967 // There should be two tasks posted. One will retry probing and the other
4968 // will retry migrate back.
4969 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
4970 next_task_delay = task_runner->NextPendingTaskDelay();
4971 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
4972 next_task_delay);
4973
4974 // Deliver the signal that the default network is disconnected.
4975 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4976 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
4977 // Verify no connectivity probes will be sent as probing will be cancelled.
4978 task_runner->FastForwardUntilNoTasksRemain();
4979 // Deliver the signal that the alternate network is made default.
4980 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4981 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
4982 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4983
Zhongyi Shi8de43832018-08-15 23:40:004984 stream.reset();
4985 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4986 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4987 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
4988 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
4989}
4990
Zhongyi Shi247d6322018-07-24 07:03:354991// Test that connection will be closed with PACKET_WRITE_ERROR if a write error
4992// is triggered before handshake is confirmed and connection migration is turned
4993// on.
4994TEST_P(QuicStreamFactoryTest, MigrationOnWriteErrorBeforeHandshakeConfirmed) {
4995 InitializeConnectionMigrationV2Test(
4996 {kDefaultNetworkForTests, kNewNetworkForTests});
4997
4998 // Use unmocked crypto stream to do crypto connect.
4999 crypto_client_stream_factory_.set_handshake_mode(
Zhongyi Shi879659422018-08-02 17:58:255000 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
Zhongyi Shi247d6322018-07-24 07:03:355001
5002 MockQuicData socket_data;
5003 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5004 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
5005 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
5006 socket_data.AddSocketDataToFactory(socket_factory_.get());
5007
5008 // Create request, should fail after the write of the CHLO fails.
5009 QuicStreamRequest request(factory_.get());
5010 EXPECT_EQ(ERR_IO_PENDING,
5011 request.Request(host_port_pair_, version_, privacy_mode_,
5012 DEFAULT_PRIORITY, SocketTag(),
5013 /*cert_verify_flags=*/0, url_, net_log_,
5014 &net_error_details_, callback_.callback()));
5015 EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED, callback_.WaitForResult());
5016 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5017 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
5018
5019 // Verify new requests can be sent normally.
5020 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:275021 MockCryptoClientStream::COLD_START);
Zhongyi Shi247d6322018-07-24 07:03:355022 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5023 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5024 MockQuicData socket_data2;
5025 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5026 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
5027 socket_data2.AddSocketDataToFactory(socket_factory_.get());
5028
5029 QuicStreamRequest request2(factory_.get());
5030 EXPECT_EQ(ERR_IO_PENDING,
5031 request2.Request(host_port_pair_, version_, privacy_mode_,
5032 DEFAULT_PRIORITY, SocketTag(),
5033 /*cert_verify_flags=*/0, url_, net_log_,
5034 &net_error_details_, callback_.callback()));
5035 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5036 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5037 // Run the message loop to complete host resolution.
5038 base::RunLoop().RunUntilIdle();
5039
5040 // Complete handshake. QuicStreamFactory::Job should complete and succeed.
5041 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5042 quic::QuicSession::HANDSHAKE_CONFIRMED);
5043 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5044 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5045 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
5046
5047 // Create QuicHttpStream.
5048 std::unique_ptr<HttpStream> stream = CreateStream(&request2);
5049 EXPECT_TRUE(stream.get());
5050 stream.reset();
5051 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5052 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5053 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
5054 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
5055}
5056
jri9f303712016-09-13 01:10:225057void QuicStreamFactoryTestBase::TestMigrationOnWriteError(
5058 IoMode write_error_mode) {
Zhongyi Shi1a054612018-06-14 04:59:085059 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:225060 {kDefaultNetworkForTests, kNewNetworkForTests});
5061 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5062 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5063 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5064
Zhongyi Shi3c4c9e92018-07-02 23:16:235065 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
5066
jri9f303712016-09-13 01:10:225067 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525068 quic::QuicStreamOffset header_stream_offset = 0;
jri9f303712016-09-13 01:10:225069 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
rch5cb522462017-04-25 20:18:365070 socket_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435071 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
jri9f303712016-09-13 01:10:225072 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:175073 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:225074
5075 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:455076 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:335077 EXPECT_EQ(ERR_IO_PENDING,
5078 request.Request(host_port_pair_, version_, privacy_mode_,
5079 DEFAULT_PRIORITY, SocketTag(),
5080 /*cert_verify_flags=*/0, url_, net_log_,
5081 &net_error_details_, callback_.callback()));
jri9f303712016-09-13 01:10:225082 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:245083 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:225084 EXPECT_TRUE(stream.get());
5085
5086 // Cause QUIC stream to be created.
5087 HttpRequestInfo request_info;
5088 request_info.method = "GET";
5089 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:395090 request_info.traffic_annotation =
5091 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:275092 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:395093 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:225094
5095 // Ensure that session is alive and active.
5096 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5097 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5098 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5099
5100 // Set up second socket data provider that is used after
5101 // migration. The request is rewritten to this new socket, and the
5102 // response to the request is read on this new socket.
5103 MockQuicData socket_data1;
Zhongyi Shi32f2fd02018-04-16 18:23:435104 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
5105 2, GetNthClientInitiatedStreamId(0),
5106 true, true, &header_stream_offset));
5107 socket_data1.AddRead(
5108 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
5109 false, false));
jri9f303712016-09-13 01:10:225110 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:435111 socket_data1.AddWrite(SYNCHRONOUS,
5112 client_maker_.MakeAckAndRstPacket(
5113 3, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:525114 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:175115 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:225116
5117 // Send GET request on stream. This should cause a write error, which triggers
5118 // a connection migration attempt.
5119 HttpResponseInfo response;
5120 HttpRequestHeaders request_headers;
5121 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5122 callback_.callback()));
5123
5124 // Run the message loop so that the migration attempt is executed and
5125 // data queued in the new socket is read by the packet reader.
5126 base::RunLoop().RunUntilIdle();
5127
Zhongyi Shia7dd46b2018-07-12 22:59:295128 // Verify that session is alive and not marked as going awya.
jri9f303712016-09-13 01:10:225129 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:295130 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri9f303712016-09-13 01:10:225131 EXPECT_EQ(1u, session->GetNumActiveStreams());
5132
5133 // Verify that response headers on the migrated socket were delivered to the
5134 // stream.
5135 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
5136 EXPECT_EQ(200, response.headers->response_code());
5137
5138 stream.reset();
5139
5140 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5141 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5142 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
5143 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
5144}
5145
5146TEST_P(QuicStreamFactoryTest, MigrateSessionOnWriteErrorSynchronous) {
5147 TestMigrationOnWriteError(SYNCHRONOUS);
5148}
5149
5150TEST_P(QuicStreamFactoryTest, MigrateSessionOnWriteErrorAsync) {
5151 TestMigrationOnWriteError(ASYNC);
5152}
5153
5154void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorNoNewNetwork(
5155 IoMode write_error_mode) {
Zhongyi Shi1a054612018-06-14 04:59:085156 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri9f303712016-09-13 01:10:225157 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5158 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5159
jri5b785512016-09-13 04:29:115160 // Use the test task runner, to force the migration alarm timeout later.
5161 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
5162
jri9f303712016-09-13 01:10:225163 MockQuicData socket_data;
5164 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:435165 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jri9f303712016-09-13 01:10:225166 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:175167 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:225168
5169 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:455170 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:335171 EXPECT_EQ(ERR_IO_PENDING,
5172 request.Request(host_port_pair_, version_, privacy_mode_,
5173 DEFAULT_PRIORITY, SocketTag(),
5174 /*cert_verify_flags=*/0, url_, net_log_,
5175 &net_error_details_, callback_.callback()));
jri9f303712016-09-13 01:10:225176 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:245177 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:225178 EXPECT_TRUE(stream.get());
5179
5180 // Cause QUIC stream to be created.
5181 HttpRequestInfo request_info;
5182 request_info.method = "GET";
5183 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:395184 request_info.traffic_annotation =
5185 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:275186 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:395187 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:225188
5189 // Ensure that session is alive and active.
5190 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5191 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5192 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5193
jri5b785512016-09-13 04:29:115194 // Send GET request on stream. This causes a write error, which triggers
5195 // a connection migration attempt. Since there are no networks
5196 // to migrate to, this causes the session to wait for a new network.
jri9f303712016-09-13 01:10:225197 HttpResponseInfo response;
5198 HttpRequestHeaders request_headers;
5199 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5200 callback_.callback()));
jri5b785512016-09-13 04:29:115201
5202 // Complete any pending writes. Pending async MockQuicData writes
5203 // are run on the message loop, not on the test runner.
jri9f303712016-09-13 01:10:225204 base::RunLoop().RunUntilIdle();
jri5b785512016-09-13 04:29:115205
5206 // Write error causes migration task to be posted. Spin the loop.
5207 if (write_error_mode == ASYNC)
5208 runner_->RunNextTask();
5209
5210 // Migration has not yet failed. The session should be alive and active.
5211 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5212 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5213 EXPECT_EQ(1u, session->GetNumActiveStreams());
5214 EXPECT_TRUE(session->connection()->writer()->IsWriteBlocked());
5215
5216 // The migration will not fail until the migration alarm timeout.
5217 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5218 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5219 EXPECT_EQ(1u, session->GetNumActiveStreams());
5220 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
5221
5222 // Force migration alarm timeout to run.
5223 RunTestLoopUntilIdle();
5224
5225 // The connection should be closed. A request for response headers
5226 // should fail.
jri9f303712016-09-13 01:10:225227 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5228 EXPECT_FALSE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:115229 EXPECT_EQ(ERR_NETWORK_CHANGED, callback_.WaitForResult());
5230 EXPECT_EQ(ERR_NETWORK_CHANGED,
5231 stream->ReadResponseHeaders(callback_.callback()));
jri9f303712016-09-13 01:10:225232
5233 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5234 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5235}
5236
5237TEST_P(QuicStreamFactoryTest,
5238 MigrateSessionOnWriteErrorNoNewNetworkSynchronous) {
5239 TestMigrationOnWriteErrorNoNewNetwork(SYNCHRONOUS);
5240}
5241
5242TEST_P(QuicStreamFactoryTest, MigrateSessionOnWriteErrorNoNewNetworkAsync) {
5243 TestMigrationOnWriteErrorNoNewNetwork(ASYNC);
5244}
5245
Zhongyi Shi0439ecc72018-07-11 04:41:265246TEST_P(QuicStreamFactoryTest,
5247 MigrateSessionOnWriteErrorWithMultipleRequestsSync) {
5248 TestMigrationOnWriteErrorWithMultipleRequests(SYNCHRONOUS);
5249}
5250
5251TEST_P(QuicStreamFactoryTest,
5252 MigrateSessionOnWriteErrorWithMultipleRequestsAsync) {
5253 TestMigrationOnWriteErrorWithMultipleRequests(ASYNC);
5254}
5255
5256// Sets up a test which verifies that connection migration on write error can
5257// eventually succeed and rewrite the packet on the new network with *multiple*
5258// migratable streams.
5259void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorWithMultipleRequests(
5260 IoMode write_error_mode) {
5261 InitializeConnectionMigrationV2Test(
5262 {kDefaultNetworkForTests, kNewNetworkForTests});
5263 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5264 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5265 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5266
5267 MockQuicData socket_data;
5268 quic::QuicStreamOffset header_stream_offset = 0;
5269 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5270 socket_data.AddWrite(
5271 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5272 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
5273 socket_data.AddSocketDataToFactory(socket_factory_.get());
5274
5275 // Set up second socket data provider that is used after
5276 // migration. The request is rewritten to this new socket, and the
5277 // response to the request is read on this new socket.
5278 MockQuicData socket_data1;
5279 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
5280 2, GetNthClientInitiatedStreamId(0),
5281 true, true, &header_stream_offset));
5282 socket_data1.AddRead(
5283 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
5284 false, false));
5285 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5286 socket_data1.AddWrite(SYNCHRONOUS,
5287 client_maker_.MakeAckAndRstPacket(
5288 3, false, GetNthClientInitiatedStreamId(0),
5289 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
5290 socket_data1.AddWrite(
5291 SYNCHRONOUS,
5292 client_maker_.MakeRstPacket(4, false, GetNthClientInitiatedStreamId(1),
5293 quic::QUIC_STREAM_CANCELLED, 0));
5294
5295 socket_data1.AddSocketDataToFactory(socket_factory_.get());
5296
5297 // Create request #1 and QuicHttpStream.
5298 QuicStreamRequest request1(factory_.get());
5299 EXPECT_EQ(ERR_IO_PENDING,
5300 request1.Request(host_port_pair_, version_, privacy_mode_,
5301 DEFAULT_PRIORITY, SocketTag(),
5302 /*cert_verify_flags=*/0, url_, net_log_,
5303 &net_error_details_, callback_.callback()));
5304 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5305 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
5306 EXPECT_TRUE(stream1.get());
5307
5308 HttpRequestInfo request_info1;
5309 request_info1.method = "GET";
5310 request_info1.url = GURL("https://www.example.org/");
5311 request_info1.traffic_annotation =
5312 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5313 EXPECT_EQ(OK,
5314 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
5315 net_log_, CompletionOnceCallback()));
5316
5317 // Second request returns synchronously because it pools to existing session.
5318 TestCompletionCallback callback2;
5319 QuicStreamRequest request2(factory_.get());
5320 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_, privacy_mode_,
5321 DEFAULT_PRIORITY, SocketTag(),
5322 /*cert_verify_flags=*/0, url_, net_log_,
5323 &net_error_details_, callback2.callback()));
5324 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
5325 EXPECT_TRUE(stream2.get());
5326 HttpRequestInfo request_info2;
5327 request_info2.method = "GET";
5328 request_info2.url = GURL("https://www.example.org/");
5329 request_info2.traffic_annotation =
5330 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5331 EXPECT_EQ(OK,
5332 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
5333 net_log_, CompletionOnceCallback()));
5334
5335 // Ensure that session is alive and active.
5336 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5337 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5338 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5339 EXPECT_EQ(2u, session->GetNumActiveStreams());
5340
5341 // Send GET request on stream. This should cause a write error, which triggers
5342 // a connection migration attempt.
5343 HttpResponseInfo response;
5344 HttpRequestHeaders request_headers;
5345 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
5346 callback_.callback()));
5347
5348 // Run the message loop so that the migration attempt is executed and
5349 // data queued in the new socket is read by the packet reader.
5350 base::RunLoop().RunUntilIdle();
5351
Zhongyi Shia7dd46b2018-07-12 22:59:295352 // Verify session is still alive and not marked as going away.
Zhongyi Shi0439ecc72018-07-11 04:41:265353 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:295354 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:265355 EXPECT_EQ(2u, session->GetNumActiveStreams());
5356
5357 // Verify that response headers on the migrated socket were delivered to the
5358 // stream.
5359 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
5360 EXPECT_EQ(200, response.headers->response_code());
5361
5362 stream1.reset();
5363 stream2.reset();
5364
5365 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5366 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5367 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
5368 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
5369}
5370
5371TEST_P(QuicStreamFactoryTest, MigrateOnWriteErrorWithMixedRequestsSync) {
5372 TestMigrationOnWriteErrorMixedStreams(SYNCHRONOUS);
5373}
5374
5375TEST_P(QuicStreamFactoryTest, MigrateOnWriteErrorWithMixedRequestsAsync) {
5376 TestMigrationOnWriteErrorMixedStreams(ASYNC);
5377}
5378
5379// Sets up a test that verifies connection migration manages to migrate to
5380// alternate network after encountering a SYNC/ASYNC write error based on
5381// |write_error_mode| on the original network.
5382// Note there are mixed types of unfinished requests before migration: one
5383// migratable and one non-migratable. The *migratable* one triggers write
5384// error.
5385void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorMixedStreams(
5386 IoMode write_error_mode) {
5387 InitializeConnectionMigrationV2Test(
5388 {kDefaultNetworkForTests, kNewNetworkForTests});
5389 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5390 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5391 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5392
5393 int packet_number = 1;
5394 MockQuicData socket_data;
5395 quic::QuicStreamOffset header_stream_offset = 0;
5396 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5397 socket_data.AddWrite(
5398 SYNCHRONOUS,
5399 ConstructInitialSettingsPacket(packet_number++, &header_stream_offset));
5400 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
5401 socket_data.AddSocketDataToFactory(socket_factory_.get());
5402
5403 // Set up second socket data provider that is used after
5404 // migration. The request is rewritten to this new socket, and the
5405 // response to the request is read on this new socket.
5406 MockQuicData socket_data1;
5407 socket_data1.AddWrite(
5408 SYNCHRONOUS, ConstructGetRequestPacket(
5409 packet_number++, GetNthClientInitiatedStreamId(0), true,
5410 true, &header_stream_offset));
5411 socket_data1.AddWrite(
5412 SYNCHRONOUS, client_maker_.MakeRstPacket(packet_number++, true,
5413 GetNthClientInitiatedStreamId(1),
5414 quic::QUIC_STREAM_CANCELLED, 0));
5415 socket_data1.AddRead(
5416 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
5417 false, false));
5418 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5419 socket_data1.AddWrite(
5420 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
5421 packet_number++, false, GetNthClientInitiatedStreamId(0),
5422 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
5423 socket_data1.AddSocketDataToFactory(socket_factory_.get());
5424
5425 // Create request #1 and QuicHttpStream.
5426 QuicStreamRequest request1(factory_.get());
5427 EXPECT_EQ(ERR_IO_PENDING,
5428 request1.Request(host_port_pair_, version_, privacy_mode_,
5429 DEFAULT_PRIORITY, SocketTag(),
5430 /*cert_verify_flags=*/0, url_, net_log_,
5431 &net_error_details_, callback_.callback()));
5432 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5433 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
5434 EXPECT_TRUE(stream1.get());
5435
5436 HttpRequestInfo request_info1;
5437 request_info1.method = "GET";
5438 request_info1.url = GURL("https://www.example.org/");
5439 request_info1.traffic_annotation =
5440 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5441 EXPECT_EQ(OK,
5442 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
5443 net_log_, CompletionOnceCallback()));
5444
5445 // Second request returns synchronously because it pools to existing session.
5446 TestCompletionCallback callback2;
5447 QuicStreamRequest request2(factory_.get());
5448 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_, privacy_mode_,
5449 DEFAULT_PRIORITY, SocketTag(),
5450 /*cert_verify_flags=*/0, url_, net_log_,
5451 &net_error_details_, callback2.callback()));
5452 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
5453 EXPECT_TRUE(stream2.get());
5454
5455 HttpRequestInfo request_info2;
5456 request_info2.method = "GET";
Zhongyi Shibb28b1f2018-07-18 02:41:265457 request_info2.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Zhongyi Shi0439ecc72018-07-11 04:41:265458 request_info2.url = GURL("https://www.example.org/");
5459 request_info2.traffic_annotation =
5460 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5461 EXPECT_EQ(OK,
5462 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
5463 net_log_, CompletionOnceCallback()));
5464
5465 // Ensure that session is alive and active.
5466 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5467 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5468 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5469 EXPECT_EQ(2u, session->GetNumActiveStreams());
5470
5471 // Send GET request on stream 1. This should cause a write error, which
5472 // triggers a connection migration attempt.
5473 HttpResponseInfo response;
5474 HttpRequestHeaders request_headers;
5475 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
5476 callback_.callback()));
5477
5478 // Run the message loop so that the migration attempt is executed and
5479 // data queued in the new socket is read by the packet reader.
5480 base::RunLoop().RunUntilIdle();
5481
Zhongyi Shia7dd46b2018-07-12 22:59:295482 // Verify that the session is still alive and not marked as going away.
5483 // Non-migratable stream should be closed due to migration.
Zhongyi Shi0439ecc72018-07-11 04:41:265484 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:295485 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:265486 EXPECT_EQ(1u, session->GetNumActiveStreams());
5487
5488 // Verify that response headers on the migrated socket were delivered to the
5489 // stream.
5490 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
5491 EXPECT_EQ(200, response.headers->response_code());
5492
5493 stream1.reset();
5494
5495 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5496 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5497 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
5498 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
5499}
5500
5501TEST_P(QuicStreamFactoryTest, MigrateOnWriteErrorWithMixedRequests2Sync) {
5502 TestMigrationOnWriteErrorMixedStreams2(SYNCHRONOUS);
5503}
5504
5505TEST_P(QuicStreamFactoryTest, MigrateOnWriteErrorWithMixedRequests2Async) {
5506 TestMigrationOnWriteErrorMixedStreams2(ASYNC);
5507}
5508
5509// The one triggers write error is a non-migratable stream.
5510// Sets up a test that verifies connection migration manages to migrate to
5511// alternate network after encountering a SYNC/ASYNC write error based on
5512// |write_error_mode| on the original network.
5513// Note there are mixed types of unfinished requests before migration: one
5514// migratable and one non-migratable. The *non-migratable* one triggers write
5515// error.
5516void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorMixedStreams2(
5517 IoMode write_error_mode) {
5518 InitializeConnectionMigrationV2Test(
5519 {kDefaultNetworkForTests, kNewNetworkForTests});
5520 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5521 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5522 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5523
5524 int packet_number = 1;
5525 MockQuicData socket_data;
5526 quic::QuicStreamOffset header_stream_offset = 0;
5527 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5528 socket_data.AddWrite(
5529 SYNCHRONOUS,
5530 ConstructInitialSettingsPacket(packet_number++, &header_stream_offset));
5531 socket_data.AddWrite(write_error_mode,
5532 ERR_ADDRESS_UNREACHABLE); // Write error.
5533 socket_data.AddSocketDataToFactory(socket_factory_.get());
5534
5535 // Set up second socket data provider that is used after
5536 // migration. The request is rewritten to this new socket, and the
5537 // response to the request is read on this new socket.
5538 MockQuicData socket_data1;
5539 // The packet triggered writer error will be sent anyway even if the stream
5540 // will be cancelled later.
5541 socket_data1.AddWrite(
5542 SYNCHRONOUS, ConstructGetRequestPacket(
5543 packet_number++, GetNthClientInitiatedStreamId(1), true,
5544 true, &header_stream_offset));
5545 socket_data1.AddWrite(
5546 SYNCHRONOUS, client_maker_.MakeRstPacket(packet_number++, true,
5547 GetNthClientInitiatedStreamId(1),
5548 quic::QUIC_STREAM_CANCELLED, 0));
5549 socket_data1.AddWrite(
5550 SYNCHRONOUS, ConstructGetRequestPacket(
5551 packet_number++, GetNthClientInitiatedStreamId(0), true,
5552 true, &header_stream_offset));
5553 socket_data1.AddRead(
5554 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
5555 false, false));
5556 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5557 socket_data1.AddWrite(
5558 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
5559 packet_number++, false, GetNthClientInitiatedStreamId(0),
5560 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
5561 socket_data1.AddSocketDataToFactory(socket_factory_.get());
5562
5563 // Create request #1 and QuicHttpStream.
5564 QuicStreamRequest request1(factory_.get());
5565 EXPECT_EQ(ERR_IO_PENDING,
5566 request1.Request(host_port_pair_, version_, privacy_mode_,
5567 DEFAULT_PRIORITY, SocketTag(),
5568 /*cert_verify_flags=*/0, url_, net_log_,
5569 &net_error_details_, callback_.callback()));
5570 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5571 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
5572 EXPECT_TRUE(stream1.get());
5573
5574 HttpRequestInfo request_info1;
5575 request_info1.method = "GET";
5576 request_info1.url = GURL("https://www.example.org/");
5577 request_info1.traffic_annotation =
5578 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5579 EXPECT_EQ(OK,
5580 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
5581 net_log_, CompletionOnceCallback()));
5582
5583 // Second request returns synchronously because it pools to existing session.
5584 TestCompletionCallback callback2;
5585 QuicStreamRequest request2(factory_.get());
5586 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_, privacy_mode_,
5587 DEFAULT_PRIORITY, SocketTag(),
5588 /*cert_verify_flags=*/0, url_, net_log_,
5589 &net_error_details_, callback2.callback()));
5590 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
5591 EXPECT_TRUE(stream2.get());
5592
5593 HttpRequestInfo request_info2;
5594 request_info2.method = "GET";
Zhongyi Shibb28b1f2018-07-18 02:41:265595 request_info2.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Zhongyi Shi0439ecc72018-07-11 04:41:265596 request_info2.url = GURL("https://www.example.org/");
5597 request_info2.traffic_annotation =
5598 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5599 EXPECT_EQ(OK,
5600 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
5601 net_log_, CompletionOnceCallback()));
5602
5603 // Ensure that session is alive and active.
5604 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5605 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5606 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5607 EXPECT_EQ(2u, session->GetNumActiveStreams());
5608
5609 // Send GET request on stream 2 which is non-migratable. This should cause a
5610 // write error, which triggers a connection migration attempt.
5611 HttpResponseInfo response2;
5612 HttpRequestHeaders request_headers2;
5613 EXPECT_EQ(OK, stream2->SendRequest(request_headers2, &response2,
5614 callback2.callback()));
5615
5616 // Run the message loop so that the migration attempt is executed and
Zhongyi Shia7dd46b2018-07-12 22:59:295617 // data queued in the new socket is read by the packet reader. Session is
5618 // still alive and not marked as going away, non-migratable stream will be
5619 // closed.
Zhongyi Shi0439ecc72018-07-11 04:41:265620 base::RunLoop().RunUntilIdle();
5621 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:295622 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:265623 EXPECT_EQ(1u, session->GetNumActiveStreams());
5624
5625 // Send GET request on stream 1.
5626 HttpResponseInfo response;
5627 HttpRequestHeaders request_headers;
5628 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
5629 callback_.callback()));
5630
5631 base::RunLoop().RunUntilIdle();
5632
5633 // Verify that response headers on the migrated socket were delivered to the
5634 // stream.
5635 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
5636 EXPECT_EQ(200, response.headers->response_code());
5637
5638 stream1.reset();
5639
5640 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5641 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5642 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
5643 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
5644}
5645
jri9f303712016-09-13 01:10:225646void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorNonMigratableStream(
5647 IoMode write_error_mode) {
5648 DVLOG(1) << "Mode: "
5649 << ((write_error_mode == SYNCHRONOUS) ? "SYNCHRONOUS" : "ASYNC");
Zhongyi Shi1a054612018-06-14 04:59:085650 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:225651 {kDefaultNetworkForTests, kNewNetworkForTests});
5652 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5653 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5654
5655 MockQuicData socket_data;
5656 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:435657 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jri9f303712016-09-13 01:10:225658 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:175659 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:225660
5661 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:455662 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:335663 EXPECT_EQ(ERR_IO_PENDING,
5664 request.Request(host_port_pair_, version_, privacy_mode_,
5665 DEFAULT_PRIORITY, SocketTag(),
5666 /*cert_verify_flags=*/0, url_, net_log_,
5667 &net_error_details_, callback_.callback()));
jri9f303712016-09-13 01:10:225668 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:245669 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:225670 EXPECT_TRUE(stream.get());
5671
5672 // Cause QUIC stream to be created, but marked as non-migratable.
5673 HttpRequestInfo request_info;
Zhongyi Shibb28b1f2018-07-18 02:41:265674 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
jri9f303712016-09-13 01:10:225675 request_info.method = "GET";
5676 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:395677 request_info.traffic_annotation =
5678 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:275679 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:395680 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:225681
5682 // Ensure that session is alive and active.
5683 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5684 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5685 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5686
5687 // Send GET request on stream. This should cause a write error, which triggers
5688 // a connection migration attempt.
5689 HttpResponseInfo response;
5690 HttpRequestHeaders request_headers;
5691 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5692 callback_.callback()));
5693
5694 // Run message loop to execute migration attempt.
5695 base::RunLoop().RunUntilIdle();
5696
5697 // Migration fails, and session is closed and deleted.
5698 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5699 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5700
5701 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5702 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5703}
5704
5705TEST_P(QuicStreamFactoryTest,
5706 MigrateSessionOnWriteErrorNonMigratableStreamSynchronous) {
5707 TestMigrationOnWriteErrorNonMigratableStream(SYNCHRONOUS);
5708}
5709
5710TEST_P(QuicStreamFactoryTest,
5711 MigrateSessionOnWriteErrorNonMigratableStreamAsync) {
5712 TestMigrationOnWriteErrorNonMigratableStream(ASYNC);
5713}
5714
5715void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorMigrationDisabled(
5716 IoMode write_error_mode) {
Zhongyi Shi1a054612018-06-14 04:59:085717 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:225718 {kDefaultNetworkForTests, kNewNetworkForTests});
5719 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5720 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5721
5722 MockQuicData socket_data;
5723 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:435724 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jri9f303712016-09-13 01:10:225725 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:175726 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:225727
5728 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:455729 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:335730 EXPECT_EQ(ERR_IO_PENDING,
5731 request.Request(host_port_pair_, version_, privacy_mode_,
5732 DEFAULT_PRIORITY, SocketTag(),
5733 /*cert_verify_flags=*/0, url_, net_log_,
5734 &net_error_details_, callback_.callback()));
jri9f303712016-09-13 01:10:225735 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:245736 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:225737 EXPECT_TRUE(stream.get());
5738
5739 // Cause QUIC stream to be created.
5740 HttpRequestInfo request_info;
5741 request_info.method = "GET";
5742 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:395743 request_info.traffic_annotation =
5744 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:275745 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:395746 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:225747
5748 // Ensure that session is alive and active.
5749 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5750 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5751 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5752
5753 // Set session config to have connection migration disabled.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525754 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
5755 session->config());
jri9f303712016-09-13 01:10:225756 EXPECT_TRUE(session->config()->DisableConnectionMigration());
5757
5758 // Send GET request on stream. This should cause a write error, which triggers
5759 // a connection migration attempt.
5760 HttpResponseInfo response;
5761 HttpRequestHeaders request_headers;
5762 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5763 callback_.callback()));
5764 // Run message loop to execute migration attempt.
5765 base::RunLoop().RunUntilIdle();
5766 // Migration fails, and session is closed and deleted.
5767 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5768 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5769 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5770 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5771}
5772
5773TEST_P(QuicStreamFactoryTest,
5774 MigrateSessionOnWriteErrorMigrationDisabledSynchronous) {
5775 TestMigrationOnWriteErrorMigrationDisabled(SYNCHRONOUS);
5776}
5777
5778TEST_P(QuicStreamFactoryTest,
5779 MigrateSessionOnWriteErrorMigrationDisabledAsync) {
5780 TestMigrationOnWriteErrorMigrationDisabled(ASYNC);
5781}
5782
Zhongyi Shi7f1d9212018-06-22 23:24:365783// Sets up a test which verifies that connection migration on write error can
5784// eventually succeed and rewrite the packet on the new network with singals
5785// delivered in the following order (alternate network is always availabe):
5786// - original network encounters a SYNC/ASYNC write error based on
5787// |write_error_mode_on_old_network|, the packet failed to be written is
5788// cached, session migrates immediately to the alternate network.
5789// - an immediate SYNC/ASYNC write error based on
5790// |write_error_mode_on_new_network| is encountered after migration to the
5791// alternate network, session migrates immediately to the original network.
5792// - an immediate SYNC/ASYNC write error based on
5793// |write_error_mode_on_old_network| is encountered after migration to the
5794// original network, session migrates immediately to the alternate network.
5795// - finally, session successfully sends the packet and reads the response on
5796// the alternate network.
5797// TODO(zhongyi): once https://crbug.com/855666 is fixed, this test should be
5798// modified to test that session is closed early if hopping between networks
5799// with consecutive write errors is detected.
jri9f303712016-09-13 01:10:225800void QuicStreamFactoryTestBase::TestMigrationOnMultipleWriteErrors(
Zhongyi Shi7f1d9212018-06-22 23:24:365801 IoMode write_error_mode_on_old_network,
5802 IoMode write_error_mode_on_new_network) {
5803 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:225804 {kDefaultNetworkForTests, kNewNetworkForTests});
5805 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5806 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5807 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5808
Zhongyi Shi7f1d9212018-06-22 23:24:365809 // Set up the socket data used by the original network, which encounters a
5810 // write erorr.
5811 MockQuicData socket_data1;
5812 quic::QuicStreamOffset header_stream_offset = 0;
5813 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5814 socket_data1.AddWrite(
5815 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5816 socket_data1.AddWrite(write_error_mode_on_old_network,
5817 ERR_ADDRESS_UNREACHABLE); // Write Error
5818 socket_data1.AddSocketDataToFactory(socket_factory_.get());
5819
5820 // Set up the socket data used by the alternate network, which also
5821 // encounters a write error.
5822 MockQuicData failed_quic_data2;
5823 failed_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5824 failed_quic_data2.AddWrite(write_error_mode_on_new_network, ERR_FAILED);
5825 failed_quic_data2.AddSocketDataToFactory(socket_factory_.get());
5826
5827 // Set up the third socket data used by original network, which encounters a
5828 // write error again.
5829 MockQuicData failed_quic_data1;
5830 failed_quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5831 failed_quic_data1.AddWrite(write_error_mode_on_old_network, ERR_FAILED);
5832 failed_quic_data1.AddSocketDataToFactory(socket_factory_.get());
5833
5834 // Set up the last socket data used by the alternate network, which will
5835 // finish migration successfully. The request is rewritten to this new socket,
5836 // and the response to the request is read on this socket.
5837 MockQuicData socket_data2;
5838 socket_data2.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
5839 2, GetNthClientInitiatedStreamId(0),
5840 true, true, &header_stream_offset));
5841 socket_data2.AddRead(
5842 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
5843 false, false));
5844 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5845 socket_data2.AddWrite(SYNCHRONOUS,
5846 client_maker_.MakeAckAndRstPacket(
5847 3, false, GetNthClientInitiatedStreamId(0),
5848 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
5849 socket_data2.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:225850
5851 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:455852 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:335853 EXPECT_EQ(ERR_IO_PENDING,
5854 request.Request(host_port_pair_, version_, privacy_mode_,
5855 DEFAULT_PRIORITY, SocketTag(),
5856 /*cert_verify_flags=*/0, url_, net_log_,
5857 &net_error_details_, callback_.callback()));
jri9f303712016-09-13 01:10:225858 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:245859 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:225860 EXPECT_TRUE(stream.get());
5861
5862 // Cause QUIC stream to be created.
5863 HttpRequestInfo request_info;
5864 request_info.method = "GET";
5865 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:395866 request_info.traffic_annotation =
5867 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:275868 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:395869 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:225870
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
Zhongyi Shi7f1d9212018-06-22 23:24:365876 // Send GET request on stream.
5877 // This should encounter a write error on network 1,
5878 // then migrate to network 2, which encounters another write error,
5879 // and migrate again to network 1, which encoutners one more write error.
5880 // Finally the session migrates to network 2 successfully.
jri9f303712016-09-13 01:10:225881 HttpResponseInfo response;
5882 HttpRequestHeaders request_headers;
5883 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5884 callback_.callback()));
jri9f303712016-09-13 01:10:225885
jri9f303712016-09-13 01:10:225886 base::RunLoop().RunUntilIdle();
Zhongyi Shi7f1d9212018-06-22 23:24:365887 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5888 EXPECT_EQ(1u, session->GetNumActiveStreams());
jri9f303712016-09-13 01:10:225889
Zhongyi Shi7f1d9212018-06-22 23:24:365890 // Verify that response headers on the migrated socket were delivered to the
5891 // stream.
5892 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
5893 EXPECT_EQ(200, response.headers->response_code());
jri9f303712016-09-13 01:10:225894
5895 stream.reset();
Zhongyi Shi7f1d9212018-06-22 23:24:365896 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
5897 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
5898 EXPECT_TRUE(failed_quic_data2.AllReadDataConsumed());
5899 EXPECT_TRUE(failed_quic_data2.AllWriteDataConsumed());
5900 EXPECT_TRUE(failed_quic_data1.AllReadDataConsumed());
5901 EXPECT_TRUE(failed_quic_data1.AllWriteDataConsumed());
5902 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
5903 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
jri9f303712016-09-13 01:10:225904}
5905
5906TEST_P(QuicStreamFactoryTest, MigrateSessionOnMultipleWriteErrorsSyncSync) {
Zhongyi Shi7f1d9212018-06-22 23:24:365907 TestMigrationOnMultipleWriteErrors(
5908 /*write_error_mode_on_old_network*/ SYNCHRONOUS,
5909 /*write_error_mode_on_new_network*/ SYNCHRONOUS);
jri9f303712016-09-13 01:10:225910}
5911
5912TEST_P(QuicStreamFactoryTest, MigrateSessionOnMultipleWriteErrorsSyncAsync) {
Zhongyi Shi7f1d9212018-06-22 23:24:365913 TestMigrationOnMultipleWriteErrors(
5914 /*write_error_mode_on_old_network*/ SYNCHRONOUS,
5915 /*write_error_mode_on_new_network*/ ASYNC);
jri9f303712016-09-13 01:10:225916}
5917
5918TEST_P(QuicStreamFactoryTest, MigrateSessionOnMultipleWriteErrorsAsyncSync) {
Zhongyi Shi7f1d9212018-06-22 23:24:365919 TestMigrationOnMultipleWriteErrors(
5920 /*write_error_mode_on_old_network*/ ASYNC,
5921 /*write_error_mode_on_new_network*/ SYNCHRONOUS);
jri9f303712016-09-13 01:10:225922}
5923
5924TEST_P(QuicStreamFactoryTest, MigrateSessionOnMultipleWriteErrorsAsyncAsync) {
Zhongyi Shi7f1d9212018-06-22 23:24:365925 TestMigrationOnMultipleWriteErrors(
5926 /*write_error_mode_on_old_network*/ ASYNC,
5927 /*write_error_mode_on_new_network*/ ASYNC);
jri9f303712016-09-13 01:10:225928}
5929
Zhongyi Shi6abe33812018-07-24 19:43:115930// Verifies that a connection is closed when connection migration is triggered
5931// on network being disconnected and the handshake is not confirmed.
5932TEST_P(QuicStreamFactoryTest, NoMigrationBeforeHandshakeOnNetworkDisconnected) {
5933 InitializeConnectionMigrationV2Test(
5934 {kDefaultNetworkForTests, kNewNetworkForTests});
5935
Zhongyi Shi879659422018-08-02 17:58:255936 // Use cold start mode to do crypto connect, and send CHLO packet on wire.
Zhongyi Shi6abe33812018-07-24 19:43:115937 crypto_client_stream_factory_.set_handshake_mode(
Zhongyi Shi879659422018-08-02 17:58:255938 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
Zhongyi Shi6abe33812018-07-24 19:43:115939
Zhongyi Shi6abe33812018-07-24 19:43:115940 MockQuicData socket_data;
Zhongyi Shi879659422018-08-02 17:58:255941 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5068bb02018-08-03 02:44:095942 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
Zhongyi Shi6abe33812018-07-24 19:43:115943 socket_data.AddSocketDataToFactory(socket_factory_.get());
5944
5945 // Create request and QuicHttpStream.
5946 QuicStreamRequest request(factory_.get());
5947 EXPECT_EQ(ERR_IO_PENDING,
5948 request.Request(host_port_pair_, version_, privacy_mode_,
5949 DEFAULT_PRIORITY, SocketTag(),
5950 /*cert_verify_flags=*/0, url_, net_log_,
5951 &net_error_details_, callback_.callback()));
5952 // Deliver the network notification, which should cause the connection to be
5953 // closed.
5954 scoped_mock_network_change_notifier_->mock_network_change_notifier()
5955 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
5956 EXPECT_EQ(ERR_NETWORK_CHANGED, callback_.WaitForResult());
Zhongyi Shi4293b142018-07-25 00:33:575957
Zhongyi Shi6abe33812018-07-24 19:43:115958 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5959 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
Zhongyi Shi4293b142018-07-25 00:33:575960 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5961 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
Zhongyi Shi6abe33812018-07-24 19:43:115962}
5963
Zhongyi Shib24001c02018-06-18 20:01:525964// Sets up the connection migration test where network change notification is
5965// queued BEFORE connection migration attempt on write error is posted.
5966void QuicStreamFactoryTestBase::
5967 TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
5968 bool disconnected) {
5969 InitializeConnectionMigrationV2Test(
jried79618b2016-07-02 03:18:525970 {kDefaultNetworkForTests, kNewNetworkForTests});
5971 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5972 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5973 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5974
rcha00569732016-08-27 11:09:365975 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525976 quic::QuicStreamOffset header_stream_offset = 0;
rcha00569732016-08-27 11:09:365977 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
rch5cb522462017-04-25 20:18:365978 socket_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435979 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
rcha00569732016-08-27 11:09:365980 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:175981 socket_data.AddSocketDataToFactory(socket_factory_.get());
jried79618b2016-07-02 03:18:525982
5983 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:455984 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:335985 EXPECT_EQ(ERR_IO_PENDING,
5986 request.Request(host_port_pair_, version_, privacy_mode_,
5987 DEFAULT_PRIORITY, SocketTag(),
5988 /*cert_verify_flags=*/0, url_, net_log_,
5989 &net_error_details_, callback_.callback()));
jried79618b2016-07-02 03:18:525990 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:245991 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jried79618b2016-07-02 03:18:525992 EXPECT_TRUE(stream.get());
5993
5994 // Cause QUIC stream to be created.
5995 HttpRequestInfo request_info;
5996 request_info.method = "GET";
5997 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:395998 request_info.traffic_annotation =
5999 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276000 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396001 net_log_, CompletionOnceCallback()));
jried79618b2016-07-02 03:18:526002
6003 // Ensure that session is alive and active.
6004 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6005 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6006 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6007
6008 // Set up second socket data provider that is used after
6009 // migration. The request is rewritten to this new socket, and the
6010 // response to the request is read on this new socket.
rcha00569732016-08-27 11:09:366011 MockQuicData socket_data1;
Zhongyi Shi32f2fd02018-04-16 18:23:436012 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
6013 2, GetNthClientInitiatedStreamId(0),
6014 true, true, &header_stream_offset));
6015 socket_data1.AddRead(
6016 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
6017 false, false));
rcha00569732016-08-27 11:09:366018 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436019 socket_data1.AddWrite(SYNCHRONOUS,
6020 client_maker_.MakeAckAndRstPacket(
6021 3, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:526022 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:176023 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jried79618b2016-07-02 03:18:526024
jri9f303712016-09-13 01:10:226025 // First queue a network change notification in the message loop.
6026 if (disconnected) {
6027 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6028 ->QueueNetworkDisconnected(kDefaultNetworkForTests);
6029 } else {
6030 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6031 ->QueueNetworkMadeDefault(kNewNetworkForTests);
6032 }
6033 // Send GET request on stream. This should cause a write error,
6034 // which triggers a connection migration attempt. This will queue a
6035 // migration attempt behind the notification in the message loop.
jried79618b2016-07-02 03:18:526036 HttpResponseInfo response;
6037 HttpRequestHeaders request_headers;
6038 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6039 callback_.callback()));
6040
jried79618b2016-07-02 03:18:526041 base::RunLoop().RunUntilIdle();
Zhongyi Shia7dd46b2018-07-12 22:59:296042 // Verify the session is still alive and not marked as going away post
6043 // migration.
jried79618b2016-07-02 03:18:526044 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:296045 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jried79618b2016-07-02 03:18:526046 EXPECT_EQ(1u, session->GetNumActiveStreams());
6047
6048 // Verify that response headers on the migrated socket were delivered to the
6049 // stream.
6050 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6051 EXPECT_EQ(200, response.headers->response_code());
6052
6053 stream.reset();
6054
6055 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6056 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6057 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6058 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6059}
6060
Zhongyi Shib24001c02018-06-18 20:01:526061// This test verifies that session attempts connection migration successfully
6062// with signals delivered in the following order (alternate network is always
6063// available):
6064// - a notification that default network is disconnected is queued.
6065// - write error is triggered: session posts a task to attempt connection
6066// migration, |migration_pending_| set to true.
6067// - default network disconnected is delivered: session immediately migrates to
6068// the alternate network, |migration_pending_| set to false.
Zhongyi Shif3d6cddb2018-07-11 03:30:026069// - connection migration on write error attempt aborts: writer encountered
6070// error is no longer in active use.
jri9f303712016-09-13 01:10:226071TEST_P(QuicStreamFactoryTest,
Zhongyi Shib24001c02018-06-18 20:01:526072 MigrateOnNetworkDisconnectedWithWriteErrorQueuedLater) {
6073 TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
6074 /*disconnected=*/true);
jri9f303712016-09-13 01:10:226075}
6076
Zhongyi Shib24001c02018-06-18 20:01:526077// This test verifies that session attempts connection migration successfully
6078// with signals delivered in the following order (alternate network is always
6079// available):
6080// - a notification that alternate network is made default is queued.
6081// - write error is triggered: session posts a task to attempt connection
6082// migration, block future migrations.
6083// - new default notification is delivered: migrate back timer spins and task is
6084// posted to migrate to the new default network.
6085// - connection migration on write error attempt proceeds successfully: session
6086// is
6087// marked as going away, future migrations unblocked.
6088// - migrate back to default network task executed: session is already on the
6089// default network, no-op.
jri9f303712016-09-13 01:10:226090TEST_P(QuicStreamFactoryTest,
Zhongyi Shib24001c02018-06-18 20:01:526091 MigrateOnWriteErrorWithNetworkMadeDefaultQueuedEarlier) {
6092 TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
6093 /*disconnected=*/false);
jri9f303712016-09-13 01:10:226094}
6095
Zhongyi Shi1e2bc742018-06-16 02:06:076096// Sets up the connection migration test where network change notification is
6097// queued AFTER connection migration attempt on write error is posted.
6098void QuicStreamFactoryTestBase::
6099 TestMigrationOnWriteErrorWithNotificationQueuedLater(bool disconnected) {
Zhongyi Shi1a054612018-06-14 04:59:086100 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:226101 {kDefaultNetworkForTests, kNewNetworkForTests});
jried79618b2016-07-02 03:18:526102 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6103 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri9f303712016-09-13 01:10:226104 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jried79618b2016-07-02 03:18:526105
rcha00569732016-08-27 11:09:366106 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526107 quic::QuicStreamOffset header_stream_offset = 0;
rcha00569732016-08-27 11:09:366108 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
rch5cb522462017-04-25 20:18:366109 socket_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436110 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
rcha00569732016-08-27 11:09:366111 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:176112 socket_data.AddSocketDataToFactory(socket_factory_.get());
jried79618b2016-07-02 03:18:526113
6114 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456115 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336116 EXPECT_EQ(ERR_IO_PENDING,
6117 request.Request(host_port_pair_, version_, privacy_mode_,
6118 DEFAULT_PRIORITY, SocketTag(),
6119 /*cert_verify_flags=*/0, url_, net_log_,
6120 &net_error_details_, callback_.callback()));
jried79618b2016-07-02 03:18:526121 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246122 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jried79618b2016-07-02 03:18:526123 EXPECT_TRUE(stream.get());
6124
6125 // Cause QUIC stream to be created.
6126 HttpRequestInfo request_info;
6127 request_info.method = "GET";
6128 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396129 request_info.traffic_annotation =
6130 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276131 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396132 net_log_, CompletionOnceCallback()));
jried79618b2016-07-02 03:18:526133
6134 // Ensure that session is alive and active.
6135 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6136 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6137 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6138
jri9f303712016-09-13 01:10:226139 // Set up second socket data provider that is used after
6140 // migration. The request is rewritten to this new socket, and the
6141 // response to the request is read on this new socket.
6142 MockQuicData socket_data1;
Zhongyi Shi32f2fd02018-04-16 18:23:436143 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
6144 2, GetNthClientInitiatedStreamId(0),
6145 true, true, &header_stream_offset));
6146 socket_data1.AddRead(
6147 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
6148 false, false));
jri9f303712016-09-13 01:10:226149 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436150 socket_data1.AddWrite(SYNCHRONOUS,
6151 client_maker_.MakeAckAndRstPacket(
6152 3, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:526153 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:176154 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:226155
6156 // Send GET request on stream. This should cause a write error,
6157 // which triggers a connection migration attempt. This will queue a
6158 // migration attempt in the message loop.
jried79618b2016-07-02 03:18:526159 HttpResponseInfo response;
6160 HttpRequestHeaders request_headers;
jri9f303712016-09-13 01:10:226161 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6162 callback_.callback()));
jried79618b2016-07-02 03:18:526163
jri9f303712016-09-13 01:10:226164 // Now queue a network change notification in the message loop behind
6165 // the migration attempt.
6166 if (disconnected) {
6167 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6168 ->QueueNetworkDisconnected(kDefaultNetworkForTests);
6169 } else {
6170 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6171 ->QueueNetworkMadeDefault(kNewNetworkForTests);
6172 }
6173
6174 base::RunLoop().RunUntilIdle();
Zhongyi Shia7dd46b2018-07-12 22:59:296175 // Verify session is still alive and not marked as going away.
jri9f303712016-09-13 01:10:226176 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:296177 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri9f303712016-09-13 01:10:226178 EXPECT_EQ(1u, session->GetNumActiveStreams());
6179
6180 // Verify that response headers on the migrated socket were delivered to the
6181 // stream.
6182 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6183 EXPECT_EQ(200, response.headers->response_code());
6184
6185 stream.reset();
jried79618b2016-07-02 03:18:526186
6187 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6188 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
jri9f303712016-09-13 01:10:226189 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6190 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
jried79618b2016-07-02 03:18:526191}
6192
Zhongyi Shi1e2bc742018-06-16 02:06:076193// This test verifies that session attempts connection migration successfully
6194// with signals delivered in the following order (alternate network is always
6195// available):
6196// - write error is triggered: session posts a task to complete connection
6197// migration.
6198// - a notification that alternate network is made default is queued.
6199// - connection migration attempt proceeds successfully, session is marked as
6200// going away.
6201// - new default notification is delivered after connection migration has been
6202// completed.
jri9f303712016-09-13 01:10:226203TEST_P(QuicStreamFactoryTest,
Zhongyi Shi1e2bc742018-06-16 02:06:076204 MigrateOnWriteErrorWithNetworkMadeDefaultQueuedLater) {
6205 TestMigrationOnWriteErrorWithNotificationQueuedLater(/*disconnected=*/false);
jried79618b2016-07-02 03:18:526206}
6207
Zhongyi Shi1e2bc742018-06-16 02:06:076208// This test verifies that session attempts connection migration successfully
6209// with signals delivered in the following order (alternate network is always
6210// available):
6211// - write error is triggered: session posts a task to complete connection
6212// migration.
6213// - a notification that default network is diconnected is queued.
6214// - connection migration attempt proceeds successfully, session is marked as
6215// going away.
6216// - disconnect notification is delivered after connection migration has been
6217// completed.
jri9f303712016-09-13 01:10:226218TEST_P(QuicStreamFactoryTest,
Zhongyi Shi1e2bc742018-06-16 02:06:076219 MigrateOnWriteErrorWithNetworkDisconnectedQueuedLater) {
6220 TestMigrationOnWriteErrorWithNotificationQueuedLater(/*disconnected=*/true);
jried79618b2016-07-02 03:18:526221}
6222
Zhongyi Shia3810c52018-06-15 23:07:196223// This tests connection migration on write error with signals delivered in the
6224// following order:
6225// - a synchronous/asynchronous write error is triggered base on
Zhongyi Shif3d6cddb2018-07-11 03:30:026226// |write_error_mode|: connection migration attempt is posted.
6227// - old default network disconnects, migration waits for a new network.
Zhongyi Shia3810c52018-06-15 23:07:196228// - after a pause, new network is connected: session will migrate to new
6229// network immediately.
Zhongyi Shif3d6cddb2018-07-11 03:30:026230// - migration on writer error is exectued and aborts as writer passed in is no
6231// longer active in use.
Zhongyi Shia3810c52018-06-15 23:07:196232// - new network is made default.
jri5b785512016-09-13 04:29:116233void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorPauseBeforeConnected(
6234 IoMode write_error_mode) {
Zhongyi Shia3810c52018-06-15 23:07:196235 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri5b785512016-09-13 04:29:116236 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6237 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6238 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6239
Zhongyi Shia3810c52018-06-15 23:07:196240 // Use the test task runner.
6241 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
6242
jri5b785512016-09-13 04:29:116243 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526244 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shia3810c52018-06-15 23:07:196245 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
rch5cb522462017-04-25 20:18:366246 socket_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436247 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Zhongyi Shia3810c52018-06-15 23:07:196248 socket_data.AddWrite(write_error_mode, ERR_FAILED);
Zhongyi Shi5f587cc2017-11-21 23:24:176249 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri5b785512016-09-13 04:29:116250
6251 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456252 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336253 EXPECT_EQ(ERR_IO_PENDING,
6254 request.Request(host_port_pair_, version_, privacy_mode_,
6255 DEFAULT_PRIORITY, SocketTag(),
6256 /*cert_verify_flags=*/0, url_, net_log_,
6257 &net_error_details_, callback_.callback()));
Zhongyi Shia3810c52018-06-15 23:07:196258 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:246259 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri5b785512016-09-13 04:29:116260 EXPECT_TRUE(stream.get());
6261
6262 // Cause QUIC stream to be created.
6263 HttpRequestInfo request_info;
6264 request_info.method = "GET";
Zhongyi Shia3810c52018-06-15 23:07:196265 request_info.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:396266 request_info.traffic_annotation =
6267 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276268 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396269 net_log_, CompletionOnceCallback()));
jri5b785512016-09-13 04:29:116270
6271 // Ensure that session is alive and active.
6272 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6273 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6274 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6275
Zhongyi Shia3810c52018-06-15 23:07:196276 // Send GET request on stream.
jri5b785512016-09-13 04:29:116277 HttpResponseInfo response;
6278 HttpRequestHeaders request_headers;
6279 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6280 callback_.callback()));
6281
Zhongyi Shia3810c52018-06-15 23:07:196282 // The connection should still be alive, not marked as going away.
jri5b785512016-09-13 04:29:116283 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6284 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6285 EXPECT_EQ(1u, session->GetNumActiveStreams());
6286 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
6287
Zhongyi Shia3810c52018-06-15 23:07:196288 // Set up second socket data provider that is used after migration.
6289 // The response to the earlier request is read on this new socket.
jri5b785512016-09-13 04:29:116290 MockQuicData socket_data1;
Zhongyi Shi32f2fd02018-04-16 18:23:436291 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
6292 2, GetNthClientInitiatedStreamId(0),
6293 true, true, &header_stream_offset));
6294 socket_data1.AddRead(
6295 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
6296 false, false));
jri5b785512016-09-13 04:29:116297 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436298 socket_data1.AddWrite(SYNCHRONOUS,
6299 client_maker_.MakeAckAndRstPacket(
6300 3, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:526301 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:176302 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri5b785512016-09-13 04:29:116303
Zhongyi Shia3810c52018-06-15 23:07:196304 // On a DISCONNECTED notification, nothing happens.
6305 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6306 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
6307 // Add a new network and notify the stream factory of a new connected network.
6308 // This causes a PING packet to be sent over the new network.
jri5b785512016-09-13 04:29:116309 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6310 ->SetConnectedNetworksList({kNewNetworkForTests});
6311 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6312 ->NotifyNetworkConnected(kNewNetworkForTests);
6313
Zhongyi Shia3810c52018-06-15 23:07:196314 // Ensure that the session is still alive.
jri5b785512016-09-13 04:29:116315 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia3810c52018-06-15 23:07:196316 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:116317 EXPECT_EQ(1u, session->GetNumActiveStreams());
6318
Zhongyi Shia3810c52018-06-15 23:07:196319 // Run the message loop migration for write error can finish.
6320 runner_->RunUntilIdle();
6321
6322 // Response headers are received over the new network.
jri5b785512016-09-13 04:29:116323 EXPECT_THAT(callback_.WaitForResult(), IsOk());
6324 EXPECT_EQ(200, response.headers->response_code());
6325
Zhongyi Shia3810c52018-06-15 23:07:196326 // Check that the session is still alive.
6327 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
jri5b785512016-09-13 04:29:116328 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shia3810c52018-06-15 23:07:196329
6330 // There should be no posted tasks not executed, no way to migrate back to
6331 // default network.
6332 EXPECT_TRUE(runner_->GetPostedTasks().empty());
6333
6334 // Receive signal to mark new network as default.
6335 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6336 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri5b785512016-09-13 04:29:116337
6338 stream.reset();
jri5b785512016-09-13 04:29:116339 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6340 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6341 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6342 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
jri5b785512016-09-13 04:29:116343}
6344
6345TEST_P(QuicStreamFactoryTest,
Zhongyi Shia3810c52018-06-15 23:07:196346 MigrateSessionOnSyncWriteErrorPauseBeforeConnected) {
jri5b785512016-09-13 04:29:116347 TestMigrationOnWriteErrorPauseBeforeConnected(SYNCHRONOUS);
6348}
6349
6350TEST_P(QuicStreamFactoryTest,
Zhongyi Shia3810c52018-06-15 23:07:196351 MigrateSessionOnAsyncWriteErrorPauseBeforeConnected) {
jri5b785512016-09-13 04:29:116352 TestMigrationOnWriteErrorPauseBeforeConnected(ASYNC);
6353}
6354
Zhongyi Shif3d6cddb2018-07-11 03:30:026355// This test verifies that when session successfully migrate to the alternate
6356// network, packet write error on the old writer will be ignored and will not
6357// trigger connection migration on write error.
6358TEST_P(QuicStreamFactoryTest, IgnoreWriteErrorFromOldWriterAfterMigration) {
6359 InitializeConnectionMigrationV2Test(
6360 {kDefaultNetworkForTests, kNewNetworkForTests});
6361 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6362 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6363 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6364
6365 // Using a testing task runner so that we can verify whether the migrate on
6366 // write error task is posted.
6367 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
6368 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
6369
6370 MockQuicData socket_data;
6371 quic::QuicStreamOffset header_stream_offset = 0;
6372 socket_data.AddWrite(
6373 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6374 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
6375 socket_data.AddWrite(ASYNC, ERR_ADDRESS_UNREACHABLE);
6376 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6377 socket_data.AddSocketDataToFactory(socket_factory_.get());
6378
6379 // Create request and QuicHttpStream.
6380 QuicStreamRequest request(factory_.get());
6381 EXPECT_EQ(ERR_IO_PENDING,
6382 request.Request(host_port_pair_, version_, privacy_mode_,
6383 DEFAULT_PRIORITY, SocketTag(),
6384 /*cert_verify_flags=*/0, url_, net_log_,
6385 &net_error_details_, callback_.callback()));
6386 EXPECT_EQ(OK, callback_.WaitForResult());
6387 std::unique_ptr<HttpStream> stream = CreateStream(&request);
6388 EXPECT_TRUE(stream.get());
6389
6390 // Cause QUIC stream to be created.
6391 HttpRequestInfo request_info;
6392 request_info.method = "GET";
6393 request_info.url = GURL("https://www.example.org/");
6394 request_info.traffic_annotation =
6395 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6396 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
6397 net_log_, CompletionOnceCallback()));
6398
6399 // Ensure that session is alive and active.
6400 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6401 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6402 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6403
6404 // Set up second socket data provider that is used after
6405 // migration. The response to the request is read on this new socket.
6406 MockQuicData socket_data1;
6407 socket_data1.AddWrite(
6408 SYNCHRONOUS, client_maker_.MakePingPacket(3, /*include_version=*/true));
6409 socket_data1.AddRead(
6410 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
6411 false, false));
6412 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6413 socket_data1.AddWrite(SYNCHRONOUS,
6414 client_maker_.MakeAckAndRstPacket(
6415 4, false, GetNthClientInitiatedStreamId(0),
6416 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
6417 socket_data1.AddSocketDataToFactory(socket_factory_.get());
6418
6419 // Send GET request on stream.
6420 HttpResponseInfo response;
6421 HttpRequestHeaders request_headers;
6422 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6423 callback_.callback()));
6424
6425 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
6426 // Now notify network is disconnected, cause the migration to complete
6427 // immediately.
6428 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6429 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
6430 // There will be two pending task, one will complete migration with no delay
6431 // and the other will attempt to migrate back to the default network with
6432 // delay.
6433 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
6434
6435 // Complete migration.
6436 task_runner->RunUntilIdle();
6437 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
6438
6439 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6440 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6441 EXPECT_EQ(1u, session->GetNumActiveStreams());
6442
6443 // Verify that response headers on the migrated socket were delivered to the
6444 // stream.
6445 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6446 EXPECT_EQ(200, response.headers->response_code());
6447
6448 // Resume the old socket data, a write error will be delivered to the old
6449 // packet writer. Verify no additional task is posted.
6450 socket_data.Resume();
6451 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
6452
6453 stream.reset();
6454 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6455 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6456 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6457}
6458
6459// This test verifies that when session successfully migrate to the alternate
6460// network, packet read error on the old reader will be ignored and will not
6461// close the connection.
6462TEST_P(QuicStreamFactoryTest, IgnoreReadErrorFromOldReaderAfterMigration) {
6463 InitializeConnectionMigrationV2Test(
6464 {kDefaultNetworkForTests, kNewNetworkForTests});
6465 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6466 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6467 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6468
6469 // Using a testing task runner.
6470 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
6471 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
6472
6473 MockQuicData socket_data;
6474 quic::QuicStreamOffset header_stream_offset = 0;
6475 socket_data.AddWrite(
6476 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6477 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
6478 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE);
6479 socket_data.AddSocketDataToFactory(socket_factory_.get());
6480
6481 // Create request and QuicHttpStream.
6482 QuicStreamRequest request(factory_.get());
6483 EXPECT_EQ(ERR_IO_PENDING,
6484 request.Request(host_port_pair_, version_, privacy_mode_,
6485 DEFAULT_PRIORITY, SocketTag(),
6486 /*cert_verify_flags=*/0, url_, net_log_,
6487 &net_error_details_, callback_.callback()));
6488 EXPECT_EQ(OK, callback_.WaitForResult());
6489 std::unique_ptr<HttpStream> stream = CreateStream(&request);
6490 EXPECT_TRUE(stream.get());
6491
6492 // Cause QUIC stream to be created.
6493 HttpRequestInfo request_info;
6494 request_info.method = "GET";
6495 request_info.url = GURL("https://www.example.org/");
6496 request_info.traffic_annotation =
6497 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6498 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
6499 net_log_, CompletionOnceCallback()));
6500
6501 // Ensure that session is alive and active.
6502 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6503 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6504 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6505
6506 // Set up second socket data provider that is used after
6507 // migration. The request is written to this new socket, and the
6508 // response to the request is read on this new socket.
6509 MockQuicData socket_data1;
6510 socket_data1.AddWrite(
6511 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
6512 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
6513 3, GetNthClientInitiatedStreamId(0),
6514 true, true, &header_stream_offset));
6515 socket_data1.AddRead(
6516 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
6517 false, false));
6518 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6519 socket_data1.AddWrite(SYNCHRONOUS,
6520 client_maker_.MakeAckAndRstPacket(
6521 4, false, GetNthClientInitiatedStreamId(0),
6522 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
6523 socket_data1.AddSocketDataToFactory(socket_factory_.get());
6524
6525 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
6526 // Now notify network is disconnected, cause the migration to complete
6527 // immediately.
6528 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6529 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
6530 // There will be two pending task, one will complete migration with no delay
6531 // and the other will attempt to migrate back to the default network with
6532 // delay.
6533 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
6534
6535 // Complete migration.
6536 task_runner->RunUntilIdle();
6537 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
6538
6539 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6540 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6541 EXPECT_EQ(1u, session->GetNumActiveStreams());
6542
6543 // Send GET request on stream.
6544 HttpResponseInfo response;
6545 HttpRequestHeaders request_headers;
6546 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6547 callback_.callback()));
6548
6549 // Verify that response headers on the migrated socket were delivered to the
6550 // stream.
6551 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
6552 EXPECT_EQ(OK, callback_.WaitForResult());
6553 EXPECT_EQ(200, response.headers->response_code());
6554
6555 // Resume the old socket data, a read error will be delivered to the old
6556 // packet reader. Verify that the session is not affected.
6557 socket_data.Resume();
6558 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
6559 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6560 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6561 EXPECT_EQ(1u, session->GetNumActiveStreams());
6562
6563 stream.reset();
6564 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6565 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6566 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6567 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6568}
6569
6570// This test verifies that after migration on network is executed, packet
6571// read error on the old reader will be ignored and will not close the
6572// connection.
6573TEST_P(QuicStreamFactoryTest, IgnoreReadErrorOnOldReaderDuringMigration) {
6574 InitializeConnectionMigrationV2Test(
6575 {kDefaultNetworkForTests, kNewNetworkForTests});
6576 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6577 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6578 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6579
6580 // Using a testing task runner.
6581 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
6582 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
6583
6584 MockQuicData socket_data;
6585 quic::QuicStreamOffset header_stream_offset = 0;
6586 socket_data.AddWrite(
6587 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6588 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
6589 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE);
6590 socket_data.AddSocketDataToFactory(socket_factory_.get());
6591
6592 // Create request and QuicHttpStream.
6593 QuicStreamRequest request(factory_.get());
6594 EXPECT_EQ(ERR_IO_PENDING,
6595 request.Request(host_port_pair_, version_, privacy_mode_,
6596 DEFAULT_PRIORITY, SocketTag(),
6597 /*cert_verify_flags=*/0, url_, net_log_,
6598 &net_error_details_, callback_.callback()));
6599 EXPECT_EQ(OK, callback_.WaitForResult());
6600 std::unique_ptr<HttpStream> stream = CreateStream(&request);
6601 EXPECT_TRUE(stream.get());
6602
6603 // Cause QUIC stream to be created.
6604 HttpRequestInfo request_info;
6605 request_info.method = "GET";
6606 request_info.url = GURL("https://www.example.org/");
6607 request_info.traffic_annotation =
6608 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6609 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
6610 net_log_, CompletionOnceCallback()));
6611
6612 // Ensure that session is alive and active.
6613 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6614 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6615 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6616
6617 // Set up second socket data provider that is used after
6618 // migration. The request is written to this new socket, and the
6619 // response to the request is read on this new socket.
6620 MockQuicData socket_data1;
6621 socket_data1.AddWrite(
6622 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
6623 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
6624 3, GetNthClientInitiatedStreamId(0),
6625 true, true, &header_stream_offset));
6626 socket_data1.AddRead(
6627 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
6628 false, false));
6629 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6630 socket_data1.AddWrite(SYNCHRONOUS,
6631 client_maker_.MakeAckAndRstPacket(
6632 4, false, GetNthClientInitiatedStreamId(0),
6633 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
6634 socket_data1.AddSocketDataToFactory(socket_factory_.get());
6635
6636 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
6637 // Now notify network is disconnected, cause the migration to complete
6638 // immediately.
6639 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6640 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
6641 // There will be two pending task, one will complete migration with no delay
6642 // and the other will attempt to migrate back to the default network with
6643 // delay.
6644 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
6645
6646 // Resume the old socket data, a read error will be delivered to the old
6647 // packet reader. Verify that the session is not affected.
6648 socket_data.Resume();
6649 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
6650 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6651 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6652 EXPECT_EQ(1u, session->GetNumActiveStreams());
6653
6654 // Complete migration.
6655 task_runner->RunUntilIdle();
6656 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
6657
6658 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6659 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6660 EXPECT_EQ(1u, session->GetNumActiveStreams());
6661
6662 // Send GET request on stream.
6663 HttpResponseInfo response;
6664 HttpRequestHeaders request_headers;
6665 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6666 callback_.callback()));
6667
6668 // Verify that response headers on the migrated socket were delivered to the
6669 // stream.
6670 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
6671 EXPECT_EQ(OK, callback_.WaitForResult());
6672 EXPECT_EQ(200, response.headers->response_code());
6673
6674 stream.reset();
6675 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6676 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6677 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6678 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6679}
6680
6681// This test verifies that after migration on write error is posted, packet
6682// read error on the old reader will be ignored and will not close the
6683// connection.
6684TEST_P(QuicStreamFactoryTest,
6685 IgnoreReadErrorOnOldReaderDuringPendingMigrationOnWriteError) {
6686 InitializeConnectionMigrationV2Test(
6687 {kDefaultNetworkForTests, kNewNetworkForTests});
6688 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6689 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6690 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6691
6692 // Using a testing task runner.
6693 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
6694 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
6695
6696 MockQuicData socket_data;
6697 quic::QuicStreamOffset header_stream_offset = 0;
6698 socket_data.AddWrite(
6699 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6700 socket_data.AddWrite(ASYNC, ERR_FAILED); // Write error.
6701 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE); // Read error.
6702 socket_data.AddSocketDataToFactory(socket_factory_.get());
6703
6704 // Create request and QuicHttpStream.
6705 QuicStreamRequest request(factory_.get());
6706 EXPECT_EQ(ERR_IO_PENDING,
6707 request.Request(host_port_pair_, version_, privacy_mode_,
6708 DEFAULT_PRIORITY, SocketTag(),
6709 /*cert_verify_flags=*/0, url_, net_log_,
6710 &net_error_details_, callback_.callback()));
6711 EXPECT_EQ(OK, callback_.WaitForResult());
6712 std::unique_ptr<HttpStream> stream = CreateStream(&request);
6713 EXPECT_TRUE(stream.get());
6714
6715 // Cause QUIC stream to be created.
6716 HttpRequestInfo request_info;
6717 request_info.method = "GET";
6718 request_info.url = GURL("https://www.example.org/");
6719 request_info.traffic_annotation =
6720 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6721 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
6722 net_log_, CompletionOnceCallback()));
6723
6724 // Ensure that session is alive and active.
6725 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6726 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6727 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6728
6729 // Set up second socket data provider that is used after
6730 // migration. The request is written to this new socket, and the
6731 // response to the request is read on this new socket.
6732 MockQuicData socket_data1;
6733 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
6734 2, GetNthClientInitiatedStreamId(0),
6735 true, true, &header_stream_offset));
6736 socket_data1.AddRead(
6737 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
6738 false, false));
6739
6740 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
6741 socket_data1.AddRead(ASYNC, ERR_FAILED); // Read error to close connection.
6742 socket_data1.AddSocketDataToFactory(socket_factory_.get());
6743
6744 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
6745 // Send GET request on stream.
6746 HttpResponseInfo response;
6747 HttpRequestHeaders request_headers;
6748 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6749 callback_.callback()));
6750 // Run the message loop to complete asynchronous write and read with errors.
6751 base::RunLoop().RunUntilIdle();
6752 // There will be one pending task to complete migration on write error.
6753 // Verify session is not closed with read error.
6754 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
6755 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6756 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6757 EXPECT_EQ(1u, session->GetNumActiveStreams());
6758
6759 // Complete migration.
6760 task_runner->RunUntilIdle();
Zhongyi Shia7dd46b2018-07-12 22:59:296761 // There will be one more task posted attempting to migrate back to the
6762 // default network.
6763 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
Zhongyi Shif3d6cddb2018-07-11 03:30:026764 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:296765 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shif3d6cddb2018-07-11 03:30:026766 EXPECT_EQ(1u, session->GetNumActiveStreams());
6767
6768 // Verify that response headers on the migrated socket were delivered to the
6769 // stream.
6770 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6771 EXPECT_EQ(200, response.headers->response_code());
6772
6773 // Resume to consume the read error on new socket, which will close
6774 // the connection.
6775 socket_data1.Resume();
6776
6777 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6778 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6779 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6780 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6781}
6782
Zhongyi Shi4ac9e1f2018-06-21 05:21:476783// Migrate on asynchronous write error, old network disconnects after alternate
6784// network connects.
6785TEST_P(QuicStreamFactoryTest,
6786 MigrateSessionOnWriteErrorWithDisconnectAfterConnectAysnc) {
6787 TestMigrationOnWriteErrorWithMultipleNotifications(
6788 ASYNC, /*disconnect_before_connect*/ false);
6789}
6790
6791// Migrate on synchronous write error, old network disconnects after alternate
6792// network connects.
6793TEST_P(QuicStreamFactoryTest,
6794 MigrateSessionOnWriteErrorWithDisconnectAfterConnectSync) {
6795 TestMigrationOnWriteErrorWithMultipleNotifications(
6796 SYNCHRONOUS, /*disconnect_before_connect*/ false);
6797}
6798
6799// Migrate on asynchronous write error, old network disconnects before alternate
6800// network connects.
6801TEST_P(QuicStreamFactoryTest,
6802 MigrateSessionOnWriteErrorWithDisconnectBeforeConnectAysnc) {
6803 TestMigrationOnWriteErrorWithMultipleNotifications(
6804 ASYNC, /*disconnect_before_connect*/ true);
6805}
6806
6807// Migrate on synchronous write error, old network disconnects before alternate
6808// network connects.
6809TEST_P(QuicStreamFactoryTest,
6810 MigrateSessionOnWriteErrorWithDisconnectBeforeConnectSync) {
6811 TestMigrationOnWriteErrorWithMultipleNotifications(
6812 SYNCHRONOUS, /*disconnect_before_connect*/ true);
6813}
6814
6815// Setps up test which verifies that session successfully migrate to alternate
6816// network with signals delivered in the following order:
6817// *NOTE* Signal (A) and (B) can reverse order based on
6818// |disconnect_before_connect|.
6819// - (No alternate network is connected) session connects to
6820// kDefaultNetworkForTests.
6821// - An async/sync write error is encountered based on |write_error_mode|:
6822// session posted task to migrate session on write error.
6823// - Posted task is executed, miration moves to pending state due to lack of
6824// alternate network.
6825// - (A) An alternate network is connected, pending migration completes.
6826// - (B) Old default network disconnects, no migration will be attempted as
Zhongyi Shi329f5cbd2018-06-22 23:51:186827// session has already migrate to the alternate network.
Zhongyi Shi4ac9e1f2018-06-21 05:21:476828// - The alternate network is made default.
jri5b785512016-09-13 04:29:116829void QuicStreamFactoryTestBase::
Zhongyi Shi4ac9e1f2018-06-21 05:21:476830 TestMigrationOnWriteErrorWithMultipleNotifications(
jri5b785512016-09-13 04:29:116831 IoMode write_error_mode,
Zhongyi Shi4ac9e1f2018-06-21 05:21:476832 bool disconnect_before_connect) {
Zhongyi Shi329f5cbd2018-06-22 23:51:186833 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri5b785512016-09-13 04:29:116834 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6835 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6836 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6837
6838 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526839 quic::QuicStreamOffset header_stream_offset = 0;
jri5b785512016-09-13 04:29:116840 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
rch5cb522462017-04-25 20:18:366841 socket_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436842 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Zhongyi Shi4ac9e1f2018-06-21 05:21:476843 socket_data.AddWrite(write_error_mode, ERR_FAILED); // Write error.
Zhongyi Shi5f587cc2017-11-21 23:24:176844 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri5b785512016-09-13 04:29:116845
6846 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456847 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336848 EXPECT_EQ(ERR_IO_PENDING,
6849 request.Request(host_port_pair_, version_, privacy_mode_,
6850 DEFAULT_PRIORITY, SocketTag(),
6851 /*cert_verify_flags=*/0, url_, net_log_,
6852 &net_error_details_, callback_.callback()));
jri5b785512016-09-13 04:29:116853 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246854 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri5b785512016-09-13 04:29:116855 EXPECT_TRUE(stream.get());
6856
6857 // Cause QUIC stream to be created.
6858 HttpRequestInfo request_info;
6859 request_info.method = "GET";
6860 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396861 request_info.traffic_annotation =
6862 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276863 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396864 net_log_, CompletionOnceCallback()));
jri5b785512016-09-13 04:29:116865
6866 // Ensure that session is alive and active.
6867 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6868 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6869 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6870
6871 // Send GET request on stream. This should cause a write error, which triggers
6872 // a connection migration attempt.
6873 HttpResponseInfo response;
6874 HttpRequestHeaders request_headers;
6875 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6876 callback_.callback()));
Zhongyi Shi4ac9e1f2018-06-21 05:21:476877 // Run the message loop so that posted task to migrate to socket will be
6878 // executed. A new task will be posted to wait for a new network.
jri5b785512016-09-13 04:29:116879 base::RunLoop().RunUntilIdle();
6880
6881 // In this particular code path, the network will not yet be marked
6882 // as going away and the session will still be alive.
6883 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6884 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6885 EXPECT_EQ(1u, session->GetNumActiveStreams());
6886 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
6887
6888 // Set up second socket data provider that is used after
6889 // migration. The request is rewritten to this new socket, and the
6890 // response to the request is read on this new socket.
6891 MockQuicData socket_data1;
Zhongyi Shi32f2fd02018-04-16 18:23:436892 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
6893 2, GetNthClientInitiatedStreamId(0),
6894 true, true, &header_stream_offset));
6895 socket_data1.AddRead(
6896 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
6897 false, false));
jri5b785512016-09-13 04:29:116898 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436899 socket_data1.AddWrite(SYNCHRONOUS,
6900 client_maker_.MakeAckAndRstPacket(
6901 3, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:526902 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:176903 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri5b785512016-09-13 04:29:116904
6905 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6906 ->SetConnectedNetworksList(
6907 {kDefaultNetworkForTests, kNewNetworkForTests});
Zhongyi Shi4ac9e1f2018-06-21 05:21:476908 if (disconnect_before_connect) {
6909 // Now deliver a DISCONNECT notification.
jri5b785512016-09-13 04:29:116910 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6911 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
Zhongyi Shi4ac9e1f2018-06-21 05:21:476912
6913 // Now deliver a CONNECTED notification and completes migration.
jri5b785512016-09-13 04:29:116914 scoped_mock_network_change_notifier_->mock_network_change_notifier()
Zhongyi Shi4ac9e1f2018-06-21 05:21:476915 ->NotifyNetworkConnected(kNewNetworkForTests);
6916 } else {
6917 // Now deliver a CONNECTED notification and completes migration.
6918 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6919 ->NotifyNetworkConnected(kNewNetworkForTests);
6920
6921 // Now deliver a DISCONNECT notification.
6922 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6923 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
jri5b785512016-09-13 04:29:116924 }
jri5b785512016-09-13 04:29:116925 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shi329f5cbd2018-06-22 23:51:186926 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:116927 EXPECT_EQ(1u, session->GetNumActiveStreams());
6928
6929 // This is the callback for the response headers that returned
6930 // pending previously, because no result was available. Check that
6931 // the result is now available due to the successful migration.
6932 EXPECT_THAT(callback_.WaitForResult(), IsOk());
6933 EXPECT_EQ(200, response.headers->response_code());
6934
Zhongyi Shi4ac9e1f2018-06-21 05:21:476935 // Deliver a MADEDEFAULT notification.
jri5b785512016-09-13 04:29:116936 scoped_mock_network_change_notifier_->mock_network_change_notifier()
Zhongyi Shi4ac9e1f2018-06-21 05:21:476937 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri5b785512016-09-13 04:29:116938
zhongyi98d6a9262017-05-19 02:47:456939 QuicStreamRequest request2(factory_.get());
Zhongyi Shi329f5cbd2018-06-22 23:51:186940 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_, privacy_mode_,
6941 DEFAULT_PRIORITY, SocketTag(),
6942 /*cert_verify_flags=*/0, url_, net_log_,
6943 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:246944 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
jri5b785512016-09-13 04:29:116945 EXPECT_TRUE(stream2.get());
6946
6947 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi329f5cbd2018-06-22 23:51:186948 EXPECT_EQ(session, GetActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:116949
6950 stream.reset();
6951 stream2.reset();
6952
6953 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6954 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6955 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6956 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
jri5b785512016-09-13 04:29:116957}
6958
jri217455a12016-07-13 20:15:096959TEST_P(QuicStreamFactoryTest, ServerMigration) {
6960 allow_server_migration_ = true;
6961 Initialize();
6962
6963 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6964 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6965 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6966
rcha00569732016-08-27 11:09:366967 MockQuicData socket_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526968 quic::QuicStreamOffset header_stream_offset = 0;
rcha00569732016-08-27 11:09:366969 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
rch5cb522462017-04-25 20:18:366970 socket_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436971 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6972 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
6973 2, GetNthClientInitiatedStreamId(0),
6974 true, true, &header_stream_offset));
Zhongyi Shi5f587cc2017-11-21 23:24:176975 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri217455a12016-07-13 20:15:096976
6977 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456978 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336979 EXPECT_EQ(ERR_IO_PENDING,
6980 request.Request(host_port_pair_, version_, privacy_mode_,
6981 DEFAULT_PRIORITY, SocketTag(),
6982 /*cert_verify_flags=*/0, url_, net_log_,
6983 &net_error_details_, callback_.callback()));
jri217455a12016-07-13 20:15:096984 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246985 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri217455a12016-07-13 20:15:096986 EXPECT_TRUE(stream.get());
6987
6988 // Cause QUIC stream to be created.
6989 HttpRequestInfo request_info;
6990 request_info.method = "GET";
6991 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396992 request_info.traffic_annotation =
6993 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276994 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396995 net_log_, CompletionOnceCallback()));
jri217455a12016-07-13 20:15:096996
6997 // Ensure that session is alive and active.
6998 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6999 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7000 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7001
7002 // Send GET request on stream.
7003 HttpResponseInfo response;
7004 HttpRequestHeaders request_headers;
7005 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7006 callback_.callback()));
7007
7008 IPEndPoint ip;
7009 session->GetDefaultSocket()->GetPeerAddress(&ip);
7010 DVLOG(1) << "Socket connected to: " << ip.address().ToString() << " "
7011 << ip.port();
7012
7013 // Set up second socket data provider that is used after
7014 // migration. The request is rewritten to this new socket, and the
7015 // response to the request is read on this new socket.
rcha00569732016-08-27 11:09:367016 MockQuicData socket_data2;
7017 socket_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437018 SYNCHRONOUS, client_maker_.MakePingPacket(3, /*include_version=*/true));
7019 socket_data2.AddRead(
7020 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
7021 false, false));
rcha00569732016-08-27 11:09:367022 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437023 socket_data2.AddWrite(SYNCHRONOUS,
7024 client_maker_.MakeAckAndRstPacket(
7025 4, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:527026 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:177027 socket_data2.AddSocketDataToFactory(socket_factory_.get());
jri217455a12016-07-13 20:15:097028
7029 const uint8_t kTestIpAddress[] = {1, 2, 3, 4};
7030 const uint16_t kTestPort = 123;
Zhongyi Shif124a582017-11-02 00:15:047031 session->Migrate(NetworkChangeNotifier::kInvalidNetworkHandle,
7032 IPEndPoint(IPAddress(kTestIpAddress), kTestPort), true,
7033 net_log_);
jri217455a12016-07-13 20:15:097034
7035 session->GetDefaultSocket()->GetPeerAddress(&ip);
7036 DVLOG(1) << "Socket migrated to: " << ip.address().ToString() << " "
7037 << ip.port();
7038
7039 // The session should be alive and active.
7040 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7041 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7042 EXPECT_EQ(1u, session->GetNumActiveStreams());
7043
7044 // Run the message loop so that data queued in the new socket is read by the
7045 // packet reader.
7046 base::RunLoop().RunUntilIdle();
7047
7048 // Verify that response headers on the migrated socket were delivered to the
7049 // stream.
7050 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
7051 EXPECT_EQ(200, response.headers->response_code());
7052
7053 stream.reset();
7054
7055 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7056 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7057 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
7058 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
7059}
7060
jri053fdbd2016-08-19 02:33:057061TEST_P(QuicStreamFactoryTest, ServerMigrationIPv4ToIPv4) {
7062 // Add alternate IPv4 server address to config.
7063 IPEndPoint alt_address = IPEndPoint(IPAddress(1, 2, 3, 4), 123);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527064 quic::QuicConfig config;
fayang91ca2012016-11-22 07:42:467065 config.SetAlternateServerAddressToSend(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527066 quic::QuicSocketAddress(quic::QuicSocketAddressImpl(alt_address)));
jri053fdbd2016-08-19 02:33:057067 VerifyServerMigration(config, alt_address);
7068}
7069
7070TEST_P(QuicStreamFactoryTest, ServerMigrationIPv6ToIPv6) {
7071 // Add a resolver rule to make initial connection to an IPv6 address.
7072 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
7073 "fe80::aebc:32ff:febb:1e33", "");
7074 // Add alternate IPv6 server address to config.
7075 IPEndPoint alt_address = IPEndPoint(
7076 IPAddress(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), 123);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527077 quic::QuicConfig config;
fayang91ca2012016-11-22 07:42:467078 config.SetAlternateServerAddressToSend(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527079 quic::QuicSocketAddress(quic::QuicSocketAddressImpl(alt_address)));
jri053fdbd2016-08-19 02:33:057080 VerifyServerMigration(config, alt_address);
7081}
7082
7083TEST_P(QuicStreamFactoryTest, ServerMigrationIPv6ToIPv4) {
7084 // Add a resolver rule to make initial connection to an IPv6 address.
7085 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
7086 "fe80::aebc:32ff:febb:1e33", "");
7087 // Add alternate IPv4 server address to config.
7088 IPEndPoint alt_address = IPEndPoint(IPAddress(1, 2, 3, 4), 123);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527089 quic::QuicConfig config;
fayang91ca2012016-11-22 07:42:467090 config.SetAlternateServerAddressToSend(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527091 quic::QuicSocketAddress(quic::QuicSocketAddressImpl(alt_address)));
jri053fdbd2016-08-19 02:33:057092 IPEndPoint expected_address(
7093 ConvertIPv4ToIPv4MappedIPv6(alt_address.address()), alt_address.port());
7094 VerifyServerMigration(config, expected_address);
7095}
7096
7097TEST_P(QuicStreamFactoryTest, ServerMigrationIPv4ToIPv6Fails) {
7098 allow_server_migration_ = true;
7099 Initialize();
7100
7101 // Add a resolver rule to make initial connection to an IPv4 address.
7102 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(), "1.2.3.4",
7103 "");
7104 // Add alternate IPv6 server address to config.
7105 IPEndPoint alt_address = IPEndPoint(
7106 IPAddress(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), 123);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527107 quic::QuicConfig config;
fayang91ca2012016-11-22 07:42:467108 config.SetAlternateServerAddressToSend(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527109 quic::QuicSocketAddress(quic::QuicSocketAddressImpl(alt_address)));
jri053fdbd2016-08-19 02:33:057110
7111 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7112 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7113 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7114
7115 crypto_client_stream_factory_.SetConfig(config);
7116
7117 // Set up only socket data provider.
rcha00569732016-08-27 11:09:367118 MockQuicData socket_data1;
7119 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437120 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
7121 socket_data1.AddWrite(
7122 SYNCHRONOUS,
7123 client_maker_.MakeRstPacket(2, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:527124 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:177125 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri053fdbd2016-08-19 02:33:057126
7127 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:457128 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337129 EXPECT_EQ(ERR_IO_PENDING,
7130 request.Request(host_port_pair_, version_, privacy_mode_,
7131 DEFAULT_PRIORITY, SocketTag(),
7132 /*cert_verify_flags=*/0, url_, net_log_,
7133 &net_error_details_, callback_.callback()));
jri053fdbd2016-08-19 02:33:057134 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:247135 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri053fdbd2016-08-19 02:33:057136 EXPECT_TRUE(stream.get());
7137
7138 // Cause QUIC stream to be created.
7139 HttpRequestInfo request_info;
7140 request_info.method = "GET";
7141 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:397142 request_info.traffic_annotation =
7143 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:277144 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:397145 net_log_, CompletionOnceCallback()));
jri053fdbd2016-08-19 02:33:057146
7147 // Ensure that session is alive and active.
7148 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7149 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7150 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7151
7152 IPEndPoint actual_address;
7153 session->GetDefaultSocket()->GetPeerAddress(&actual_address);
7154 // No migration should have happened.
7155 IPEndPoint expected_address =
7156 IPEndPoint(IPAddress(1, 2, 3, 4), kDefaultServerPort);
7157 EXPECT_EQ(actual_address, expected_address);
7158 DVLOG(1) << "Socket connected to: " << actual_address.address().ToString()
7159 << " " << actual_address.port();
7160 DVLOG(1) << "Expected address: " << expected_address.address().ToString()
7161 << " " << expected_address.port();
7162
7163 stream.reset();
7164 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7165 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7166}
7167
rch02d87792015-09-09 09:05:537168TEST_P(QuicStreamFactoryTest, OnSSLConfigChanged) {
jri7046038f2015-10-22 00:29:267169 Initialize();
rch6faa4d42016-01-05 20:48:437170 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7171 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7172 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7173
rcha00569732016-08-27 11:09:367174 MockQuicData socket_data;
7175 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437176 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Ryan Hamilton8d9ee76e2018-05-29 23:52:527177 socket_data.AddWrite(
7178 SYNCHRONOUS, ConstructClientRstPacket(2, quic::QUIC_RST_ACKNOWLEDGEMENT));
Renjieba55fae2018-09-20 03:05:167179 socket_data.AddWrite(
7180 SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
7181 3, true, quic::QUIC_CONNECTION_CANCELLED, "net error"));
Zhongyi Shi5f587cc2017-11-21 23:24:177182 socket_data.AddSocketDataToFactory(socket_factory_.get());
rch02d87792015-09-09 09:05:537183
rcha00569732016-08-27 11:09:367184 MockQuicData socket_data2;
7185 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437186 socket_data2.AddWrite(SYNCHRONOUS,
7187 ConstructInitialSettingsPacket(1, nullptr));
Zhongyi Shi5f587cc2017-11-21 23:24:177188 socket_data2.AddSocketDataToFactory(socket_factory_.get());
rch02d87792015-09-09 09:05:537189
zhongyi98d6a9262017-05-19 02:47:457190 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337191 EXPECT_EQ(ERR_IO_PENDING,
7192 request.Request(host_port_pair_, version_, privacy_mode_,
7193 DEFAULT_PRIORITY, SocketTag(),
7194 /*cert_verify_flags=*/0, url_, net_log_,
7195 &net_error_details_, callback_.callback()));
rch02d87792015-09-09 09:05:537196
robpercival214763f2016-07-01 23:27:017197 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:247198 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Cherie Shie615a0842018-02-28 02:01:137199 HttpRequestInfo request_info;
7200 request_info.traffic_annotation =
7201 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7202 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békyd8a21fc32018-06-27 18:29:587203 net_log_, CompletionOnceCallback()));
rch02d87792015-09-09 09:05:537204
nharper642ae4b2016-06-30 00:40:367205 ssl_config_service_->NotifySSLConfigChange();
Cherie Shie615a0842018-02-28 02:01:137206 EXPECT_EQ(ERR_CERT_DATABASE_CHANGED,
7207 stream->ReadResponseHeaders(callback_.callback()));
jri7046038f2015-10-22 00:29:267208 EXPECT_FALSE(factory_->require_confirmation());
rch02d87792015-09-09 09:05:537209
7210 // Now attempting to request a stream to the same origin should create
7211 // a new session.
Cherie Shie615a0842018-02-28 02:01:137212
zhongyi98d6a9262017-05-19 02:47:457213 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337214 EXPECT_EQ(ERR_IO_PENDING,
7215 request2.Request(host_port_pair_, version_, privacy_mode_,
7216 DEFAULT_PRIORITY, SocketTag(),
7217 /*cert_verify_flags=*/0, url_, net_log_,
7218 &net_error_details_, callback_.callback()));
rch02d87792015-09-09 09:05:537219
robpercival214763f2016-07-01 23:27:017220 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Cherie Shie615a0842018-02-28 02:01:137221 stream = CreateStream(&request2);
7222 stream.reset(); // Will reset stream 3.
rch02d87792015-09-09 09:05:537223
7224 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7225 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7226 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
7227 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
7228}
7229
rsleevi17784692016-10-12 01:36:207230TEST_P(QuicStreamFactoryTest, OnCertDBChanged) {
jri7046038f2015-10-22 00:29:267231 Initialize();
rch6faa4d42016-01-05 20:48:437232 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7233 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7234 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7235
rcha00569732016-08-27 11:09:367236 MockQuicData socket_data;
7237 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437238 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:177239 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]d7d1e50b2013-11-25 22:08:097240
rcha00569732016-08-27 11:09:367241 MockQuicData socket_data2;
7242 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437243 socket_data2.AddWrite(SYNCHRONOUS,
7244 ConstructInitialSettingsPacket(1, nullptr));
Zhongyi Shi5f587cc2017-11-21 23:24:177245 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]d7d1e50b2013-11-25 22:08:097246
zhongyi98d6a9262017-05-19 02:47:457247 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337248 EXPECT_EQ(ERR_IO_PENDING,
7249 request.Request(host_port_pair_, version_, privacy_mode_,
7250 DEFAULT_PRIORITY, SocketTag(),
7251 /*cert_verify_flags=*/0, url_, net_log_,
7252 &net_error_details_, callback_.callback()));
[email protected]d7d1e50b2013-11-25 22:08:097253
robpercival214763f2016-07-01 23:27:017254 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:247255 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Charles 'Buck' Krasic71763c9f2018-02-16 02:37:287256 EXPECT_TRUE(stream);
7257 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
[email protected]d7d1e50b2013-11-25 22:08:097258
7259 // Change the CA cert and verify that stream saw the event.
mattmfd05a1f2017-02-18 06:18:447260 factory_->OnCertDBChanged();
Charles 'Buck' Krasic71763c9f2018-02-16 02:37:287261
jri7046038f2015-10-22 00:29:267262 EXPECT_FALSE(factory_->require_confirmation());
Charles 'Buck' Krasic71763c9f2018-02-16 02:37:287263 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7264 EXPECT_FALSE(HasActiveSession(host_port_pair_));
[email protected]d7d1e50b2013-11-25 22:08:097265
7266 // Now attempting to request a stream to the same origin should create
7267 // a new session.
7268
zhongyi98d6a9262017-05-19 02:47:457269 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337270 EXPECT_EQ(ERR_IO_PENDING,
7271 request2.Request(host_port_pair_, version_, privacy_mode_,
7272 DEFAULT_PRIORITY, SocketTag(),
7273 /*cert_verify_flags=*/0, url_, net_log_,
7274 &net_error_details_, callback_.callback()));
[email protected]d7d1e50b2013-11-25 22:08:097275
robpercival214763f2016-07-01 23:27:017276 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Charles 'Buck' Krasic71763c9f2018-02-16 02:37:287277 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
7278 EXPECT_TRUE(stream2);
7279 QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
7280 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7281 EXPECT_NE(session, session2);
7282 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7283 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
7284
7285 stream2.reset();
7286 stream.reset();
[email protected]d7d1e50b2013-11-25 22:08:097287
rch37de576c2015-05-17 20:28:177288 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7289 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7290 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
7291 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]d7d1e50b2013-11-25 22:08:097292}
7293
[email protected]1e960032013-12-20 19:00:207294TEST_P(QuicStreamFactoryTest, SharedCryptoConfig) {
jri7046038f2015-10-22 00:29:267295 Initialize();
rch6faa4d42016-01-05 20:48:437296
rch872e00e2016-12-02 02:48:187297 std::vector<string> cannoncial_suffixes;
[email protected]6e12d702013-11-13 00:17:177298 cannoncial_suffixes.push_back(string(".c.youtube.com"));
7299 cannoncial_suffixes.push_back(string(".googlevideo.com"));
[email protected]c49ff182013-09-28 08:33:267300
[email protected]6e12d702013-11-13 00:17:177301 for (unsigned i = 0; i < cannoncial_suffixes.size(); ++i) {
7302 string r1_host_name("r1");
7303 string r2_host_name("r2");
7304 r1_host_name.append(cannoncial_suffixes[i]);
7305 r2_host_name.append(cannoncial_suffixes[i]);
[email protected]b70fdb792013-10-25 19:04:147306
[email protected]bf4ea2f2014-03-10 22:57:537307 HostPortPair host_port_pair1(r1_host_name, 80);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527308 quic::QuicCryptoClientConfig* crypto_config =
jri7046038f2015-10-22 00:29:267309 QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
Ryan Hamilton4f0b26e2018-06-27 23:52:327310 quic::QuicServerId server_id1(host_port_pair1.host(),
7311 host_port_pair1.port(), privacy_mode_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527312 quic::QuicCryptoClientConfig::CachedState* cached1 =
[email protected]257f24f2014-04-01 09:15:377313 crypto_config->LookupOrCreate(server_id1);
[email protected]6e12d702013-11-13 00:17:177314 EXPECT_FALSE(cached1->proof_valid());
7315 EXPECT_TRUE(cached1->source_address_token().empty());
7316
7317 // Mutate the cached1 to have different data.
7318 // TODO(rtenneti): mutate other members of CachedState.
7319 cached1->set_source_address_token(r1_host_name);
7320 cached1->SetProofValid();
7321
[email protected]bf4ea2f2014-03-10 22:57:537322 HostPortPair host_port_pair2(r2_host_name, 80);
Ryan Hamilton4f0b26e2018-06-27 23:52:327323 quic::QuicServerId server_id2(host_port_pair2.host(),
7324 host_port_pair2.port(), privacy_mode_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527325 quic::QuicCryptoClientConfig::CachedState* cached2 =
[email protected]257f24f2014-04-01 09:15:377326 crypto_config->LookupOrCreate(server_id2);
[email protected]6e12d702013-11-13 00:17:177327 EXPECT_EQ(cached1->source_address_token(), cached2->source_address_token());
7328 EXPECT_TRUE(cached2->proof_valid());
7329 }
[email protected]b70fdb792013-10-25 19:04:147330}
7331
[email protected]1e960032013-12-20 19:00:207332TEST_P(QuicStreamFactoryTest, CryptoConfigWhenProofIsInvalid) {
jri7046038f2015-10-22 00:29:267333 Initialize();
rch872e00e2016-12-02 02:48:187334 std::vector<string> cannoncial_suffixes;
[email protected]6e12d702013-11-13 00:17:177335 cannoncial_suffixes.push_back(string(".c.youtube.com"));
7336 cannoncial_suffixes.push_back(string(".googlevideo.com"));
[email protected]b70fdb792013-10-25 19:04:147337
[email protected]6e12d702013-11-13 00:17:177338 for (unsigned i = 0; i < cannoncial_suffixes.size(); ++i) {
7339 string r3_host_name("r3");
7340 string r4_host_name("r4");
7341 r3_host_name.append(cannoncial_suffixes[i]);
7342 r4_host_name.append(cannoncial_suffixes[i]);
[email protected]b70fdb792013-10-25 19:04:147343
[email protected]bf4ea2f2014-03-10 22:57:537344 HostPortPair host_port_pair1(r3_host_name, 80);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527345 quic::QuicCryptoClientConfig* crypto_config =
jri7046038f2015-10-22 00:29:267346 QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
Ryan Hamilton4f0b26e2018-06-27 23:52:327347 quic::QuicServerId server_id1(host_port_pair1.host(),
7348 host_port_pair1.port(), privacy_mode_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527349 quic::QuicCryptoClientConfig::CachedState* cached1 =
[email protected]257f24f2014-04-01 09:15:377350 crypto_config->LookupOrCreate(server_id1);
[email protected]6e12d702013-11-13 00:17:177351 EXPECT_FALSE(cached1->proof_valid());
7352 EXPECT_TRUE(cached1->source_address_token().empty());
7353
7354 // Mutate the cached1 to have different data.
7355 // TODO(rtenneti): mutate other members of CachedState.
7356 cached1->set_source_address_token(r3_host_name);
7357 cached1->SetProofInvalid();
7358
[email protected]bf4ea2f2014-03-10 22:57:537359 HostPortPair host_port_pair2(r4_host_name, 80);
Ryan Hamilton4f0b26e2018-06-27 23:52:327360 quic::QuicServerId server_id2(host_port_pair2.host(),
7361 host_port_pair2.port(), privacy_mode_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527362 quic::QuicCryptoClientConfig::CachedState* cached2 =
[email protected]257f24f2014-04-01 09:15:377363 crypto_config->LookupOrCreate(server_id2);
[email protected]6e12d702013-11-13 00:17:177364 EXPECT_NE(cached1->source_address_token(), cached2->source_address_token());
7365 EXPECT_TRUE(cached2->source_address_token().empty());
7366 EXPECT_FALSE(cached2->proof_valid());
7367 }
[email protected]c49ff182013-09-28 08:33:267368}
7369
rtenneti34dffe752015-02-24 23:27:327370TEST_P(QuicStreamFactoryTest, EnableNotLoadFromDiskCache) {
jri7046038f2015-10-22 00:29:267371 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:207372 factory_->set_require_confirmation(false);
rch6faa4d42016-01-05 20:48:437373 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7374 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7375
jri7046038f2015-10-22 00:29:267376 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
rtenneti34dffe752015-02-24 23:27:327377
rcha00569732016-08-27 11:09:367378 MockQuicData socket_data;
7379 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:177380 socket_data.AddSocketDataToFactory(socket_factory_.get());
rtenneti34dffe752015-02-24 23:27:327381
7382 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:277383 MockCryptoClientStream::ZERO_RTT);
rtenneti34dffe752015-02-24 23:27:327384 host_resolver_.set_synchronous_mode(true);
7385 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
7386 "192.168.0.1", "");
7387
zhongyi98d6a9262017-05-19 02:47:457388 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337389 EXPECT_EQ(OK, request.Request(host_port_pair_, version_, privacy_mode_,
7390 DEFAULT_PRIORITY, SocketTag(),
7391 /*cert_verify_flags=*/0, url_, net_log_,
7392 &net_error_details_, callback_.callback()));
rtenneti34dffe752015-02-24 23:27:327393
7394 // If we are waiting for disk cache, we would have posted a task. Verify that
7395 // the CancelWaitForDataReady task hasn't been posted.
7396 ASSERT_EQ(0u, runner_->GetPostedTasks().size());
7397
Yixin Wang7891a39d2017-11-08 20:59:247398 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rtenneti34dffe752015-02-24 23:27:327399 EXPECT_TRUE(stream.get());
rch37de576c2015-05-17 20:28:177400 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7401 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
rtenneti34dffe752015-02-24 23:27:327402}
7403
dmurph44ca4f42016-09-09 20:39:097404TEST_P(QuicStreamFactoryTest, ReducePingTimeoutOnConnectionTimeOutOpenStreams) {
7405 reduced_ping_timeout_seconds_ = 10;
dmurph44ca4f42016-09-09 20:39:097406 Initialize();
7407 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7408 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7409 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7410
7411 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
zhongyidd1439f62016-09-02 02:02:267412
7413 MockQuicData socket_data;
7414 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437415 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:177416 socket_data.AddSocketDataToFactory(socket_factory_.get());
zhongyidd1439f62016-09-02 02:02:267417
7418 MockQuicData socket_data2;
7419 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437420 socket_data2.AddWrite(SYNCHRONOUS,
7421 ConstructInitialSettingsPacket(1, nullptr));
Zhongyi Shi5f587cc2017-11-21 23:24:177422 socket_data2.AddSocketDataToFactory(socket_factory_.get());
zhongyidd1439f62016-09-02 02:02:267423
7424 HostPortPair server2(kServer2HostName, kDefaultServerPort);
7425
7426 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:277427 MockCryptoClientStream::CONFIRM_HANDSHAKE);
zhongyidd1439f62016-09-02 02:02:267428 host_resolver_.set_synchronous_mode(true);
7429 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
7430 "192.168.0.1", "");
7431 host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
7432
7433 // Quic should use default PING timeout when no previous connection times out
7434 // with open stream.
Ryan Hamilton8d9ee76e2018-05-29 23:52:527435 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(quic::kPingTimeoutSecs),
zhongyidd1439f62016-09-02 02:02:267436 QuicStreamFactoryPeer::GetPingTimeout(factory_.get()));
zhongyi98d6a9262017-05-19 02:47:457437 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337438 EXPECT_EQ(OK, request.Request(host_port_pair_, version_, privacy_mode_,
7439 DEFAULT_PRIORITY, SocketTag(),
7440 /*cert_verify_flags=*/0, url_, net_log_,
7441 &net_error_details_, callback_.callback()));
zhongyidd1439f62016-09-02 02:02:267442
7443 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527444 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(quic::kPingTimeoutSecs),
zhongyidd1439f62016-09-02 02:02:267445 session->connection()->ping_timeout());
7446
Yixin Wang7891a39d2017-11-08 20:59:247447 std::unique_ptr<HttpStream> stream = CreateStream(&request);
zhongyidd1439f62016-09-02 02:02:267448 EXPECT_TRUE(stream.get());
7449 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:397450 request_info.traffic_annotation =
7451 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:277452 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:397453 net_log_, CompletionOnceCallback()));
zhongyidd1439f62016-09-02 02:02:267454
7455 DVLOG(1)
7456 << "Created 1st session and initialized a stream. Now trigger timeout";
Ryan Hamilton8d9ee76e2018-05-29 23:52:527457 session->connection()->CloseConnection(
7458 quic::QUIC_NETWORK_IDLE_TIMEOUT, "test",
7459 quic::ConnectionCloseBehavior::SILENT_CLOSE);
zhongyidd1439f62016-09-02 02:02:267460 // Need to spin the loop now to ensure that
7461 // QuicStreamFactory::OnSessionClosed() runs.
7462 base::RunLoop run_loop;
7463 run_loop.RunUntilIdle();
7464
zhongyidd1439f62016-09-02 02:02:267465 // The first connection times out with open stream, QUIC should reduce initial
7466 // PING time for subsequent connections.
Ryan Hamilton8d9ee76e2018-05-29 23:52:527467 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(10),
zhongyidd1439f62016-09-02 02:02:267468 QuicStreamFactoryPeer::GetPingTimeout(factory_.get()));
7469
7470 // Test two-in-a-row timeouts with open streams.
7471 DVLOG(1) << "Create 2nd session and timeout with open stream";
7472 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:457473 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337474 EXPECT_EQ(OK, request2.Request(server2, version_, privacy_mode_,
7475 DEFAULT_PRIORITY, SocketTag(),
7476 /*cert_verify_flags=*/0, url2_, net_log_,
7477 &net_error_details_, callback2.callback()));
zhongyidd1439f62016-09-02 02:02:267478 QuicChromiumClientSession* session2 = GetActiveSession(server2);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527479 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(10),
zhongyidd1439f62016-09-02 02:02:267480 session2->connection()->ping_timeout());
7481
Yixin Wang7891a39d2017-11-08 20:59:247482 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
zhongyidd1439f62016-09-02 02:02:267483 EXPECT_TRUE(stream2.get());
Steven Valdezb4ff0412018-01-18 22:39:277484 EXPECT_EQ(OK,
7485 stream2->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:397486 net_log_, CompletionOnceCallback()));
zhongyidd1439f62016-09-02 02:02:267487 session2->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527488 quic::QUIC_NETWORK_IDLE_TIMEOUT, "test",
7489 quic::ConnectionCloseBehavior::SILENT_CLOSE);
zhongyidd1439f62016-09-02 02:02:267490 // Need to spin the loop now to ensure that
7491 // QuicStreamFactory::OnSessionClosed() runs.
7492 base::RunLoop run_loop2;
7493 run_loop2.RunUntilIdle();
zhongyidd1439f62016-09-02 02:02:267494
7495 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7496 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7497 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
7498 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
7499}
7500
tbansal3b966952016-10-25 23:25:147501// Verifies that the QUIC stream factory is initialized correctly.
rtenneticd2aaa15b2015-10-10 20:29:337502TEST_P(QuicStreamFactoryTest, MaybeInitialize) {
tbansal9b1cdf32017-05-10 17:28:397503 VerifyInitialization();
rtenneti8a80a6dc2015-09-21 19:51:137504}
7505
rtennetid073dd22016-08-04 01:58:337506TEST_P(QuicStreamFactoryTest, StartCertVerifyJob) {
7507 Initialize();
7508
rcha00569732016-08-27 11:09:367509 MockQuicData socket_data;
7510 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437511 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:177512 socket_data.AddSocketDataToFactory(socket_factory_.get());
rtennetid073dd22016-08-04 01:58:337513
7514 // Save current state of |race_cert_verification|.
7515 bool race_cert_verification =
7516 QuicStreamFactoryPeer::GetRaceCertVerification(factory_.get());
7517
7518 // Load server config.
7519 HostPortPair host_port_pair(kDefaultServerHostName, kDefaultServerPort);
Ryan Hamilton4f0b26e2018-06-27 23:52:327520 quic::QuicServerId quic_server_id(host_port_pair_.host(),
7521 host_port_pair_.port(),
7522 privacy_mode_ == PRIVACY_MODE_ENABLED);
rtennetid073dd22016-08-04 01:58:337523 QuicStreamFactoryPeer::CacheDummyServerConfig(factory_.get(), quic_server_id);
7524
7525 QuicStreamFactoryPeer::SetRaceCertVerification(factory_.get(), true);
7526 EXPECT_FALSE(HasActiveCertVerifierJob(quic_server_id));
7527
7528 // Start CertVerifyJob.
Ryan Hamilton8d9ee76e2018-05-29 23:52:527529 quic::QuicAsyncStatus status = QuicStreamFactoryPeer::StartCertVerifyJob(
rtennetid073dd22016-08-04 01:58:337530 factory_.get(), quic_server_id, /*cert_verify_flags=*/0, net_log_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527531 if (status == quic::QUIC_PENDING) {
rtennetid073dd22016-08-04 01:58:337532 // Verify CertVerifierJob has started.
7533 EXPECT_TRUE(HasActiveCertVerifierJob(quic_server_id));
7534
7535 while (HasActiveCertVerifierJob(quic_server_id)) {
7536 base::RunLoop().RunUntilIdle();
7537 }
7538 }
7539 // Verify CertVerifierJob has finished.
7540 EXPECT_FALSE(HasActiveCertVerifierJob(quic_server_id));
7541
7542 // Start a QUIC request.
zhongyi98d6a9262017-05-19 02:47:457543 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337544 EXPECT_EQ(ERR_IO_PENDING,
7545 request.Request(host_port_pair_, version_, privacy_mode_,
7546 DEFAULT_PRIORITY, SocketTag(),
7547 /*cert_verify_flags=*/0, url_, net_log_,
7548 &net_error_details_, callback_.callback()));
rtennetid073dd22016-08-04 01:58:337549
7550 EXPECT_EQ(OK, callback_.WaitForResult());
7551
Yixin Wang7891a39d2017-11-08 20:59:247552 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rtennetid073dd22016-08-04 01:58:337553 EXPECT_TRUE(stream.get());
7554
7555 // Restore |race_cert_verification|.
7556 QuicStreamFactoryPeer::SetRaceCertVerification(factory_.get(),
7557 race_cert_verification);
7558
7559 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7560 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7561
7562 // Verify there are no outstanding CertVerifierJobs after request has
7563 // finished.
7564 EXPECT_FALSE(HasActiveCertVerifierJob(quic_server_id));
7565}
7566
rtenneti1cd3b162015-09-29 02:58:287567TEST_P(QuicStreamFactoryTest, YieldAfterPackets) {
jri7046038f2015-10-22 00:29:267568 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:207569 factory_->set_require_confirmation(false);
rch6faa4d42016-01-05 20:48:437570 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7571 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:267572 QuicStreamFactoryPeer::SetYieldAfterPackets(factory_.get(), 0);
rtenneti1cd3b162015-09-29 02:58:287573
rcha00569732016-08-27 11:09:367574 MockQuicData socket_data;
Zhongyi Shi32f2fd02018-04-16 18:23:437575 socket_data.AddRead(SYNCHRONOUS, ConstructClientConnectionClosePacket(0));
rcha00569732016-08-27 11:09:367576 socket_data.AddRead(ASYNC, OK);
Zhongyi Shi5f587cc2017-11-21 23:24:177577 socket_data.AddSocketDataToFactory(socket_factory_.get());
rtenneti1cd3b162015-09-29 02:58:287578
7579 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:277580 MockCryptoClientStream::ZERO_RTT);
rtenneti1cd3b162015-09-29 02:58:287581 host_resolver_.set_synchronous_mode(true);
7582 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
7583 "192.168.0.1", "");
7584
rcha02807b42016-01-29 21:56:157585 // Set up the TaskObserver to verify QuicChromiumPacketReader::StartReading
7586 // posts a task.
rtenneti1cd3b162015-09-29 02:58:287587 // TODO(rtenneti): Change SpdySessionTestTaskObserver to NetTestTaskObserver??
rcha02807b42016-01-29 21:56:157588 SpdySessionTestTaskObserver observer("quic_chromium_packet_reader.cc",
7589 "StartReading");
rtenneti1cd3b162015-09-29 02:58:287590
zhongyi98d6a9262017-05-19 02:47:457591 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337592 EXPECT_EQ(OK, request.Request(host_port_pair_, version_, privacy_mode_,
7593 DEFAULT_PRIORITY, SocketTag(),
7594 /*cert_verify_flags=*/0, url_, net_log_,
7595 &net_error_details_, callback_.callback()));
rtenneti1cd3b162015-09-29 02:58:287596
rcha02807b42016-01-29 21:56:157597 // Call run_loop so that QuicChromiumPacketReader::OnReadComplete() gets
7598 // called.
rtenneti1cd3b162015-09-29 02:58:287599 base::RunLoop run_loop;
7600 run_loop.RunUntilIdle();
7601
7602 // Verify task that the observer's executed_count is 1, which indicates
rcha02807b42016-01-29 21:56:157603 // QuicChromiumPacketReader::StartReading() has posted only one task and
7604 // yielded the read.
rtenneti1cd3b162015-09-29 02:58:287605 EXPECT_EQ(1u, observer.executed_count());
7606
Yixin Wang7891a39d2017-11-08 20:59:247607 std::unique_ptr<HttpStream> stream = CreateStream(&request);
xunjieli2608f9b2016-03-14 13:39:237608 EXPECT_FALSE(stream.get()); // Session is already closed.
rtenneti1cd3b162015-09-29 02:58:287609 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7610 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7611}
7612
7613TEST_P(QuicStreamFactoryTest, YieldAfterDuration) {
jri7046038f2015-10-22 00:29:267614 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:207615 factory_->set_require_confirmation(false);
rch6faa4d42016-01-05 20:48:437616 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7617 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rtenneti1cd3b162015-09-29 02:58:287618 QuicStreamFactoryPeer::SetYieldAfterDuration(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527619 factory_.get(), quic::QuicTime::Delta::FromMilliseconds(-1));
rtenneti1cd3b162015-09-29 02:58:287620
rcha00569732016-08-27 11:09:367621 MockQuicData socket_data;
Zhongyi Shi32f2fd02018-04-16 18:23:437622 socket_data.AddRead(SYNCHRONOUS, ConstructClientConnectionClosePacket(0));
rcha00569732016-08-27 11:09:367623 socket_data.AddRead(ASYNC, OK);
Zhongyi Shi5f587cc2017-11-21 23:24:177624 socket_data.AddSocketDataToFactory(socket_factory_.get());
rtenneti1cd3b162015-09-29 02:58:287625
7626 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:277627 MockCryptoClientStream::ZERO_RTT);
rtenneti1cd3b162015-09-29 02:58:287628 host_resolver_.set_synchronous_mode(true);
7629 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
7630 "192.168.0.1", "");
7631
rcha02807b42016-01-29 21:56:157632 // Set up the TaskObserver to verify QuicChromiumPacketReader::StartReading
7633 // posts a task.
rtenneti1cd3b162015-09-29 02:58:287634 // TODO(rtenneti): Change SpdySessionTestTaskObserver to NetTestTaskObserver??
rcha02807b42016-01-29 21:56:157635 SpdySessionTestTaskObserver observer("quic_chromium_packet_reader.cc",
7636 "StartReading");
rtenneti1cd3b162015-09-29 02:58:287637
zhongyi98d6a9262017-05-19 02:47:457638 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337639 EXPECT_EQ(OK, request.Request(host_port_pair_, version_, privacy_mode_,
7640 DEFAULT_PRIORITY, SocketTag(),
7641 /*cert_verify_flags=*/0, url_, net_log_,
7642 &net_error_details_, callback_.callback()));
rtenneti1cd3b162015-09-29 02:58:287643
rcha02807b42016-01-29 21:56:157644 // Call run_loop so that QuicChromiumPacketReader::OnReadComplete() gets
7645 // called.
rtenneti1cd3b162015-09-29 02:58:287646 base::RunLoop run_loop;
7647 run_loop.RunUntilIdle();
7648
7649 // Verify task that the observer's executed_count is 1, which indicates
rcha02807b42016-01-29 21:56:157650 // QuicChromiumPacketReader::StartReading() has posted only one task and
7651 // yielded the read.
rtenneti1cd3b162015-09-29 02:58:287652 EXPECT_EQ(1u, observer.executed_count());
7653
Yixin Wang7891a39d2017-11-08 20:59:247654 std::unique_ptr<HttpStream> stream = CreateStream(&request);
xunjieli2608f9b2016-03-14 13:39:237655 EXPECT_FALSE(stream.get()); // Session is already closed.
rtenneti1cd3b162015-09-29 02:58:287656 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7657 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7658}
7659
ckrasic3865ee0f2016-02-29 22:04:567660TEST_P(QuicStreamFactoryTest, ServerPushSessionAffinity) {
7661 Initialize();
7662 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7663 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7664
rcha00569732016-08-27 11:09:367665 MockQuicData socket_data;
7666 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437667 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:177668 socket_data.AddSocketDataToFactory(socket_factory_.get());
ckrasic3865ee0f2016-02-29 22:04:567669
zhongyi98d6a9262017-05-19 02:47:457670 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337671 EXPECT_EQ(ERR_IO_PENDING,
7672 request.Request(host_port_pair_, version_, privacy_mode_,
7673 DEFAULT_PRIORITY, SocketTag(),
7674 /*cert_verify_flags=*/0, url_, net_log_,
7675 &net_error_details_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:567676
robpercival214763f2016-07-01 23:27:017677 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:247678 std::unique_ptr<HttpStream> stream = CreateStream(&request);
ckrasic3865ee0f2016-02-29 22:04:567679 EXPECT_TRUE(stream.get());
7680
7681 EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumPushStreamsCreated(factory_.get()));
7682
bnc5fdc07162016-05-23 17:36:037683 string url = "https://www.example.org/";
ckrasic3865ee0f2016-02-29 22:04:567684
bnc912a04b2016-04-20 14:19:507685 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
ckrasic3865ee0f2016-02-29 22:04:567686
Ryan Hamilton8d9ee76e2018-05-29 23:52:527687 quic::QuicClientPromisedInfo promised(
7688 session, GetNthServerInitiatedStreamId(0), kDefaultUrl);
ckrasic3865ee0f2016-02-29 22:04:567689 (*QuicStreamFactoryPeer::GetPushPromiseIndex(factory_.get())
bnc3d9035b32016-06-30 18:18:487690 ->promised_by_url())[kDefaultUrl] = &promised;
ckrasic3865ee0f2016-02-29 22:04:567691
zhongyi98d6a9262017-05-19 02:47:457692 QuicStreamRequest request2(factory_.get());
zhongyia00ca012017-07-06 23:36:397693 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_, privacy_mode_,
Paul Jensen8e3c5d32018-02-19 17:06:337694 DEFAULT_PRIORITY, SocketTag(),
7695 /*cert_verify_flags=*/0, url_, net_log_,
7696 &net_error_details_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:567697
7698 EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumPushStreamsCreated(factory_.get()));
7699}
7700
7701TEST_P(QuicStreamFactoryTest, ServerPushPrivacyModeMismatch) {
7702 Initialize();
7703 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7704 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7705 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7706
rcha00569732016-08-27 11:09:367707 MockQuicData socket_data1;
7708 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437709 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
7710 socket_data1.AddWrite(
7711 SYNCHRONOUS,
7712 client_maker_.MakeRstPacket(2, true, GetNthServerInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:527713 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:177714 socket_data1.AddSocketDataToFactory(socket_factory_.get());
ckrasic3865ee0f2016-02-29 22:04:567715
rcha00569732016-08-27 11:09:367716 MockQuicData socket_data2;
7717 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437718 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:177719 socket_data2.AddSocketDataToFactory(socket_factory_.get());
ckrasic3865ee0f2016-02-29 22:04:567720
zhongyi98d6a9262017-05-19 02:47:457721 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337722 EXPECT_EQ(ERR_IO_PENDING,
7723 request.Request(host_port_pair_, version_, privacy_mode_,
7724 DEFAULT_PRIORITY, SocketTag(),
7725 /*cert_verify_flags=*/0, url_, net_log_,
7726 &net_error_details_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:567727
robpercival214763f2016-07-01 23:27:017728 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:247729 std::unique_ptr<HttpStream> stream = CreateStream(&request);
ckrasic3865ee0f2016-02-29 22:04:567730 EXPECT_TRUE(stream.get());
7731
7732 EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumPushStreamsCreated(factory_.get()));
7733
bnc5fdc07162016-05-23 17:36:037734 string url = "https://www.example.org/";
bnc912a04b2016-04-20 14:19:507735 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
ckrasic3865ee0f2016-02-29 22:04:567736
Ryan Hamilton8d9ee76e2018-05-29 23:52:527737 quic::QuicClientPromisedInfo promised(
7738 session, GetNthServerInitiatedStreamId(0), kDefaultUrl);
ckrasic3865ee0f2016-02-29 22:04:567739
Ryan Hamilton8d9ee76e2018-05-29 23:52:527740 quic::QuicClientPushPromiseIndex* index =
ckrasic3865ee0f2016-02-29 22:04:567741 QuicStreamFactoryPeer::GetPushPromiseIndex(factory_.get());
7742
bnc3d9035b32016-06-30 18:18:487743 (*index->promised_by_url())[kDefaultUrl] = &promised;
7744 EXPECT_EQ(index->GetPromised(kDefaultUrl), &promised);
ckrasic3865ee0f2016-02-29 22:04:567745
7746 // Doing the request should not use the push stream, but rather
7747 // cancel it because the privacy modes do not match.
zhongyi98d6a9262017-05-19 02:47:457748 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337749 EXPECT_EQ(ERR_IO_PENDING,
7750 request2.Request(host_port_pair_, version_, PRIVACY_MODE_ENABLED,
7751 DEFAULT_PRIORITY, SocketTag(),
7752 /*cert_verify_flags=*/0, url_, net_log_,
7753 &net_error_details_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:567754
7755 EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumPushStreamsCreated(factory_.get()));
bnc3d9035b32016-06-30 18:18:487756 EXPECT_EQ(index->GetPromised(kDefaultUrl), nullptr);
ckrasic3865ee0f2016-02-29 22:04:567757
robpercival214763f2016-07-01 23:27:017758 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:247759 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
ckrasic3865ee0f2016-02-29 22:04:567760 EXPECT_TRUE(stream2.get());
7761
7762 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7763 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7764 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
7765 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
7766}
7767
Ryan Hamilton8d9ee76e2018-05-29 23:52:527768// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:457769// even if destination is different.
7770TEST_P(QuicStreamFactoryTest, PoolByOrigin) {
7771 Initialize();
7772
7773 HostPortPair destination1("first.example.com", 443);
7774 HostPortPair destination2("second.example.com", 443);
7775
7776 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7777 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7778
rcha00569732016-08-27 11:09:367779 MockQuicData socket_data;
7780 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437781 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:177782 socket_data.AddSocketDataToFactory(socket_factory_.get());
bnc359ed2a2016-04-29 20:43:457783
zhongyi98d6a9262017-05-19 02:47:457784 QuicStreamRequest request1(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337785 EXPECT_EQ(ERR_IO_PENDING,
7786 request1.Request(destination1, version_, privacy_mode_,
7787 DEFAULT_PRIORITY, SocketTag(),
7788 /*cert_verify_flags=*/0, url_, net_log_,
7789 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:017790 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:247791 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
bnc359ed2a2016-04-29 20:43:457792 EXPECT_TRUE(stream1.get());
7793 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7794
7795 // Second request returns synchronously because it pools to existing session.
7796 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:457797 QuicStreamRequest request2(factory_.get());
zhongyia00ca012017-07-06 23:36:397798 EXPECT_EQ(OK, request2.Request(destination2, version_, privacy_mode_,
Paul Jensen8e3c5d32018-02-19 17:06:337799 DEFAULT_PRIORITY, SocketTag(),
7800 /*cert_verify_flags=*/0, url_, net_log_,
7801 &net_error_details_, callback2.callback()));
Yixin Wang7891a39d2017-11-08 20:59:247802 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
bnc359ed2a2016-04-29 20:43:457803 EXPECT_TRUE(stream2.get());
7804
rchf0b18c8a2017-05-05 19:31:577805 QuicChromiumClientSession::Handle* session1 =
7806 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
7807 QuicChromiumClientSession::Handle* session2 =
7808 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
7809 EXPECT_TRUE(session1->SharesSameSession(*session2));
Ryan Hamilton4f0b26e2018-06-27 23:52:327810 EXPECT_EQ(quic::QuicServerId(host_port_pair_.host(), host_port_pair_.port(),
7811 privacy_mode_ == PRIVACY_MODE_ENABLED),
bnc359ed2a2016-04-29 20:43:457812 session1->server_id());
7813
7814 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7815 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7816}
7817
7818class QuicStreamFactoryWithDestinationTest
7819 : public QuicStreamFactoryTestBase,
7820 public ::testing::TestWithParam<PoolingTestParams> {
7821 protected:
7822 QuicStreamFactoryWithDestinationTest()
Yixin Wang079ad542018-01-11 04:06:057823 : QuicStreamFactoryTestBase(
7824 GetParam().version,
7825 GetParam().client_headers_include_h2_stream_dependency),
bnc359ed2a2016-04-29 20:43:457826 destination_type_(GetParam().destination_type),
7827 hanging_read_(SYNCHRONOUS, ERR_IO_PENDING, 0) {}
7828
7829 HostPortPair GetDestination() {
7830 switch (destination_type_) {
7831 case SAME_AS_FIRST:
7832 return origin1_;
7833 case SAME_AS_SECOND:
7834 return origin2_;
7835 case DIFFERENT:
7836 return HostPortPair(kDifferentHostname, 443);
7837 default:
7838 NOTREACHED();
7839 return HostPortPair();
7840 }
7841 }
7842
7843 void AddHangingSocketData() {
7844 std::unique_ptr<SequencedSocketData> sequenced_socket_data(
Ryan Sleevib8d7ea02018-05-07 20:01:017845 new SequencedSocketData(base::make_span(&hanging_read_, 1),
7846 base::span<MockWrite>()));
Zhongyi Shi5f587cc2017-11-21 23:24:177847 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
bnc359ed2a2016-04-29 20:43:457848 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
7849 }
7850
7851 bool AllDataConsumed() {
7852 for (const auto& socket_data_ptr : sequenced_socket_data_vector_) {
7853 if (!socket_data_ptr->AllReadDataConsumed() ||
7854 !socket_data_ptr->AllWriteDataConsumed()) {
7855 return false;
7856 }
7857 }
7858 return true;
7859 }
7860
7861 DestinationType destination_type_;
7862 HostPortPair origin1_;
7863 HostPortPair origin2_;
7864 MockRead hanging_read_;
rch872e00e2016-12-02 02:48:187865 std::vector<std::unique_ptr<SequencedSocketData>>
7866 sequenced_socket_data_vector_;
bnc359ed2a2016-04-29 20:43:457867};
7868
Bence Békyce380cb2018-04-26 23:39:557869INSTANTIATE_TEST_CASE_P(VersionIncludeStreamDependencySequence,
bnc359ed2a2016-04-29 20:43:457870 QuicStreamFactoryWithDestinationTest,
7871 ::testing::ValuesIn(GetPoolingTestParams()));
7872
7873// A single QUIC request fails because the certificate does not match the origin
7874// hostname, regardless of whether it matches the alternative service hostname.
7875TEST_P(QuicStreamFactoryWithDestinationTest, InvalidCertificate) {
7876 if (destination_type_ == DIFFERENT)
7877 return;
7878
7879 Initialize();
7880
7881 GURL url("https://mail.example.com/");
7882 origin1_ = HostPortPair::FromURL(url);
7883
7884 // Not used for requests, but this provides a test case where the certificate
7885 // is valid for the hostname of the alternative service.
7886 origin2_ = HostPortPair("mail.example.org", 433);
7887
7888 HostPortPair destination = GetDestination();
7889
7890 scoped_refptr<X509Certificate> cert(
7891 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247892 ASSERT_FALSE(cert->VerifyNameMatch(origin1_.host()));
7893 ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host()));
bnc359ed2a2016-04-29 20:43:457894
7895 ProofVerifyDetailsChromium verify_details;
7896 verify_details.cert_verify_result.verified_cert = cert;
7897 verify_details.cert_verify_result.is_issued_by_known_root = true;
7898 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7899
7900 AddHangingSocketData();
7901
zhongyi98d6a9262017-05-19 02:47:457902 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337903 EXPECT_EQ(ERR_IO_PENDING,
7904 request.Request(destination, version_, privacy_mode_,
7905 DEFAULT_PRIORITY, SocketTag(),
7906 /*cert_verify_flags=*/0, url, net_log_,
7907 &net_error_details_, callback_.callback()));
bnc359ed2a2016-04-29 20:43:457908
robpercival214763f2016-07-01 23:27:017909 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_QUIC_HANDSHAKE_FAILED));
bnc359ed2a2016-04-29 20:43:457910
7911 EXPECT_TRUE(AllDataConsumed());
7912}
7913
7914// QuicStreamRequest is pooled based on |destination| if certificate matches.
7915TEST_P(QuicStreamFactoryWithDestinationTest, SharedCertificate) {
7916 Initialize();
7917
7918 GURL url1("https://www.example.org/");
7919 GURL url2("https://mail.example.org/");
7920 origin1_ = HostPortPair::FromURL(url1);
7921 origin2_ = HostPortPair::FromURL(url2);
7922
7923 HostPortPair destination = GetDestination();
7924
7925 scoped_refptr<X509Certificate> cert(
7926 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247927 ASSERT_TRUE(cert->VerifyNameMatch(origin1_.host()));
7928 ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host()));
7929 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457930
7931 ProofVerifyDetailsChromium verify_details;
7932 verify_details.cert_verify_result.verified_cert = cert;
7933 verify_details.cert_verify_result.is_issued_by_known_root = true;
7934 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7935
fayang3bcb8b502016-12-07 21:44:377936 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:527937 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:367938 client_maker_.MakeInitialSettingsPacket(1, nullptr));
bnceb9aa7112017-01-05 01:03:467939 MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(),
7940 settings_packet->length(), 1)};
fayang3bcb8b502016-12-07 21:44:377941 std::unique_ptr<SequencedSocketData> sequenced_socket_data(
Ryan Sleevib8d7ea02018-05-07 20:01:017942 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:177943 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
fayang3bcb8b502016-12-07 21:44:377944 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
bnc359ed2a2016-04-29 20:43:457945
zhongyi98d6a9262017-05-19 02:47:457946 QuicStreamRequest request1(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337947 EXPECT_EQ(ERR_IO_PENDING,
7948 request1.Request(destination, version_, privacy_mode_,
7949 DEFAULT_PRIORITY, SocketTag(),
7950 /*cert_verify_flags=*/0, url1, net_log_,
7951 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:017952 EXPECT_THAT(callback_.WaitForResult(), IsOk());
fayang3bcb8b502016-12-07 21:44:377953
Yixin Wang7891a39d2017-11-08 20:59:247954 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
bnc359ed2a2016-04-29 20:43:457955 EXPECT_TRUE(stream1.get());
7956 EXPECT_TRUE(HasActiveSession(origin1_));
7957
7958 // Second request returns synchronously because it pools to existing session.
7959 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:457960 QuicStreamRequest request2(factory_.get());
zhongyia00ca012017-07-06 23:36:397961 EXPECT_EQ(OK, request2.Request(destination, version_, privacy_mode_,
Paul Jensen8e3c5d32018-02-19 17:06:337962 DEFAULT_PRIORITY, SocketTag(),
7963 /*cert_verify_flags=*/0, url2, net_log_,
7964 &net_error_details_, callback2.callback()));
Yixin Wang7891a39d2017-11-08 20:59:247965 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
bnc359ed2a2016-04-29 20:43:457966 EXPECT_TRUE(stream2.get());
7967
rchf0b18c8a2017-05-05 19:31:577968 QuicChromiumClientSession::Handle* session1 =
7969 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
7970 QuicChromiumClientSession::Handle* session2 =
7971 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
7972 EXPECT_TRUE(session1->SharesSameSession(*session2));
bnc359ed2a2016-04-29 20:43:457973
Ryan Hamilton4f0b26e2018-06-27 23:52:327974 EXPECT_EQ(quic::QuicServerId(origin1_.host(), origin1_.port(),
7975 privacy_mode_ == PRIVACY_MODE_ENABLED),
7976 session1->server_id());
bnc359ed2a2016-04-29 20:43:457977
7978 EXPECT_TRUE(AllDataConsumed());
7979}
7980
bnc47eba7d2016-07-01 00:43:387981// QuicStreamRequest is not pooled if PrivacyMode differs.
7982TEST_P(QuicStreamFactoryWithDestinationTest, DifferentPrivacyMode) {
7983 Initialize();
7984
7985 GURL url1("https://www.example.org/");
7986 GURL url2("https://mail.example.org/");
7987 origin1_ = HostPortPair::FromURL(url1);
7988 origin2_ = HostPortPair::FromURL(url2);
7989
7990 HostPortPair destination = GetDestination();
7991
7992 scoped_refptr<X509Certificate> cert(
7993 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247994 ASSERT_TRUE(cert->VerifyNameMatch(origin1_.host()));
7995 ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host()));
7996 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc47eba7d2016-07-01 00:43:387997
7998 ProofVerifyDetailsChromium verify_details1;
7999 verify_details1.cert_verify_result.verified_cert = cert;
8000 verify_details1.cert_verify_result.is_issued_by_known_root = true;
8001 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
8002
8003 ProofVerifyDetailsChromium verify_details2;
8004 verify_details2.cert_verify_result.verified_cert = cert;
8005 verify_details2.cert_verify_result.is_issued_by_known_root = true;
8006 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
8007
fayang3bcb8b502016-12-07 21:44:378008 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:528009 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:368010 client_maker_.MakeInitialSettingsPacket(1, nullptr));
bnceb9aa7112017-01-05 01:03:468011 MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(),
8012 settings_packet->length(), 1)};
fayang3bcb8b502016-12-07 21:44:378013 std::unique_ptr<SequencedSocketData> sequenced_socket_data(
Ryan Sleevib8d7ea02018-05-07 20:01:018014 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:178015 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
fayang3bcb8b502016-12-07 21:44:378016 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
8017 std::unique_ptr<SequencedSocketData> sequenced_socket_data1(
Ryan Sleevib8d7ea02018-05-07 20:01:018018 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:178019 socket_factory_->AddSocketDataProvider(sequenced_socket_data1.get());
fayang3bcb8b502016-12-07 21:44:378020 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data1));
bnc47eba7d2016-07-01 00:43:388021
zhongyi98d6a9262017-05-19 02:47:458022 QuicStreamRequest request1(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338023 EXPECT_EQ(ERR_IO_PENDING,
8024 request1.Request(destination, version_, PRIVACY_MODE_DISABLED,
8025 DEFAULT_PRIORITY, SocketTag(),
8026 /*cert_verify_flags=*/0, url1, net_log_,
8027 &net_error_details_, callback_.callback()));
bnc47eba7d2016-07-01 00:43:388028 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:248029 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
bnc47eba7d2016-07-01 00:43:388030 EXPECT_TRUE(stream1.get());
8031 EXPECT_TRUE(HasActiveSession(origin1_));
8032
8033 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:458034 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338035 EXPECT_EQ(ERR_IO_PENDING,
8036 request2.Request(destination, version_, PRIVACY_MODE_ENABLED,
8037 DEFAULT_PRIORITY, SocketTag(),
8038 /*cert_verify_flags=*/0, url2, net_log_,
8039 &net_error_details_, callback2.callback()));
bnc47eba7d2016-07-01 00:43:388040 EXPECT_EQ(OK, callback2.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:248041 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
bnc47eba7d2016-07-01 00:43:388042 EXPECT_TRUE(stream2.get());
8043
8044 // |request2| does not pool to the first session, because PrivacyMode does not
8045 // match. Instead, another session is opened to the same destination, but
Ryan Hamilton8d9ee76e2018-05-29 23:52:528046 // with a different quic::QuicServerId.
rchf0b18c8a2017-05-05 19:31:578047 QuicChromiumClientSession::Handle* session1 =
8048 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
8049 QuicChromiumClientSession::Handle* session2 =
8050 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
8051 EXPECT_FALSE(session1->SharesSameSession(*session2));
bnc47eba7d2016-07-01 00:43:388052
Ryan Hamilton4f0b26e2018-06-27 23:52:328053 EXPECT_EQ(quic::QuicServerId(origin1_.host(), origin1_.port(), false),
bnc47eba7d2016-07-01 00:43:388054 session1->server_id());
Ryan Hamilton4f0b26e2018-06-27 23:52:328055 EXPECT_EQ(quic::QuicServerId(origin2_.host(), origin2_.port(), true),
bnc47eba7d2016-07-01 00:43:388056 session2->server_id());
8057
8058 EXPECT_TRUE(AllDataConsumed());
8059}
8060
bnc359ed2a2016-04-29 20:43:458061// QuicStreamRequest is not pooled if certificate does not match its origin.
8062TEST_P(QuicStreamFactoryWithDestinationTest, DisjointCertificate) {
8063 Initialize();
8064
8065 GURL url1("https://news.example.org/");
8066 GURL url2("https://mail.example.com/");
8067 origin1_ = HostPortPair::FromURL(url1);
8068 origin2_ = HostPortPair::FromURL(url2);
8069
8070 HostPortPair destination = GetDestination();
8071
8072 scoped_refptr<X509Certificate> cert1(
8073 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:248074 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_.host()));
8075 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_.host()));
8076 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:458077
8078 ProofVerifyDetailsChromium verify_details1;
8079 verify_details1.cert_verify_result.verified_cert = cert1;
8080 verify_details1.cert_verify_result.is_issued_by_known_root = true;
8081 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
8082
8083 scoped_refptr<X509Certificate> cert2(
8084 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:248085 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_.host()));
8086 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:458087
8088 ProofVerifyDetailsChromium verify_details2;
8089 verify_details2.cert_verify_result.verified_cert = cert2;
8090 verify_details2.cert_verify_result.is_issued_by_known_root = true;
8091 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
8092
fayang3bcb8b502016-12-07 21:44:378093 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:528094 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:368095 client_maker_.MakeInitialSettingsPacket(1, nullptr));
bnceb9aa7112017-01-05 01:03:468096 MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(),
8097 settings_packet->length(), 1)};
fayang3bcb8b502016-12-07 21:44:378098 std::unique_ptr<SequencedSocketData> sequenced_socket_data(
Ryan Sleevib8d7ea02018-05-07 20:01:018099 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:178100 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
fayang3bcb8b502016-12-07 21:44:378101 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
8102 std::unique_ptr<SequencedSocketData> sequenced_socket_data1(
Ryan Sleevib8d7ea02018-05-07 20:01:018103 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:178104 socket_factory_->AddSocketDataProvider(sequenced_socket_data1.get());
fayang3bcb8b502016-12-07 21:44:378105 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data1));
bnc359ed2a2016-04-29 20:43:458106
zhongyi98d6a9262017-05-19 02:47:458107 QuicStreamRequest request1(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338108 EXPECT_EQ(ERR_IO_PENDING,
8109 request1.Request(destination, version_, privacy_mode_,
8110 DEFAULT_PRIORITY, SocketTag(),
8111 /*cert_verify_flags=*/0, url1, net_log_,
8112 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:018113 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:248114 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
bnc359ed2a2016-04-29 20:43:458115 EXPECT_TRUE(stream1.get());
8116 EXPECT_TRUE(HasActiveSession(origin1_));
8117
8118 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:458119 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338120 EXPECT_EQ(ERR_IO_PENDING,
8121 request2.Request(destination, version_, privacy_mode_,
8122 DEFAULT_PRIORITY, SocketTag(),
8123 /*cert_verify_flags=*/0, url2, net_log_,
8124 &net_error_details_, callback2.callback()));
robpercival214763f2016-07-01 23:27:018125 EXPECT_THAT(callback2.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:248126 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
bnc359ed2a2016-04-29 20:43:458127 EXPECT_TRUE(stream2.get());
8128
8129 // |request2| does not pool to the first session, because the certificate does
8130 // not match. Instead, another session is opened to the same destination, but
Ryan Hamilton8d9ee76e2018-05-29 23:52:528131 // with a different quic::QuicServerId.
rchf0b18c8a2017-05-05 19:31:578132 QuicChromiumClientSession::Handle* session1 =
8133 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
8134 QuicChromiumClientSession::Handle* session2 =
8135 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
8136 EXPECT_FALSE(session1->SharesSameSession(*session2));
bnc359ed2a2016-04-29 20:43:458137
Ryan Hamilton4f0b26e2018-06-27 23:52:328138 EXPECT_EQ(quic::QuicServerId(origin1_.host(), origin1_.port(),
8139 privacy_mode_ == PRIVACY_MODE_ENABLED),
8140 session1->server_id());
8141 EXPECT_EQ(quic::QuicServerId(origin2_.host(), origin2_.port(),
8142 privacy_mode_ == PRIVACY_MODE_ENABLED),
8143 session2->server_id());
bnc359ed2a2016-04-29 20:43:458144
8145 EXPECT_TRUE(AllDataConsumed());
8146}
8147
msramek992625ec2016-08-04 18:33:588148// This test verifies that QuicStreamFactory::ClearCachedStatesInCryptoConfig
8149// correctly transform an origin filter to a ServerIdFilter. Whether the
8150// deletion itself works correctly is tested in QuicCryptoClientConfigTest.
8151TEST_P(QuicStreamFactoryTest, ClearCachedStatesInCryptoConfig) {
8152 Initialize();
Ryan Hamilton8d9ee76e2018-05-29 23:52:528153 quic::QuicCryptoClientConfig* crypto_config =
msramek992625ec2016-08-04 18:33:588154 QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
8155
8156 struct TestCase {
8157 TestCase(const std::string& host,
8158 int port,
8159 PrivacyMode privacy_mode,
Ryan Hamilton8d9ee76e2018-05-29 23:52:528160 quic::QuicCryptoClientConfig* crypto_config)
msramek992625ec2016-08-04 18:33:588161 : server_id(host, port, privacy_mode),
8162 state(crypto_config->LookupOrCreate(server_id)) {
rch872e00e2016-12-02 02:48:188163 std::vector<string> certs(1);
msramek992625ec2016-08-04 18:33:588164 certs[0] = "cert";
8165 state->SetProof(certs, "cert_sct", "chlo_hash", "signature");
8166 state->set_source_address_token("TOKEN");
8167 state->SetProofValid();
8168
8169 EXPECT_FALSE(state->certs().empty());
8170 }
8171
Ryan Hamilton8d9ee76e2018-05-29 23:52:528172 quic::QuicServerId server_id;
8173 quic::QuicCryptoClientConfig::CachedState* state;
msramek992625ec2016-08-04 18:33:588174 } test_cases[] = {
8175 TestCase("www.google.com", 443, privacy_mode_, crypto_config),
8176 TestCase("www.example.com", 443, privacy_mode_, crypto_config),
8177 TestCase("www.example.com", 4433, privacy_mode_, crypto_config)};
8178
8179 // Clear cached states for the origin https://www.example.com:4433.
8180 GURL origin("https://www.example.com:4433");
csharrisonebeca8e2016-10-18 02:35:368181 factory_->ClearCachedStatesInCryptoConfig(base::Bind(
8182 static_cast<bool (*)(const GURL&, const GURL&)>(::operator==), origin));
msramek992625ec2016-08-04 18:33:588183 EXPECT_FALSE(test_cases[0].state->certs().empty());
8184 EXPECT_FALSE(test_cases[1].state->certs().empty());
8185 EXPECT_TRUE(test_cases[2].state->certs().empty());
8186
8187 // Clear all cached states.
8188 factory_->ClearCachedStatesInCryptoConfig(
8189 base::Callback<bool(const GURL&)>());
8190 EXPECT_TRUE(test_cases[0].state->certs().empty());
8191 EXPECT_TRUE(test_cases[1].state->certs().empty());
8192 EXPECT_TRUE(test_cases[2].state->certs().empty());
8193}
8194
Yixin Wang46a425f2017-08-10 23:02:208195// Passes connection options and client connection options to QuicStreamFactory,
Ryan Hamilton8d9ee76e2018-05-29 23:52:528196// then checks that its internal quic::QuicConfig is correct.
Yixin Wang46a425f2017-08-10 23:02:208197TEST_P(QuicStreamFactoryTest, ConfigConnectionOptions) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:528198 connection_options_.push_back(quic::kTIME);
8199 connection_options_.push_back(quic::kTBBR);
8200 connection_options_.push_back(quic::kREJ);
Yixin Wang46a425f2017-08-10 23:02:208201
Ryan Hamilton8d9ee76e2018-05-29 23:52:528202 client_connection_options_.push_back(quic::kTBBR);
8203 client_connection_options_.push_back(quic::k1RTT);
Yixin Wang46a425f2017-08-10 23:02:208204
8205 Initialize();
8206
Ryan Hamilton8d9ee76e2018-05-29 23:52:528207 const quic::QuicConfig* config =
8208 QuicStreamFactoryPeer::GetConfig(factory_.get());
Yixin Wang46a425f2017-08-10 23:02:208209 EXPECT_EQ(connection_options_, config->SendConnectionOptions());
8210 EXPECT_TRUE(config->HasClientRequestedIndependentOption(
Ryan Hamilton8d9ee76e2018-05-29 23:52:528211 quic::kTBBR, quic::Perspective::IS_CLIENT));
Yixin Wang46a425f2017-08-10 23:02:208212 EXPECT_TRUE(config->HasClientRequestedIndependentOption(
Ryan Hamilton8d9ee76e2018-05-29 23:52:528213 quic::k1RTT, quic::Perspective::IS_CLIENT));
Yixin Wang46a425f2017-08-10 23:02:208214}
8215
Yixin Wang247ea642017-11-15 01:15:508216// Verifies that the host resolver uses the request priority passed to
8217// QuicStreamRequest::Request().
8218TEST_P(QuicStreamFactoryTest, HostResolverUsesRequestPriority) {
8219 Initialize();
8220 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8221 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8222
8223 MockQuicData socket_data;
8224 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:438225 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:178226 socket_data.AddSocketDataToFactory(socket_factory_.get());
Yixin Wang247ea642017-11-15 01:15:508227
8228 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338229 EXPECT_EQ(ERR_IO_PENDING,
8230 request.Request(host_port_pair_, version_, privacy_mode_,
8231 MAXIMUM_PRIORITY, SocketTag(),
8232 /*cert_verify_flags=*/0, url_, net_log_,
8233 &net_error_details_, callback_.callback()));
Yixin Wang247ea642017-11-15 01:15:508234
8235 EXPECT_THAT(callback_.WaitForResult(), IsOk());
8236 std::unique_ptr<HttpStream> stream = CreateStream(&request);
8237 EXPECT_TRUE(stream.get());
8238
8239 EXPECT_EQ(MAXIMUM_PRIORITY, host_resolver_.last_request_priority());
8240
8241 EXPECT_TRUE(socket_data.AllReadDataConsumed());
8242 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
8243}
8244
Yixin Wang469da562017-11-15 21:34:588245// Passes |max_time_before_crypto_handshake_seconds| and
8246// |max_idle_time_before_crypto_handshake_seconds| to QuicStreamFactory, then
Ryan Hamilton8d9ee76e2018-05-29 23:52:528247// checks that its internal quic::QuicConfig is correct.
Yixin Wang469da562017-11-15 21:34:588248TEST_P(QuicStreamFactoryTest, ConfigMaxTimeBeforeCryptoHandshake) {
8249 max_time_before_crypto_handshake_seconds_ = 11;
8250 max_idle_time_before_crypto_handshake_seconds_ = 13;
8251
8252 Initialize();
8253
Ryan Hamilton8d9ee76e2018-05-29 23:52:528254 const quic::QuicConfig* config =
8255 QuicStreamFactoryPeer::GetConfig(factory_.get());
8256 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(11),
Yixin Wang469da562017-11-15 21:34:588257 config->max_time_before_crypto_handshake());
Ryan Hamilton8d9ee76e2018-05-29 23:52:528258 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(13),
Yixin Wang469da562017-11-15 21:34:588259 config->max_idle_time_before_crypto_handshake());
8260}
8261
Yixin Wang7c5d11a82017-12-21 02:40:008262// Verify ResultAfterHostResolutionCallback behavior when host resolution
8263// succeeds asynchronously, then crypto handshake fails synchronously.
8264TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackAsyncSync) {
8265 Initialize();
8266 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8267 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8268
8269 host_resolver_.set_ondemand_mode(true);
8270
8271 MockQuicData socket_data;
8272 socket_data.AddRead(SYNCHRONOUS, ERR_FAILED);
8273 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
8274 socket_data.AddSocketDataToFactory(socket_factory_.get());
8275
8276 QuicStreamRequest request(factory_.get());
8277 EXPECT_EQ(ERR_IO_PENDING,
8278 request.Request(host_port_pair_, version_, privacy_mode_,
Paul Jensen8e3c5d32018-02-19 17:06:338279 DEFAULT_PRIORITY, SocketTag(),
Yixin Wang7c5d11a82017-12-21 02:40:008280 /*cert_verify_flags=*/0, url_, net_log_,
8281 &net_error_details_, callback_.callback()));
8282
8283 TestCompletionCallback host_resolution_callback;
8284 EXPECT_TRUE(
8285 request.WaitForHostResolution(host_resolution_callback.callback()));
8286
8287 // |host_resolver_| has not finished host resolution at this point, so
8288 // |host_resolution_callback| should not have a result.
8289 base::RunLoop().RunUntilIdle();
8290 EXPECT_FALSE(host_resolution_callback.have_result());
8291
8292 // Allow |host_resolver_| to finish host resolution.
8293 // Since the request fails immediately after host resolution (getting
8294 // ERR_FAILED from socket reads/writes), |host_resolution_callback| should be
8295 // called with ERR_QUIC_PROTOCOL_ERROR since that's the next result in
8296 // forming the connection.
8297 host_resolver_.ResolveAllPending();
8298 base::RunLoop().RunUntilIdle();
8299 EXPECT_TRUE(host_resolution_callback.have_result());
8300 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, host_resolution_callback.WaitForResult());
8301
8302 // Calling WaitForHostResolution() a second time should return
8303 // false since host resolution has finished already.
8304 EXPECT_FALSE(
8305 request.WaitForHostResolution(host_resolution_callback.callback()));
8306
8307 EXPECT_TRUE(callback_.have_result());
8308 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
8309}
8310
8311// Verify ResultAfterHostResolutionCallback behavior when host resolution
8312// succeeds asynchronously, then crypto handshake fails asynchronously.
8313TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackAsyncAsync) {
8314 Initialize();
8315 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8316 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8317
8318 host_resolver_.set_ondemand_mode(true);
8319 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:278320 MockCryptoClientStream::ZERO_RTT);
Yixin Wang7c5d11a82017-12-21 02:40:008321 factory_->set_require_confirmation(true);
8322
8323 MockQuicData socket_data;
8324 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
8325 socket_data.AddRead(ASYNC, ERR_FAILED);
8326 socket_data.AddWrite(ASYNC, ERR_FAILED);
8327 socket_data.AddSocketDataToFactory(socket_factory_.get());
8328
8329 QuicStreamRequest request(factory_.get());
8330 EXPECT_EQ(ERR_IO_PENDING,
8331 request.Request(host_port_pair_, version_, privacy_mode_,
Paul Jensen8e3c5d32018-02-19 17:06:338332 DEFAULT_PRIORITY, SocketTag(),
Yixin Wang7c5d11a82017-12-21 02:40:008333 /*cert_verify_flags=*/0, url_, net_log_,
8334 &net_error_details_, callback_.callback()));
8335
8336 TestCompletionCallback host_resolution_callback;
8337 EXPECT_TRUE(
8338 request.WaitForHostResolution(host_resolution_callback.callback()));
8339
8340 // |host_resolver_| has not finished host resolution at this point, so
8341 // |host_resolution_callback| should not have a result.
8342 base::RunLoop().RunUntilIdle();
8343 EXPECT_FALSE(host_resolution_callback.have_result());
8344
8345 // Allow |host_resolver_| to finish host resolution. Since crypto handshake
8346 // will hang after host resolution, |host_resolution_callback| should run with
8347 // ERR_IO_PENDING since that's the next result in forming the connection.
8348 host_resolver_.ResolveAllPending();
8349 base::RunLoop().RunUntilIdle();
8350 EXPECT_TRUE(host_resolution_callback.have_result());
8351 EXPECT_EQ(ERR_IO_PENDING, host_resolution_callback.WaitForResult());
8352
8353 // Calling WaitForHostResolution() a second time should return
8354 // false since host resolution has finished already.
8355 EXPECT_FALSE(
8356 request.WaitForHostResolution(host_resolution_callback.callback()));
8357
8358 EXPECT_FALSE(callback_.have_result());
8359 socket_data.GetSequencedSocketData()->Resume();
8360 base::RunLoop().RunUntilIdle();
8361 EXPECT_TRUE(callback_.have_result());
8362 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
8363}
8364
8365// Verify ResultAfterHostResolutionCallback behavior when host resolution
8366// succeeds synchronously, then crypto handshake fails synchronously.
8367TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackSyncSync) {
8368 Initialize();
8369 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8370 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8371
8372 host_resolver_.set_synchronous_mode(true);
8373
8374 MockQuicData socket_data;
8375 socket_data.AddRead(SYNCHRONOUS, ERR_FAILED);
8376 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
8377 socket_data.AddSocketDataToFactory(socket_factory_.get());
8378
8379 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338380 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR,
8381 request.Request(host_port_pair_, version_, privacy_mode_,
8382 DEFAULT_PRIORITY, SocketTag(),
8383 /*cert_verify_flags=*/0, url_, net_log_,
8384 &net_error_details_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:008385
8386 // WaitForHostResolution() should return false since host
8387 // resolution has finished already.
8388 TestCompletionCallback host_resolution_callback;
8389 EXPECT_FALSE(
8390 request.WaitForHostResolution(host_resolution_callback.callback()));
8391 base::RunLoop().RunUntilIdle();
8392 EXPECT_FALSE(host_resolution_callback.have_result());
8393 EXPECT_FALSE(callback_.have_result());
8394}
8395
8396// Verify ResultAfterHostResolutionCallback behavior when host resolution
8397// succeeds synchronously, then crypto handshake fails asynchronously.
8398TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackSyncAsync) {
8399 Initialize();
8400 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8401 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8402
8403 // Host resolution will succeed synchronously, but Request() as a whole
8404 // will fail asynchronously.
8405 host_resolver_.set_synchronous_mode(true);
8406 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:278407 MockCryptoClientStream::ZERO_RTT);
Yixin Wang7c5d11a82017-12-21 02:40:008408 factory_->set_require_confirmation(true);
8409
8410 MockQuicData socket_data;
8411 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
8412 socket_data.AddRead(ASYNC, ERR_FAILED);
8413 socket_data.AddWrite(ASYNC, ERR_FAILED);
8414 socket_data.AddSocketDataToFactory(socket_factory_.get());
8415
8416 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338417 EXPECT_EQ(ERR_IO_PENDING,
8418 request.Request(host_port_pair_, version_, privacy_mode_,
8419 DEFAULT_PRIORITY, SocketTag(),
8420 /*cert_verify_flags=*/0, url_, net_log_,
8421 &net_error_details_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:008422
8423 // WaitForHostResolution() should return false since host
8424 // resolution has finished already.
8425 TestCompletionCallback host_resolution_callback;
8426 EXPECT_FALSE(
8427 request.WaitForHostResolution(host_resolution_callback.callback()));
8428 base::RunLoop().RunUntilIdle();
8429 EXPECT_FALSE(host_resolution_callback.have_result());
8430
8431 EXPECT_FALSE(callback_.have_result());
8432 socket_data.GetSequencedSocketData()->Resume();
8433 base::RunLoop().RunUntilIdle();
8434 EXPECT_TRUE(callback_.have_result());
8435 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
8436}
8437
8438// Verify ResultAfterHostResolutionCallback behavior when host resolution fails
8439// synchronously.
8440TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackFailSync) {
8441 Initialize();
8442 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8443 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8444
8445 // Host resolution will fail synchronously.
8446 host_resolver_.rules()->AddSimulatedFailure(host_port_pair_.host());
8447 host_resolver_.set_synchronous_mode(true);
8448
8449 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338450 EXPECT_EQ(ERR_NAME_NOT_RESOLVED,
8451 request.Request(host_port_pair_, version_, privacy_mode_,
8452 DEFAULT_PRIORITY, SocketTag(),
8453 /*cert_verify_flags=*/0, url_, net_log_,
8454 &net_error_details_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:008455
8456 // WaitForHostResolution() should return false since host
8457 // resolution has failed already.
8458 TestCompletionCallback host_resolution_callback;
8459 EXPECT_FALSE(
8460 request.WaitForHostResolution(host_resolution_callback.callback()));
8461 base::RunLoop().RunUntilIdle();
8462 EXPECT_FALSE(host_resolution_callback.have_result());
8463}
8464
8465// Verify ResultAfterHostResolutionCallback behavior when host resolution fails
8466// asynchronously.
8467TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackFailAsync) {
8468 Initialize();
8469 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8470 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8471
8472 host_resolver_.rules()->AddSimulatedFailure(host_port_pair_.host());
8473
8474 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338475 EXPECT_EQ(ERR_IO_PENDING,
8476 request.Request(host_port_pair_, version_, privacy_mode_,
8477 DEFAULT_PRIORITY, SocketTag(),
8478 /*cert_verify_flags=*/0, url_, net_log_,
8479 &net_error_details_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:008480
8481 TestCompletionCallback host_resolution_callback;
8482 EXPECT_TRUE(
8483 request.WaitForHostResolution(host_resolution_callback.callback()));
8484
8485 // Allow |host_resolver_| to fail host resolution. |host_resolution_callback|
8486 // Should run with ERR_NAME_NOT_RESOLVED since that's the error host
8487 // resolution failed with.
8488 base::RunLoop().RunUntilIdle();
8489 EXPECT_TRUE(host_resolution_callback.have_result());
8490 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, host_resolution_callback.WaitForResult());
8491
8492 EXPECT_TRUE(callback_.have_result());
8493 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, callback_.WaitForResult());
8494}
8495
Paul Jensen8e3c5d32018-02-19 17:06:338496// Test that QuicStreamRequests with similar and different tags results in
8497// reused and unique QUIC streams using appropriately tagged sockets.
8498TEST_P(QuicStreamFactoryTest, Tag) {
8499 MockTaggingClientSocketFactory* socket_factory =
8500 new MockTaggingClientSocketFactory();
8501 socket_factory_.reset(socket_factory);
8502 Initialize();
8503 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8504 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8505
8506 // Prepare to establish two QUIC sessions.
8507 MockQuicData socket_data;
8508 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:438509 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Paul Jensen8e3c5d32018-02-19 17:06:338510 socket_data.AddSocketDataToFactory(socket_factory_.get());
8511 MockQuicData socket_data2;
8512 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:438513 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Paul Jensen8e3c5d32018-02-19 17:06:338514 socket_data2.AddSocketDataToFactory(socket_factory_.get());
8515
8516#if defined(OS_ANDROID)
8517 SocketTag tag1(SocketTag::UNSET_UID, 0x12345678);
8518 SocketTag tag2(getuid(), 0x87654321);
8519#else
8520 // On non-Android platforms we can only use the default constructor.
8521 SocketTag tag1, tag2;
8522#endif
8523
8524 // Request a stream with |tag1|.
8525 QuicStreamRequest request1(factory_.get());
8526 int rv =
8527 request1.Request(host_port_pair_, version_, privacy_mode_,
8528 DEFAULT_PRIORITY, tag1, /*cert_verify_flags=*/0, url_,
8529 net_log_, &net_error_details_, callback_.callback());
8530 EXPECT_THAT(callback_.GetResult(rv), IsOk());
8531 EXPECT_EQ(socket_factory->GetLastProducedUDPSocket()->tag(), tag1);
8532 EXPECT_TRUE(socket_factory->GetLastProducedUDPSocket()
8533 ->tagged_before_data_transferred());
8534 std::unique_ptr<QuicChromiumClientSession::Handle> stream1 =
8535 request1.ReleaseSessionHandle();
8536 EXPECT_TRUE(stream1);
8537 EXPECT_TRUE(stream1->IsConnected());
8538
8539 // Request a stream with |tag1| and verify underlying session is reused.
8540 QuicStreamRequest request2(factory_.get());
8541 rv = request2.Request(host_port_pair_, version_, privacy_mode_,
8542 DEFAULT_PRIORITY, tag1,
8543 /*cert_verify_flags=*/0, url_, net_log_,
8544 &net_error_details_, callback_.callback());
8545 EXPECT_THAT(callback_.GetResult(rv), IsOk());
8546 std::unique_ptr<QuicChromiumClientSession::Handle> stream2 =
8547 request2.ReleaseSessionHandle();
8548 EXPECT_TRUE(stream2);
8549 EXPECT_TRUE(stream2->IsConnected());
8550 EXPECT_TRUE(stream2->SharesSameSession(*stream1));
8551
8552 // Request a stream with |tag2| and verify a new session is created.
8553 QuicStreamRequest request3(factory_.get());
8554 rv = request3.Request(host_port_pair_, version_, privacy_mode_,
8555 DEFAULT_PRIORITY, tag2,
8556 /*cert_verify_flags=*/0, url_, net_log_,
8557 &net_error_details_, callback_.callback());
8558 EXPECT_THAT(callback_.GetResult(rv), IsOk());
8559 EXPECT_EQ(socket_factory->GetLastProducedUDPSocket()->tag(), tag2);
8560 EXPECT_TRUE(socket_factory->GetLastProducedUDPSocket()
8561 ->tagged_before_data_transferred());
8562 std::unique_ptr<QuicChromiumClientSession::Handle> stream3 =
8563 request3.ReleaseSessionHandle();
8564 EXPECT_TRUE(stream3);
8565 EXPECT_TRUE(stream3->IsConnected());
8566#if defined(OS_ANDROID)
8567 EXPECT_FALSE(stream3->SharesSameSession(*stream1));
8568#else
8569 // Same tag should reuse session.
8570 EXPECT_TRUE(stream3->SharesSameSession(*stream1));
8571#endif
8572}
8573
[email protected]e13201d82012-12-12 05:00:328574} // namespace test
[email protected]e13201d82012-12-12 05:00:328575} // namespace net