blob: da78e6347ede2ffcfe9229b1b928579861ed70e4 [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_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521310 session->CloseSessionOnError(0u, quic::QUIC_NO_ERROR);
jri94ddc3142016-08-26 01:32:431311
1312 // Set up server IP, socket, proof, and config for new session.
1313 HostPortPair server2(kServer2HostName, kDefaultServerPort);
1314 host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
1315
1316 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521317 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361318 client_maker_.MakeInitialSettingsPacket(1, nullptr));
bnceb9aa7112017-01-05 01:03:461319 MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(),
1320 settings_packet->length(), 1)};
fayang3bcb8b502016-12-07 21:44:371321
Ryan Sleevib8d7ea02018-05-07 20:01:011322 SequencedSocketData socket_data(reads, writes);
Zhongyi Shi5f587cc2017-11-21 23:24:171323 socket_factory_->AddSocketDataProvider(&socket_data);
jri94ddc3142016-08-26 01:32:431324
1325 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1326 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521327 quic::QuicConfig config2;
jri94ddc3142016-08-26 01:32:431328 crypto_client_stream_factory_.SetConfig(config2);
1329
1330 // Create new request to cause new session creation.
1331 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451332 QuicStreamRequest request2(factory_.get());
jri94ddc3142016-08-26 01:32:431333 EXPECT_EQ(ERR_IO_PENDING,
Yixin Wang247ea642017-11-15 01:15:501334 request2.Request(server2, version_, privacy_mode_, DEFAULT_PRIORITY,
Paul Jensen8e3c5d32018-02-19 17:06:331335 SocketTag(),
Yixin Wang7f3cdc3f2017-11-10 01:44:141336 /*cert_verify_flags=*/0, url2_, net_log_,
Ryan Hamilton75f197262017-08-17 14:00:071337 &net_error_details_, callback.callback()));
jri94ddc3142016-08-26 01:32:431338 EXPECT_EQ(OK, callback.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:241339 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
jri94ddc3142016-08-26 01:32:431340 EXPECT_TRUE(stream2.get());
1341
1342 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1343 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1344 // EXPECT_EQ(GetActiveSession(host_port_pair_), GetActiveSession(server2));
1345}
1346
[email protected]eed749f92013-12-23 18:57:381347TEST_P(QuicStreamFactoryTest, NoPoolingAfterGoAway) {
jri7046038f2015-10-22 00:29:261348 Initialize();
rch6faa4d42016-01-05 20:48:431349 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1350 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1351 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:261352
rcha00569732016-08-27 11:09:361353 MockQuicData socket_data1;
1354 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431355 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171356 socket_data1.AddSocketDataToFactory(socket_factory_.get());
rcha00569732016-08-27 11:09:361357 MockQuicData socket_data2;
1358 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431359 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171360 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]eed749f92013-12-23 18:57:381361
rch6faa4d42016-01-05 20:48:431362 HostPortPair server2(kServer2HostName, kDefaultServerPort);
[email protected]eed749f92013-12-23 18:57:381363 host_resolver_.set_synchronous_mode(true);
rch6faa4d42016-01-05 20:48:431364 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
rjshaded5ced072015-12-18 19:26:021365 "192.168.0.1", "");
rch6faa4d42016-01-05 20:48:431366 host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]eed749f92013-12-23 18:57:381367
zhongyi98d6a9262017-05-19 02:47:451368 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331369 EXPECT_EQ(OK, request.Request(host_port_pair_, version_, privacy_mode_,
1370 DEFAULT_PRIORITY, SocketTag(),
1371 /*cert_verify_flags=*/0, url_, net_log_,
1372 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241373 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]eed749f92013-12-23 18:57:381374 EXPECT_TRUE(stream.get());
1375
1376 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451377 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331378 EXPECT_EQ(OK, request2.Request(server2, version_, privacy_mode_,
1379 DEFAULT_PRIORITY, SocketTag(),
1380 /*cert_verify_flags=*/0, url2_, net_log_,
1381 &net_error_details_, callback.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241382 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]eed749f92013-12-23 18:57:381383 EXPECT_TRUE(stream2.get());
1384
bnc912a04b2016-04-20 14:19:501385 factory_->OnSessionGoingAway(GetActiveSession(host_port_pair_));
1386 EXPECT_FALSE(HasActiveSession(host_port_pair_));
1387 EXPECT_FALSE(HasActiveSession(server2));
[email protected]eed749f92013-12-23 18:57:381388
1389 TestCompletionCallback callback3;
zhongyi98d6a9262017-05-19 02:47:451390 QuicStreamRequest request3(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331391 EXPECT_EQ(OK, request3.Request(server2, version_, privacy_mode_,
1392 DEFAULT_PRIORITY, SocketTag(),
1393 /*cert_verify_flags=*/0, url2_, net_log_,
1394 &net_error_details_, callback3.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241395 std::unique_ptr<HttpStream> stream3 = CreateStream(&request3);
[email protected]eed749f92013-12-23 18:57:381396 EXPECT_TRUE(stream3.get());
1397
bnc912a04b2016-04-20 14:19:501398 EXPECT_TRUE(HasActiveSession(server2));
[email protected]eed749f92013-12-23 18:57:381399
rch37de576c2015-05-17 20:28:171400 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
1401 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
1402 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1403 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]eed749f92013-12-23 18:57:381404}
1405
[email protected]5db452202014-08-19 05:22:151406TEST_P(QuicStreamFactoryTest, HttpsPooling) {
jri7046038f2015-10-22 00:29:261407 Initialize();
rch6faa4d42016-01-05 20:48:431408
rcha00569732016-08-27 11:09:361409 MockQuicData socket_data;
1410 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431411 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171412 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]eed749f92013-12-23 18:57:381413
rch6faa4d42016-01-05 20:48:431414 HostPortPair server1(kDefaultServerHostName, 443);
1415 HostPortPair server2(kServer2HostName, 443);
[email protected]eed749f92013-12-23 18:57:381416
bncf8bf0722015-05-19 20:04:131417 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
bnc20daf9a2015-05-15 17:11:011418 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
[email protected]eed749f92013-12-23 18:57:381419
1420 host_resolver_.set_synchronous_mode(true);
[email protected]bf4ea2f2014-03-10 22:57:531421 host_resolver_.rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
1422 host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]eed749f92013-12-23 18:57:381423
zhongyi98d6a9262017-05-19 02:47:451424 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331425 EXPECT_EQ(OK, request.Request(server1, version_, privacy_mode_,
1426 DEFAULT_PRIORITY, SocketTag(),
1427 /*cert_verify_flags=*/0, url_, net_log_,
1428 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241429 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]eed749f92013-12-23 18:57:381430 EXPECT_TRUE(stream.get());
1431
1432 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451433 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331434 EXPECT_EQ(OK, request2.Request(server2, version_, privacy_mode_,
1435 DEFAULT_PRIORITY, SocketTag(),
1436 /*cert_verify_flags=*/0, url2_, net_log_,
1437 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241438 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]eed749f92013-12-23 18:57:381439 EXPECT_TRUE(stream2.get());
1440
bnc912a04b2016-04-20 14:19:501441 EXPECT_EQ(GetActiveSession(server1), GetActiveSession(server2));
[email protected]eed749f92013-12-23 18:57:381442
rch37de576c2015-05-17 20:28:171443 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1444 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]eed749f92013-12-23 18:57:381445}
1446
[email protected]5db452202014-08-19 05:22:151447TEST_P(QuicStreamFactoryTest, HttpsPoolingWithMatchingPins) {
jri7046038f2015-10-22 00:29:261448 Initialize();
rcha00569732016-08-27 11:09:361449 MockQuicData socket_data;
1450 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431451 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171452 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]5db452202014-08-19 05:22:151453
rch6faa4d42016-01-05 20:48:431454 HostPortPair server1(kDefaultServerHostName, 443);
1455 HostPortPair server2(kServer2HostName, 443);
Avi Drissman13fc8932015-12-20 04:40:461456 uint8_t primary_pin = 1;
1457 uint8_t backup_pin = 2;
rch6faa4d42016-01-05 20:48:431458 test::AddPin(&transport_security_state_, kServer2HostName, primary_pin,
[email protected]5db452202014-08-19 05:22:151459 backup_pin);
1460
bncf8bf0722015-05-19 20:04:131461 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
[email protected]5db452202014-08-19 05:22:151462 verify_details.cert_verify_result.public_key_hashes.push_back(
1463 test::GetTestHashValue(primary_pin));
bnc20daf9a2015-05-15 17:11:011464 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
[email protected]5db452202014-08-19 05:22:151465
1466 host_resolver_.set_synchronous_mode(true);
1467 host_resolver_.rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
1468 host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
1469
zhongyi98d6a9262017-05-19 02:47:451470 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331471 EXPECT_EQ(OK, request.Request(server1, version_, privacy_mode_,
1472 DEFAULT_PRIORITY, SocketTag(),
1473 /*cert_verify_flags=*/0, url_, net_log_,
1474 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241475 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]5db452202014-08-19 05:22:151476 EXPECT_TRUE(stream.get());
1477
1478 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451479 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331480 EXPECT_EQ(OK, request2.Request(server2, version_, privacy_mode_,
1481 DEFAULT_PRIORITY, SocketTag(),
1482 /*cert_verify_flags=*/0, url2_, net_log_,
1483 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241484 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]5db452202014-08-19 05:22:151485 EXPECT_TRUE(stream2.get());
1486
bnc912a04b2016-04-20 14:19:501487 EXPECT_EQ(GetActiveSession(server1), GetActiveSession(server2));
[email protected]5db452202014-08-19 05:22:151488
rch37de576c2015-05-17 20:28:171489 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1490 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]5db452202014-08-19 05:22:151491}
1492
1493TEST_P(QuicStreamFactoryTest, NoHttpsPoolingWithDifferentPins) {
jri7046038f2015-10-22 00:29:261494 Initialize();
rcha00569732016-08-27 11:09:361495
1496 MockQuicData socket_data1;
1497 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431498 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171499 socket_data1.AddSocketDataToFactory(socket_factory_.get());
rcha00569732016-08-27 11:09:361500 MockQuicData socket_data2;
1501 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431502 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171503 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]5db452202014-08-19 05:22:151504
rch6faa4d42016-01-05 20:48:431505 HostPortPair server1(kDefaultServerHostName, 443);
1506 HostPortPair server2(kServer2HostName, 443);
Avi Drissman13fc8932015-12-20 04:40:461507 uint8_t primary_pin = 1;
1508 uint8_t backup_pin = 2;
1509 uint8_t bad_pin = 3;
rch6faa4d42016-01-05 20:48:431510 test::AddPin(&transport_security_state_, kServer2HostName, primary_pin,
[email protected]5db452202014-08-19 05:22:151511 backup_pin);
1512
bncf8bf0722015-05-19 20:04:131513 ProofVerifyDetailsChromium verify_details1 = DefaultProofVerifyDetails();
bnc20daf9a2015-05-15 17:11:011514 verify_details1.cert_verify_result.public_key_hashes.push_back(
1515 test::GetTestHashValue(bad_pin));
1516 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
1517
bncf8bf0722015-05-19 20:04:131518 ProofVerifyDetailsChromium verify_details2 = DefaultProofVerifyDetails();
bnc20daf9a2015-05-15 17:11:011519 verify_details2.cert_verify_result.public_key_hashes.push_back(
1520 test::GetTestHashValue(primary_pin));
1521 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
[email protected]5db452202014-08-19 05:22:151522
1523 host_resolver_.set_synchronous_mode(true);
1524 host_resolver_.rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
1525 host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
1526
zhongyi98d6a9262017-05-19 02:47:451527 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331528 EXPECT_EQ(OK, request.Request(server1, version_, privacy_mode_,
1529 DEFAULT_PRIORITY, SocketTag(),
1530 /*cert_verify_flags=*/0, url_, net_log_,
1531 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241532 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]5db452202014-08-19 05:22:151533 EXPECT_TRUE(stream.get());
1534
1535 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451536 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331537 EXPECT_EQ(OK, request2.Request(server2, version_, privacy_mode_,
1538 DEFAULT_PRIORITY, SocketTag(),
1539 /*cert_verify_flags=*/0, url2_, net_log_,
1540 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241541 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]5db452202014-08-19 05:22:151542 EXPECT_TRUE(stream2.get());
1543
bnc912a04b2016-04-20 14:19:501544 EXPECT_NE(GetActiveSession(server1), GetActiveSession(server2));
[email protected]5db452202014-08-19 05:22:151545
rch37de576c2015-05-17 20:28:171546 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
1547 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
1548 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1549 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]5db452202014-08-19 05:22:151550}
1551
[email protected]1e960032013-12-20 19:00:201552TEST_P(QuicStreamFactoryTest, Goaway) {
jri7046038f2015-10-22 00:29:261553 Initialize();
rch6faa4d42016-01-05 20:48:431554 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1555 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1556 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1557
rcha00569732016-08-27 11:09:361558 MockQuicData socket_data;
1559 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431560 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171561 socket_data.AddSocketDataToFactory(socket_factory_.get());
rcha00569732016-08-27 11:09:361562 MockQuicData socket_data2;
1563 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431564 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171565 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]4d283b32013-10-17 12:57:271566
zhongyi98d6a9262017-05-19 02:47:451567 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331568 EXPECT_EQ(ERR_IO_PENDING,
1569 request.Request(host_port_pair_, version_, privacy_mode_,
1570 DEFAULT_PRIORITY, SocketTag(),
1571 /*cert_verify_flags=*/0, url_, net_log_,
1572 &net_error_details_, callback_.callback()));
[email protected]4d283b32013-10-17 12:57:271573
robpercival214763f2016-07-01 23:27:011574 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241575 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]4d283b32013-10-17 12:57:271576 EXPECT_TRUE(stream.get());
1577
1578 // Mark the session as going away. Ensure that while it is still alive
1579 // that it is no longer active.
bnc912a04b2016-04-20 14:19:501580 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri7046038f2015-10-22 00:29:261581 factory_->OnSessionGoingAway(session);
1582 EXPECT_EQ(true,
1583 QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
bnc912a04b2016-04-20 14:19:501584 EXPECT_FALSE(HasActiveSession(host_port_pair_));
[email protected]4d283b32013-10-17 12:57:271585
1586 // Create a new request for the same destination and verify that a
1587 // new session is created.
zhongyi98d6a9262017-05-19 02:47:451588 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331589 EXPECT_EQ(ERR_IO_PENDING,
1590 request2.Request(host_port_pair_, version_, privacy_mode_,
1591 DEFAULT_PRIORITY, SocketTag(),
1592 /*cert_verify_flags=*/0, url_, net_log_,
1593 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:011594 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241595 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]4d283b32013-10-17 12:57:271596 EXPECT_TRUE(stream2.get());
1597
bnc912a04b2016-04-20 14:19:501598 EXPECT_TRUE(HasActiveSession(host_port_pair_));
1599 EXPECT_NE(session, GetActiveSession(host_port_pair_));
jri7046038f2015-10-22 00:29:261600 EXPECT_EQ(true,
1601 QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
[email protected]4d283b32013-10-17 12:57:271602
1603 stream2.reset();
1604 stream.reset();
1605
rch37de576c2015-05-17 20:28:171606 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1607 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1608 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1609 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]4d283b32013-10-17 12:57:271610}
1611
[email protected]1e960032013-12-20 19:00:201612TEST_P(QuicStreamFactoryTest, MaxOpenStream) {
jri7046038f2015-10-22 00:29:261613 Initialize();
rch6faa4d42016-01-05 20:48:431614 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1615 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1616
Ryan Hamilton8d9ee76e2018-05-29 23:52:521617 quic::QuicStreamId stream_id = GetNthClientInitiatedStreamId(0);
rcha00569732016-08-27 11:09:361618 MockQuicData socket_data;
Zhongyi Shi32f2fd02018-04-16 18:23:431619 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
fayang3bcb8b502016-12-07 21:44:371620 socket_data.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521621 SYNCHRONOUS, client_maker_.MakeRstPacket(2, true, stream_id,
1622 quic::QUIC_STREAM_CANCELLED));
1623 socket_data.AddRead(ASYNC,
1624 server_maker_.MakeRstPacket(1, false, stream_id,
1625 quic::QUIC_STREAM_CANCELLED));
rcha00569732016-08-27 11:09:361626 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:171627 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]0b2294d32013-08-02 00:46:361628
1629 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:391630 request_info.traffic_annotation =
1631 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1632
xunjieli1d2b4272017-04-25 22:37:171633 std::vector<std::unique_ptr<HttpStream>> streams;
Ryan Hamilton9835e662018-08-02 05:36:271634 // The MockCryptoClientStream sets max_open_streams to be
Ryan Hamilton8d9ee76e2018-05-29 23:52:521635 // quic::kDefaultMaxStreamsPerConnection / 2.
1636 for (size_t i = 0; i < quic::kDefaultMaxStreamsPerConnection / 2; i++) {
zhongyi98d6a9262017-05-19 02:47:451637 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331638 int rv = request.Request(host_port_pair_, version_, privacy_mode_,
1639 DEFAULT_PRIORITY, SocketTag(),
1640 /*cert_verify_flags=*/0, url_, net_log_,
1641 &net_error_details_, callback_.callback());
[email protected]0b2294d32013-08-02 00:46:361642 if (i == 0) {
robpercival214763f2016-07-01 23:27:011643 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1644 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]0b2294d32013-08-02 00:46:361645 } else {
robpercival214763f2016-07-01 23:27:011646 EXPECT_THAT(rv, IsOk());
[email protected]0b2294d32013-08-02 00:46:361647 }
Yixin Wang7891a39d2017-11-08 20:59:241648 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0b2294d32013-08-02 00:46:361649 EXPECT_TRUE(stream);
Steven Valdezb4ff0412018-01-18 22:39:271650 EXPECT_EQ(OK,
1651 stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:391652 net_log_, CompletionOnceCallback()));
avib3635452016-10-21 18:33:531653 streams.push_back(std::move(stream));
[email protected]0b2294d32013-08-02 00:46:361654 }
1655
zhongyi98d6a9262017-05-19 02:47:451656 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331657 EXPECT_EQ(OK, request.Request(host_port_pair_, version_, privacy_mode_,
1658 DEFAULT_PRIORITY, SocketTag(),
1659 /*cert_verify_flags=*/0, url_, net_log_,
Bence Békyd8a21fc32018-06-27 18:29:581660 &net_error_details_, CompletionOnceCallback()));
Yixin Wang7891a39d2017-11-08 20:59:241661 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0b2294d32013-08-02 00:46:361662 EXPECT_TRUE(stream);
rjshaded5ced072015-12-18 19:26:021663 EXPECT_EQ(ERR_IO_PENDING,
Steven Valdezb4ff0412018-01-18 22:39:271664 stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
1665 net_log_, callback_.callback()));
[email protected]0b2294d32013-08-02 00:46:361666
1667 // Close the first stream.
1668 streams.front()->Close(false);
ckrasicea295fe2015-10-31 05:03:271669 // Trigger exchange of RSTs that in turn allow progress for the last
1670 // stream.
robpercival214763f2016-07-01 23:27:011671 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]0b2294d32013-08-02 00:46:361672
rch37de576c2015-05-17 20:28:171673 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1674 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
ckrasicea295fe2015-10-31 05:03:271675
1676 // Force close of the connection to suppress the generation of RST
1677 // packets when streams are torn down, which wouldn't be relevant to
1678 // this test anyway.
bnc912a04b2016-04-20 14:19:501679 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521680 session->connection()->CloseConnection(
1681 quic::QUIC_PUBLIC_RESET, "test",
1682 quic::ConnectionCloseBehavior::SILENT_CLOSE);
[email protected]0b2294d32013-08-02 00:46:361683}
1684
[email protected]1e960032013-12-20 19:00:201685TEST_P(QuicStreamFactoryTest, ResolutionErrorInCreate) {
jri7046038f2015-10-22 00:29:261686 Initialize();
rcha00569732016-08-27 11:09:361687 MockQuicData socket_data;
Zhongyi Shi5f587cc2017-11-21 23:24:171688 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]e13201d82012-12-12 05:00:321689
[email protected]3c772402013-12-18 21:38:111690 host_resolver_.rules()->AddSimulatedFailure(kDefaultServerHostName);
[email protected]e13201d82012-12-12 05:00:321691
zhongyi98d6a9262017-05-19 02:47:451692 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331693 EXPECT_EQ(ERR_IO_PENDING,
1694 request.Request(host_port_pair_, version_, privacy_mode_,
1695 DEFAULT_PRIORITY, SocketTag(),
1696 /*cert_verify_flags=*/0, url_, net_log_,
1697 &net_error_details_, callback_.callback()));
[email protected]e13201d82012-12-12 05:00:321698
robpercival214763f2016-07-01 23:27:011699 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
[email protected]e13201d82012-12-12 05:00:321700
rch37de576c2015-05-17 20:28:171701 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1702 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]e13201d82012-12-12 05:00:321703}
1704
[email protected]1e960032013-12-20 19:00:201705TEST_P(QuicStreamFactoryTest, ConnectErrorInCreate) {
jri7046038f2015-10-22 00:29:261706 Initialize();
rcha00569732016-08-27 11:09:361707
1708 MockQuicData socket_data;
1709 socket_data.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
Zhongyi Shi5f587cc2017-11-21 23:24:171710 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]3c772402013-12-18 21:38:111711
zhongyi98d6a9262017-05-19 02:47:451712 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331713 EXPECT_EQ(ERR_IO_PENDING,
1714 request.Request(host_port_pair_, version_, privacy_mode_,
1715 DEFAULT_PRIORITY, SocketTag(),
1716 /*cert_verify_flags=*/0, url_, net_log_,
1717 &net_error_details_, callback_.callback()));
[email protected]3c772402013-12-18 21:38:111718
robpercival214763f2016-07-01 23:27:011719 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_ADDRESS_IN_USE));
[email protected]3c772402013-12-18 21:38:111720
rch37de576c2015-05-17 20:28:171721 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1722 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]3c772402013-12-18 21:38:111723}
1724
[email protected]1e960032013-12-20 19:00:201725TEST_P(QuicStreamFactoryTest, CancelCreate) {
jri7046038f2015-10-22 00:29:261726 Initialize();
rcha00569732016-08-27 11:09:361727 MockQuicData socket_data;
1728 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431729 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171730 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]e13201d82012-12-12 05:00:321731 {
zhongyi98d6a9262017-05-19 02:47:451732 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331733 EXPECT_EQ(ERR_IO_PENDING,
1734 request.Request(host_port_pair_, version_, privacy_mode_,
1735 DEFAULT_PRIORITY, SocketTag(),
1736 /*cert_verify_flags=*/0, url_, net_log_,
1737 &net_error_details_, callback_.callback()));
[email protected]e13201d82012-12-12 05:00:321738 }
1739
mmenke651bae7f2015-12-18 21:26:451740 base::RunLoop().RunUntilIdle();
[email protected]e13201d82012-12-12 05:00:321741
zhongyi98d6a9262017-05-19 02:47:451742 QuicStreamRequest request2(factory_.get());
zhongyia00ca012017-07-06 23:36:391743 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_, privacy_mode_,
Paul Jensen8e3c5d32018-02-19 17:06:331744 DEFAULT_PRIORITY, SocketTag(),
1745 /*cert_verify_flags=*/0, url_, net_log_,
1746 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241747 std::unique_ptr<HttpStream> stream = CreateStream(&request2);
rch68a80eb2017-04-25 05:24:241748
[email protected]e13201d82012-12-12 05:00:321749 EXPECT_TRUE(stream.get());
1750 stream.reset();
1751
rch37de576c2015-05-17 20:28:171752 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1753 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]e13201d82012-12-12 05:00:321754}
1755
[email protected]1e960032013-12-20 19:00:201756TEST_P(QuicStreamFactoryTest, CloseAllSessions) {
jri7046038f2015-10-22 00:29:261757 Initialize();
rch6faa4d42016-01-05 20:48:431758 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1759 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1760 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1761
rcha00569732016-08-27 11:09:361762 MockQuicData socket_data;
1763 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431764 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Ryan Hamilton8d9ee76e2018-05-29 23:52:521765 socket_data.AddWrite(
1766 SYNCHRONOUS, ConstructClientRstPacket(2, quic::QUIC_RST_ACKNOWLEDGEMENT));
Zhongyi Shi5f587cc2017-11-21 23:24:171767 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]56dfb902013-01-03 23:17:551768
rcha00569732016-08-27 11:09:361769 MockQuicData socket_data2;
1770 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431771 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171772 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]56dfb902013-01-03 23:17:551773
zhongyi98d6a9262017-05-19 02:47:451774 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331775 EXPECT_EQ(ERR_IO_PENDING,
1776 request.Request(host_port_pair_, version_, privacy_mode_,
1777 DEFAULT_PRIORITY, SocketTag(),
1778 /*cert_verify_flags=*/0, url_, net_log_,
1779 &net_error_details_, callback_.callback()));
[email protected]56dfb902013-01-03 23:17:551780
robpercival214763f2016-07-01 23:27:011781 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241782 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0b2294d32013-08-02 00:46:361783 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:391784 request_info.traffic_annotation =
1785 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:271786 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:391787 net_log_, CompletionOnceCallback()));
[email protected]56dfb902013-01-03 23:17:551788
1789 // Close the session and verify that stream saw the error.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521790 factory_->CloseAllSessions(ERR_INTERNET_DISCONNECTED,
1791 quic::QUIC_INTERNAL_ERROR);
[email protected]56dfb902013-01-03 23:17:551792 EXPECT_EQ(ERR_INTERNET_DISCONNECTED,
1793 stream->ReadResponseHeaders(callback_.callback()));
1794
1795 // Now attempting to request a stream to the same origin should create
1796 // a new session.
1797
zhongyi98d6a9262017-05-19 02:47:451798 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331799 EXPECT_EQ(ERR_IO_PENDING,
1800 request2.Request(host_port_pair_, version_, privacy_mode_,
1801 DEFAULT_PRIORITY, SocketTag(),
1802 /*cert_verify_flags=*/0, url_, net_log_,
1803 &net_error_details_, callback_.callback()));
[email protected]56dfb902013-01-03 23:17:551804
robpercival214763f2016-07-01 23:27:011805 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241806 stream = CreateStream(&request2);
[email protected]56dfb902013-01-03 23:17:551807 stream.reset(); // Will reset stream 3.
1808
rch37de576c2015-05-17 20:28:171809 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1810 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1811 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1812 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]56dfb902013-01-03 23:17:551813}
1814
zhongyi363c91c2017-03-23 23:16:081815// Regression test for crbug.com/700617. Test a write error during the
1816// crypto handshake will not hang QuicStreamFactory::Job and should
1817// report QUIC_HANDSHAKE_FAILED to upper layers. Subsequent
1818// QuicStreamRequest should succeed without hanging.
1819TEST_P(QuicStreamFactoryTest,
1820 WriteErrorInCryptoConnectWithAsyncHostResolution) {
1821 Initialize();
1822 // Use unmocked crypto stream to do crypto connect.
1823 crypto_client_stream_factory_.set_handshake_mode(
Zhongyi Shi879659422018-08-02 17:58:251824 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
zhongyi363c91c2017-03-23 23:16:081825
1826 MockQuicData socket_data;
1827 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1828 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
1829 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:171830 socket_data.AddSocketDataToFactory(socket_factory_.get());
zhongyi363c91c2017-03-23 23:16:081831
1832 // Create request, should fail after the write of the CHLO fails.
zhongyi98d6a9262017-05-19 02:47:451833 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331834 EXPECT_EQ(ERR_IO_PENDING,
1835 request.Request(host_port_pair_, version_, privacy_mode_,
1836 DEFAULT_PRIORITY, SocketTag(),
1837 /*cert_verify_flags=*/0, url_, net_log_,
1838 &net_error_details_, callback_.callback()));
zhongyi363c91c2017-03-23 23:16:081839 EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED, callback_.WaitForResult());
1840 EXPECT_FALSE(HasActiveSession(host_port_pair_));
1841 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
1842
1843 // Verify new requests can be sent normally without hanging.
1844 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271845 MockCryptoClientStream::COLD_START);
zhongyi363c91c2017-03-23 23:16:081846 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1847 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1848 MockQuicData socket_data2;
1849 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431850 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171851 socket_data2.AddSocketDataToFactory(socket_factory_.get());
zhongyi363c91c2017-03-23 23:16:081852
zhongyi98d6a9262017-05-19 02:47:451853 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331854 EXPECT_EQ(ERR_IO_PENDING,
1855 request2.Request(host_port_pair_, version_, privacy_mode_,
1856 DEFAULT_PRIORITY, SocketTag(),
1857 /*cert_verify_flags=*/0, url_, net_log_,
1858 &net_error_details_, callback_.callback()));
zhongyi363c91c2017-03-23 23:16:081859 EXPECT_FALSE(HasActiveSession(host_port_pair_));
1860 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
1861 // Run the message loop to complete host resolution.
1862 base::RunLoop().RunUntilIdle();
1863
1864 // Complete handshake. QuicStreamFactory::Job should complete and succeed.
1865 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521866 quic::QuicSession::HANDSHAKE_CONFIRMED);
zhongyi363c91c2017-03-23 23:16:081867 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1868 EXPECT_TRUE(HasActiveSession(host_port_pair_));
1869 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
1870
1871 // Create QuicHttpStream.
Yixin Wang7891a39d2017-11-08 20:59:241872 std::unique_ptr<HttpStream> stream = CreateStream(&request2);
zhongyi363c91c2017-03-23 23:16:081873 EXPECT_TRUE(stream.get());
1874 stream.reset();
1875 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1876 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1877 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1878 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
1879}
1880
1881TEST_P(QuicStreamFactoryTest, WriteErrorInCryptoConnectWithSyncHostResolution) {
1882 Initialize();
1883 // Use unmocked crypto stream to do crypto connect.
1884 crypto_client_stream_factory_.set_handshake_mode(
Zhongyi Shi879659422018-08-02 17:58:251885 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
zhongyi363c91c2017-03-23 23:16:081886 host_resolver_.set_synchronous_mode(true);
1887 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
1888 "192.168.0.1", "");
1889
1890 MockQuicData socket_data;
1891 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1892 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
1893 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:171894 socket_data.AddSocketDataToFactory(socket_factory_.get());
zhongyi363c91c2017-03-23 23:16:081895
1896 // Create request, should fail immediately.
zhongyi98d6a9262017-05-19 02:47:451897 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331898 EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED,
1899 request.Request(host_port_pair_, version_, privacy_mode_,
1900 DEFAULT_PRIORITY, SocketTag(),
1901 /*cert_verify_flags=*/0, url_, net_log_,
1902 &net_error_details_, callback_.callback()));
zhongyi363c91c2017-03-23 23:16:081903 // Check no active session, or active jobs left for this server.
1904 EXPECT_FALSE(HasActiveSession(host_port_pair_));
1905 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
1906
1907 // Verify new requests can be sent normally without hanging.
1908 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271909 MockCryptoClientStream::COLD_START);
zhongyi363c91c2017-03-23 23:16:081910 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1911 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1912 MockQuicData socket_data2;
1913 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431914 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171915 socket_data2.AddSocketDataToFactory(socket_factory_.get());
zhongyi363c91c2017-03-23 23:16:081916
zhongyi98d6a9262017-05-19 02:47:451917 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331918 EXPECT_EQ(ERR_IO_PENDING,
1919 request2.Request(host_port_pair_, version_, privacy_mode_,
1920 DEFAULT_PRIORITY, SocketTag(),
1921 /*cert_verify_flags=*/0, url_, net_log_,
1922 &net_error_details_, callback_.callback()));
zhongyi363c91c2017-03-23 23:16:081923 EXPECT_FALSE(HasActiveSession(host_port_pair_));
1924 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
1925
1926 // Complete handshake.
1927 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521928 quic::QuicSession::HANDSHAKE_CONFIRMED);
zhongyi363c91c2017-03-23 23:16:081929 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1930 EXPECT_TRUE(HasActiveSession(host_port_pair_));
1931 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
1932
1933 // Create QuicHttpStream.
Yixin Wang7891a39d2017-11-08 20:59:241934 std::unique_ptr<HttpStream> stream = CreateStream(&request2);
zhongyi363c91c2017-03-23 23:16:081935 EXPECT_TRUE(stream.get());
1936 stream.reset();
1937 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1938 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1939 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1940 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
1941}
1942
Zhongyi Shi63574b72018-06-01 20:22:251943TEST_P(QuicStreamFactoryTest, CloseSessionsOnIPAddressChanged) {
Jana Iyengar903dec22017-11-28 00:44:231944 close_sessions_on_ip_change_ = true;
jri7046038f2015-10-22 00:29:261945 Initialize();
rch6faa4d42016-01-05 20:48:431946 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1947 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1948 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri8c44d692015-10-23 23:53:411949
rcha00569732016-08-27 11:09:361950 MockQuicData socket_data;
1951 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431952 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Ryan Hamilton8d9ee76e2018-05-29 23:52:521953 socket_data.AddWrite(
1954 SYNCHRONOUS, ConstructClientRstPacket(2, quic::QUIC_RST_ACKNOWLEDGEMENT));
Zhongyi Shi5f587cc2017-11-21 23:24:171955 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]f698a012013-05-06 20:18:591956
rcha00569732016-08-27 11:09:361957 MockQuicData socket_data2;
1958 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431959 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171960 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]f698a012013-05-06 20:18:591961
zhongyi98d6a9262017-05-19 02:47:451962 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331963 EXPECT_EQ(ERR_IO_PENDING,
1964 request.Request(host_port_pair_, version_, privacy_mode_,
1965 DEFAULT_PRIORITY, SocketTag(),
1966 /*cert_verify_flags=*/0, url_, net_log_,
1967 &net_error_details_, callback_.callback()));
[email protected]f698a012013-05-06 20:18:591968
robpercival214763f2016-07-01 23:27:011969 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241970 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0b2294d32013-08-02 00:46:361971 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:391972 request_info.traffic_annotation =
1973 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:271974 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:391975 net_log_, CompletionOnceCallback()));
[email protected]f698a012013-05-06 20:18:591976
Zhongyi Shi63574b72018-06-01 20:22:251977 // Check an active session exisits for the destination.
1978 EXPECT_TRUE(HasActiveSession(host_port_pair_));
1979 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1980 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
1981
Ryan Hamilton8e32a2b2017-08-28 20:06:521982 IPAddress last_address;
1983 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
Zhongyi Shi63574b72018-06-01 20:22:251984 // Change the IP address and verify that stream saw the error and the active
1985 // session is closed.
jri8c44d692015-10-23 23:53:411986 NotifyIPAddressChanged();
[email protected]f698a012013-05-06 20:18:591987 EXPECT_EQ(ERR_NETWORK_CHANGED,
1988 stream->ReadResponseHeaders(callback_.callback()));
jri7046038f2015-10-22 00:29:261989 EXPECT_TRUE(factory_->require_confirmation());
Ryan Hamilton8e32a2b2017-08-28 20:06:521990 EXPECT_FALSE(http_server_properties_.GetSupportsQuic(&last_address));
Zhongyi Shi63574b72018-06-01 20:22:251991 // Check no active session exists for the destination.
1992 EXPECT_FALSE(HasActiveSession(host_port_pair_));
[email protected]f698a012013-05-06 20:18:591993
1994 // Now attempting to request a stream to the same origin should create
1995 // a new session.
zhongyi98d6a9262017-05-19 02:47:451996 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331997 EXPECT_EQ(ERR_IO_PENDING,
1998 request2.Request(host_port_pair_, version_, privacy_mode_,
1999 DEFAULT_PRIORITY, SocketTag(),
2000 /*cert_verify_flags=*/0, url_, net_log_,
2001 &net_error_details_, callback_.callback()));
[email protected]f698a012013-05-06 20:18:592002
robpercival214763f2016-07-01 23:27:012003 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242004 stream = CreateStream(&request2);
[email protected]f698a012013-05-06 20:18:592005
Zhongyi Shi63574b72018-06-01 20:22:252006 // Check a new active session exisits for the destination and the old session
2007 // is no longer live.
2008 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2009 QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
2010 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
2011
2012 stream.reset(); // Will reset stream 3.
rch37de576c2015-05-17 20:28:172013 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2014 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2015 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
2016 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]f698a012013-05-06 20:18:592017}
2018
Zhongyi Shi63574b72018-06-01 20:22:252019// Test that if goaway_session_on_ip_change is set, old sessions will be marked
2020// as going away on IP address change instead of being closed. New requests will
2021// go to a new connection.
2022TEST_P(QuicStreamFactoryTest, GoAwaySessionsOnIPAddressChanged) {
2023 goaway_sessions_on_ip_change_ = true;
2024 Initialize();
2025 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2026 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2027 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2028
2029 MockQuicData quic_data1;
2030 quic::QuicStreamOffset header_stream_offset = 0;
2031 quic_data1.AddWrite(SYNCHRONOUS,
2032 ConstructInitialSettingsPacket(1, &header_stream_offset));
2033 quic_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
2034 2, GetNthClientInitiatedStreamId(0),
2035 true, true, &header_stream_offset));
2036 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
2037 quic_data1.AddRead(
2038 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
2039 false, true));
2040 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
2041 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2042
2043 MockQuicData quic_data2;
2044 quic::QuicStreamOffset header_stream_offset2 = 0;
2045 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
2046 quic_data2.AddWrite(
2047 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset2));
2048 quic_data2.AddSocketDataToFactory(socket_factory_.get());
2049
2050 // Create request and QuicHttpStream.
2051 QuicStreamRequest request(factory_.get());
2052 EXPECT_EQ(ERR_IO_PENDING,
2053 request.Request(host_port_pair_, version_, privacy_mode_,
2054 DEFAULT_PRIORITY, SocketTag(),
2055 /*cert_verify_flags=*/0, url_, net_log_,
2056 &net_error_details_, callback_.callback()));
2057 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2058 std::unique_ptr<HttpStream> stream = CreateStream(&request);
2059 EXPECT_TRUE(stream.get());
2060
2061 // Cause QUIC stream to be created.
2062 HttpRequestInfo request_info;
2063 request_info.method = "GET";
2064 request_info.url = url_;
2065 request_info.traffic_annotation =
2066 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2067 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
2068 net_log_, CompletionOnceCallback()));
2069
2070 // Ensure that session is alive and active.
2071 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
2072 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2073 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2074
2075 // Send GET request on stream.
2076 HttpResponseInfo response;
2077 HttpRequestHeaders request_headers;
2078 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
2079 callback_.callback()));
2080
2081 // Receive an IP address change notification.
2082 NotifyIPAddressChanged();
2083
2084 // The connection should still be alive, but marked as going away.
2085 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2086 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2087 EXPECT_EQ(1u, session->GetNumActiveStreams());
2088
2089 // Resume the data, response should be read from the original connection.
2090 quic_data1.Resume();
2091 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
2092 EXPECT_EQ(200, response.headers->response_code());
2093 EXPECT_EQ(0u, session->GetNumActiveStreams());
2094
2095 // Second request should be sent on a new connection.
2096 QuicStreamRequest request2(factory_.get());
2097 EXPECT_EQ(ERR_IO_PENDING,
2098 request2.Request(host_port_pair_, version_, privacy_mode_,
2099 DEFAULT_PRIORITY, SocketTag(),
2100 /*cert_verify_flags=*/0, url_, net_log_,
2101 &net_error_details_, callback_.callback()));
2102 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2103 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
2104 EXPECT_TRUE(stream2.get());
2105
2106 // Check an active session exisits for the destination.
2107 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2108 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2109 QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
2110 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
2111
2112 stream.reset();
2113 stream2.reset();
2114 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
2115 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
2116 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
2117 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
2118}
2119
Jana Iyengarba355772017-09-21 22:03:212120TEST_P(QuicStreamFactoryTest, OnIPAddressChangedWithConnectionMigration) {
Zhongyi Shi1a054612018-06-14 04:59:082121 InitializeConnectionMigrationV2Test(
Jana Iyengarba355772017-09-21 22:03:212122 {kDefaultNetworkForTests, kNewNetworkForTests});
2123 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2124 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2125 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2126
2127 MockQuicData socket_data;
2128 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432129 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Ryan Hamilton8d9ee76e2018-05-29 23:52:522130 socket_data.AddWrite(
2131 SYNCHRONOUS, ConstructClientRstPacket(2, quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:172132 socket_data.AddSocketDataToFactory(socket_factory_.get());
Jana Iyengarba355772017-09-21 22:03:212133
2134 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332135 EXPECT_EQ(ERR_IO_PENDING,
2136 request.Request(host_port_pair_, version_, privacy_mode_,
2137 DEFAULT_PRIORITY, SocketTag(),
2138 /*cert_verify_flags=*/0, url_, net_log_,
2139 &net_error_details_, callback_.callback()));
Jana Iyengarba355772017-09-21 22:03:212140
2141 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242142 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Jana Iyengarba355772017-09-21 22:03:212143 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392144 request_info.traffic_annotation =
2145 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272146 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392147 net_log_, CompletionOnceCallback()));
Jana Iyengarba355772017-09-21 22:03:212148
2149 IPAddress last_address;
2150 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
2151
2152 // Change the IP address and verify that the connection is unaffected.
2153 NotifyIPAddressChanged();
2154 EXPECT_FALSE(factory_->require_confirmation());
2155 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
2156
2157 // Attempting a new request to the same origin uses the same connection.
2158 QuicStreamRequest request2(factory_.get());
2159 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_, privacy_mode_,
Paul Jensen8e3c5d32018-02-19 17:06:332160 DEFAULT_PRIORITY, SocketTag(),
2161 /*cert_verify_flags=*/0, url_, net_log_,
2162 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:242163 stream = CreateStream(&request2);
Jana Iyengarba355772017-09-21 22:03:212164
2165 stream.reset();
2166 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2167 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2168}
2169
Zhongyi Shia0644e32018-06-21 05:19:522170TEST_P(QuicStreamFactoryTest, MigrateOnNetworkMadeDefaultWithSynchronousWrite) {
2171 TestMigrationOnNetworkMadeDefault(SYNCHRONOUS);
jri9f303712016-09-13 01:10:222172}
2173
Zhongyi Shia0644e32018-06-21 05:19:522174TEST_P(QuicStreamFactoryTest, MigrateOnNetworkMadeDefaultWithAsyncWrite) {
2175 TestMigrationOnNetworkMadeDefault(ASYNC);
jri9f303712016-09-13 01:10:222176}
2177
Zhongyi Shia0644e32018-06-21 05:19:522178// Sets up a test which attempts connection migration successfully after probing
2179// when a new network is made as default and the old default is still available.
2180// |write_mode| specifies the write mode for the last write before
2181// OnNetworkMadeDefault is delivered to session.
2182void QuicStreamFactoryTestBase::TestMigrationOnNetworkMadeDefault(
2183 IoMode write_mode) {
2184 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri7e636642016-01-14 06:57:082185 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2186 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2187 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2188
Zhongyi Shia0644e32018-06-21 05:19:522189 // Using a testing task runner so that we can control time.
2190 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
2191 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
2192
2193 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2194 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
2195
2196 MockQuicData quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522197 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shia0644e32018-06-21 05:19:522198 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
2199 quic_data1.AddWrite(SYNCHRONOUS,
2200 ConstructInitialSettingsPacket(1, &header_stream_offset));
2201 quic_data1.AddWrite(
2202 write_mode, ConstructGetRequestPacket(2, GetNthClientInitiatedStreamId(0),
2203 true, true, &header_stream_offset));
2204 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2205
2206 // Set up the second socket data provider that is used after migration.
2207 // The response to the earlier request is read on the new socket.
2208 MockQuicData quic_data2;
2209 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:252210 quic_data2.AddWrite(SYNCHRONOUS,
2211 client_maker_.MakeConnectivityProbingPacket(3, true));
Zhongyi Shia0644e32018-06-21 05:19:522212 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
2213 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:252214 quic_data2.AddRead(ASYNC,
2215 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shia0644e32018-06-21 05:19:522216 // Ping packet to send after migration is completed.
2217 quic_data2.AddWrite(ASYNC,
2218 client_maker_.MakeAckAndPingPacket(4, false, 1, 1, 1));
2219 quic_data2.AddRead(
2220 ASYNC, ConstructOkResponsePacket(2, GetNthClientInitiatedStreamId(0),
2221 false, false));
2222 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2223 quic_data2.AddWrite(SYNCHRONOUS,
2224 client_maker_.MakeAckAndRstPacket(
2225 5, false, GetNthClientInitiatedStreamId(0),
2226 quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true));
2227 quic_data2.AddSocketDataToFactory(socket_factory_.get());
jri7e636642016-01-14 06:57:082228
2229 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452230 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332231 EXPECT_EQ(ERR_IO_PENDING,
2232 request.Request(host_port_pair_, version_, privacy_mode_,
2233 DEFAULT_PRIORITY, SocketTag(),
2234 /*cert_verify_flags=*/0, url_, net_log_,
2235 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012236 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242237 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri7e636642016-01-14 06:57:082238 EXPECT_TRUE(stream.get());
2239
2240 // Cause QUIC stream to be created.
2241 HttpRequestInfo request_info;
2242 request_info.method = "GET";
bnc3d9035b32016-06-30 18:18:482243 request_info.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:392244 request_info.traffic_annotation =
2245 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272246 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392247 net_log_, CompletionOnceCallback()));
jri7e636642016-01-14 06:57:082248
2249 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502250 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri7e636642016-01-14 06:57:082251 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2252 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2253
2254 // Send GET request on stream.
2255 HttpResponseInfo response;
2256 HttpRequestHeaders request_headers;
2257 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
2258 callback_.callback()));
2259
Zhongyi Shia0644e32018-06-21 05:19:522260 // Deliver a signal that a alternate network is connected now, this should
2261 // cause the connection to start early migration on path degrading.
2262 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2263 ->SetConnectedNetworksList(
2264 {kDefaultNetworkForTests, kNewNetworkForTests});
2265 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2266 ->NotifyNetworkConnected(kNewNetworkForTests);
jri9f303712016-09-13 01:10:222267
Zhongyi Shia0644e32018-06-21 05:19:522268 // Cause the connection to report path degrading to the session.
2269 // Due to lack of alternate network, session will not mgirate connection.
2270 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
jri7e636642016-01-14 06:57:082271 scoped_mock_network_change_notifier_->mock_network_change_notifier()
jrie2661982016-08-20 08:24:342272 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri7e636642016-01-14 06:57:082273
Zhongyi Shia0644e32018-06-21 05:19:522274 // A task will be posted to migrate to the new default network.
2275 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2276 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
2277
2278 // Execute the posted task to migrate back to the default network.
2279 task_runner->RunUntilIdle();
2280 // Another task to try send a new connectivity probe is posted. And a task to
2281 // retry migrate back to default network is scheduled.
2282 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
2283 // Next connectivity probe is scheduled to be sent in 2 *
2284 // kDefaultRTTMilliSecs.
2285 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
2286 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
2287 next_task_delay);
2288
2289 // The connection should still be alive, and not marked as going away.
jri7e636642016-01-14 06:57:082290 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia0644e32018-06-21 05:19:522291 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2292 EXPECT_EQ(1u, session->GetNumActiveStreams());
2293 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
2294
2295 // Resume quic data and a connectivity probe response will be read on the new
2296 // socket, declare probing as successful. And a new task to WriteToNewSocket
2297 // will be posted to complete migration.
2298 quic_data2.Resume();
2299
2300 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2301 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri7e636642016-01-14 06:57:082302 EXPECT_EQ(1u, session->GetNumActiveStreams());
2303
Zhongyi Shia0644e32018-06-21 05:19:522304 // There should be three pending tasks, the nearest one will complete
2305 // migration to the new network.
2306 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
2307 next_task_delay = task_runner->NextPendingTaskDelay();
2308 EXPECT_EQ(base::TimeDelta(), next_task_delay);
2309 task_runner->FastForwardBy(next_task_delay);
2310
2311 // Response headers are received over the new network.
2312 EXPECT_THAT(callback_.WaitForResult(), IsOk());
jri7e636642016-01-14 06:57:082313 EXPECT_EQ(200, response.headers->response_code());
2314
Zhongyi Shia0644e32018-06-21 05:19:522315 // Now there are two pending tasks, the nearest one was to send connectivity
2316 // probe and has been cancelled due to successful migration.
2317 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
2318 next_task_delay = task_runner->NextPendingTaskDelay();
2319 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
2320 next_task_delay);
2321 task_runner->FastForwardBy(next_task_delay);
jri7e636642016-01-14 06:57:082322
Zhongyi Shia0644e32018-06-21 05:19:522323 // There's one more task to mgirate back to the default network in 0.4s, which
2324 // is also cancelled due to the success migration on the previous trial.
2325 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2326 next_task_delay = task_runner->NextPendingTaskDelay();
2327 base::TimeDelta expected_delay =
2328 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
2329 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
2330 EXPECT_EQ(expected_delay, next_task_delay);
2331 task_runner->FastForwardBy(next_task_delay);
2332 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
jri7e636642016-01-14 06:57:082333
Zhongyi Shia0644e32018-06-21 05:19:522334 // Verify that the session is still alive.
jri7e636642016-01-14 06:57:082335 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia0644e32018-06-21 05:19:522336 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri7e636642016-01-14 06:57:082337
Zhongyi Shia0644e32018-06-21 05:19:522338 stream.reset();
2339 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
2340 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
2341 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
2342 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
jri7e636642016-01-14 06:57:082343}
2344
Zhongyi Shib3bc982c2018-07-10 19:59:242345// Regression test for http://859674.
2346// This test veries that a writer will not attempt to write packets until being
2347// unblocked on both socket level and network level. In this test, a probing
2348// writer is used to send two connectivity probes to the peer: where the first
2349// one completes successfully, while a connectivity response is received before
2350// completes sending the second one. The connection migration attempt will
2351// proceed while the probing writer is blocked at the socket level, which will
2352// block the writer on the network level. Once connection migration completes
2353// successfully, the probing writer will be unblocked on the network level, it
2354// will not attempt to write new packets until the socket level is unblocked.
2355TEST_P(QuicStreamFactoryTest, MigratedToBlockedSocketAfterProbing) {
2356 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
2357 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2358 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2359 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2360
2361 // Using a testing task runner so that we can control time.
2362 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
2363 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
2364
2365 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2366 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
2367
2368 MockQuicData quic_data1;
2369 quic::QuicStreamOffset header_stream_offset = 0;
2370 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
2371 quic_data1.AddWrite(SYNCHRONOUS,
2372 ConstructInitialSettingsPacket(1, &header_stream_offset));
2373 quic_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
2374 2, GetNthClientInitiatedStreamId(0),
2375 true, true, &header_stream_offset));
2376 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2377
2378 // Set up the second socket data provider that is used after migration.
2379 // The response to the earlier request is read on the new socket.
2380 MockQuicData quic_data2;
2381 // First connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:252382 quic_data2.AddWrite(SYNCHRONOUS,
2383 client_maker_.MakeConnectivityProbingPacket(3, true));
Zhongyi Shib3bc982c2018-07-10 19:59:242384 quic_data2.AddRead(ASYNC,
2385 ERR_IO_PENDING); // Pause so that we can control time.
2386 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:252387 quic_data2.AddRead(ASYNC,
2388 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shib3bc982c2018-07-10 19:59:242389 // Second connectivity probe which will complete asynchronously.
Zhongyi Shi879659422018-08-02 17:58:252390 quic_data2.AddWrite(ASYNC,
2391 client_maker_.MakeConnectivityProbingPacket(4, true));
Zhongyi Shib3bc982c2018-07-10 19:59:242392 quic_data2.AddRead(
2393 ASYNC, ConstructOkResponsePacket(2, GetNthClientInitiatedStreamId(0),
2394 false, false));
2395 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2396 quic_data2.AddWrite(ASYNC,
2397 client_maker_.MakeAckAndPingPacket(5, false, 1, 1, 1));
2398 quic_data2.AddWrite(SYNCHRONOUS,
2399 client_maker_.MakeAckAndRstPacket(
2400 6, false, GetNthClientInitiatedStreamId(0),
2401 quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true));
2402
2403 quic_data2.AddSocketDataToFactory(socket_factory_.get());
2404
2405 // Create request and QuicHttpStream.
2406 QuicStreamRequest request(factory_.get());
2407 EXPECT_EQ(ERR_IO_PENDING,
2408 request.Request(host_port_pair_, version_, privacy_mode_,
2409 DEFAULT_PRIORITY, SocketTag(),
2410 /*cert_verify_flags=*/0, url_, net_log_,
2411 &net_error_details_, callback_.callback()));
2412 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2413 std::unique_ptr<HttpStream> stream = CreateStream(&request);
2414 EXPECT_TRUE(stream.get());
2415
2416 // Cause QUIC stream to be created.
2417 HttpRequestInfo request_info;
2418 request_info.method = "GET";
2419 request_info.url = url_;
2420 request_info.traffic_annotation =
2421 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2422 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
2423 net_log_, CompletionOnceCallback()));
2424
2425 // Ensure that session is alive and active.
2426 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
2427 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2428 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2429
2430 // Send GET request on stream.
2431 HttpResponseInfo response;
2432 HttpRequestHeaders request_headers;
2433 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
2434 callback_.callback()));
2435
2436 // Deliver a signal that a alternate network is connected now, this should
2437 // cause the connection to start early migration on path degrading.
2438 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2439 ->SetConnectedNetworksList(
2440 {kDefaultNetworkForTests, kNewNetworkForTests});
2441 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2442 ->NotifyNetworkConnected(kNewNetworkForTests);
2443
2444 // Cause the connection to report path degrading to the session.
2445 // Due to lack of alternate network, session will not mgirate connection.
2446 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
2447 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2448 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2449
2450 // A task will be posted to migrate to the new default network.
2451 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2452 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
2453
2454 // Execute the posted task to migrate back to the default network.
2455 task_runner->RunUntilIdle();
2456 // Another task to resend a new connectivity probe is posted. And a task to
2457 // retry migrate back to default network is scheduled.
2458 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
2459 // Next connectivity probe is scheduled to be sent in 2 *
2460 // kDefaultRTTMilliSecs.
2461 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
2462 base::TimeDelta expected_delay =
2463 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
2464 EXPECT_EQ(expected_delay, next_task_delay);
2465
2466 // Fast forward to send the second connectivity probe. The write will be
2467 // asynchronous and complete after the read completes.
2468 task_runner->FastForwardBy(next_task_delay);
2469
2470 // Resume quic data and a connectivity probe response will be read on the new
2471 // socket, declare probing as successful.
2472 quic_data2.Resume();
2473
2474 // The connection should still be alive, and not marked as going away.
2475 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2476 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2477 EXPECT_EQ(1u, session->GetNumActiveStreams());
2478 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
2479
2480 // There should be three pending tasks, the nearest one will complete
2481 // migration to the new network. Second task will retry migrate back to
2482 // default but cancelled, and the third task will retry send connectivity
2483 // probe but also cancelled.
2484 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
2485 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
2486 task_runner->RunUntilIdle();
2487
2488 // Response headers are received over the new network.
2489 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2490 EXPECT_EQ(200, response.headers->response_code());
2491
2492 // Run the message loop to complete the asynchronous write of ack and ping.
2493 base::RunLoop().RunUntilIdle();
2494
2495 // Now there are two pending tasks, the nearest one was to retry migrate back
2496 // to default network and has been cancelled due to successful migration.
2497 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
2498 expected_delay =
2499 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
2500 expected_delay;
2501 next_task_delay = task_runner->NextPendingTaskDelay();
2502 EXPECT_EQ(expected_delay, next_task_delay);
2503 task_runner->FastForwardBy(next_task_delay);
2504
2505 // There's one more task to retry sending connectivity probe in 0.4s and has
2506 // also been cancelled due to the successful probing.
2507 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2508 next_task_delay = task_runner->NextPendingTaskDelay();
2509 expected_delay =
2510 base::TimeDelta::FromMilliseconds(3 * 2 * kDefaultRTTMilliSecs) -
2511 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs);
2512 EXPECT_EQ(expected_delay, next_task_delay);
2513 task_runner->FastForwardBy(next_task_delay);
2514 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
2515
2516 // Verify that the session is still alive.
2517 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2518 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2519
2520 stream.reset();
2521 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
2522 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
2523 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
2524 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
2525}
2526
Zhongyi Shib1b1fa42018-06-19 23:13:472527// This test verifies that session times out connection migration attempt
2528// with signals delivered in the following order (no alternate network is
2529// available):
2530// - default network disconnected is delivered: session attempts connection
2531// migration but found not alternate network. Session waits for a new network
2532// comes up in the next kWaitTimeForNewNetworkSecs seonds.
2533// - no new network is connected, migration times out. Session is closed.
2534TEST_P(QuicStreamFactoryTest, MigrationTimeoutWithNoNewNetwork) {
2535 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri7e636642016-01-14 06:57:082536 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2537 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2538
Zhongyi Shib1b1fa42018-06-19 23:13:472539 // Using a testing task runner so that we can control time.
2540 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
2541 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
jri5b785512016-09-13 04:29:112542
rcha00569732016-08-27 11:09:362543 MockQuicData socket_data;
2544 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432545 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:172546 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri7e636642016-01-14 06:57:082547
2548 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452549 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332550 EXPECT_EQ(ERR_IO_PENDING,
2551 request.Request(host_port_pair_, version_, privacy_mode_,
2552 DEFAULT_PRIORITY, SocketTag(),
2553 /*cert_verify_flags=*/0, url_, net_log_,
2554 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012555 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242556 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri7e636642016-01-14 06:57:082557 EXPECT_TRUE(stream.get());
2558
2559 // Cause QUIC stream to be created.
2560 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392561 request_info.traffic_annotation =
2562 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272563 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392564 net_log_, CompletionOnceCallback()));
jri7e636642016-01-14 06:57:082565
2566 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502567 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri7e636642016-01-14 06:57:082568 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2569 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2570
2571 // Trigger connection migration. Since there are no networks
jri5b785512016-09-13 04:29:112572 // to migrate to, this should cause the session to wait for a new network.
jri7e636642016-01-14 06:57:082573 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2574 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
2575
jri5b785512016-09-13 04:29:112576 // The migration will not fail until the migration alarm timeout.
2577 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shib1b1fa42018-06-19 23:13:472578 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:112579 EXPECT_EQ(1u, session->GetNumActiveStreams());
2580 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
2581 EXPECT_EQ(true, session->connection()->writer()->IsWriteBlocked());
2582
Zhongyi Shib1b1fa42018-06-19 23:13:472583 // Migration will be timed out after kWaitTimeForNewNetwokSecs.
2584 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2585 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
2586 EXPECT_EQ(base::TimeDelta::FromSeconds(kWaitTimeForNewNetworkSecs),
2587 next_task_delay);
2588 task_runner->FastForwardBy(next_task_delay);
jri5b785512016-09-13 04:29:112589
2590 // The connection should now be closed. A request for response
2591 // headers should fail.
jri7e636642016-01-14 06:57:082592 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2593 EXPECT_FALSE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:112594 EXPECT_EQ(ERR_NETWORK_CHANGED, callback_.WaitForResult());
jri7e636642016-01-14 06:57:082595
2596 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2597 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2598}
2599
Zhongyi Shi21e99532018-07-17 22:23:072600// This test verifies that connectivity probes will be sent even if there is
2601// a non-migratable stream. However, when connection migrates to the
2602// successfully probed path, any non-migratable stream will be reset. And if
2603// the connection becomes idle then, close the connection.
jri9f303712016-09-13 01:10:222604TEST_P(QuicStreamFactoryTest, OnNetworkMadeDefaultNonMigratableStream) {
Zhongyi Shi5f587cc2017-11-21 23:24:172605 InitializeConnectionMigrationV2Test(
2606 {kDefaultNetworkForTests, kNewNetworkForTests});
2607 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2608 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2609
2610 MockQuicData socket_data;
2611 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432612 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:172613 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri231c2972016-03-08 19:50:112614
Zhongyi Shi21e99532018-07-17 22:23:072615 // Set up the second socket data provider that is used for probing.
2616 MockQuicData quic_data1;
2617 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:252618 quic_data1.AddWrite(SYNCHRONOUS,
2619 client_maker_.MakeConnectivityProbingPacket(2, true));
Zhongyi Shi21e99532018-07-17 22:23:072620 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
2621 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:252622 quic_data1.AddRead(ASYNC,
2623 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shi21e99532018-07-17 22:23:072624 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2625
jri231c2972016-03-08 19:50:112626 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452627 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332628 EXPECT_EQ(ERR_IO_PENDING,
2629 request.Request(host_port_pair_, version_, privacy_mode_,
2630 DEFAULT_PRIORITY, SocketTag(),
2631 /*cert_verify_flags=*/0, url_, net_log_,
2632 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012633 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242634 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri231c2972016-03-08 19:50:112635 EXPECT_TRUE(stream.get());
2636
2637 // Cause QUIC stream to be created, but marked as non-migratable.
2638 HttpRequestInfo request_info;
Zhongyi Shibb28b1f2018-07-18 02:41:262639 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Ramin Halavati683bcaa92018-02-14 08:42:392640 request_info.traffic_annotation =
2641 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272642 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392643 net_log_, CompletionOnceCallback()));
jri231c2972016-03-08 19:50:112644
2645 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502646 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri231c2972016-03-08 19:50:112647 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2648 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2649
Zhongyi Shi21e99532018-07-17 22:23:072650 // Trigger connection migration. Session will start to probe the alternative
2651 // network. Although there is a non-migratable stream, session will still be
2652 // active until probing is declared as successful.
jri231c2972016-03-08 19:50:112653 scoped_mock_network_change_notifier_->mock_network_change_notifier()
jrie2661982016-08-20 08:24:342654 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri231c2972016-03-08 19:50:112655
2656 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shi21e99532018-07-17 22:23:072657 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri231c2972016-03-08 19:50:112658 EXPECT_EQ(1u, session->GetNumActiveStreams());
2659
Zhongyi Shi21e99532018-07-17 22:23:072660 // Resume data to read a connectivity probing response, which will cause
2661 // non-migtable streams to be closed. As session becomes idle, connection will
2662 // be closed.
2663 quic_data1.Resume();
2664 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2665 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2666 EXPECT_EQ(0u, session->GetNumActiveStreams());
jri231c2972016-03-08 19:50:112667
Zhongyi Shi21e99532018-07-17 22:23:072668 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
2669 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
jri231c2972016-03-08 19:50:112670 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2671 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2672}
2673
jri9f303712016-09-13 01:10:222674TEST_P(QuicStreamFactoryTest, OnNetworkMadeDefaultConnectionMigrationDisabled) {
Zhongyi Shi5f587cc2017-11-21 23:24:172675 InitializeConnectionMigrationV2Test(
2676 {kDefaultNetworkForTests, kNewNetworkForTests});
2677 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2678 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2679
2680 MockQuicData socket_data;
2681 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432682 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
2683 socket_data.AddWrite(
2684 SYNCHRONOUS,
2685 client_maker_.MakeRstPacket(2, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:522686 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:172687 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9c541572016-03-29 17:51:482688
2689 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452690 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332691 EXPECT_EQ(ERR_IO_PENDING,
2692 request.Request(host_port_pair_, version_, privacy_mode_,
2693 DEFAULT_PRIORITY, SocketTag(),
2694 /*cert_verify_flags=*/0, url_, net_log_,
2695 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012696 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242697 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9c541572016-03-29 17:51:482698 EXPECT_TRUE(stream.get());
2699
2700 // Cause QUIC stream to be created.
2701 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392702 request_info.traffic_annotation =
2703 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272704 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392705 net_log_, CompletionOnceCallback()));
jri9c541572016-03-29 17:51:482706
2707 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502708 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri9c541572016-03-29 17:51:482709 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2710 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2711
2712 // Set session config to have connection migration disabled.
Ryan Hamilton8d9ee76e2018-05-29 23:52:522713 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
2714 session->config());
jri9c541572016-03-29 17:51:482715 EXPECT_TRUE(session->config()->DisableConnectionMigration());
2716
2717 // Trigger connection migration. Since there is a non-migratable stream,
2718 // this should cause session to continue but be marked as going away.
2719 scoped_mock_network_change_notifier_->mock_network_change_notifier()
jrie2661982016-08-20 08:24:342720 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri9c541572016-03-29 17:51:482721
2722 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2723 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2724 EXPECT_EQ(1u, session->GetNumActiveStreams());
2725
2726 stream.reset();
2727
2728 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2729 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2730}
2731
jri9f303712016-09-13 01:10:222732TEST_P(QuicStreamFactoryTest, OnNetworkDisconnectedNonMigratableStream) {
Zhongyi Shi5f587cc2017-11-21 23:24:172733 InitializeConnectionMigrationV2Test(
2734 {kDefaultNetworkForTests, kNewNetworkForTests});
2735 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2736 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2737
2738 MockQuicData socket_data;
2739 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432740 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
2741 socket_data.AddWrite(
2742 SYNCHRONOUS,
2743 client_maker_.MakeRstPacket(2, true, GetNthClientInitiatedStreamId(0),
Zhongyi Shi0439ecc72018-07-11 04:41:262744 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:172745 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri231c2972016-03-08 19:50:112746
2747 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452748 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332749 EXPECT_EQ(ERR_IO_PENDING,
2750 request.Request(host_port_pair_, version_, privacy_mode_,
2751 DEFAULT_PRIORITY, SocketTag(),
2752 /*cert_verify_flags=*/0, url_, net_log_,
2753 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012754 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242755 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri231c2972016-03-08 19:50:112756 EXPECT_TRUE(stream.get());
2757
2758 // Cause QUIC stream to be created, but marked as non-migratable.
2759 HttpRequestInfo request_info;
Zhongyi Shibb28b1f2018-07-18 02:41:262760 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Ramin Halavati683bcaa92018-02-14 08:42:392761 request_info.traffic_annotation =
2762 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272763 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392764 net_log_, CompletionOnceCallback()));
jri231c2972016-03-08 19:50:112765
2766 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502767 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri231c2972016-03-08 19:50:112768 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2769 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2770
2771 // Trigger connection migration. Since there is a non-migratable stream,
2772 // this should cause a RST_STREAM frame to be emitted with
Zhongyi Shi0439ecc72018-07-11 04:41:262773 // quic::QUIC_STREAM_CANCELLED error code, and the session will be closed.
jri231c2972016-03-08 19:50:112774 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2775 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
2776
2777 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2778 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2779
2780 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2781 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2782}
2783
jri9c541572016-03-29 17:51:482784TEST_P(QuicStreamFactoryTest,
jri9f303712016-09-13 01:10:222785 OnNetworkDisconnectedConnectionMigrationDisabled) {
Zhongyi Shi5f587cc2017-11-21 23:24:172786 InitializeConnectionMigrationV2Test(
2787 {kDefaultNetworkForTests, kNewNetworkForTests});
2788 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2789 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2790
2791 MockQuicData socket_data;
2792 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432793 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
2794 socket_data.AddWrite(
2795 SYNCHRONOUS,
2796 client_maker_.MakeRstPacket(2, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:522797 quic::QUIC_RST_ACKNOWLEDGEMENT));
Zhongyi Shi5f587cc2017-11-21 23:24:172798 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9c541572016-03-29 17:51:482799
2800 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452801 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332802 EXPECT_EQ(ERR_IO_PENDING,
2803 request.Request(host_port_pair_, version_, privacy_mode_,
2804 DEFAULT_PRIORITY, SocketTag(),
2805 /*cert_verify_flags=*/0, url_, net_log_,
2806 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012807 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242808 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9c541572016-03-29 17:51:482809 EXPECT_TRUE(stream.get());
2810
2811 // Cause QUIC stream to be created.
2812 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392813 request_info.traffic_annotation =
2814 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272815 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392816 net_log_, CompletionOnceCallback()));
jri9c541572016-03-29 17:51:482817
2818 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502819 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri9c541572016-03-29 17:51:482820 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2821 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2822
2823 // Set session config to have connection migration disabled.
Ryan Hamilton8d9ee76e2018-05-29 23:52:522824 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
2825 session->config());
jri9c541572016-03-29 17:51:482826 EXPECT_TRUE(session->config()->DisableConnectionMigration());
2827
2828 // Trigger connection migration. Since there is a non-migratable stream,
2829 // this should cause a RST_STREAM frame to be emitted with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522830 // quic::QUIC_RST_ACKNOWLEDGEMENT error code, and the session will be closed.
jri9c541572016-03-29 17:51:482831 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2832 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
2833
2834 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2835 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2836
2837 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2838 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2839}
2840
jri9f303712016-09-13 01:10:222841TEST_P(QuicStreamFactoryTest, OnNetworkMadeDefaultNoOpenStreams) {
Zhongyi Shi5f587cc2017-11-21 23:24:172842 InitializeConnectionMigrationV2Test(
2843 {kDefaultNetworkForTests, kNewNetworkForTests});
2844 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2845 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2846
2847 MockQuicData socket_data;
2848 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432849 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:172850 socket_data.AddSocketDataToFactory(socket_factory_.get());
2851
2852 // Create request and QuicHttpStream.
2853 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332854 EXPECT_EQ(ERR_IO_PENDING,
2855 request.Request(host_port_pair_, version_, privacy_mode_,
2856 DEFAULT_PRIORITY, SocketTag(),
2857 /*cert_verify_flags=*/0, url_, net_log_,
2858 &net_error_details_, callback_.callback()));
Zhongyi Shi5f587cc2017-11-21 23:24:172859 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2860 std::unique_ptr<HttpStream> stream = CreateStream(&request);
2861 EXPECT_TRUE(stream.get());
2862
2863 // Ensure that session is alive and active.
2864 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
2865 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2866 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2867
2868 // Trigger connection migration.
2869 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2870 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2871
2872 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2873 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2874
2875 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2876 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2877}
2878
jri9f303712016-09-13 01:10:222879TEST_P(QuicStreamFactoryTest, OnNetworkDisconnectedNoOpenStreams) {
Zhongyi Shi5f587cc2017-11-21 23:24:172880 InitializeConnectionMigrationV2Test(
2881 {kDefaultNetworkForTests, kNewNetworkForTests});
2882 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2883 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2884
2885 MockQuicData socket_data;
2886 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432887 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:172888 socket_data.AddSocketDataToFactory(socket_factory_.get());
2889
2890 // Create request and QuicHttpStream.
2891 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332892 EXPECT_EQ(ERR_IO_PENDING,
2893 request.Request(host_port_pair_, version_, privacy_mode_,
2894 DEFAULT_PRIORITY, SocketTag(),
2895 /*cert_verify_flags=*/0, url_, net_log_,
2896 &net_error_details_, callback_.callback()));
Zhongyi Shi5f587cc2017-11-21 23:24:172897 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2898 std::unique_ptr<HttpStream> stream = CreateStream(&request);
2899 EXPECT_TRUE(stream.get());
2900
2901 // Ensure that session is alive and active.
2902 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
2903 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2904 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2905
2906 // Trigger connection migration. Since there are no active streams,
2907 // the session will be closed.
2908 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2909 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
2910
2911 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2912 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2913
2914 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2915 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2916}
2917
Zhongyi Shi9f316b262018-06-18 22:01:162918// This test verifies session migrates to the alternate network immediately when
2919// default network disconnects with a synchronous write before migration.
2920TEST_P(QuicStreamFactoryTest, MigrateOnDefaultNetworkDisconnectedSync) {
2921 TestMigrationOnNetworkDisconnected(/*async_write_before*/ false);
2922}
2923
2924// This test verifies session migrates to the alternate network immediately when
2925// default network disconnects with an asynchronously write before migration.
2926TEST_P(QuicStreamFactoryTest, MigrateOnDefaultNetworkDisconnectedAsync) {
2927 TestMigrationOnNetworkDisconnected(/*async_write_before*/ true);
2928}
2929
2930void QuicStreamFactoryTestBase::TestMigrationOnNetworkDisconnected(
2931 bool async_write_before) {
2932 InitializeConnectionMigrationV2Test(
2933 {kDefaultNetworkForTests, kNewNetworkForTests});
2934 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2935 ->NotifyNetworkMadeDefault(kDefaultNetworkForTests);
2936 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2937 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2938 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2939
2940 // Use the test task runner.
2941 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
2942
2943 int packet_number = 1;
2944 MockQuicData socket_data;
2945 quic::QuicStreamOffset header_stream_offset = 0;
2946 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2947 socket_data.AddWrite(
2948 SYNCHRONOUS,
2949 ConstructInitialSettingsPacket(packet_number++, &header_stream_offset));
2950 socket_data.AddWrite(
2951 SYNCHRONOUS, ConstructGetRequestPacket(
2952 packet_number++, GetNthClientInitiatedStreamId(0), true,
2953 true, &header_stream_offset));
2954 if (async_write_before) {
2955 socket_data.AddWrite(ASYNC, OK);
2956 packet_number++;
2957 }
2958 socket_data.AddSocketDataToFactory(socket_factory_.get());
2959
2960 // Create request and QuicHttpStream.
2961 QuicStreamRequest request(factory_.get());
2962 EXPECT_EQ(ERR_IO_PENDING,
2963 request.Request(host_port_pair_, version_, privacy_mode_,
2964 DEFAULT_PRIORITY, SocketTag(),
2965 /*cert_verify_flags=*/0, url_, net_log_,
2966 &net_error_details_, callback_.callback()));
2967 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2968 std::unique_ptr<HttpStream> stream = CreateStream(&request);
2969 EXPECT_TRUE(stream.get());
2970
2971 // Cause QUIC stream to be created.
2972 HttpRequestInfo request_info;
2973 request_info.method = "GET";
2974 request_info.url = url_;
2975 request_info.traffic_annotation =
2976 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2977 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
2978 net_log_, CompletionOnceCallback()));
2979
2980 // Ensure that session is alive and active.
2981 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
2982 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2983 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2984
2985 // Send GET request on stream.
2986 HttpResponseInfo response;
2987 HttpRequestHeaders request_headers;
2988 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
2989 callback_.callback()));
2990
Zhongyi Shi22fd5f52018-06-20 17:39:092991 if (async_write_before)
Zhongyi Shi9f316b262018-06-18 22:01:162992 session->SendPing();
Zhongyi Shi9f316b262018-06-18 22:01:162993
2994 // Set up second socket data provider that is used after migration.
2995 // The response to the earlier request is read on this new socket.
2996 MockQuicData socket_data1;
2997 socket_data1.AddWrite(
2998 SYNCHRONOUS,
2999 client_maker_.MakePingPacket(packet_number++, /*include_version=*/true));
3000 socket_data1.AddRead(
3001 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
3002 false, false));
3003 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3004 socket_data1.AddWrite(
3005 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
3006 packet_number++, false, GetNthClientInitiatedStreamId(0),
3007 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
3008 socket_data1.AddSocketDataToFactory(socket_factory_.get());
3009
3010 // Trigger connection migration.
3011 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3012 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
3013
3014 // The connection should still be alive, not marked as going away.
3015 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3016 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3017 EXPECT_EQ(1u, session->GetNumActiveStreams());
3018 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3019
3020 // Ensure that the session is still alive.
3021 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3022 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3023 EXPECT_EQ(1u, session->GetNumActiveStreams());
3024
3025 // Run the message loop so that data queued in the new socket is read by the
3026 // packet reader.
3027 runner_->RunNextTask();
3028
3029 // Response headers are received over the new network.
3030 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3031 EXPECT_EQ(200, response.headers->response_code());
3032
3033 // Check that the session is still alive.
3034 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3035 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3036
3037 // There should be posted tasks not executed, which is to migrate back to
3038 // default network.
3039 EXPECT_FALSE(runner_->GetPostedTasks().empty());
3040
3041 // Receive signal to mark new network as default.
3042 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3043 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3044
3045 stream.reset();
3046 EXPECT_TRUE(socket_data.AllReadDataConsumed());
3047 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
3048 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
3049 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
3050}
3051
Zhongyi Shi5f587cc2017-11-21 23:24:173052// This test receives NCN signals in the following order:
3053// - default network disconnected
3054// - after a pause, new network is connected.
3055// - new network is made default.
3056TEST_P(QuicStreamFactoryTest, NewNetworkConnectedAfterNoNetwork) {
3057 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
3058 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3059 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3060 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3061
3062 // Use the test task runner.
3063 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
3064
3065 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523066 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shi5f587cc2017-11-21 23:24:173067 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3068 socket_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433069 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
3070 socket_data.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
3071 2, GetNthClientInitiatedStreamId(0),
3072 true, true, &header_stream_offset));
Zhongyi Shi5f587cc2017-11-21 23:24:173073 socket_data.AddSocketDataToFactory(socket_factory_.get());
3074
3075 // Create request and QuicHttpStream.
3076 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:333077 EXPECT_EQ(ERR_IO_PENDING,
3078 request.Request(host_port_pair_, version_, privacy_mode_,
3079 DEFAULT_PRIORITY, SocketTag(),
3080 /*cert_verify_flags=*/0, url_, net_log_,
3081 &net_error_details_, callback_.callback()));
Zhongyi Shi5f587cc2017-11-21 23:24:173082 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3083 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3084 EXPECT_TRUE(stream.get());
3085
3086 // Cause QUIC stream to be created.
3087 HttpRequestInfo request_info;
3088 request_info.method = "GET";
3089 request_info.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:393090 request_info.traffic_annotation =
3091 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:273092 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:393093 net_log_, CompletionOnceCallback()));
Zhongyi Shi5f587cc2017-11-21 23:24:173094
3095 // Ensure that session is alive and active.
3096 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3097 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3098 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3099
3100 // Send GET request on stream.
3101 HttpResponseInfo response;
3102 HttpRequestHeaders request_headers;
3103 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3104 callback_.callback()));
3105
3106 // Trigger connection migration. Since there are no networks
3107 // to migrate to, this should cause the session to wait for a new network.
3108 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3109 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
3110
3111 // The connection should still be alive, not marked as going away.
3112 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3113 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3114 EXPECT_EQ(1u, session->GetNumActiveStreams());
3115 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3116
3117 // Set up second socket data provider that is used after migration.
3118 // The response to the earlier request is read on this new socket.
3119 MockQuicData socket_data1;
3120 socket_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433121 SYNCHRONOUS, client_maker_.MakePingPacket(3, /*include_version=*/true));
3122 socket_data1.AddRead(
3123 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
3124 false, false));
Zhongyi Shi5f587cc2017-11-21 23:24:173125 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:433126 socket_data1.AddWrite(SYNCHRONOUS,
3127 client_maker_.MakeAckAndRstPacket(
3128 4, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:523129 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:173130 socket_data1.AddSocketDataToFactory(socket_factory_.get());
3131
3132 // Add a new network and notify the stream factory of a new connected network.
3133 // This causes a PING packet to be sent over the new network.
3134 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3135 ->SetConnectedNetworksList({kNewNetworkForTests});
3136 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3137 ->NotifyNetworkConnected(kNewNetworkForTests);
3138
3139 // Ensure that the session is still alive.
3140 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3141 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3142 EXPECT_EQ(1u, session->GetNumActiveStreams());
3143
3144 // Run the message loop so that data queued in the new socket is read by the
3145 // packet reader.
3146 runner_->RunNextTask();
3147
3148 // Response headers are received over the new network.
3149 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3150 EXPECT_EQ(200, response.headers->response_code());
3151
3152 // Check that the session is still alive.
3153 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3154 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3155
3156 // There should posted tasks not executed, which is to migrate back to default
3157 // network.
3158 EXPECT_FALSE(runner_->GetPostedTasks().empty());
3159
3160 // Receive signal to mark new network as default.
3161 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3162 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3163
3164 stream.reset();
3165 EXPECT_TRUE(socket_data.AllReadDataConsumed());
3166 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
3167 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
3168 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
3169}
3170
Zhongyi Shid3d5f502018-08-10 00:22:223171// Regression test for http://crbug.com/872011.
3172// This test verifies that migrate to the probing socket will not trigger
3173// new packets being read synchronously and generate ACK frame while
3174// processing the initial connectivity probe response, which may cause a
3175// connection being closed with INTERNAL_ERROR as pending ACK frame is not
3176// allowed when processing a new packet.
3177TEST_P(QuicStreamFactoryTest, MigrateToProbingSocket) {
3178 InitializeConnectionMigrationV2Test(
3179 {kDefaultNetworkForTests, kNewNetworkForTests});
3180 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3181 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3182 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3183
3184 // Using a testing task runner so that we can control time.
3185 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3186 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
3187
3188 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3189 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3190
3191 int packet_number = 1;
3192 MockQuicData quic_data1;
3193 quic::QuicStreamOffset header_stream_offset = 0;
3194 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
3195 quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
3196 packet_number++, &header_stream_offset));
3197 quic_data1.AddWrite(
3198 SYNCHRONOUS, ConstructGetRequestPacket(
3199 packet_number++, GetNthClientInitiatedStreamId(0), true,
3200 true, &header_stream_offset));
3201 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3202
3203 // Set up the second socket data provider that is used for probing on the
3204 // alternate network.
3205 MockQuicData quic_data2;
3206 // Connectivity probe to be sent on the new path.
3207 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(
3208 packet_number++, true));
3209 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3210 // First connectivity probe to receive from the server, which will complete
3211 // connection migraiton on path degrading.
3212 quic_data2.AddRead(ASYNC,
3213 server_maker_.MakeConnectivityProbingPacket(1, false));
3214 // Read multiple connectivity probes synchronously.
3215 quic_data2.AddRead(SYNCHRONOUS,
3216 server_maker_.MakeConnectivityProbingPacket(2, false));
3217 quic_data2.AddRead(SYNCHRONOUS,
3218 server_maker_.MakeConnectivityProbingPacket(3, false));
3219 quic_data2.AddRead(SYNCHRONOUS,
3220 server_maker_.MakeConnectivityProbingPacket(4, false));
3221 quic_data2.AddWrite(
3222 ASYNC, client_maker_.MakeAckPacket(packet_number++, 1, 4, 1, 1, true));
3223 quic_data2.AddRead(
3224 ASYNC, ConstructOkResponsePacket(5, GetNthClientInitiatedStreamId(0),
3225 false, false));
3226 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3227 quic_data2.AddWrite(
3228 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
3229 packet_number++, false, GetNthClientInitiatedStreamId(0),
3230 quic::QUIC_STREAM_CANCELLED, 5, 1, 1, true));
3231 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3232
3233 // Create request and QuicHttpStream.
3234 QuicStreamRequest request(factory_.get());
3235 EXPECT_EQ(ERR_IO_PENDING,
3236 request.Request(host_port_pair_, version_, privacy_mode_,
3237 DEFAULT_PRIORITY, SocketTag(),
3238 /*cert_verify_flags=*/0, url_, net_log_,
3239 &net_error_details_, callback_.callback()));
3240 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3241 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3242 EXPECT_TRUE(stream.get());
3243
3244 // Cause QUIC stream to be created.
3245 HttpRequestInfo request_info;
3246 request_info.method = "GET";
3247 request_info.url = url_;
3248 request_info.traffic_annotation =
3249 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3250 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3251 net_log_, CompletionOnceCallback()));
3252
3253 // Ensure that session is alive and active.
3254 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3255 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3256 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3257
3258 // Send GET request on stream.
3259 HttpResponseInfo response;
3260 HttpRequestHeaders request_headers;
3261 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3262 callback_.callback()));
3263
3264 // Cause the connection to report path degrading to the session.
3265 // Session will start to probe the alternate network.
3266 session->connection()->OnPathDegradingTimeout();
3267
3268 // Next connectivity probe is scheduled to be sent in 2 *
3269 // kDefaultRTTMilliSecs.
3270 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3271 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
3272 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3273 next_task_delay);
3274
3275 // The connection should still be alive, and not marked as going away.
3276 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3277 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3278 EXPECT_EQ(1u, session->GetNumActiveStreams());
3279 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3280
3281 // Resume quic data and a connectivity probe response will be read on the new
3282 // socket.
3283 quic_data2.Resume();
3284
3285 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3286 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3287 EXPECT_EQ(1u, session->GetNumActiveStreams());
3288
3289 // There should be three pending tasks, the nearest one will complete
3290 // migration to the new network.
3291 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
3292 next_task_delay = task_runner->NextPendingTaskDelay();
3293 EXPECT_EQ(base::TimeDelta(), next_task_delay);
3294 task_runner->FastForwardBy(next_task_delay);
3295
3296 // Response headers are received over the new network.
3297 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3298 EXPECT_EQ(200, response.headers->response_code());
3299
3300 // Now there are two pending tasks, the nearest one was to send connectivity
3301 // probe and has been cancelled due to successful migration.
3302 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
3303 next_task_delay = task_runner->NextPendingTaskDelay();
3304 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3305 next_task_delay);
3306 task_runner->FastForwardBy(next_task_delay);
3307
3308 // There's one more task to mgirate back to the default network in 0.4s.
3309 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3310 next_task_delay = task_runner->NextPendingTaskDelay();
3311 base::TimeDelta expected_delay =
3312 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
3313 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
3314 EXPECT_EQ(expected_delay, next_task_delay);
3315
3316 // Deliver a signal that the alternate network now becomes default to session,
3317 // this will cancel mgirate back to default network timer.
3318 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3319 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3320
3321 task_runner->FastForwardBy(next_task_delay);
3322 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
3323
3324 // Verify that the session is still alive.
3325 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3326 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3327
3328 stream.reset();
3329 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
3330 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
3331 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
3332 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
3333}
3334
Zhongyi Shic4823bd2018-04-27 00:49:193335// This test verifies that the connection migrates to the alternate network
Zhongyi Shi22fd5f52018-06-20 17:39:093336// early when path degrading is detected with an ASYNCHRONOUS write before
3337// migration.
3338TEST_P(QuicStreamFactoryTest, MigrateEarlyOnPathDegradingAysnc) {
3339 TestMigrationOnPathDegrading(/*async_write_before_migration*/ true);
3340}
3341
3342// This test verifies that the connection migrates to the alternate network
3343// early when path degrading is detected with a SYNCHRONOUS write before
3344// migration.
3345TEST_P(QuicStreamFactoryTest, MigrateEarlyOnPathDegradingSync) {
3346 TestMigrationOnPathDegrading(/*async_write_before_migration*/ false);
3347}
3348
3349void QuicStreamFactoryTestBase::TestMigrationOnPathDegrading(
3350 bool async_write_before) {
Zhongyi Shic4823bd2018-04-27 00:49:193351 InitializeConnectionMigrationV2Test(
3352 {kDefaultNetworkForTests, kNewNetworkForTests});
3353 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3354 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3355 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3356
3357 // Using a testing task runner so that we can control time.
3358 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3359 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
3360
3361 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3362 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3363
Zhongyi Shi22fd5f52018-06-20 17:39:093364 int packet_number = 1;
Zhongyi Shic4823bd2018-04-27 00:49:193365 MockQuicData quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523366 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shic4823bd2018-04-27 00:49:193367 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
Zhongyi Shi22fd5f52018-06-20 17:39:093368 quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
3369 packet_number++, &header_stream_offset));
3370 quic_data1.AddWrite(
3371 SYNCHRONOUS, ConstructGetRequestPacket(
3372 packet_number++, GetNthClientInitiatedStreamId(0), true,
3373 true, &header_stream_offset));
3374 if (async_write_before) {
3375 quic_data1.AddWrite(ASYNC, OK);
3376 packet_number++;
3377 }
Zhongyi Shic4823bd2018-04-27 00:49:193378 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3379
3380 // Set up the second socket data provider that is used after migration.
3381 // The response to the earlier request is read on the new socket.
3382 MockQuicData quic_data2;
3383 // Connectivity probe to be sent on the new path.
Zhongyi Shi22fd5f52018-06-20 17:39:093384 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(
Zhongyi Shi879659422018-08-02 17:58:253385 packet_number++, true));
Zhongyi Shic4823bd2018-04-27 00:49:193386 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3387 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:253388 quic_data2.AddRead(ASYNC,
3389 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shic4823bd2018-04-27 00:49:193390 // Ping packet to send after migration is completed.
Zhongyi Shi22fd5f52018-06-20 17:39:093391 quic_data2.AddWrite(ASYNC, client_maker_.MakeAckAndPingPacket(
3392 packet_number++, false, 1, 1, 1));
Ryan Hamiltona3ee93a72018-08-01 22:03:083393 quic_data2.AddRead(
3394 ASYNC, ConstructOkResponsePacket(2, GetNthClientInitiatedStreamId(0),
3395 false, false));
Zhongyi Shic4823bd2018-04-27 00:49:193396 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi22fd5f52018-06-20 17:39:093397 quic_data2.AddWrite(
3398 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
3399 packet_number++, false, GetNthClientInitiatedStreamId(0),
3400 quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true));
Zhongyi Shic4823bd2018-04-27 00:49:193401 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3402
3403 // Create request and QuicHttpStream.
3404 QuicStreamRequest request(factory_.get());
3405 EXPECT_EQ(ERR_IO_PENDING,
3406 request.Request(host_port_pair_, version_, privacy_mode_,
3407 DEFAULT_PRIORITY, SocketTag(),
3408 /*cert_verify_flags=*/0, url_, net_log_,
3409 &net_error_details_, callback_.callback()));
3410 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3411 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3412 EXPECT_TRUE(stream.get());
3413
3414 // Cause QUIC stream to be created.
3415 HttpRequestInfo request_info;
3416 request_info.method = "GET";
3417 request_info.url = url_;
3418 request_info.traffic_annotation =
3419 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3420 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3421 net_log_, CompletionOnceCallback()));
3422
3423 // Ensure that session is alive and active.
3424 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3425 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3426 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3427
3428 // Send GET request on stream.
3429 HttpResponseInfo response;
3430 HttpRequestHeaders request_headers;
3431 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3432 callback_.callback()));
3433
Zhongyi Shi22fd5f52018-06-20 17:39:093434 if (async_write_before)
3435 session->SendPing();
3436
Zhongyi Shiaba4a832018-04-30 20:29:083437 // Cause the connection to report path degrading to the session.
3438 // Session will start to probe the alternate network.
3439 session->connection()->OnPathDegradingTimeout();
3440
3441 // Next connectivity probe is scheduled to be sent in 2 *
3442 // kDefaultRTTMilliSecs.
3443 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3444 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
3445 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3446 next_task_delay);
3447
3448 // The connection should still be alive, and not marked as going away.
3449 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3450 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3451 EXPECT_EQ(1u, session->GetNumActiveStreams());
3452 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3453
3454 // Resume quic data and a connectivity probe response will be read on the new
3455 // socket.
3456 quic_data2.Resume();
3457
3458 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3459 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3460 EXPECT_EQ(1u, session->GetNumActiveStreams());
3461
3462 // There should be three pending tasks, the nearest one will complete
3463 // migration to the new network.
3464 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
3465 next_task_delay = task_runner->NextPendingTaskDelay();
3466 EXPECT_EQ(base::TimeDelta(), next_task_delay);
3467 task_runner->FastForwardBy(next_task_delay);
3468
3469 // Response headers are received over the new network.
3470 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3471 EXPECT_EQ(200, response.headers->response_code());
3472
3473 // Now there are two pending tasks, the nearest one was to send connectivity
3474 // probe and has been cancelled due to successful migration.
3475 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
3476 next_task_delay = task_runner->NextPendingTaskDelay();
3477 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3478 next_task_delay);
3479 task_runner->FastForwardBy(next_task_delay);
3480
3481 // There's one more task to mgirate back to the default network in 0.4s.
3482 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3483 next_task_delay = task_runner->NextPendingTaskDelay();
3484 base::TimeDelta expected_delay =
3485 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
3486 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
3487 EXPECT_EQ(expected_delay, next_task_delay);
3488
3489 // Deliver a signal that the alternate network now becomes default to session,
3490 // this will cancel mgirate back to default network timer.
3491 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3492 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3493
3494 task_runner->FastForwardBy(next_task_delay);
3495 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
3496
3497 // Verify that the session is still alive.
3498 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3499 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3500
3501 stream.reset();
3502 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
3503 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
3504 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
3505 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
3506}
3507
Renjiea5722ccf2018-08-10 00:18:493508// This test verifies that the session marks itself GOAWAY on path degrading
3509// and it does not receive any new request
3510TEST_P(QuicStreamFactoryTest, GoawayOnPathDegrading) {
3511 go_away_on_path_degrading_ = true;
3512 Initialize();
3513 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3514 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3515 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3516
3517 MockQuicData quic_data1;
3518 quic::QuicStreamOffset header_stream_offset = 0;
3519 quic_data1.AddWrite(SYNCHRONOUS,
3520 ConstructInitialSettingsPacket(1, &header_stream_offset));
3521 quic_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
3522 2, GetNthClientInitiatedStreamId(0),
3523 true, true, &header_stream_offset));
3524 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3525 quic_data1.AddRead(
3526 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
3527 false, true));
3528 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
3529 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3530
3531 MockQuicData quic_data2;
3532 quic::QuicStreamOffset header_stream_offset2 = 0;
3533 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
3534 quic_data2.AddWrite(
3535 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset2));
3536 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3537
3538 // Creat request and QuicHttpStream.
3539 QuicStreamRequest request(factory_.get());
3540 EXPECT_EQ(ERR_IO_PENDING,
3541 request.Request(host_port_pair_, version_, privacy_mode_,
3542 DEFAULT_PRIORITY, SocketTag(),
3543 /*cerf_verify_flags=*/0, url_, net_log_,
3544 &net_error_details_, callback_.callback()));
3545 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3546 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3547 EXPECT_TRUE(stream.get());
3548
3549 // Cause QUIC stream to be created.
3550 HttpRequestInfo request_info;
3551 request_info.method = "GET";
3552 request_info.url = url_;
3553 request_info.traffic_annotation =
3554 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3555 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3556 net_log_, CompletionOnceCallback()));
3557
3558 // Ensure that session is alive and active.
3559 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3560 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3561 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3562
3563 // Send GET request on stream.
3564 HttpResponseInfo response;
3565 HttpRequestHeaders request_headers;
3566 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3567 callback_.callback()));
3568
3569 // Trigger the connection to report path degrading to the session.
3570 // Session will mark itself GOAWAY.
3571 session->connection()->OnPathDegradingTimeout();
3572
3573 // The connection should still be alive, but marked as going away.
3574 EXPECT_FALSE(HasActiveSession(host_port_pair_));
3575 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3576 EXPECT_EQ(1u, session->GetNumActiveStreams());
3577
3578 // Second request should be sent on a new connection.
3579 QuicStreamRequest request2(factory_.get());
3580 EXPECT_EQ(ERR_IO_PENDING,
3581 request2.Request(host_port_pair_, version_, privacy_mode_,
3582 DEFAULT_PRIORITY, SocketTag(),
3583 /*cert_verify_flags=*/0, url_, net_log_,
3584 &net_error_details_, callback_.callback()));
3585 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3586 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
3587 EXPECT_TRUE(stream2.get());
3588
3589 // Resume the data, verify old request can read response on the old session
3590 // successfully.
3591 quic_data1.Resume();
3592 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
3593 EXPECT_EQ(200, response.headers->response_code());
3594 EXPECT_EQ(0U, session->GetNumActiveStreams());
3595
3596 // Check an active session exists for the destination.
3597 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3598 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3599 QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
3600 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
3601 EXPECT_NE(session, session2);
3602
3603 stream.reset();
3604 stream2.reset();
3605 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
3606 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
3607 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
3608 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
3609}
3610
Zhongyi Shibb770d92018-06-16 02:07:003611// This test verifies that the connection will not migrate to a bad socket
3612// when path degrading is detected.
3613TEST_P(QuicStreamFactoryTest, DoNotMigrateToBadSocketOnPathDegrading) {
3614 InitializeConnectionMigrationV2Test(
3615 {kDefaultNetworkForTests, kNewNetworkForTests});
3616 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3617 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3618 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3619
3620 // Using a testing task runner so that we can control time.
3621 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3622 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
3623
3624 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3625 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3626
3627 MockQuicData quic_data;
3628 quic::QuicStreamOffset header_stream_offset = 0;
3629 quic_data.AddWrite(SYNCHRONOUS,
3630 ConstructInitialSettingsPacket(1, &header_stream_offset));
3631 quic_data.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
3632 2, GetNthClientInitiatedStreamId(0), true,
3633 true, &header_stream_offset));
3634 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3635 quic_data.AddRead(
3636 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
3637 false, false));
3638 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3639 quic_data.AddWrite(SYNCHRONOUS,
3640 client_maker_.MakeAckAndRstPacket(
3641 3, false, GetNthClientInitiatedStreamId(0),
3642 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
3643 quic_data.AddSocketDataToFactory(socket_factory_.get());
3644
3645 // Set up second socket that will immediately return disconnected.
3646 // The stream factory will abort probe the alternate network.
3647 MockConnect bad_connect = MockConnect(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
3648 SequencedSocketData socket_data(bad_connect, base::span<MockRead>(),
3649 base::span<MockWrite>());
3650 socket_factory_->AddSocketDataProvider(&socket_data);
3651
3652 // Create request and QuicHttpStream.
3653 QuicStreamRequest request(factory_.get());
3654 EXPECT_EQ(ERR_IO_PENDING,
3655 request.Request(host_port_pair_, version_, privacy_mode_,
3656 DEFAULT_PRIORITY, SocketTag(),
3657 /*cert_verify_flags=*/0, url_, net_log_,
3658 &net_error_details_, callback_.callback()));
3659 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3660 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3661 EXPECT_TRUE(stream.get());
3662
3663 // Cause QUIC stream to be created.
3664 HttpRequestInfo request_info;
3665 request_info.method = "GET";
3666 request_info.url = url_;
3667 request_info.traffic_annotation =
3668 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3669 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3670 net_log_, CompletionOnceCallback()));
3671
3672 // Ensure that session is alive and active.
3673 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3674 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3675 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3676
3677 // Send GET request on stream.
3678 HttpResponseInfo response;
3679 HttpRequestHeaders request_headers;
3680 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3681 callback_.callback()));
3682
3683 // Cause the connection to report path degrading to the session.
3684 // Session will start to probe the alternate network.
3685 session->connection()->OnPathDegradingTimeout();
3686
3687 // The connection should still be alive, and not marked as going away.
3688 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3689 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3690 EXPECT_EQ(1u, session->GetNumActiveStreams());
3691 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3692
3693 // Resume the data, and response header is received over the original network.
3694 quic_data.Resume();
3695 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3696 EXPECT_EQ(200, response.headers->response_code());
3697
3698 // Verify there is no pending task as probing alternate network is halted.
3699 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
3700
3701 // Verify that the session is still alive.
3702 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3703 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3704
3705 stream.reset();
3706 EXPECT_TRUE(quic_data.AllReadDataConsumed());
3707 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
3708}
3709
Zhongyi Shif5cc30392018-05-30 18:25:153710// Regression test for http://crbug.com/847569.
3711// This test verifies that the connection migrates to the alternate network
3712// early when there is no active stream but a draining stream.
Zhongyi Shib3bc982c2018-07-10 19:59:243713// The first packet being written after migration is a synchrnous write, which
3714// will cause a PING packet being sent.
3715TEST_P(QuicStreamFactoryTest, MigrateSessionWithDrainingStreamSync) {
3716 TestMigrateSessionWithDrainingStream(SYNCHRONOUS);
3717}
3718
3719// Regression test for http://crbug.com/847569.
3720// This test verifies that the connection migrates to the alternate network
3721// early when there is no active stream but a draining stream.
3722// The first packet being written after migration is an asynchronous write, no
3723// PING packet will be sent.
3724TEST_P(QuicStreamFactoryTest, MigrateSessionWithDrainingStreamAsync) {
3725 TestMigrateSessionWithDrainingStream(ASYNC);
3726}
3727
3728void QuicStreamFactoryTestBase::TestMigrateSessionWithDrainingStream(
3729 IoMode write_mode_for_queued_packet) {
Zhongyi Shif5cc30392018-05-30 18:25:153730 InitializeConnectionMigrationV2Test(
3731 {kDefaultNetworkForTests, kNewNetworkForTests});
3732 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3733 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3734 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3735
3736 // Using a testing task runner so that we can control time.
3737 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3738 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
3739
3740 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3741 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3742
Zhongyi Shib3bc982c2018-07-10 19:59:243743 int packet_number = 1;
Zhongyi Shif5cc30392018-05-30 18:25:153744 MockQuicData quic_data1;
3745 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shib3bc982c2018-07-10 19:59:243746 quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
3747 packet_number++, &header_stream_offset));
3748 quic_data1.AddWrite(
3749 SYNCHRONOUS, ConstructGetRequestPacket(
3750 packet_number++, GetNthClientInitiatedStreamId(0), true,
3751 true, &header_stream_offset));
Zhongyi Shif5cc30392018-05-30 18:25:153752 // Read an out of order packet with FIN to drain the stream.
3753 quic_data1.AddRead(
3754 ASYNC, ConstructOkResponsePacket(2, GetNthClientInitiatedStreamId(0),
3755 false, true)); // keep sending version.
Zhongyi Shib3bc982c2018-07-10 19:59:243756 quic_data1.AddWrite(SYNCHRONOUS, client_maker_.MakeAckPacket(
3757 packet_number++, 2, 2, 2, 1, true));
Zhongyi Shif5cc30392018-05-30 18:25:153758 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3759 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3760
3761 // Set up the second socket data provider that is used after migration.
3762 MockQuicData quic_data2;
3763 // Connectivity probe to be sent on the new path.
Zhongyi Shib3bc982c2018-07-10 19:59:243764 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(
Zhongyi Shi879659422018-08-02 17:58:253765 packet_number++, false));
Zhongyi Shif5cc30392018-05-30 18:25:153766 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3767 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:253768 quic_data2.AddRead(ASYNC,
3769 server_maker_.MakeConnectivityProbingPacket(3, false));
Zhongyi Shif5cc30392018-05-30 18:25:153770 // Ping packet to send after migration is completed.
Zhongyi Shib3bc982c2018-07-10 19:59:243771 quic_data2.AddWrite(
3772 write_mode_for_queued_packet,
3773 client_maker_.MakeAckPacket(packet_number++, 2, 3, 3, 1, true));
3774 if (write_mode_for_queued_packet == SYNCHRONOUS) {
3775 quic_data2.AddWrite(ASYNC,
3776 client_maker_.MakePingPacket(packet_number++, false));
3777 }
Zhongyi Shif5cc30392018-05-30 18:25:153778 quic_data2.AddRead(
3779 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
3780 false, false));
Zhongyi Shib3bc982c2018-07-10 19:59:243781 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeAckPacket(
3782 packet_number++, 1, 3, 1, 1, true));
Zhongyi Shif5cc30392018-05-30 18:25:153783 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3784 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3785
3786 // Create request and QuicHttpStream.
3787 QuicStreamRequest request(factory_.get());
3788 EXPECT_EQ(ERR_IO_PENDING,
3789 request.Request(host_port_pair_, version_, privacy_mode_,
3790 DEFAULT_PRIORITY, SocketTag(),
3791 /*cert_verify_flags=*/0, url_, net_log_,
3792 &net_error_details_, callback_.callback()));
3793 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3794 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3795 EXPECT_TRUE(stream.get());
3796
3797 // Cause QUIC stream to be created.
3798 HttpRequestInfo request_info;
3799 request_info.method = "GET";
3800 request_info.url = url_;
3801 request_info.traffic_annotation =
3802 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3803 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3804 net_log_, CompletionOnceCallback()));
3805
3806 // Ensure that session is alive and active.
3807 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3808 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3809 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3810
3811 // Send GET request on stream.
3812 HttpResponseInfo response;
3813 HttpRequestHeaders request_headers;
3814 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3815 callback_.callback()));
3816
3817 // Run the message loop to receive the out of order packet which contains a
3818 // FIN and drains the stream.
3819 base::RunLoop().RunUntilIdle();
3820 EXPECT_EQ(0u, session->GetNumActiveStreams());
3821
3822 // Cause the connection to report path degrading to the session.
3823 // Session should still start to probe the alternate network.
3824 session->connection()->OnPathDegradingTimeout();
3825 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3826
3827 // Next connectivity probe is scheduled to be sent in 2 *
3828 // kDefaultRTTMilliSecs.
3829 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3830 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
3831 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3832 next_task_delay);
3833
3834 // The connection should still be alive, and not marked as going away.
3835 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shif5cc30392018-05-30 18:25:153836
3837 // Resume quic data and a connectivity probe response will be read on the new
3838 // socket.
3839 quic_data2.Resume();
3840
3841 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3842 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:263843 EXPECT_EQ(0u, session->GetNumActiveStreams());
3844 EXPECT_EQ(1u, session->GetNumDrainingStreams());
Zhongyi Shif5cc30392018-05-30 18:25:153845
3846 // There should be three pending tasks, the nearest one will complete
3847 // migration to the new network.
3848 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
3849 next_task_delay = task_runner->NextPendingTaskDelay();
3850 EXPECT_EQ(base::TimeDelta(), next_task_delay);
3851 task_runner->FastForwardBy(next_task_delay);
3852
3853 // Now there are two pending tasks, the nearest one was to send connectivity
3854 // probe and has been cancelled due to successful migration.
3855 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
3856 next_task_delay = task_runner->NextPendingTaskDelay();
3857 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3858 next_task_delay);
3859 task_runner->FastForwardBy(next_task_delay);
3860
3861 // There's one more task to mgirate back to the default network in 0.4s.
3862 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3863 next_task_delay = task_runner->NextPendingTaskDelay();
3864 base::TimeDelta expected_delay =
3865 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
3866 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
3867 EXPECT_EQ(expected_delay, next_task_delay);
3868
Zhongyi Shib3bc982c2018-07-10 19:59:243869 base::RunLoop().RunUntilIdle();
3870
Zhongyi Shif5cc30392018-05-30 18:25:153871 // Deliver a signal that the alternate network now becomes default to session,
3872 // this will cancel mgirate back to default network timer.
3873 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3874 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3875
3876 task_runner->FastForwardBy(next_task_delay);
3877 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
3878
3879 // Verify that the session is still alive.
3880 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3881 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:263882 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
Zhongyi Shif5cc30392018-05-30 18:25:153883
3884 stream.reset();
3885 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
3886 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
3887 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
3888 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
3889}
3890
Zhongyi Shiaba4a832018-04-30 20:29:083891// Regression test for http://crbug.com/835444.
3892// This test verifies that the connection migrates to the alternate network
3893// when the alternate network is connected after path has been degrading.
3894TEST_P(QuicStreamFactoryTest, MigrateOnNewNetworkConnectAfterPathDegrading) {
3895 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
3896 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3897 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3898 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3899
3900 // Using a testing task runner so that we can control time.
3901 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3902 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
3903
3904 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3905 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3906
3907 MockQuicData quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523908 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shiaba4a832018-04-30 20:29:083909 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
3910 quic_data1.AddWrite(SYNCHRONOUS,
3911 ConstructInitialSettingsPacket(1, &header_stream_offset));
3912 quic_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
3913 2, GetNthClientInitiatedStreamId(0),
3914 true, true, &header_stream_offset));
3915 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3916
3917 // Set up the second socket data provider that is used after migration.
3918 // The response to the earlier request is read on the new socket.
3919 MockQuicData quic_data2;
3920 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:253921 quic_data2.AddWrite(SYNCHRONOUS,
3922 client_maker_.MakeConnectivityProbingPacket(3, true));
Zhongyi Shiaba4a832018-04-30 20:29:083923 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3924 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:253925 quic_data2.AddRead(ASYNC,
3926 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shiaba4a832018-04-30 20:29:083927 // Ping packet to send after migration is completed.
3928 quic_data2.AddWrite(ASYNC,
3929 client_maker_.MakeAckAndPingPacket(4, false, 1, 1, 1));
3930 quic_data2.AddRead(
3931 ASYNC, ConstructOkResponsePacket(2, GetNthClientInitiatedStreamId(0),
3932 false, false));
3933 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3934 quic_data2.AddWrite(SYNCHRONOUS,
3935 client_maker_.MakeAckAndRstPacket(
3936 5, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:523937 quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true));
Zhongyi Shiaba4a832018-04-30 20:29:083938 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3939
3940 // Create request and QuicHttpStream.
3941 QuicStreamRequest request(factory_.get());
3942 EXPECT_EQ(ERR_IO_PENDING,
3943 request.Request(host_port_pair_, version_, privacy_mode_,
3944 DEFAULT_PRIORITY, SocketTag(),
3945 /*cert_verify_flags=*/0, url_, net_log_,
3946 &net_error_details_, callback_.callback()));
3947 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3948 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3949 EXPECT_TRUE(stream.get());
3950
3951 // Cause QUIC stream to be created.
3952 HttpRequestInfo request_info;
3953 request_info.method = "GET";
3954 request_info.url = url_;
3955 request_info.traffic_annotation =
3956 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3957 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3958 net_log_, CompletionOnceCallback()));
3959
3960 // Ensure that session is alive and active.
3961 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3962 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3963 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3964
3965 // Send GET request on stream.
3966 HttpResponseInfo response;
3967 HttpRequestHeaders request_headers;
3968 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3969 callback_.callback()));
3970
3971 // Cause the connection to report path degrading to the session.
3972 // Due to lack of alternate network, session will not mgirate connection.
3973 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
3974 session->connection()->OnPathDegradingTimeout();
3975 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
3976
3977 // Deliver a signal that a alternate network is connected now, this should
3978 // cause the connection to start early migration on path degrading.
3979 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3980 ->SetConnectedNetworksList(
3981 {kDefaultNetworkForTests, kNewNetworkForTests});
3982 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3983 ->NotifyNetworkConnected(kNewNetworkForTests);
Zhongyi Shic4823bd2018-04-27 00:49:193984
3985 // Next connectivity probe is scheduled to be sent in 2 *
3986 // kDefaultRTTMilliSecs.
3987 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3988 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
3989 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3990 next_task_delay);
3991
3992 // The connection should still be alive, and not marked as going away.
3993 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3994 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3995 EXPECT_EQ(1u, session->GetNumActiveStreams());
3996 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3997
3998 // Resume quic data and a connectivity probe response will be read on the new
3999 // socket.
4000 quic_data2.Resume();
4001
4002 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4003 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4004 EXPECT_EQ(1u, session->GetNumActiveStreams());
4005
4006 // There should be three pending tasks, the nearest one will complete
4007 // migration to the new network.
4008 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
4009 next_task_delay = task_runner->NextPendingTaskDelay();
4010 EXPECT_EQ(base::TimeDelta(), next_task_delay);
4011 task_runner->FastForwardBy(next_task_delay);
4012
4013 // Response headers are received over the new network.
4014 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4015 EXPECT_EQ(200, response.headers->response_code());
4016
4017 // Now there are two pending tasks, the nearest one was to send connectivity
4018 // probe and has been cancelled due to successful migration.
4019 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
4020 next_task_delay = task_runner->NextPendingTaskDelay();
4021 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
4022 next_task_delay);
4023 task_runner->FastForwardBy(next_task_delay);
4024
4025 // There's one more task to mgirate back to the default network in 0.4s.
4026 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4027 next_task_delay = task_runner->NextPendingTaskDelay();
4028 base::TimeDelta expected_delay =
4029 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
4030 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
4031 EXPECT_EQ(expected_delay, next_task_delay);
4032
4033 // Deliver a signal that the alternate network now becomes default to session,
4034 // this will cancel mgirate back to default network timer.
4035 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4036 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
4037
4038 task_runner->FastForwardBy(next_task_delay);
4039 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4040
4041 // Verify that the session is still alive.
4042 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4043 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4044
4045 stream.reset();
4046 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
4047 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
4048 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
4049 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
4050}
4051
Zhongyi Shi28f6e352018-06-20 21:15:434052// This test verifies that multiple sessions are migrated on connection
4053// migration signal.
jrie3d187c2016-09-16 14:29:174054TEST_P(QuicStreamFactoryTest,
Zhongyi Shi28f6e352018-06-20 21:15:434055 MigrateMultipleSessionsToBadSocketsAfterDisconnected) {
4056 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jrie3d187c2016-09-16 14:29:174057
4058 MockQuicData socket_data1;
4059 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434060 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jrie3d187c2016-09-16 14:29:174061 socket_data1.AddWrite(ASYNC, OK);
Zhongyi Shi5f587cc2017-11-21 23:24:174062 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jrie3d187c2016-09-16 14:29:174063 MockQuicData socket_data2;
4064 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434065 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jrie3d187c2016-09-16 14:29:174066 socket_data2.AddWrite(ASYNC, OK);
Zhongyi Shi5f587cc2017-11-21 23:24:174067 socket_data2.AddSocketDataToFactory(socket_factory_.get());
jrie3d187c2016-09-16 14:29:174068
4069 HostPortPair server1(kDefaultServerHostName, 443);
4070 HostPortPair server2(kServer2HostName, 443);
4071
4072 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4073 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4074 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4075
4076 host_resolver_.set_synchronous_mode(true);
4077 host_resolver_.rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
4078 host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.2", "");
4079
4080 // Create request and QuicHttpStream to create session1.
zhongyi98d6a9262017-05-19 02:47:454081 QuicStreamRequest request1(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:334082 EXPECT_EQ(OK, request1.Request(server1, version_, privacy_mode_,
4083 DEFAULT_PRIORITY, SocketTag(),
4084 /*cert_verify_flags=*/0, url_, net_log_,
4085 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:244086 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
jrie3d187c2016-09-16 14:29:174087 EXPECT_TRUE(stream1.get());
4088
4089 // Create request and QuicHttpStream to create session2.
zhongyi98d6a9262017-05-19 02:47:454090 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:334091 EXPECT_EQ(OK, request2.Request(server2, version_, privacy_mode_,
4092 DEFAULT_PRIORITY, SocketTag(),
4093 /*cert_verify_flags=*/0, url2_, net_log_,
4094 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:244095 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
jrie3d187c2016-09-16 14:29:174096 EXPECT_TRUE(stream2.get());
4097
4098 QuicChromiumClientSession* session1 = GetActiveSession(server1);
4099 QuicChromiumClientSession* session2 = GetActiveSession(server2);
4100 EXPECT_NE(session1, session2);
4101
4102 // Cause QUIC stream to be created and send GET so session1 has an open
4103 // stream.
4104 HttpRequestInfo request_info1;
4105 request_info1.method = "GET";
4106 request_info1.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:394107 request_info1.traffic_annotation =
4108 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274109 EXPECT_EQ(OK,
4110 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394111 net_log_, CompletionOnceCallback()));
jrie3d187c2016-09-16 14:29:174112 HttpResponseInfo response1;
4113 HttpRequestHeaders request_headers1;
4114 EXPECT_EQ(OK, stream1->SendRequest(request_headers1, &response1,
4115 callback_.callback()));
4116
4117 // Cause QUIC stream to be created and send GET so session2 has an open
4118 // stream.
4119 HttpRequestInfo request_info2;
4120 request_info2.method = "GET";
4121 request_info2.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:394122 request_info2.traffic_annotation =
4123 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274124 EXPECT_EQ(OK,
4125 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394126 net_log_, CompletionOnceCallback()));
jrie3d187c2016-09-16 14:29:174127 HttpResponseInfo response2;
4128 HttpRequestHeaders request_headers2;
4129 EXPECT_EQ(OK, stream2->SendRequest(request_headers2, &response2,
4130 callback_.callback()));
4131
4132 // Cause both sessions to be paused due to DISCONNECTED.
4133 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4134 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
4135
4136 // Ensure that both sessions are paused but alive.
4137 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session1));
4138 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
4139
Zhongyi Shi28f6e352018-06-20 21:15:434140 // Add new sockets to use post migration. Those are bad sockets and will cause
4141 // migration to fail.
jrie3d187c2016-09-16 14:29:174142 MockConnect connect_result =
4143 MockConnect(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
Ryan Sleevib8d7ea02018-05-07 20:01:014144 SequencedSocketData socket_data3(connect_result, base::span<MockRead>(),
4145 base::span<MockWrite>());
Zhongyi Shi5f587cc2017-11-21 23:24:174146 socket_factory_->AddSocketDataProvider(&socket_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:014147 SequencedSocketData socket_data4(connect_result, base::span<MockRead>(),
4148 base::span<MockWrite>());
Zhongyi Shi5f587cc2017-11-21 23:24:174149 socket_factory_->AddSocketDataProvider(&socket_data4);
jrie3d187c2016-09-16 14:29:174150
Zhongyi Shi28f6e352018-06-20 21:15:434151 // Connect the new network and cause migration to bad sockets, causing
4152 // sessions to close.
jrie3d187c2016-09-16 14:29:174153 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4154 ->SetConnectedNetworksList({kNewNetworkForTests});
4155 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4156 ->NotifyNetworkConnected(kNewNetworkForTests);
4157
4158 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session1));
4159 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
4160
4161 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
4162 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
4163 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
4164 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
4165}
4166
Zhongyi Shi6ec9b36e2018-06-20 20:32:544167// This test verifies that session attempts connection migration with signals
4168// delivered in the following order (no alternate network is available):
4169// - path degrading is detected: session attempts connection migration but no
4170// alternate network is available, session caches path degrading signal in
4171// connection and stays on the original network.
4172// - original network backs up, request is served in the orignal network,
4173// session is not marked as going away.
4174TEST_P(QuicStreamFactoryTest, MigrateOnPathDegradingWithNoNewNetwork) {
4175 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jrid36ada62016-02-06 02:42:084176 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4177 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4178
Zhongyi Shi6ec9b36e2018-06-20 20:32:544179 MockQuicData quic_data;
4180 quic::QuicStreamOffset header_stream_offset = 0;
4181 quic_data.AddWrite(SYNCHRONOUS,
4182 ConstructInitialSettingsPacket(1, &header_stream_offset));
4183 quic_data.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
4184 2, GetNthClientInitiatedStreamId(0), true,
4185 true, &header_stream_offset));
4186 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause for path degrading signal.
4187
4188 // The rest of the data will still flow in the original socket as there is no
4189 // new network after path degrading.
4190 quic_data.AddRead(
4191 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
4192 false, false));
4193 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4194 quic_data.AddWrite(SYNCHRONOUS,
4195 client_maker_.MakeAckAndRstPacket(
4196 3, false, GetNthClientInitiatedStreamId(0),
4197 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
4198 quic_data.AddSocketDataToFactory(socket_factory_.get());
jrid36ada62016-02-06 02:42:084199
4200 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:454201 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:334202 EXPECT_EQ(ERR_IO_PENDING,
4203 request.Request(host_port_pair_, version_, privacy_mode_,
4204 DEFAULT_PRIORITY, SocketTag(),
4205 /*cert_verify_flags=*/0, url_, net_log_,
4206 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:014207 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:244208 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jrid36ada62016-02-06 02:42:084209 EXPECT_TRUE(stream.get());
4210
4211 // Cause QUIC stream to be created.
4212 HttpRequestInfo request_info;
Zhongyi Shi6ec9b36e2018-06-20 20:32:544213 request_info.method = "GET";
4214 request_info.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:394215 request_info.traffic_annotation =
4216 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Zhongyi Shi6ec9b36e2018-06-20 20:32:544217 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394218 net_log_, CompletionOnceCallback()));
jrid36ada62016-02-06 02:42:084219
4220 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:504221 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jrid36ada62016-02-06 02:42:084222 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4223 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4224
Zhongyi Shi6ec9b36e2018-06-20 20:32:544225 // Send GET request on stream.
4226 HttpResponseInfo response;
4227 HttpRequestHeaders request_headers;
4228 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
4229 callback_.callback()));
jrid36ada62016-02-06 02:42:084230
Zhongyi Shi6ec9b36e2018-06-20 20:32:544231 // Trigger connection migration on path degrading. Since there are no networks
4232 // to migrate to, the session will remain on the original network, not marked
4233 // as going away.
4234 session->connection()->OnPathDegradingTimeout();
4235 EXPECT_TRUE(session->connection()->IsPathDegrading());
4236
4237 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4238 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4239 EXPECT_EQ(1u, session->GetNumActiveStreams());
4240 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
4241
4242 // Resume so that rest of the data will flow in the original socket.
4243 quic_data.Resume();
jrid36ada62016-02-06 02:42:084244
4245 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4246 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4247 EXPECT_EQ(1u, session->GetNumActiveStreams());
4248
4249 stream.reset();
Zhongyi Shi6ec9b36e2018-06-20 20:32:544250 EXPECT_TRUE(quic_data.AllReadDataConsumed());
4251 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
jrid36ada62016-02-06 02:42:084252}
4253
Zhongyi Shi21e99532018-07-17 22:23:074254// This test verifies that session with non-migratable stream will probe the
4255// alternate network on path degrading, and close the non-migratable streams
4256// when probe is successful.
jri231c2972016-03-08 19:50:114257TEST_P(QuicStreamFactoryTest, MigrateSessionEarlyNonMigratableStream) {
Zhongyi Shi1a054612018-06-14 04:59:084258 InitializeConnectionMigrationV2Test(
jri231c2972016-03-08 19:50:114259 {kDefaultNetworkForTests, kNewNetworkForTests});
4260 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4261 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4262
rcha00569732016-08-27 11:09:364263 MockQuicData socket_data;
4264 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434265 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:174266 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri231c2972016-03-08 19:50:114267
Zhongyi Shi21e99532018-07-17 22:23:074268 // Set up the second socket data provider that is used for probing.
4269 MockQuicData quic_data1;
4270 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:254271 quic_data1.AddWrite(SYNCHRONOUS,
4272 client_maker_.MakeConnectivityProbingPacket(2, true));
Zhongyi Shi21e99532018-07-17 22:23:074273 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
4274 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:254275 quic_data1.AddRead(ASYNC,
4276 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shi21e99532018-07-17 22:23:074277 quic_data1.AddSocketDataToFactory(socket_factory_.get());
4278
jri231c2972016-03-08 19:50:114279 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:454280 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:334281 EXPECT_EQ(ERR_IO_PENDING,
4282 request.Request(host_port_pair_, version_, privacy_mode_,
4283 DEFAULT_PRIORITY, SocketTag(),
4284 /*cert_verify_flags=*/0, url_, net_log_,
4285 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:014286 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:244287 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri231c2972016-03-08 19:50:114288 EXPECT_TRUE(stream.get());
4289
4290 // Cause QUIC stream to be created, but marked as non-migratable.
4291 HttpRequestInfo request_info;
Zhongyi Shibb28b1f2018-07-18 02:41:264292 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Ramin Halavati683bcaa92018-02-14 08:42:394293 request_info.traffic_annotation =
4294 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274295 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394296 net_log_, CompletionOnceCallback()));
jri231c2972016-03-08 19:50:114297
4298 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:504299 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri231c2972016-03-08 19:50:114300 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4301 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4302
4303 // Trigger connection migration. Since there is a non-migratable stream,
4304 // this should cause session to be continue without migrating.
4305 session->OnPathDegrading();
4306
4307 // Run the message loop so that data queued in the new socket is read by the
4308 // packet reader.
4309 base::RunLoop().RunUntilIdle();
4310
4311 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4312 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4313 EXPECT_EQ(1u, session->GetNumActiveStreams());
4314
Zhongyi Shi21e99532018-07-17 22:23:074315 // Resume the data to read the connectivity probing response to declare probe
4316 // as successful. Non-migratable streams will be closed.
4317 quic_data1.Resume();
4318 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4319 EXPECT_FALSE(HasActiveSession(host_port_pair_));
4320 EXPECT_EQ(0u, session->GetNumActiveStreams());
jri231c2972016-03-08 19:50:114321
Zhongyi Shi21e99532018-07-17 22:23:074322 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
4323 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
jri231c2972016-03-08 19:50:114324 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4325 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4326}
4327
jri9c541572016-03-29 17:51:484328TEST_P(QuicStreamFactoryTest, MigrateSessionEarlyConnectionMigrationDisabled) {
Zhongyi Shi1a054612018-06-14 04:59:084329 InitializeConnectionMigrationV2Test(
jri9c541572016-03-29 17:51:484330 {kDefaultNetworkForTests, kNewNetworkForTests});
4331 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4332 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4333
rcha00569732016-08-27 11:09:364334 MockQuicData socket_data;
4335 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434336 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
4337 socket_data.AddWrite(
4338 SYNCHRONOUS,
4339 client_maker_.MakeRstPacket(2, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:524340 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:174341 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9c541572016-03-29 17:51:484342
4343 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:454344 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:334345 EXPECT_EQ(ERR_IO_PENDING,
4346 request.Request(host_port_pair_, version_, privacy_mode_,
4347 DEFAULT_PRIORITY, SocketTag(),
4348 /*cert_verify_flags=*/0, url_, net_log_,
4349 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:014350 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:244351 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9c541572016-03-29 17:51:484352 EXPECT_TRUE(stream.get());
4353
4354 // Cause QUIC stream to be created.
4355 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:394356 request_info.traffic_annotation =
4357 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274358 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394359 net_log_, CompletionOnceCallback()));
jri9c541572016-03-29 17:51:484360
4361 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:504362 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri9c541572016-03-29 17:51:484363 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4364 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4365
4366 // Set session config to have connection migration disabled.
Ryan Hamilton8d9ee76e2018-05-29 23:52:524367 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
4368 session->config());
jri9c541572016-03-29 17:51:484369 EXPECT_TRUE(session->config()->DisableConnectionMigration());
4370
4371 // Trigger connection migration. Since there is a non-migratable stream,
4372 // this should cause session to be continue without migrating.
4373 session->OnPathDegrading();
4374
4375 // Run the message loop so that data queued in the new socket is read by the
4376 // packet reader.
4377 base::RunLoop().RunUntilIdle();
4378
4379 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4380 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4381 EXPECT_EQ(1u, session->GetNumActiveStreams());
4382
4383 stream.reset();
4384
4385 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4386 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4387}
4388
Zhongyi Shi3c4c9e92018-07-02 23:16:234389// Regression test for http://crbug.com/791886.
4390// This test verifies that the old packet writer which encountered an
4391// asynchronous write error will be blocked during migration on write error. New
4392// packets would not be written until the one with write error is rewritten on
4393// the new network.
4394TEST_P(QuicStreamFactoryTest, MigrateSessionOnAysncWriteError) {
4395 InitializeConnectionMigrationV2Test(
4396 {kDefaultNetworkForTests, kNewNetworkForTests});
4397 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4398 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4399 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4400
4401 // Using a testing task runner so that we can control time.
4402 // base::RunLoop() controls mocked socket writes and reads.
4403 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4404 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4405
4406 MockQuicData socket_data;
4407 quic::QuicStreamOffset header_stream_offset = 0;
4408 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4409 socket_data.AddWrite(
4410 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4411 socket_data.AddWrite(ASYNC, ERR_ADDRESS_UNREACHABLE);
4412 socket_data.AddSocketDataToFactory(socket_factory_.get());
4413
4414 // Set up second socket data provider that is used after
4415 // migration. The request is rewritten to this new socket, and the
4416 // response to the request is read on this new socket.
4417 MockQuicData socket_data1;
4418 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
4419 2, GetNthClientInitiatedStreamId(0),
4420 true, true, &header_stream_offset));
4421 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
4422 3, GetNthClientInitiatedStreamId(1),
4423 GetNthClientInitiatedStreamId(0), true,
4424 true, &header_stream_offset));
4425 socket_data1.AddRead(
4426 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
4427 false, false));
4428 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4429 socket_data1.AddWrite(SYNCHRONOUS,
4430 client_maker_.MakeAckAndRstPacket(
4431 4, false, GetNthClientInitiatedStreamId(0),
4432 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
4433 socket_data1.AddWrite(
4434 SYNCHRONOUS,
4435 client_maker_.MakeRstPacket(5, false, GetNthClientInitiatedStreamId(1),
4436 quic::QUIC_STREAM_CANCELLED, 0));
4437
4438 socket_data1.AddSocketDataToFactory(socket_factory_.get());
4439
4440 // Create request #1 and QuicHttpStream.
4441 QuicStreamRequest request1(factory_.get());
4442 EXPECT_EQ(ERR_IO_PENDING,
4443 request1.Request(host_port_pair_, version_, privacy_mode_,
4444 DEFAULT_PRIORITY, SocketTag(),
4445 /*cert_verify_flags=*/0, url_, net_log_,
4446 &net_error_details_, callback_.callback()));
4447 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4448 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
4449 EXPECT_TRUE(stream1.get());
4450
4451 HttpRequestInfo request_info1;
4452 request_info1.method = "GET";
4453 request_info1.url = GURL("https://www.example.org/");
4454 request_info1.traffic_annotation =
4455 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4456 EXPECT_EQ(OK,
4457 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
4458 net_log_, CompletionOnceCallback()));
4459
4460 // Request #2 returns synchronously because it pools to existing session.
4461 TestCompletionCallback callback2;
4462 QuicStreamRequest request2(factory_.get());
4463 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_, privacy_mode_,
4464 DEFAULT_PRIORITY, SocketTag(),
4465 /*cert_verify_flags=*/0, url_, net_log_,
4466 &net_error_details_, callback2.callback()));
4467 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
4468 EXPECT_TRUE(stream2.get());
4469
4470 HttpRequestInfo request_info2;
4471 request_info2.method = "GET";
4472 request_info2.url = GURL("https://www.example.org/");
4473 request_info2.traffic_annotation =
4474 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4475 EXPECT_EQ(OK,
4476 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
4477 net_log_, CompletionOnceCallback()));
4478
4479 // Ensure that session is alive and active.
4480 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
4481 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4482 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4483 EXPECT_EQ(2u, session->GetNumActiveStreams());
4484
4485 // Send GET request on stream1. This should cause an async write error.
4486 HttpResponseInfo response;
4487 HttpRequestHeaders request_headers;
4488 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
4489 callback_.callback()));
4490 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4491
4492 // Run the message loop so that asynchronous write completes and a connection
4493 // migration on write error attempt is posted in QuicStreamFactory's task
4494 // runner.
4495 base::RunLoop().RunUntilIdle();
4496 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4497
4498 // Send GET request on stream. This will cause another write attempt before
4499 // migration on write error is exectued.
4500 HttpResponseInfo response2;
4501 HttpRequestHeaders request_headers2;
4502 EXPECT_EQ(OK, stream2->SendRequest(request_headers2, &response2,
4503 callback2.callback()));
4504
4505 // Run the task runner so that migration on write error is finally executed.
4506 task_runner->RunUntilIdle();
4507
Zhongyi Shia7dd46b2018-07-12 22:59:294508 // Verify the session is still alive and not marked as going away.
Zhongyi Shi3c4c9e92018-07-02 23:16:234509 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:294510 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi3c4c9e92018-07-02 23:16:234511 EXPECT_EQ(2u, session->GetNumActiveStreams());
Zhongyi Shia7dd46b2018-07-12 22:59:294512 // There should be one task posted to migrate back to the default network in
4513 // kMinRetryTimeForDefaultNetworkSecs.
4514 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4515 EXPECT_EQ(base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs),
4516 task_runner->NextPendingTaskDelay());
Zhongyi Shi3c4c9e92018-07-02 23:16:234517
4518 // Verify that response headers on the migrated socket were delivered to the
4519 // stream.
4520 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
4521 EXPECT_EQ(200, response.headers->response_code());
4522
4523 stream1.reset();
4524 stream2.reset();
4525
4526 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4527 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4528 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
4529 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
4530}
4531
Zhongyi Shia7dd46b2018-07-12 22:59:294532// Verify session is not marked as going away after connection migration on
4533// write error and migrate back to default network logic is applied to bring the
4534// migrated session back to the default network. Migration singals delivered
4535// in the following order (alternate network is always availabe):
4536// - session on the default network encountered a write error;
4537// - session successfully migrated to the non-default network;
4538// - session attempts to migrate back to default network post migration;
4539// - migration back to the default network is successful.
4540TEST_P(QuicStreamFactoryTest, MigrateBackToDefaultPostMigrationOnWriteError) {
4541 InitializeConnectionMigrationV2Test(
4542 {kDefaultNetworkForTests, kNewNetworkForTests});
4543 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4544 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4545 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4546
4547 // Using a testing task runner so that we can control time.
4548 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4549 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4550
4551 MockQuicData socket_data;
4552 quic::QuicStreamOffset header_stream_offset = 0;
4553 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4554 socket_data.AddWrite(
4555 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4556 socket_data.AddWrite(ASYNC, ERR_ADDRESS_UNREACHABLE);
4557 socket_data.AddSocketDataToFactory(socket_factory_.get());
4558
4559 // Set up second socket data provider that is used after
4560 // migration. The request is rewritten to this new socket, and the
4561 // response to the request is read on this new socket.
4562 MockQuicData quic_data2;
4563 quic_data2.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
4564 2, GetNthClientInitiatedStreamId(0),
4565 true, true, &header_stream_offset));
4566 quic_data2.AddRead(
4567 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
4568 false, false));
4569 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4570 quic_data2.AddSocketDataToFactory(socket_factory_.get());
4571
4572 // Create request QuicHttpStream.
4573 QuicStreamRequest request1(factory_.get());
4574 EXPECT_EQ(ERR_IO_PENDING,
4575 request1.Request(host_port_pair_, version_, privacy_mode_,
4576 DEFAULT_PRIORITY, SocketTag(),
4577 /*cert_verify_flags=*/0, url_, net_log_,
4578 &net_error_details_, callback_.callback()));
4579 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4580 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
4581 EXPECT_TRUE(stream1.get());
4582
4583 HttpRequestInfo request_info1;
4584 request_info1.method = "GET";
4585 request_info1.url = GURL("https://www.example.org/");
4586 request_info1.traffic_annotation =
4587 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4588 EXPECT_EQ(OK,
4589 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
4590 net_log_, CompletionOnceCallback()));
4591
4592 // Ensure that session is alive and active.
4593 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
4594 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4595 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4596 EXPECT_EQ(1u, session->GetNumActiveStreams());
4597
4598 // Send GET request. This should cause an async write error.
4599 HttpResponseInfo response;
4600 HttpRequestHeaders request_headers;
4601 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
4602 callback_.callback()));
4603 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4604
4605 // Run the message loop so that asynchronous write completes and a connection
4606 // migration on write error attempt is posted in QuicStreamFactory's task
4607 // runner.
4608 base::RunLoop().RunUntilIdle();
4609 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4610
4611 // Run the task runner so that migration on write error is finally executed.
4612 task_runner->RunUntilIdle();
4613
4614 // Verify the session is still alive and not marked as going away.
4615 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4616 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4617 EXPECT_EQ(1u, session->GetNumActiveStreams());
4618 // There should be one task posted to migrate back to the default network in
4619 // kMinRetryTimeForDefaultNetworkSecs.
4620 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4621 base::TimeDelta expected_delay =
4622 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs);
4623 EXPECT_EQ(expected_delay, task_runner->NextPendingTaskDelay());
4624
4625 // Verify that response headers on the migrated socket were delivered to the
4626 // stream.
4627 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
4628 EXPECT_EQ(200, response.headers->response_code());
4629
4630 // Set up the third socket data provider for migrate back to default network.
4631 MockQuicData quic_data3;
4632 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:254633 quic_data3.AddWrite(SYNCHRONOUS,
4634 client_maker_.MakeConnectivityProbingPacket(3, false));
Zhongyi Shia7dd46b2018-07-12 22:59:294635 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:254636 quic_data3.AddRead(ASYNC,
4637 server_maker_.MakeConnectivityProbingPacket(2, false));
Zhongyi Shia7dd46b2018-07-12 22:59:294638 quic_data3.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4639 quic_data3.AddWrite(ASYNC, client_maker_.MakeAckPacket(4, 1, 2, 1, 1, true));
4640 quic_data3.AddWrite(
4641 SYNCHRONOUS,
4642 client_maker_.MakeRstPacket(5, false, GetNthClientInitiatedStreamId(0),
4643 quic::QUIC_STREAM_CANCELLED, 0));
4644 quic_data3.AddSocketDataToFactory(socket_factory_.get());
4645
4646 // Fast forward to fire the migrate back timer and verify the session
4647 // successfully migrates back to the default network.
4648 task_runner->FastForwardBy(expected_delay);
4649
4650 // Verify the session is still alive and not marked as going away.
4651 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4652 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4653 EXPECT_EQ(1u, session->GetNumActiveStreams());
4654
4655 // There should be one task posted to one will resend a connectivity probe and
4656 // the other will retry migrate back, both are cancelled.
4657 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
4658 task_runner->FastForwardBy(
4659 base::TimeDelta::FromSeconds(2 * kMinRetryTimeForDefaultNetworkSecs));
4660 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4661
4662 stream1.reset();
4663 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4664 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4665 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
4666 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
4667 EXPECT_TRUE(quic_data3.AllReadDataConsumed());
4668 EXPECT_TRUE(quic_data3.AllWriteDataConsumed());
4669}
4670
Zhongyi Shic1449372018-08-09 09:58:584671// This test verifies that the connection will not attempt connection migration
4672// (send connectivity probes on alternate path) when path degrading is detected
4673// and handshake is not confirmed.
4674TEST_P(QuicStreamFactoryTest,
4675 NoMigrationOnPathDegradingBeforeHandshakeConfirmed) {
4676 InitializeConnectionMigrationV2Test(
4677 {kDefaultNetworkForTests, kNewNetworkForTests});
4678
4679 // Using a testing task runner.
4680 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4681 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4682
4683 // Use cold start mode to send crypto message for handshake.
4684 crypto_client_stream_factory_.set_handshake_mode(
4685 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
4686
4687 MockQuicData socket_data;
4688 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4689 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
4690 socket_data.AddSocketDataToFactory(socket_factory_.get());
4691
4692 // Create request and QuicHttpStream.
4693 QuicStreamRequest request(factory_.get());
4694 EXPECT_EQ(ERR_IO_PENDING,
4695 request.Request(host_port_pair_, version_, privacy_mode_,
4696 DEFAULT_PRIORITY, SocketTag(),
4697 /*cert_verify_flags=*/0, url_, net_log_,
4698 &net_error_details_, callback_.callback()));
4699
4700 base::RunLoop().RunUntilIdle();
4701
4702 // Ensure that session is alive but not active.
4703 EXPECT_FALSE(HasActiveSession(host_port_pair_));
4704 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
4705 QuicChromiumClientSession* session = GetPendingSession(host_port_pair_);
4706 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4707 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4708
4709 // Cause the connection to report path degrading to the session.
4710 // Session will ignore the signal as handshake is not completed.
4711 session->connection()->OnPathDegradingTimeout();
4712 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4713
4714 EXPECT_FALSE(HasActiveSession(host_port_pair_));
Zhongyi Shi8de43832018-08-15 23:40:004715 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
Zhongyi Shic1449372018-08-09 09:58:584716 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4717 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4718}
4719
Zhongyi Shi634c1882018-08-16 04:05:594720// This test verifies that if a connection is closed with
4721// QUIC_NETWORK_IDLE_TIMEOUT before handshake is completed and there is no
4722// alternate network, no new connection will be created.
4723TEST_P(QuicStreamFactoryTest, NoAlternateNetworkBeforeHandshakeOnIdleTimeout) {
4724 TestNoAlternateNetworkBeforeHandshake(quic::QUIC_NETWORK_IDLE_TIMEOUT);
4725}
4726
4727// This test verifies that if a connection is closed with QUIC_HANDSHAKE_TIMEOUT
4728// and there is no alternate network, no new connection will be created.
4729TEST_P(QuicStreamFactoryTest, NoAlternateNetworkOnHandshakeTimeout) {
4730 TestNoAlternateNetworkBeforeHandshake(quic::QUIC_HANDSHAKE_TIMEOUT);
4731}
4732
4733void QuicStreamFactoryTestBase::TestNoAlternateNetworkBeforeHandshake(
4734 quic::QuicErrorCode quic_error) {
4735 DCHECK(quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT ||
4736 quic_error == quic::QUIC_HANDSHAKE_TIMEOUT);
4737 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
4738
4739 // Using a testing task runner.
4740 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4741 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4742
4743 // Use cold start mode to send crypto message for handshake.
4744 crypto_client_stream_factory_.set_handshake_mode(
4745 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
4746
4747 MockQuicData socket_data;
4748 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4749 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
4750 socket_data.AddSocketDataToFactory(socket_factory_.get());
4751
4752 // Create request.
4753 QuicStreamRequest request(factory_.get());
4754 EXPECT_EQ(ERR_IO_PENDING,
4755 request.Request(host_port_pair_, version_, privacy_mode_,
4756 DEFAULT_PRIORITY, SocketTag(),
4757 /*cert_verify_flags=*/0, url_, net_log_,
4758 &net_error_details_, callback_.callback()));
4759
4760 base::RunLoop().RunUntilIdle();
4761
4762 // Ensure that session is alive but not active.
4763 EXPECT_FALSE(HasActiveSession(host_port_pair_));
4764 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
4765 QuicChromiumClientSession* session = GetPendingSession(host_port_pair_);
4766 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4767 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4768
4769 // Cause the connection to report path degrading to the session.
4770 // Session will ignore the signal as handshake is not completed.
4771 session->connection()->OnPathDegradingTimeout();
4772 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4773 EXPECT_FALSE(HasActiveSession(host_port_pair_));
4774 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
4775
4776 // Cause the connection to close due to |quic_error| before handshake.
4777 quic::QuicString error_details;
4778 if (quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT) {
4779 error_details = "No recent network activity.";
4780 } else {
4781 error_details = "Handshake timeout expired.";
4782 }
4783 session->connection()->CloseConnection(
4784 quic_error, error_details, quic::ConnectionCloseBehavior::SILENT_CLOSE);
4785
4786 // A task will be posted to clean up the session in the factory.
4787 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4788 task_runner->FastForwardUntilNoTasksRemain();
4789
4790 // No new session should be created as there is no alternate network.
4791 EXPECT_FALSE(HasActiveSession(host_port_pair_));
4792 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
4793 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4794 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4795}
4796
Zhongyi Shi8de43832018-08-15 23:40:004797TEST_P(QuicStreamFactoryTest, NewConnectionBeforeHandshakeAfterIdleTimeout) {
4798 TestNewConnectionOnAlternateNetworkBeforeHandshake(
4799 quic::QUIC_NETWORK_IDLE_TIMEOUT);
4800}
4801
4802TEST_P(QuicStreamFactoryTest, NewConnectionAfterHandshakeTimeout) {
4803 TestNewConnectionOnAlternateNetworkBeforeHandshake(
4804 quic::QUIC_HANDSHAKE_TIMEOUT);
4805}
4806
Zhongyi Shif3fcbbe62018-08-16 22:52:084807// Sets up a test to verify that a new connection will be created on the
4808// alternate network after the initial connection fails before handshake with
4809// signals delivered in the following order (alternate network is available):
4810// - the default network is not able to complete crypto handshake;
4811// - the original connection is closed with |quic_error|;
4812// - a new connection is created on the alternate network and is able to finish
4813// crypto handshake;
4814// - the new session on the alternate network attempts to migrate back to the
4815// default network by sending probes;
4816// - default network being disconnected is delivered: session will stop probing
4817// the original network.
4818// - alternate network is made by default.
Zhongyi Shi8de43832018-08-15 23:40:004819void QuicStreamFactoryTestBase::
4820 TestNewConnectionOnAlternateNetworkBeforeHandshake(
4821 quic::QuicErrorCode quic_error) {
4822 DCHECK(quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT ||
4823 quic_error == quic::QUIC_HANDSHAKE_TIMEOUT);
4824 InitializeConnectionMigrationV2Test(
4825 {kDefaultNetworkForTests, kNewNetworkForTests});
4826
4827 // Using a testing task runner.
4828 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4829 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4830
4831 // Use cold start mode to send crypto message for handshake.
4832 crypto_client_stream_factory_.set_handshake_mode(
4833 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
4834
4835 // Socket data for connection on the default network.
4836 MockQuicData socket_data;
4837 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4838 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
4839 socket_data.AddSocketDataToFactory(socket_factory_.get());
4840
4841 // Socket data for connection on the alternate network.
4842 MockQuicData socket_data2;
4843 quic::QuicStreamOffset header_stream_offset = 0;
4844 socket_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
4845 socket_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
4846 // Change the encryption level after handshake is confirmed.
4847 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
4848 socket_data2.AddWrite(
4849 ASYNC, ConstructInitialSettingsPacket(2, &header_stream_offset));
4850 socket_data2.AddWrite(
4851 ASYNC, ConstructGetRequestPacket(3, GetNthClientInitiatedStreamId(0),
4852 true, true, &header_stream_offset));
4853 socket_data2.AddRead(
4854 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
4855 false, false));
4856 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4857 socket_data2.AddWrite(SYNCHRONOUS,
4858 client_maker_.MakeAckAndRstPacket(
Zhongyi Shif3fcbbe62018-08-16 22:52:084859 5, false, GetNthClientInitiatedStreamId(0),
Zhongyi Shi8de43832018-08-15 23:40:004860 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
4861 socket_data2.AddSocketDataToFactory(socket_factory_.get());
4862
Zhongyi Shif3fcbbe62018-08-16 22:52:084863 // Socket data for probing on the default network.
4864 MockQuicData probing_data;
4865 probing_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
4866 probing_data.AddWrite(SYNCHRONOUS,
4867 client_maker_.MakeConnectivityProbingPacket(4, false));
4868 probing_data.AddSocketDataToFactory(socket_factory_.get());
4869
Zhongyi Shi8de43832018-08-15 23:40:004870 // Create request and QuicHttpStream.
4871 QuicStreamRequest request(factory_.get());
4872 EXPECT_EQ(ERR_IO_PENDING,
4873 request.Request(host_port_pair_, version_, privacy_mode_,
4874 DEFAULT_PRIORITY, SocketTag(),
4875 /*cert_verify_flags=*/0, url_, net_log_,
4876 &net_error_details_, callback_.callback()));
4877
4878 base::RunLoop().RunUntilIdle();
4879
4880 // Ensure that session is alive but not active.
4881 EXPECT_FALSE(HasActiveSession(host_port_pair_));
4882 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
4883 QuicChromiumClientSession* session = GetPendingSession(host_port_pair_);
4884 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4885 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4886
4887 quic::QuicString error_details;
4888 if (quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT) {
4889 error_details = "No recent network activity.";
4890 } else {
4891 error_details = "Handshake timeout expired.";
4892 }
4893 session->connection()->CloseConnection(
4894 quic_error, error_details, quic::ConnectionCloseBehavior::SILENT_CLOSE);
4895
4896 // A task will be posted to clean up the session in the factory.
4897 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4898 task_runner->FastForwardUntilNoTasksRemain();
4899
4900 // Verify a new session is created on the alternate network.
4901 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
4902 EXPECT_FALSE(HasActiveSession(host_port_pair_));
4903 QuicChromiumClientSession* session2 = GetPendingSession(host_port_pair_);
4904 EXPECT_NE(session, session2);
4905
4906 // Confirm the handshake on the alternate network.
4907 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
4908 quic::QuicSession::HANDSHAKE_CONFIRMED);
4909 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4910 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4911 // Resume the data now so that data can be sent and read.
4912 socket_data2.Resume();
4913
4914 // Create the stream.
4915 std::unique_ptr<HttpStream> stream = CreateStream(&request);
4916 EXPECT_TRUE(stream.get());
4917 HttpRequestInfo request_info;
4918 request_info.method = "GET";
4919 request_info.url = GURL("https://www.example.org/");
4920 request_info.traffic_annotation =
4921 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4922 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
4923 net_log_, CompletionOnceCallback()));
4924 // Send the request.
4925 HttpResponseInfo response;
4926 HttpRequestHeaders request_headers;
4927 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
4928 callback_.callback()));
4929 // Run the message loop to finish asynchronous mock write.
4930 base::RunLoop().RunUntilIdle();
4931 // Read the response.
4932 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
4933 EXPECT_EQ(200, response.headers->response_code());
4934
Zhongyi Shif3fcbbe62018-08-16 22:52:084935 // There should be a new task posted to migrate back to the default network.
4936 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4937 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
4938 EXPECT_EQ(base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs),
4939 next_task_delay);
4940 task_runner->FastForwardBy(next_task_delay);
4941
4942 // There should be two tasks posted. One will retry probing and the other
4943 // will retry migrate back.
4944 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
4945 next_task_delay = task_runner->NextPendingTaskDelay();
4946 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
4947 next_task_delay);
4948
4949 // Deliver the signal that the default network is disconnected.
4950 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4951 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
4952 // Verify no connectivity probes will be sent as probing will be cancelled.
4953 task_runner->FastForwardUntilNoTasksRemain();
4954 // Deliver the signal that the alternate network is made default.
4955 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4956 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
4957 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4958
Zhongyi Shi8de43832018-08-15 23:40:004959 stream.reset();
4960 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4961 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4962 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
4963 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
4964}
4965
Zhongyi Shi247d6322018-07-24 07:03:354966// Test that connection will be closed with PACKET_WRITE_ERROR if a write error
4967// is triggered before handshake is confirmed and connection migration is turned
4968// on.
4969TEST_P(QuicStreamFactoryTest, MigrationOnWriteErrorBeforeHandshakeConfirmed) {
4970 InitializeConnectionMigrationV2Test(
4971 {kDefaultNetworkForTests, kNewNetworkForTests});
4972
4973 // Use unmocked crypto stream to do crypto connect.
4974 crypto_client_stream_factory_.set_handshake_mode(
Zhongyi Shi879659422018-08-02 17:58:254975 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
Zhongyi Shi247d6322018-07-24 07:03:354976
4977 MockQuicData socket_data;
4978 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4979 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
4980 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
4981 socket_data.AddSocketDataToFactory(socket_factory_.get());
4982
4983 // Create request, should fail after the write of the CHLO fails.
4984 QuicStreamRequest request(factory_.get());
4985 EXPECT_EQ(ERR_IO_PENDING,
4986 request.Request(host_port_pair_, version_, privacy_mode_,
4987 DEFAULT_PRIORITY, SocketTag(),
4988 /*cert_verify_flags=*/0, url_, net_log_,
4989 &net_error_details_, callback_.callback()));
4990 EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED, callback_.WaitForResult());
4991 EXPECT_FALSE(HasActiveSession(host_port_pair_));
4992 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
4993
4994 // Verify new requests can be sent normally.
4995 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:274996 MockCryptoClientStream::COLD_START);
Zhongyi Shi247d6322018-07-24 07:03:354997 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4998 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4999 MockQuicData socket_data2;
5000 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5001 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
5002 socket_data2.AddSocketDataToFactory(socket_factory_.get());
5003
5004 QuicStreamRequest request2(factory_.get());
5005 EXPECT_EQ(ERR_IO_PENDING,
5006 request2.Request(host_port_pair_, version_, privacy_mode_,
5007 DEFAULT_PRIORITY, SocketTag(),
5008 /*cert_verify_flags=*/0, url_, net_log_,
5009 &net_error_details_, callback_.callback()));
5010 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5011 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5012 // Run the message loop to complete host resolution.
5013 base::RunLoop().RunUntilIdle();
5014
5015 // Complete handshake. QuicStreamFactory::Job should complete and succeed.
5016 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5017 quic::QuicSession::HANDSHAKE_CONFIRMED);
5018 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5019 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5020 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
5021
5022 // Create QuicHttpStream.
5023 std::unique_ptr<HttpStream> stream = CreateStream(&request2);
5024 EXPECT_TRUE(stream.get());
5025 stream.reset();
5026 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5027 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5028 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
5029 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
5030}
5031
jri9f303712016-09-13 01:10:225032void QuicStreamFactoryTestBase::TestMigrationOnWriteError(
5033 IoMode write_error_mode) {
Zhongyi Shi1a054612018-06-14 04:59:085034 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:225035 {kDefaultNetworkForTests, kNewNetworkForTests});
5036 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5037 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5038 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5039
Zhongyi Shi3c4c9e92018-07-02 23:16:235040 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
5041
jri9f303712016-09-13 01:10:225042 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525043 quic::QuicStreamOffset header_stream_offset = 0;
jri9f303712016-09-13 01:10:225044 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
rch5cb522462017-04-25 20:18:365045 socket_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435046 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
jri9f303712016-09-13 01:10:225047 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:175048 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:225049
5050 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:455051 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:335052 EXPECT_EQ(ERR_IO_PENDING,
5053 request.Request(host_port_pair_, version_, privacy_mode_,
5054 DEFAULT_PRIORITY, SocketTag(),
5055 /*cert_verify_flags=*/0, url_, net_log_,
5056 &net_error_details_, callback_.callback()));
jri9f303712016-09-13 01:10:225057 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:245058 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:225059 EXPECT_TRUE(stream.get());
5060
5061 // Cause QUIC stream to be created.
5062 HttpRequestInfo request_info;
5063 request_info.method = "GET";
5064 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:395065 request_info.traffic_annotation =
5066 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:275067 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:395068 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:225069
5070 // Ensure that session is alive and active.
5071 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5072 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5073 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5074
5075 // Set up second socket data provider that is used after
5076 // migration. The request is rewritten to this new socket, and the
5077 // response to the request is read on this new socket.
5078 MockQuicData socket_data1;
Zhongyi Shi32f2fd02018-04-16 18:23:435079 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
5080 2, GetNthClientInitiatedStreamId(0),
5081 true, true, &header_stream_offset));
5082 socket_data1.AddRead(
5083 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
5084 false, false));
jri9f303712016-09-13 01:10:225085 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:435086 socket_data1.AddWrite(SYNCHRONOUS,
5087 client_maker_.MakeAckAndRstPacket(
5088 3, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:525089 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:175090 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:225091
5092 // Send GET request on stream. This should cause a write error, which triggers
5093 // a connection migration attempt.
5094 HttpResponseInfo response;
5095 HttpRequestHeaders request_headers;
5096 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5097 callback_.callback()));
5098
5099 // Run the message loop so that the migration attempt is executed and
5100 // data queued in the new socket is read by the packet reader.
5101 base::RunLoop().RunUntilIdle();
5102
Zhongyi Shia7dd46b2018-07-12 22:59:295103 // Verify that session is alive and not marked as going awya.
jri9f303712016-09-13 01:10:225104 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:295105 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri9f303712016-09-13 01:10:225106 EXPECT_EQ(1u, session->GetNumActiveStreams());
5107
5108 // Verify that response headers on the migrated socket were delivered to the
5109 // stream.
5110 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
5111 EXPECT_EQ(200, response.headers->response_code());
5112
5113 stream.reset();
5114
5115 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5116 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5117 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
5118 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
5119}
5120
5121TEST_P(QuicStreamFactoryTest, MigrateSessionOnWriteErrorSynchronous) {
5122 TestMigrationOnWriteError(SYNCHRONOUS);
5123}
5124
5125TEST_P(QuicStreamFactoryTest, MigrateSessionOnWriteErrorAsync) {
5126 TestMigrationOnWriteError(ASYNC);
5127}
5128
5129void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorNoNewNetwork(
5130 IoMode write_error_mode) {
Zhongyi Shi1a054612018-06-14 04:59:085131 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri9f303712016-09-13 01:10:225132 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5133 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5134
jri5b785512016-09-13 04:29:115135 // Use the test task runner, to force the migration alarm timeout later.
5136 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
5137
jri9f303712016-09-13 01:10:225138 MockQuicData socket_data;
5139 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:435140 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jri9f303712016-09-13 01:10:225141 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:175142 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:225143
5144 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:455145 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:335146 EXPECT_EQ(ERR_IO_PENDING,
5147 request.Request(host_port_pair_, version_, privacy_mode_,
5148 DEFAULT_PRIORITY, SocketTag(),
5149 /*cert_verify_flags=*/0, url_, net_log_,
5150 &net_error_details_, callback_.callback()));
jri9f303712016-09-13 01:10:225151 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:245152 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:225153 EXPECT_TRUE(stream.get());
5154
5155 // Cause QUIC stream to be created.
5156 HttpRequestInfo request_info;
5157 request_info.method = "GET";
5158 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:395159 request_info.traffic_annotation =
5160 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:275161 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:395162 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:225163
5164 // Ensure that session is alive and active.
5165 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5166 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5167 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5168
jri5b785512016-09-13 04:29:115169 // Send GET request on stream. This causes a write error, which triggers
5170 // a connection migration attempt. Since there are no networks
5171 // to migrate to, this causes the session to wait for a new network.
jri9f303712016-09-13 01:10:225172 HttpResponseInfo response;
5173 HttpRequestHeaders request_headers;
5174 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5175 callback_.callback()));
jri5b785512016-09-13 04:29:115176
5177 // Complete any pending writes. Pending async MockQuicData writes
5178 // are run on the message loop, not on the test runner.
jri9f303712016-09-13 01:10:225179 base::RunLoop().RunUntilIdle();
jri5b785512016-09-13 04:29:115180
5181 // Write error causes migration task to be posted. Spin the loop.
5182 if (write_error_mode == ASYNC)
5183 runner_->RunNextTask();
5184
5185 // Migration has not yet failed. The session should be alive and active.
5186 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5187 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5188 EXPECT_EQ(1u, session->GetNumActiveStreams());
5189 EXPECT_TRUE(session->connection()->writer()->IsWriteBlocked());
5190
5191 // The migration will not fail until the migration alarm timeout.
5192 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5193 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5194 EXPECT_EQ(1u, session->GetNumActiveStreams());
5195 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
5196
5197 // Force migration alarm timeout to run.
5198 RunTestLoopUntilIdle();
5199
5200 // The connection should be closed. A request for response headers
5201 // should fail.
jri9f303712016-09-13 01:10:225202 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5203 EXPECT_FALSE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:115204 EXPECT_EQ(ERR_NETWORK_CHANGED, callback_.WaitForResult());
5205 EXPECT_EQ(ERR_NETWORK_CHANGED,
5206 stream->ReadResponseHeaders(callback_.callback()));
jri9f303712016-09-13 01:10:225207
5208 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5209 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5210}
5211
5212TEST_P(QuicStreamFactoryTest,
5213 MigrateSessionOnWriteErrorNoNewNetworkSynchronous) {
5214 TestMigrationOnWriteErrorNoNewNetwork(SYNCHRONOUS);
5215}
5216
5217TEST_P(QuicStreamFactoryTest, MigrateSessionOnWriteErrorNoNewNetworkAsync) {
5218 TestMigrationOnWriteErrorNoNewNetwork(ASYNC);
5219}
5220
Zhongyi Shi0439ecc72018-07-11 04:41:265221TEST_P(QuicStreamFactoryTest,
5222 MigrateSessionOnWriteErrorWithMultipleRequestsSync) {
5223 TestMigrationOnWriteErrorWithMultipleRequests(SYNCHRONOUS);
5224}
5225
5226TEST_P(QuicStreamFactoryTest,
5227 MigrateSessionOnWriteErrorWithMultipleRequestsAsync) {
5228 TestMigrationOnWriteErrorWithMultipleRequests(ASYNC);
5229}
5230
5231// Sets up a test which verifies that connection migration on write error can
5232// eventually succeed and rewrite the packet on the new network with *multiple*
5233// migratable streams.
5234void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorWithMultipleRequests(
5235 IoMode write_error_mode) {
5236 InitializeConnectionMigrationV2Test(
5237 {kDefaultNetworkForTests, kNewNetworkForTests});
5238 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5239 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5240 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5241
5242 MockQuicData socket_data;
5243 quic::QuicStreamOffset header_stream_offset = 0;
5244 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5245 socket_data.AddWrite(
5246 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5247 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
5248 socket_data.AddSocketDataToFactory(socket_factory_.get());
5249
5250 // Set up second socket data provider that is used after
5251 // migration. The request is rewritten to this new socket, and the
5252 // response to the request is read on this new socket.
5253 MockQuicData socket_data1;
5254 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
5255 2, GetNthClientInitiatedStreamId(0),
5256 true, true, &header_stream_offset));
5257 socket_data1.AddRead(
5258 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
5259 false, false));
5260 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5261 socket_data1.AddWrite(SYNCHRONOUS,
5262 client_maker_.MakeAckAndRstPacket(
5263 3, false, GetNthClientInitiatedStreamId(0),
5264 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
5265 socket_data1.AddWrite(
5266 SYNCHRONOUS,
5267 client_maker_.MakeRstPacket(4, false, GetNthClientInitiatedStreamId(1),
5268 quic::QUIC_STREAM_CANCELLED, 0));
5269
5270 socket_data1.AddSocketDataToFactory(socket_factory_.get());
5271
5272 // Create request #1 and QuicHttpStream.
5273 QuicStreamRequest request1(factory_.get());
5274 EXPECT_EQ(ERR_IO_PENDING,
5275 request1.Request(host_port_pair_, version_, privacy_mode_,
5276 DEFAULT_PRIORITY, SocketTag(),
5277 /*cert_verify_flags=*/0, url_, net_log_,
5278 &net_error_details_, callback_.callback()));
5279 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5280 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
5281 EXPECT_TRUE(stream1.get());
5282
5283 HttpRequestInfo request_info1;
5284 request_info1.method = "GET";
5285 request_info1.url = GURL("https://www.example.org/");
5286 request_info1.traffic_annotation =
5287 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5288 EXPECT_EQ(OK,
5289 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
5290 net_log_, CompletionOnceCallback()));
5291
5292 // Second request returns synchronously because it pools to existing session.
5293 TestCompletionCallback callback2;
5294 QuicStreamRequest request2(factory_.get());
5295 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_, privacy_mode_,
5296 DEFAULT_PRIORITY, SocketTag(),
5297 /*cert_verify_flags=*/0, url_, net_log_,
5298 &net_error_details_, callback2.callback()));
5299 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
5300 EXPECT_TRUE(stream2.get());
5301 HttpRequestInfo request_info2;
5302 request_info2.method = "GET";
5303 request_info2.url = GURL("https://www.example.org/");
5304 request_info2.traffic_annotation =
5305 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5306 EXPECT_EQ(OK,
5307 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
5308 net_log_, CompletionOnceCallback()));
5309
5310 // Ensure that session is alive and active.
5311 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5312 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5313 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5314 EXPECT_EQ(2u, session->GetNumActiveStreams());
5315
5316 // Send GET request on stream. This should cause a write error, which triggers
5317 // a connection migration attempt.
5318 HttpResponseInfo response;
5319 HttpRequestHeaders request_headers;
5320 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
5321 callback_.callback()));
5322
5323 // Run the message loop so that the migration attempt is executed and
5324 // data queued in the new socket is read by the packet reader.
5325 base::RunLoop().RunUntilIdle();
5326
Zhongyi Shia7dd46b2018-07-12 22:59:295327 // Verify session is still alive and not marked as going away.
Zhongyi Shi0439ecc72018-07-11 04:41:265328 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:295329 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:265330 EXPECT_EQ(2u, session->GetNumActiveStreams());
5331
5332 // Verify that response headers on the migrated socket were delivered to the
5333 // stream.
5334 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
5335 EXPECT_EQ(200, response.headers->response_code());
5336
5337 stream1.reset();
5338 stream2.reset();
5339
5340 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5341 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5342 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
5343 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
5344}
5345
5346TEST_P(QuicStreamFactoryTest, MigrateOnWriteErrorWithMixedRequestsSync) {
5347 TestMigrationOnWriteErrorMixedStreams(SYNCHRONOUS);
5348}
5349
5350TEST_P(QuicStreamFactoryTest, MigrateOnWriteErrorWithMixedRequestsAsync) {
5351 TestMigrationOnWriteErrorMixedStreams(ASYNC);
5352}
5353
5354// Sets up a test that verifies connection migration manages to migrate to
5355// alternate network after encountering a SYNC/ASYNC write error based on
5356// |write_error_mode| on the original network.
5357// Note there are mixed types of unfinished requests before migration: one
5358// migratable and one non-migratable. The *migratable* one triggers write
5359// error.
5360void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorMixedStreams(
5361 IoMode write_error_mode) {
5362 InitializeConnectionMigrationV2Test(
5363 {kDefaultNetworkForTests, kNewNetworkForTests});
5364 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5365 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5366 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5367
5368 int packet_number = 1;
5369 MockQuicData socket_data;
5370 quic::QuicStreamOffset header_stream_offset = 0;
5371 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5372 socket_data.AddWrite(
5373 SYNCHRONOUS,
5374 ConstructInitialSettingsPacket(packet_number++, &header_stream_offset));
5375 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
5376 socket_data.AddSocketDataToFactory(socket_factory_.get());
5377
5378 // Set up second socket data provider that is used after
5379 // migration. The request is rewritten to this new socket, and the
5380 // response to the request is read on this new socket.
5381 MockQuicData socket_data1;
5382 socket_data1.AddWrite(
5383 SYNCHRONOUS, ConstructGetRequestPacket(
5384 packet_number++, GetNthClientInitiatedStreamId(0), true,
5385 true, &header_stream_offset));
5386 socket_data1.AddWrite(
5387 SYNCHRONOUS, client_maker_.MakeRstPacket(packet_number++, true,
5388 GetNthClientInitiatedStreamId(1),
5389 quic::QUIC_STREAM_CANCELLED, 0));
5390 socket_data1.AddRead(
5391 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
5392 false, false));
5393 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5394 socket_data1.AddWrite(
5395 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
5396 packet_number++, false, GetNthClientInitiatedStreamId(0),
5397 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
5398 socket_data1.AddSocketDataToFactory(socket_factory_.get());
5399
5400 // Create request #1 and QuicHttpStream.
5401 QuicStreamRequest request1(factory_.get());
5402 EXPECT_EQ(ERR_IO_PENDING,
5403 request1.Request(host_port_pair_, version_, privacy_mode_,
5404 DEFAULT_PRIORITY, SocketTag(),
5405 /*cert_verify_flags=*/0, url_, net_log_,
5406 &net_error_details_, callback_.callback()));
5407 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5408 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
5409 EXPECT_TRUE(stream1.get());
5410
5411 HttpRequestInfo request_info1;
5412 request_info1.method = "GET";
5413 request_info1.url = GURL("https://www.example.org/");
5414 request_info1.traffic_annotation =
5415 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5416 EXPECT_EQ(OK,
5417 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
5418 net_log_, CompletionOnceCallback()));
5419
5420 // Second request returns synchronously because it pools to existing session.
5421 TestCompletionCallback callback2;
5422 QuicStreamRequest request2(factory_.get());
5423 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_, privacy_mode_,
5424 DEFAULT_PRIORITY, SocketTag(),
5425 /*cert_verify_flags=*/0, url_, net_log_,
5426 &net_error_details_, callback2.callback()));
5427 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
5428 EXPECT_TRUE(stream2.get());
5429
5430 HttpRequestInfo request_info2;
5431 request_info2.method = "GET";
Zhongyi Shibb28b1f2018-07-18 02:41:265432 request_info2.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Zhongyi Shi0439ecc72018-07-11 04:41:265433 request_info2.url = GURL("https://www.example.org/");
5434 request_info2.traffic_annotation =
5435 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5436 EXPECT_EQ(OK,
5437 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
5438 net_log_, CompletionOnceCallback()));
5439
5440 // Ensure that session is alive and active.
5441 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5442 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5443 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5444 EXPECT_EQ(2u, session->GetNumActiveStreams());
5445
5446 // Send GET request on stream 1. This should cause a write error, which
5447 // triggers a connection migration attempt.
5448 HttpResponseInfo response;
5449 HttpRequestHeaders request_headers;
5450 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
5451 callback_.callback()));
5452
5453 // Run the message loop so that the migration attempt is executed and
5454 // data queued in the new socket is read by the packet reader.
5455 base::RunLoop().RunUntilIdle();
5456
Zhongyi Shia7dd46b2018-07-12 22:59:295457 // Verify that the session is still alive and not marked as going away.
5458 // Non-migratable stream should be closed due to migration.
Zhongyi Shi0439ecc72018-07-11 04:41:265459 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:295460 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:265461 EXPECT_EQ(1u, session->GetNumActiveStreams());
5462
5463 // Verify that response headers on the migrated socket were delivered to the
5464 // stream.
5465 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
5466 EXPECT_EQ(200, response.headers->response_code());
5467
5468 stream1.reset();
5469
5470 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5471 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5472 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
5473 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
5474}
5475
5476TEST_P(QuicStreamFactoryTest, MigrateOnWriteErrorWithMixedRequests2Sync) {
5477 TestMigrationOnWriteErrorMixedStreams2(SYNCHRONOUS);
5478}
5479
5480TEST_P(QuicStreamFactoryTest, MigrateOnWriteErrorWithMixedRequests2Async) {
5481 TestMigrationOnWriteErrorMixedStreams2(ASYNC);
5482}
5483
5484// The one triggers write error is a non-migratable stream.
5485// Sets up a test that verifies connection migration manages to migrate to
5486// alternate network after encountering a SYNC/ASYNC write error based on
5487// |write_error_mode| on the original network.
5488// Note there are mixed types of unfinished requests before migration: one
5489// migratable and one non-migratable. The *non-migratable* one triggers write
5490// error.
5491void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorMixedStreams2(
5492 IoMode write_error_mode) {
5493 InitializeConnectionMigrationV2Test(
5494 {kDefaultNetworkForTests, kNewNetworkForTests});
5495 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5496 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5497 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5498
5499 int packet_number = 1;
5500 MockQuicData socket_data;
5501 quic::QuicStreamOffset header_stream_offset = 0;
5502 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5503 socket_data.AddWrite(
5504 SYNCHRONOUS,
5505 ConstructInitialSettingsPacket(packet_number++, &header_stream_offset));
5506 socket_data.AddWrite(write_error_mode,
5507 ERR_ADDRESS_UNREACHABLE); // Write error.
5508 socket_data.AddSocketDataToFactory(socket_factory_.get());
5509
5510 // Set up second socket data provider that is used after
5511 // migration. The request is rewritten to this new socket, and the
5512 // response to the request is read on this new socket.
5513 MockQuicData socket_data1;
5514 // The packet triggered writer error will be sent anyway even if the stream
5515 // will be cancelled later.
5516 socket_data1.AddWrite(
5517 SYNCHRONOUS, ConstructGetRequestPacket(
5518 packet_number++, GetNthClientInitiatedStreamId(1), true,
5519 true, &header_stream_offset));
5520 socket_data1.AddWrite(
5521 SYNCHRONOUS, client_maker_.MakeRstPacket(packet_number++, true,
5522 GetNthClientInitiatedStreamId(1),
5523 quic::QUIC_STREAM_CANCELLED, 0));
5524 socket_data1.AddWrite(
5525 SYNCHRONOUS, ConstructGetRequestPacket(
5526 packet_number++, GetNthClientInitiatedStreamId(0), true,
5527 true, &header_stream_offset));
5528 socket_data1.AddRead(
5529 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
5530 false, false));
5531 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5532 socket_data1.AddWrite(
5533 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
5534 packet_number++, false, GetNthClientInitiatedStreamId(0),
5535 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
5536 socket_data1.AddSocketDataToFactory(socket_factory_.get());
5537
5538 // Create request #1 and QuicHttpStream.
5539 QuicStreamRequest request1(factory_.get());
5540 EXPECT_EQ(ERR_IO_PENDING,
5541 request1.Request(host_port_pair_, version_, privacy_mode_,
5542 DEFAULT_PRIORITY, SocketTag(),
5543 /*cert_verify_flags=*/0, url_, net_log_,
5544 &net_error_details_, callback_.callback()));
5545 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5546 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
5547 EXPECT_TRUE(stream1.get());
5548
5549 HttpRequestInfo request_info1;
5550 request_info1.method = "GET";
5551 request_info1.url = GURL("https://www.example.org/");
5552 request_info1.traffic_annotation =
5553 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5554 EXPECT_EQ(OK,
5555 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
5556 net_log_, CompletionOnceCallback()));
5557
5558 // Second request returns synchronously because it pools to existing session.
5559 TestCompletionCallback callback2;
5560 QuicStreamRequest request2(factory_.get());
5561 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_, privacy_mode_,
5562 DEFAULT_PRIORITY, SocketTag(),
5563 /*cert_verify_flags=*/0, url_, net_log_,
5564 &net_error_details_, callback2.callback()));
5565 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
5566 EXPECT_TRUE(stream2.get());
5567
5568 HttpRequestInfo request_info2;
5569 request_info2.method = "GET";
Zhongyi Shibb28b1f2018-07-18 02:41:265570 request_info2.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Zhongyi Shi0439ecc72018-07-11 04:41:265571 request_info2.url = GURL("https://www.example.org/");
5572 request_info2.traffic_annotation =
5573 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5574 EXPECT_EQ(OK,
5575 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
5576 net_log_, CompletionOnceCallback()));
5577
5578 // Ensure that session is alive and active.
5579 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5580 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5581 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5582 EXPECT_EQ(2u, session->GetNumActiveStreams());
5583
5584 // Send GET request on stream 2 which is non-migratable. This should cause a
5585 // write error, which triggers a connection migration attempt.
5586 HttpResponseInfo response2;
5587 HttpRequestHeaders request_headers2;
5588 EXPECT_EQ(OK, stream2->SendRequest(request_headers2, &response2,
5589 callback2.callback()));
5590
5591 // Run the message loop so that the migration attempt is executed and
Zhongyi Shia7dd46b2018-07-12 22:59:295592 // data queued in the new socket is read by the packet reader. Session is
5593 // still alive and not marked as going away, non-migratable stream will be
5594 // closed.
Zhongyi Shi0439ecc72018-07-11 04:41:265595 base::RunLoop().RunUntilIdle();
5596 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:295597 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:265598 EXPECT_EQ(1u, session->GetNumActiveStreams());
5599
5600 // Send GET request on stream 1.
5601 HttpResponseInfo response;
5602 HttpRequestHeaders request_headers;
5603 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
5604 callback_.callback()));
5605
5606 base::RunLoop().RunUntilIdle();
5607
5608 // Verify that response headers on the migrated socket were delivered to the
5609 // stream.
5610 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
5611 EXPECT_EQ(200, response.headers->response_code());
5612
5613 stream1.reset();
5614
5615 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5616 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5617 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
5618 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
5619}
5620
jri9f303712016-09-13 01:10:225621void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorNonMigratableStream(
5622 IoMode write_error_mode) {
5623 DVLOG(1) << "Mode: "
5624 << ((write_error_mode == SYNCHRONOUS) ? "SYNCHRONOUS" : "ASYNC");
Zhongyi Shi1a054612018-06-14 04:59:085625 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:225626 {kDefaultNetworkForTests, kNewNetworkForTests});
5627 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5628 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5629
5630 MockQuicData socket_data;
5631 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:435632 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jri9f303712016-09-13 01:10:225633 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:175634 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:225635
5636 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:455637 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:335638 EXPECT_EQ(ERR_IO_PENDING,
5639 request.Request(host_port_pair_, version_, privacy_mode_,
5640 DEFAULT_PRIORITY, SocketTag(),
5641 /*cert_verify_flags=*/0, url_, net_log_,
5642 &net_error_details_, callback_.callback()));
jri9f303712016-09-13 01:10:225643 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:245644 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:225645 EXPECT_TRUE(stream.get());
5646
5647 // Cause QUIC stream to be created, but marked as non-migratable.
5648 HttpRequestInfo request_info;
Zhongyi Shibb28b1f2018-07-18 02:41:265649 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
jri9f303712016-09-13 01:10:225650 request_info.method = "GET";
5651 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:395652 request_info.traffic_annotation =
5653 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:275654 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:395655 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:225656
5657 // Ensure that session is alive and active.
5658 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5659 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5660 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5661
5662 // Send GET request on stream. This should cause a write error, which triggers
5663 // a connection migration attempt.
5664 HttpResponseInfo response;
5665 HttpRequestHeaders request_headers;
5666 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5667 callback_.callback()));
5668
5669 // Run message loop to execute migration attempt.
5670 base::RunLoop().RunUntilIdle();
5671
5672 // Migration fails, and session is closed and deleted.
5673 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5674 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5675
5676 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5677 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5678}
5679
5680TEST_P(QuicStreamFactoryTest,
5681 MigrateSessionOnWriteErrorNonMigratableStreamSynchronous) {
5682 TestMigrationOnWriteErrorNonMigratableStream(SYNCHRONOUS);
5683}
5684
5685TEST_P(QuicStreamFactoryTest,
5686 MigrateSessionOnWriteErrorNonMigratableStreamAsync) {
5687 TestMigrationOnWriteErrorNonMigratableStream(ASYNC);
5688}
5689
5690void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorMigrationDisabled(
5691 IoMode write_error_mode) {
Zhongyi Shi1a054612018-06-14 04:59:085692 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:225693 {kDefaultNetworkForTests, kNewNetworkForTests});
5694 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5695 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5696
5697 MockQuicData socket_data;
5698 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:435699 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jri9f303712016-09-13 01:10:225700 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:175701 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:225702
5703 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:455704 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:335705 EXPECT_EQ(ERR_IO_PENDING,
5706 request.Request(host_port_pair_, version_, privacy_mode_,
5707 DEFAULT_PRIORITY, SocketTag(),
5708 /*cert_verify_flags=*/0, url_, net_log_,
5709 &net_error_details_, callback_.callback()));
jri9f303712016-09-13 01:10:225710 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:245711 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:225712 EXPECT_TRUE(stream.get());
5713
5714 // Cause QUIC stream to be created.
5715 HttpRequestInfo request_info;
5716 request_info.method = "GET";
5717 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:395718 request_info.traffic_annotation =
5719 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:275720 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:395721 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:225722
5723 // Ensure that session is alive and active.
5724 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5725 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5726 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5727
5728 // Set session config to have connection migration disabled.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525729 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
5730 session->config());
jri9f303712016-09-13 01:10:225731 EXPECT_TRUE(session->config()->DisableConnectionMigration());
5732
5733 // Send GET request on stream. This should cause a write error, which triggers
5734 // a connection migration attempt.
5735 HttpResponseInfo response;
5736 HttpRequestHeaders request_headers;
5737 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5738 callback_.callback()));
5739 // Run message loop to execute migration attempt.
5740 base::RunLoop().RunUntilIdle();
5741 // Migration fails, and session is closed and deleted.
5742 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5743 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5744 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5745 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5746}
5747
5748TEST_P(QuicStreamFactoryTest,
5749 MigrateSessionOnWriteErrorMigrationDisabledSynchronous) {
5750 TestMigrationOnWriteErrorMigrationDisabled(SYNCHRONOUS);
5751}
5752
5753TEST_P(QuicStreamFactoryTest,
5754 MigrateSessionOnWriteErrorMigrationDisabledAsync) {
5755 TestMigrationOnWriteErrorMigrationDisabled(ASYNC);
5756}
5757
Zhongyi Shi7f1d9212018-06-22 23:24:365758// Sets up a test which verifies that connection migration on write error can
5759// eventually succeed and rewrite the packet on the new network with singals
5760// delivered in the following order (alternate network is always availabe):
5761// - original network encounters a SYNC/ASYNC write error based on
5762// |write_error_mode_on_old_network|, the packet failed to be written is
5763// cached, session migrates immediately to the alternate network.
5764// - an immediate SYNC/ASYNC write error based on
5765// |write_error_mode_on_new_network| is encountered after migration to the
5766// alternate network, session migrates immediately to the original network.
5767// - an immediate SYNC/ASYNC write error based on
5768// |write_error_mode_on_old_network| is encountered after migration to the
5769// original network, session migrates immediately to the alternate network.
5770// - finally, session successfully sends the packet and reads the response on
5771// the alternate network.
5772// TODO(zhongyi): once https://crbug.com/855666 is fixed, this test should be
5773// modified to test that session is closed early if hopping between networks
5774// with consecutive write errors is detected.
jri9f303712016-09-13 01:10:225775void QuicStreamFactoryTestBase::TestMigrationOnMultipleWriteErrors(
Zhongyi Shi7f1d9212018-06-22 23:24:365776 IoMode write_error_mode_on_old_network,
5777 IoMode write_error_mode_on_new_network) {
5778 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:225779 {kDefaultNetworkForTests, kNewNetworkForTests});
5780 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5781 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5782 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5783
Zhongyi Shi7f1d9212018-06-22 23:24:365784 // Set up the socket data used by the original network, which encounters a
5785 // write erorr.
5786 MockQuicData socket_data1;
5787 quic::QuicStreamOffset header_stream_offset = 0;
5788 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5789 socket_data1.AddWrite(
5790 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5791 socket_data1.AddWrite(write_error_mode_on_old_network,
5792 ERR_ADDRESS_UNREACHABLE); // Write Error
5793 socket_data1.AddSocketDataToFactory(socket_factory_.get());
5794
5795 // Set up the socket data used by the alternate network, which also
5796 // encounters a write error.
5797 MockQuicData failed_quic_data2;
5798 failed_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5799 failed_quic_data2.AddWrite(write_error_mode_on_new_network, ERR_FAILED);
5800 failed_quic_data2.AddSocketDataToFactory(socket_factory_.get());
5801
5802 // Set up the third socket data used by original network, which encounters a
5803 // write error again.
5804 MockQuicData failed_quic_data1;
5805 failed_quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5806 failed_quic_data1.AddWrite(write_error_mode_on_old_network, ERR_FAILED);
5807 failed_quic_data1.AddSocketDataToFactory(socket_factory_.get());
5808
5809 // Set up the last socket data used by the alternate network, which will
5810 // finish migration successfully. The request is rewritten to this new socket,
5811 // and the response to the request is read on this socket.
5812 MockQuicData socket_data2;
5813 socket_data2.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
5814 2, GetNthClientInitiatedStreamId(0),
5815 true, true, &header_stream_offset));
5816 socket_data2.AddRead(
5817 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
5818 false, false));
5819 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5820 socket_data2.AddWrite(SYNCHRONOUS,
5821 client_maker_.MakeAckAndRstPacket(
5822 3, false, GetNthClientInitiatedStreamId(0),
5823 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
5824 socket_data2.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:225825
5826 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:455827 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:335828 EXPECT_EQ(ERR_IO_PENDING,
5829 request.Request(host_port_pair_, version_, privacy_mode_,
5830 DEFAULT_PRIORITY, SocketTag(),
5831 /*cert_verify_flags=*/0, url_, net_log_,
5832 &net_error_details_, callback_.callback()));
jri9f303712016-09-13 01:10:225833 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:245834 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:225835 EXPECT_TRUE(stream.get());
5836
5837 // Cause QUIC stream to be created.
5838 HttpRequestInfo request_info;
5839 request_info.method = "GET";
5840 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:395841 request_info.traffic_annotation =
5842 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:275843 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:395844 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:225845
5846 // Ensure that session is alive and active.
5847 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5848 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5849 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5850
Zhongyi Shi7f1d9212018-06-22 23:24:365851 // Send GET request on stream.
5852 // This should encounter a write error on network 1,
5853 // then migrate to network 2, which encounters another write error,
5854 // and migrate again to network 1, which encoutners one more write error.
5855 // Finally the session migrates to network 2 successfully.
jri9f303712016-09-13 01:10:225856 HttpResponseInfo response;
5857 HttpRequestHeaders request_headers;
5858 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5859 callback_.callback()));
jri9f303712016-09-13 01:10:225860
jri9f303712016-09-13 01:10:225861 base::RunLoop().RunUntilIdle();
Zhongyi Shi7f1d9212018-06-22 23:24:365862 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5863 EXPECT_EQ(1u, session->GetNumActiveStreams());
jri9f303712016-09-13 01:10:225864
Zhongyi Shi7f1d9212018-06-22 23:24:365865 // Verify that response headers on the migrated socket were delivered to the
5866 // stream.
5867 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
5868 EXPECT_EQ(200, response.headers->response_code());
jri9f303712016-09-13 01:10:225869
5870 stream.reset();
Zhongyi Shi7f1d9212018-06-22 23:24:365871 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
5872 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
5873 EXPECT_TRUE(failed_quic_data2.AllReadDataConsumed());
5874 EXPECT_TRUE(failed_quic_data2.AllWriteDataConsumed());
5875 EXPECT_TRUE(failed_quic_data1.AllReadDataConsumed());
5876 EXPECT_TRUE(failed_quic_data1.AllWriteDataConsumed());
5877 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
5878 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
jri9f303712016-09-13 01:10:225879}
5880
5881TEST_P(QuicStreamFactoryTest, MigrateSessionOnMultipleWriteErrorsSyncSync) {
Zhongyi Shi7f1d9212018-06-22 23:24:365882 TestMigrationOnMultipleWriteErrors(
5883 /*write_error_mode_on_old_network*/ SYNCHRONOUS,
5884 /*write_error_mode_on_new_network*/ SYNCHRONOUS);
jri9f303712016-09-13 01:10:225885}
5886
5887TEST_P(QuicStreamFactoryTest, MigrateSessionOnMultipleWriteErrorsSyncAsync) {
Zhongyi Shi7f1d9212018-06-22 23:24:365888 TestMigrationOnMultipleWriteErrors(
5889 /*write_error_mode_on_old_network*/ SYNCHRONOUS,
5890 /*write_error_mode_on_new_network*/ ASYNC);
jri9f303712016-09-13 01:10:225891}
5892
5893TEST_P(QuicStreamFactoryTest, MigrateSessionOnMultipleWriteErrorsAsyncSync) {
Zhongyi Shi7f1d9212018-06-22 23:24:365894 TestMigrationOnMultipleWriteErrors(
5895 /*write_error_mode_on_old_network*/ ASYNC,
5896 /*write_error_mode_on_new_network*/ SYNCHRONOUS);
jri9f303712016-09-13 01:10:225897}
5898
5899TEST_P(QuicStreamFactoryTest, MigrateSessionOnMultipleWriteErrorsAsyncAsync) {
Zhongyi Shi7f1d9212018-06-22 23:24:365900 TestMigrationOnMultipleWriteErrors(
5901 /*write_error_mode_on_old_network*/ ASYNC,
5902 /*write_error_mode_on_new_network*/ ASYNC);
jri9f303712016-09-13 01:10:225903}
5904
Zhongyi Shi6abe33812018-07-24 19:43:115905// Verifies that a connection is closed when connection migration is triggered
5906// on network being disconnected and the handshake is not confirmed.
5907TEST_P(QuicStreamFactoryTest, NoMigrationBeforeHandshakeOnNetworkDisconnected) {
5908 InitializeConnectionMigrationV2Test(
5909 {kDefaultNetworkForTests, kNewNetworkForTests});
5910
Zhongyi Shi879659422018-08-02 17:58:255911 // Use cold start mode to do crypto connect, and send CHLO packet on wire.
Zhongyi Shi6abe33812018-07-24 19:43:115912 crypto_client_stream_factory_.set_handshake_mode(
Zhongyi Shi879659422018-08-02 17:58:255913 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
Zhongyi Shi6abe33812018-07-24 19:43:115914
Zhongyi Shi6abe33812018-07-24 19:43:115915 MockQuicData socket_data;
Zhongyi Shi879659422018-08-02 17:58:255916 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5068bb02018-08-03 02:44:095917 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
Zhongyi Shi6abe33812018-07-24 19:43:115918 socket_data.AddSocketDataToFactory(socket_factory_.get());
5919
5920 // Create request and QuicHttpStream.
5921 QuicStreamRequest request(factory_.get());
5922 EXPECT_EQ(ERR_IO_PENDING,
5923 request.Request(host_port_pair_, version_, privacy_mode_,
5924 DEFAULT_PRIORITY, SocketTag(),
5925 /*cert_verify_flags=*/0, url_, net_log_,
5926 &net_error_details_, callback_.callback()));
5927 // Deliver the network notification, which should cause the connection to be
5928 // closed.
5929 scoped_mock_network_change_notifier_->mock_network_change_notifier()
5930 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
5931 EXPECT_EQ(ERR_NETWORK_CHANGED, callback_.WaitForResult());
Zhongyi Shi4293b142018-07-25 00:33:575932
Zhongyi Shi6abe33812018-07-24 19:43:115933 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5934 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
Zhongyi Shi4293b142018-07-25 00:33:575935 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5936 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
Zhongyi Shi6abe33812018-07-24 19:43:115937}
5938
Zhongyi Shib24001c02018-06-18 20:01:525939// Sets up the connection migration test where network change notification is
5940// queued BEFORE connection migration attempt on write error is posted.
5941void QuicStreamFactoryTestBase::
5942 TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
5943 bool disconnected) {
5944 InitializeConnectionMigrationV2Test(
jried79618b2016-07-02 03:18:525945 {kDefaultNetworkForTests, kNewNetworkForTests});
5946 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5947 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5948 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5949
rcha00569732016-08-27 11:09:365950 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525951 quic::QuicStreamOffset header_stream_offset = 0;
rcha00569732016-08-27 11:09:365952 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
rch5cb522462017-04-25 20:18:365953 socket_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435954 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
rcha00569732016-08-27 11:09:365955 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:175956 socket_data.AddSocketDataToFactory(socket_factory_.get());
jried79618b2016-07-02 03:18:525957
5958 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:455959 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:335960 EXPECT_EQ(ERR_IO_PENDING,
5961 request.Request(host_port_pair_, version_, privacy_mode_,
5962 DEFAULT_PRIORITY, SocketTag(),
5963 /*cert_verify_flags=*/0, url_, net_log_,
5964 &net_error_details_, callback_.callback()));
jried79618b2016-07-02 03:18:525965 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:245966 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jried79618b2016-07-02 03:18:525967 EXPECT_TRUE(stream.get());
5968
5969 // Cause QUIC stream to be created.
5970 HttpRequestInfo request_info;
5971 request_info.method = "GET";
5972 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:395973 request_info.traffic_annotation =
5974 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:275975 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:395976 net_log_, CompletionOnceCallback()));
jried79618b2016-07-02 03:18:525977
5978 // Ensure that session is alive and active.
5979 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5980 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5981 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5982
5983 // Set up second socket data provider that is used after
5984 // migration. The request is rewritten to this new socket, and the
5985 // response to the request is read on this new socket.
rcha00569732016-08-27 11:09:365986 MockQuicData socket_data1;
Zhongyi Shi32f2fd02018-04-16 18:23:435987 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
5988 2, GetNthClientInitiatedStreamId(0),
5989 true, true, &header_stream_offset));
5990 socket_data1.AddRead(
5991 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
5992 false, false));
rcha00569732016-08-27 11:09:365993 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:435994 socket_data1.AddWrite(SYNCHRONOUS,
5995 client_maker_.MakeAckAndRstPacket(
5996 3, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:525997 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:175998 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jried79618b2016-07-02 03:18:525999
jri9f303712016-09-13 01:10:226000 // First queue a network change notification in the message loop.
6001 if (disconnected) {
6002 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6003 ->QueueNetworkDisconnected(kDefaultNetworkForTests);
6004 } else {
6005 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6006 ->QueueNetworkMadeDefault(kNewNetworkForTests);
6007 }
6008 // Send GET request on stream. This should cause a write error,
6009 // which triggers a connection migration attempt. This will queue a
6010 // migration attempt behind the notification in the message loop.
jried79618b2016-07-02 03:18:526011 HttpResponseInfo response;
6012 HttpRequestHeaders request_headers;
6013 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6014 callback_.callback()));
6015
jried79618b2016-07-02 03:18:526016 base::RunLoop().RunUntilIdle();
Zhongyi Shia7dd46b2018-07-12 22:59:296017 // Verify the session is still alive and not marked as going away post
6018 // migration.
jried79618b2016-07-02 03:18:526019 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:296020 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jried79618b2016-07-02 03:18:526021 EXPECT_EQ(1u, session->GetNumActiveStreams());
6022
6023 // Verify that response headers on the migrated socket were delivered to the
6024 // stream.
6025 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6026 EXPECT_EQ(200, response.headers->response_code());
6027
6028 stream.reset();
6029
6030 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6031 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6032 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6033 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6034}
6035
Zhongyi Shib24001c02018-06-18 20:01:526036// This test verifies that session attempts connection migration successfully
6037// with signals delivered in the following order (alternate network is always
6038// available):
6039// - a notification that default network is disconnected is queued.
6040// - write error is triggered: session posts a task to attempt connection
6041// migration, |migration_pending_| set to true.
6042// - default network disconnected is delivered: session immediately migrates to
6043// the alternate network, |migration_pending_| set to false.
Zhongyi Shif3d6cddb2018-07-11 03:30:026044// - connection migration on write error attempt aborts: writer encountered
6045// error is no longer in active use.
jri9f303712016-09-13 01:10:226046TEST_P(QuicStreamFactoryTest,
Zhongyi Shib24001c02018-06-18 20:01:526047 MigrateOnNetworkDisconnectedWithWriteErrorQueuedLater) {
6048 TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
6049 /*disconnected=*/true);
jri9f303712016-09-13 01:10:226050}
6051
Zhongyi Shib24001c02018-06-18 20:01:526052// This test verifies that session attempts connection migration successfully
6053// with signals delivered in the following order (alternate network is always
6054// available):
6055// - a notification that alternate network is made default is queued.
6056// - write error is triggered: session posts a task to attempt connection
6057// migration, block future migrations.
6058// - new default notification is delivered: migrate back timer spins and task is
6059// posted to migrate to the new default network.
6060// - connection migration on write error attempt proceeds successfully: session
6061// is
6062// marked as going away, future migrations unblocked.
6063// - migrate back to default network task executed: session is already on the
6064// default network, no-op.
jri9f303712016-09-13 01:10:226065TEST_P(QuicStreamFactoryTest,
Zhongyi Shib24001c02018-06-18 20:01:526066 MigrateOnWriteErrorWithNetworkMadeDefaultQueuedEarlier) {
6067 TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
6068 /*disconnected=*/false);
jri9f303712016-09-13 01:10:226069}
6070
Zhongyi Shi1e2bc742018-06-16 02:06:076071// Sets up the connection migration test where network change notification is
6072// queued AFTER connection migration attempt on write error is posted.
6073void QuicStreamFactoryTestBase::
6074 TestMigrationOnWriteErrorWithNotificationQueuedLater(bool disconnected) {
Zhongyi Shi1a054612018-06-14 04:59:086075 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:226076 {kDefaultNetworkForTests, kNewNetworkForTests});
jried79618b2016-07-02 03:18:526077 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6078 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri9f303712016-09-13 01:10:226079 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jried79618b2016-07-02 03:18:526080
rcha00569732016-08-27 11:09:366081 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526082 quic::QuicStreamOffset header_stream_offset = 0;
rcha00569732016-08-27 11:09:366083 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
rch5cb522462017-04-25 20:18:366084 socket_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436085 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
rcha00569732016-08-27 11:09:366086 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:176087 socket_data.AddSocketDataToFactory(socket_factory_.get());
jried79618b2016-07-02 03:18:526088
6089 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456090 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336091 EXPECT_EQ(ERR_IO_PENDING,
6092 request.Request(host_port_pair_, version_, privacy_mode_,
6093 DEFAULT_PRIORITY, SocketTag(),
6094 /*cert_verify_flags=*/0, url_, net_log_,
6095 &net_error_details_, callback_.callback()));
jried79618b2016-07-02 03:18:526096 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246097 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jried79618b2016-07-02 03:18:526098 EXPECT_TRUE(stream.get());
6099
6100 // Cause QUIC stream to be created.
6101 HttpRequestInfo request_info;
6102 request_info.method = "GET";
6103 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396104 request_info.traffic_annotation =
6105 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276106 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396107 net_log_, CompletionOnceCallback()));
jried79618b2016-07-02 03:18:526108
6109 // Ensure that session is alive and active.
6110 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6111 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6112 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6113
jri9f303712016-09-13 01:10:226114 // Set up second socket data provider that is used after
6115 // migration. The request is rewritten to this new socket, and the
6116 // response to the request is read on this new socket.
6117 MockQuicData socket_data1;
Zhongyi Shi32f2fd02018-04-16 18:23:436118 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
6119 2, GetNthClientInitiatedStreamId(0),
6120 true, true, &header_stream_offset));
6121 socket_data1.AddRead(
6122 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
6123 false, false));
jri9f303712016-09-13 01:10:226124 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436125 socket_data1.AddWrite(SYNCHRONOUS,
6126 client_maker_.MakeAckAndRstPacket(
6127 3, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:526128 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:176129 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:226130
6131 // Send GET request on stream. This should cause a write error,
6132 // which triggers a connection migration attempt. This will queue a
6133 // migration attempt in the message loop.
jried79618b2016-07-02 03:18:526134 HttpResponseInfo response;
6135 HttpRequestHeaders request_headers;
jri9f303712016-09-13 01:10:226136 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6137 callback_.callback()));
jried79618b2016-07-02 03:18:526138
jri9f303712016-09-13 01:10:226139 // Now queue a network change notification in the message loop behind
6140 // the migration attempt.
6141 if (disconnected) {
6142 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6143 ->QueueNetworkDisconnected(kDefaultNetworkForTests);
6144 } else {
6145 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6146 ->QueueNetworkMadeDefault(kNewNetworkForTests);
6147 }
6148
6149 base::RunLoop().RunUntilIdle();
Zhongyi Shia7dd46b2018-07-12 22:59:296150 // Verify session is still alive and not marked as going away.
jri9f303712016-09-13 01:10:226151 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:296152 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri9f303712016-09-13 01:10:226153 EXPECT_EQ(1u, session->GetNumActiveStreams());
6154
6155 // Verify that response headers on the migrated socket were delivered to the
6156 // stream.
6157 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6158 EXPECT_EQ(200, response.headers->response_code());
6159
6160 stream.reset();
jried79618b2016-07-02 03:18:526161
6162 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6163 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
jri9f303712016-09-13 01:10:226164 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6165 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
jried79618b2016-07-02 03:18:526166}
6167
Zhongyi Shi1e2bc742018-06-16 02:06:076168// This test verifies that session attempts connection migration successfully
6169// with signals delivered in the following order (alternate network is always
6170// available):
6171// - write error is triggered: session posts a task to complete connection
6172// migration.
6173// - a notification that alternate network is made default is queued.
6174// - connection migration attempt proceeds successfully, session is marked as
6175// going away.
6176// - new default notification is delivered after connection migration has been
6177// completed.
jri9f303712016-09-13 01:10:226178TEST_P(QuicStreamFactoryTest,
Zhongyi Shi1e2bc742018-06-16 02:06:076179 MigrateOnWriteErrorWithNetworkMadeDefaultQueuedLater) {
6180 TestMigrationOnWriteErrorWithNotificationQueuedLater(/*disconnected=*/false);
jried79618b2016-07-02 03:18:526181}
6182
Zhongyi Shi1e2bc742018-06-16 02:06:076183// This test verifies that session attempts connection migration successfully
6184// with signals delivered in the following order (alternate network is always
6185// available):
6186// - write error is triggered: session posts a task to complete connection
6187// migration.
6188// - a notification that default network is diconnected is queued.
6189// - connection migration attempt proceeds successfully, session is marked as
6190// going away.
6191// - disconnect notification is delivered after connection migration has been
6192// completed.
jri9f303712016-09-13 01:10:226193TEST_P(QuicStreamFactoryTest,
Zhongyi Shi1e2bc742018-06-16 02:06:076194 MigrateOnWriteErrorWithNetworkDisconnectedQueuedLater) {
6195 TestMigrationOnWriteErrorWithNotificationQueuedLater(/*disconnected=*/true);
jried79618b2016-07-02 03:18:526196}
6197
Zhongyi Shia3810c52018-06-15 23:07:196198// This tests connection migration on write error with signals delivered in the
6199// following order:
6200// - a synchronous/asynchronous write error is triggered base on
Zhongyi Shif3d6cddb2018-07-11 03:30:026201// |write_error_mode|: connection migration attempt is posted.
6202// - old default network disconnects, migration waits for a new network.
Zhongyi Shia3810c52018-06-15 23:07:196203// - after a pause, new network is connected: session will migrate to new
6204// network immediately.
Zhongyi Shif3d6cddb2018-07-11 03:30:026205// - migration on writer error is exectued and aborts as writer passed in is no
6206// longer active in use.
Zhongyi Shia3810c52018-06-15 23:07:196207// - new network is made default.
jri5b785512016-09-13 04:29:116208void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorPauseBeforeConnected(
6209 IoMode write_error_mode) {
Zhongyi Shia3810c52018-06-15 23:07:196210 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri5b785512016-09-13 04:29:116211 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6212 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6213 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6214
Zhongyi Shia3810c52018-06-15 23:07:196215 // Use the test task runner.
6216 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
6217
jri5b785512016-09-13 04:29:116218 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526219 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shia3810c52018-06-15 23:07:196220 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
rch5cb522462017-04-25 20:18:366221 socket_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436222 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Zhongyi Shia3810c52018-06-15 23:07:196223 socket_data.AddWrite(write_error_mode, ERR_FAILED);
Zhongyi Shi5f587cc2017-11-21 23:24:176224 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri5b785512016-09-13 04:29:116225
6226 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456227 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336228 EXPECT_EQ(ERR_IO_PENDING,
6229 request.Request(host_port_pair_, version_, privacy_mode_,
6230 DEFAULT_PRIORITY, SocketTag(),
6231 /*cert_verify_flags=*/0, url_, net_log_,
6232 &net_error_details_, callback_.callback()));
Zhongyi Shia3810c52018-06-15 23:07:196233 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:246234 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri5b785512016-09-13 04:29:116235 EXPECT_TRUE(stream.get());
6236
6237 // Cause QUIC stream to be created.
6238 HttpRequestInfo request_info;
6239 request_info.method = "GET";
Zhongyi Shia3810c52018-06-15 23:07:196240 request_info.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:396241 request_info.traffic_annotation =
6242 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276243 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396244 net_log_, CompletionOnceCallback()));
jri5b785512016-09-13 04:29:116245
6246 // Ensure that session is alive and active.
6247 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6248 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6249 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6250
Zhongyi Shia3810c52018-06-15 23:07:196251 // Send GET request on stream.
jri5b785512016-09-13 04:29:116252 HttpResponseInfo response;
6253 HttpRequestHeaders request_headers;
6254 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6255 callback_.callback()));
6256
Zhongyi Shia3810c52018-06-15 23:07:196257 // The connection should still be alive, not marked as going away.
jri5b785512016-09-13 04:29:116258 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6259 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6260 EXPECT_EQ(1u, session->GetNumActiveStreams());
6261 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
6262
Zhongyi Shia3810c52018-06-15 23:07:196263 // Set up second socket data provider that is used after migration.
6264 // The response to the earlier request is read on this new socket.
jri5b785512016-09-13 04:29:116265 MockQuicData socket_data1;
Zhongyi Shi32f2fd02018-04-16 18:23:436266 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
6267 2, GetNthClientInitiatedStreamId(0),
6268 true, true, &header_stream_offset));
6269 socket_data1.AddRead(
6270 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
6271 false, false));
jri5b785512016-09-13 04:29:116272 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436273 socket_data1.AddWrite(SYNCHRONOUS,
6274 client_maker_.MakeAckAndRstPacket(
6275 3, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:526276 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:176277 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri5b785512016-09-13 04:29:116278
Zhongyi Shia3810c52018-06-15 23:07:196279 // On a DISCONNECTED notification, nothing happens.
6280 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6281 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
6282 // Add a new network and notify the stream factory of a new connected network.
6283 // This causes a PING packet to be sent over the new network.
jri5b785512016-09-13 04:29:116284 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6285 ->SetConnectedNetworksList({kNewNetworkForTests});
6286 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6287 ->NotifyNetworkConnected(kNewNetworkForTests);
6288
Zhongyi Shia3810c52018-06-15 23:07:196289 // Ensure that the session is still alive.
jri5b785512016-09-13 04:29:116290 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia3810c52018-06-15 23:07:196291 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:116292 EXPECT_EQ(1u, session->GetNumActiveStreams());
6293
Zhongyi Shia3810c52018-06-15 23:07:196294 // Run the message loop migration for write error can finish.
6295 runner_->RunUntilIdle();
6296
6297 // Response headers are received over the new network.
jri5b785512016-09-13 04:29:116298 EXPECT_THAT(callback_.WaitForResult(), IsOk());
6299 EXPECT_EQ(200, response.headers->response_code());
6300
Zhongyi Shia3810c52018-06-15 23:07:196301 // Check that the session is still alive.
6302 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
jri5b785512016-09-13 04:29:116303 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shia3810c52018-06-15 23:07:196304
6305 // There should be no posted tasks not executed, no way to migrate back to
6306 // default network.
6307 EXPECT_TRUE(runner_->GetPostedTasks().empty());
6308
6309 // Receive signal to mark new network as default.
6310 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6311 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri5b785512016-09-13 04:29:116312
6313 stream.reset();
jri5b785512016-09-13 04:29:116314 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6315 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6316 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6317 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
jri5b785512016-09-13 04:29:116318}
6319
6320TEST_P(QuicStreamFactoryTest,
Zhongyi Shia3810c52018-06-15 23:07:196321 MigrateSessionOnSyncWriteErrorPauseBeforeConnected) {
jri5b785512016-09-13 04:29:116322 TestMigrationOnWriteErrorPauseBeforeConnected(SYNCHRONOUS);
6323}
6324
6325TEST_P(QuicStreamFactoryTest,
Zhongyi Shia3810c52018-06-15 23:07:196326 MigrateSessionOnAsyncWriteErrorPauseBeforeConnected) {
jri5b785512016-09-13 04:29:116327 TestMigrationOnWriteErrorPauseBeforeConnected(ASYNC);
6328}
6329
Zhongyi Shif3d6cddb2018-07-11 03:30:026330// This test verifies that when session successfully migrate to the alternate
6331// network, packet write error on the old writer will be ignored and will not
6332// trigger connection migration on write error.
6333TEST_P(QuicStreamFactoryTest, IgnoreWriteErrorFromOldWriterAfterMigration) {
6334 InitializeConnectionMigrationV2Test(
6335 {kDefaultNetworkForTests, kNewNetworkForTests});
6336 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6337 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6338 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6339
6340 // Using a testing task runner so that we can verify whether the migrate on
6341 // write error task is posted.
6342 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
6343 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
6344
6345 MockQuicData socket_data;
6346 quic::QuicStreamOffset header_stream_offset = 0;
6347 socket_data.AddWrite(
6348 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6349 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
6350 socket_data.AddWrite(ASYNC, ERR_ADDRESS_UNREACHABLE);
6351 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6352 socket_data.AddSocketDataToFactory(socket_factory_.get());
6353
6354 // Create request and QuicHttpStream.
6355 QuicStreamRequest request(factory_.get());
6356 EXPECT_EQ(ERR_IO_PENDING,
6357 request.Request(host_port_pair_, version_, privacy_mode_,
6358 DEFAULT_PRIORITY, SocketTag(),
6359 /*cert_verify_flags=*/0, url_, net_log_,
6360 &net_error_details_, callback_.callback()));
6361 EXPECT_EQ(OK, callback_.WaitForResult());
6362 std::unique_ptr<HttpStream> stream = CreateStream(&request);
6363 EXPECT_TRUE(stream.get());
6364
6365 // Cause QUIC stream to be created.
6366 HttpRequestInfo request_info;
6367 request_info.method = "GET";
6368 request_info.url = GURL("https://www.example.org/");
6369 request_info.traffic_annotation =
6370 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6371 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
6372 net_log_, CompletionOnceCallback()));
6373
6374 // Ensure that session is alive and active.
6375 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6376 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6377 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6378
6379 // Set up second socket data provider that is used after
6380 // migration. The response to the request is read on this new socket.
6381 MockQuicData socket_data1;
6382 socket_data1.AddWrite(
6383 SYNCHRONOUS, client_maker_.MakePingPacket(3, /*include_version=*/true));
6384 socket_data1.AddRead(
6385 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
6386 false, false));
6387 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6388 socket_data1.AddWrite(SYNCHRONOUS,
6389 client_maker_.MakeAckAndRstPacket(
6390 4, false, GetNthClientInitiatedStreamId(0),
6391 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
6392 socket_data1.AddSocketDataToFactory(socket_factory_.get());
6393
6394 // Send GET request on stream.
6395 HttpResponseInfo response;
6396 HttpRequestHeaders request_headers;
6397 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6398 callback_.callback()));
6399
6400 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
6401 // Now notify network is disconnected, cause the migration to complete
6402 // immediately.
6403 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6404 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
6405 // There will be two pending task, one will complete migration with no delay
6406 // and the other will attempt to migrate back to the default network with
6407 // delay.
6408 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
6409
6410 // Complete migration.
6411 task_runner->RunUntilIdle();
6412 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
6413
6414 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6415 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6416 EXPECT_EQ(1u, session->GetNumActiveStreams());
6417
6418 // Verify that response headers on the migrated socket were delivered to the
6419 // stream.
6420 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6421 EXPECT_EQ(200, response.headers->response_code());
6422
6423 // Resume the old socket data, a write error will be delivered to the old
6424 // packet writer. Verify no additional task is posted.
6425 socket_data.Resume();
6426 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
6427
6428 stream.reset();
6429 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6430 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6431 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6432}
6433
6434// This test verifies that when session successfully migrate to the alternate
6435// network, packet read error on the old reader will be ignored and will not
6436// close the connection.
6437TEST_P(QuicStreamFactoryTest, IgnoreReadErrorFromOldReaderAfterMigration) {
6438 InitializeConnectionMigrationV2Test(
6439 {kDefaultNetworkForTests, kNewNetworkForTests});
6440 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6441 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6442 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6443
6444 // Using a testing task runner.
6445 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
6446 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
6447
6448 MockQuicData socket_data;
6449 quic::QuicStreamOffset header_stream_offset = 0;
6450 socket_data.AddWrite(
6451 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6452 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
6453 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE);
6454 socket_data.AddSocketDataToFactory(socket_factory_.get());
6455
6456 // Create request and QuicHttpStream.
6457 QuicStreamRequest request(factory_.get());
6458 EXPECT_EQ(ERR_IO_PENDING,
6459 request.Request(host_port_pair_, version_, privacy_mode_,
6460 DEFAULT_PRIORITY, SocketTag(),
6461 /*cert_verify_flags=*/0, url_, net_log_,
6462 &net_error_details_, callback_.callback()));
6463 EXPECT_EQ(OK, callback_.WaitForResult());
6464 std::unique_ptr<HttpStream> stream = CreateStream(&request);
6465 EXPECT_TRUE(stream.get());
6466
6467 // Cause QUIC stream to be created.
6468 HttpRequestInfo request_info;
6469 request_info.method = "GET";
6470 request_info.url = GURL("https://www.example.org/");
6471 request_info.traffic_annotation =
6472 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6473 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
6474 net_log_, CompletionOnceCallback()));
6475
6476 // Ensure that session is alive and active.
6477 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6478 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6479 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6480
6481 // Set up second socket data provider that is used after
6482 // migration. The request is written to this new socket, and the
6483 // response to the request is read on this new socket.
6484 MockQuicData socket_data1;
6485 socket_data1.AddWrite(
6486 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
6487 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
6488 3, GetNthClientInitiatedStreamId(0),
6489 true, true, &header_stream_offset));
6490 socket_data1.AddRead(
6491 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
6492 false, false));
6493 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6494 socket_data1.AddWrite(SYNCHRONOUS,
6495 client_maker_.MakeAckAndRstPacket(
6496 4, false, GetNthClientInitiatedStreamId(0),
6497 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
6498 socket_data1.AddSocketDataToFactory(socket_factory_.get());
6499
6500 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
6501 // Now notify network is disconnected, cause the migration to complete
6502 // immediately.
6503 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6504 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
6505 // There will be two pending task, one will complete migration with no delay
6506 // and the other will attempt to migrate back to the default network with
6507 // delay.
6508 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
6509
6510 // Complete migration.
6511 task_runner->RunUntilIdle();
6512 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
6513
6514 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6515 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6516 EXPECT_EQ(1u, session->GetNumActiveStreams());
6517
6518 // Send GET request on stream.
6519 HttpResponseInfo response;
6520 HttpRequestHeaders request_headers;
6521 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6522 callback_.callback()));
6523
6524 // Verify that response headers on the migrated socket were delivered to the
6525 // stream.
6526 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
6527 EXPECT_EQ(OK, callback_.WaitForResult());
6528 EXPECT_EQ(200, response.headers->response_code());
6529
6530 // Resume the old socket data, a read error will be delivered to the old
6531 // packet reader. Verify that the session is not affected.
6532 socket_data.Resume();
6533 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
6534 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6535 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6536 EXPECT_EQ(1u, session->GetNumActiveStreams());
6537
6538 stream.reset();
6539 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6540 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6541 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6542 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6543}
6544
6545// This test verifies that after migration on network is executed, packet
6546// read error on the old reader will be ignored and will not close the
6547// connection.
6548TEST_P(QuicStreamFactoryTest, IgnoreReadErrorOnOldReaderDuringMigration) {
6549 InitializeConnectionMigrationV2Test(
6550 {kDefaultNetworkForTests, kNewNetworkForTests});
6551 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6552 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6553 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6554
6555 // Using a testing task runner.
6556 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
6557 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
6558
6559 MockQuicData socket_data;
6560 quic::QuicStreamOffset header_stream_offset = 0;
6561 socket_data.AddWrite(
6562 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6563 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
6564 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE);
6565 socket_data.AddSocketDataToFactory(socket_factory_.get());
6566
6567 // Create request and QuicHttpStream.
6568 QuicStreamRequest request(factory_.get());
6569 EXPECT_EQ(ERR_IO_PENDING,
6570 request.Request(host_port_pair_, version_, privacy_mode_,
6571 DEFAULT_PRIORITY, SocketTag(),
6572 /*cert_verify_flags=*/0, url_, net_log_,
6573 &net_error_details_, callback_.callback()));
6574 EXPECT_EQ(OK, callback_.WaitForResult());
6575 std::unique_ptr<HttpStream> stream = CreateStream(&request);
6576 EXPECT_TRUE(stream.get());
6577
6578 // Cause QUIC stream to be created.
6579 HttpRequestInfo request_info;
6580 request_info.method = "GET";
6581 request_info.url = GURL("https://www.example.org/");
6582 request_info.traffic_annotation =
6583 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6584 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
6585 net_log_, CompletionOnceCallback()));
6586
6587 // Ensure that session is alive and active.
6588 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6589 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6590 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6591
6592 // Set up second socket data provider that is used after
6593 // migration. The request is written to this new socket, and the
6594 // response to the request is read on this new socket.
6595 MockQuicData socket_data1;
6596 socket_data1.AddWrite(
6597 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
6598 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
6599 3, GetNthClientInitiatedStreamId(0),
6600 true, true, &header_stream_offset));
6601 socket_data1.AddRead(
6602 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
6603 false, false));
6604 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6605 socket_data1.AddWrite(SYNCHRONOUS,
6606 client_maker_.MakeAckAndRstPacket(
6607 4, false, GetNthClientInitiatedStreamId(0),
6608 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
6609 socket_data1.AddSocketDataToFactory(socket_factory_.get());
6610
6611 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
6612 // Now notify network is disconnected, cause the migration to complete
6613 // immediately.
6614 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6615 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
6616 // There will be two pending task, one will complete migration with no delay
6617 // and the other will attempt to migrate back to the default network with
6618 // delay.
6619 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
6620
6621 // Resume the old socket data, a read error will be delivered to the old
6622 // packet reader. Verify that the session is not affected.
6623 socket_data.Resume();
6624 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
6625 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6626 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6627 EXPECT_EQ(1u, session->GetNumActiveStreams());
6628
6629 // Complete migration.
6630 task_runner->RunUntilIdle();
6631 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
6632
6633 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6634 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6635 EXPECT_EQ(1u, session->GetNumActiveStreams());
6636
6637 // Send GET request on stream.
6638 HttpResponseInfo response;
6639 HttpRequestHeaders request_headers;
6640 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6641 callback_.callback()));
6642
6643 // Verify that response headers on the migrated socket were delivered to the
6644 // stream.
6645 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
6646 EXPECT_EQ(OK, callback_.WaitForResult());
6647 EXPECT_EQ(200, response.headers->response_code());
6648
6649 stream.reset();
6650 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6651 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6652 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6653 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6654}
6655
6656// This test verifies that after migration on write error is posted, packet
6657// read error on the old reader will be ignored and will not close the
6658// connection.
6659TEST_P(QuicStreamFactoryTest,
6660 IgnoreReadErrorOnOldReaderDuringPendingMigrationOnWriteError) {
6661 InitializeConnectionMigrationV2Test(
6662 {kDefaultNetworkForTests, kNewNetworkForTests});
6663 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6664 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6665 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6666
6667 // Using a testing task runner.
6668 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
6669 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
6670
6671 MockQuicData socket_data;
6672 quic::QuicStreamOffset header_stream_offset = 0;
6673 socket_data.AddWrite(
6674 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6675 socket_data.AddWrite(ASYNC, ERR_FAILED); // Write error.
6676 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE); // Read error.
6677 socket_data.AddSocketDataToFactory(socket_factory_.get());
6678
6679 // Create request and QuicHttpStream.
6680 QuicStreamRequest request(factory_.get());
6681 EXPECT_EQ(ERR_IO_PENDING,
6682 request.Request(host_port_pair_, version_, privacy_mode_,
6683 DEFAULT_PRIORITY, SocketTag(),
6684 /*cert_verify_flags=*/0, url_, net_log_,
6685 &net_error_details_, callback_.callback()));
6686 EXPECT_EQ(OK, callback_.WaitForResult());
6687 std::unique_ptr<HttpStream> stream = CreateStream(&request);
6688 EXPECT_TRUE(stream.get());
6689
6690 // Cause QUIC stream to be created.
6691 HttpRequestInfo request_info;
6692 request_info.method = "GET";
6693 request_info.url = GURL("https://www.example.org/");
6694 request_info.traffic_annotation =
6695 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6696 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
6697 net_log_, CompletionOnceCallback()));
6698
6699 // Ensure that session is alive and active.
6700 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6701 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6702 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6703
6704 // Set up second socket data provider that is used after
6705 // migration. The request is written to this new socket, and the
6706 // response to the request is read on this new socket.
6707 MockQuicData socket_data1;
6708 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
6709 2, GetNthClientInitiatedStreamId(0),
6710 true, true, &header_stream_offset));
6711 socket_data1.AddRead(
6712 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
6713 false, false));
6714
6715 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
6716 socket_data1.AddRead(ASYNC, ERR_FAILED); // Read error to close connection.
6717 socket_data1.AddSocketDataToFactory(socket_factory_.get());
6718
6719 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
6720 // Send GET request on stream.
6721 HttpResponseInfo response;
6722 HttpRequestHeaders request_headers;
6723 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6724 callback_.callback()));
6725 // Run the message loop to complete asynchronous write and read with errors.
6726 base::RunLoop().RunUntilIdle();
6727 // There will be one pending task to complete migration on write error.
6728 // Verify session is not closed with read error.
6729 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
6730 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6731 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6732 EXPECT_EQ(1u, session->GetNumActiveStreams());
6733
6734 // Complete migration.
6735 task_runner->RunUntilIdle();
Zhongyi Shia7dd46b2018-07-12 22:59:296736 // There will be one more task posted attempting to migrate back to the
6737 // default network.
6738 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
Zhongyi Shif3d6cddb2018-07-11 03:30:026739 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:296740 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shif3d6cddb2018-07-11 03:30:026741 EXPECT_EQ(1u, session->GetNumActiveStreams());
6742
6743 // Verify that response headers on the migrated socket were delivered to the
6744 // stream.
6745 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6746 EXPECT_EQ(200, response.headers->response_code());
6747
6748 // Resume to consume the read error on new socket, which will close
6749 // the connection.
6750 socket_data1.Resume();
6751
6752 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6753 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6754 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6755 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6756}
6757
Zhongyi Shi4ac9e1f2018-06-21 05:21:476758// Migrate on asynchronous write error, old network disconnects after alternate
6759// network connects.
6760TEST_P(QuicStreamFactoryTest,
6761 MigrateSessionOnWriteErrorWithDisconnectAfterConnectAysnc) {
6762 TestMigrationOnWriteErrorWithMultipleNotifications(
6763 ASYNC, /*disconnect_before_connect*/ false);
6764}
6765
6766// Migrate on synchronous write error, old network disconnects after alternate
6767// network connects.
6768TEST_P(QuicStreamFactoryTest,
6769 MigrateSessionOnWriteErrorWithDisconnectAfterConnectSync) {
6770 TestMigrationOnWriteErrorWithMultipleNotifications(
6771 SYNCHRONOUS, /*disconnect_before_connect*/ false);
6772}
6773
6774// Migrate on asynchronous write error, old network disconnects before alternate
6775// network connects.
6776TEST_P(QuicStreamFactoryTest,
6777 MigrateSessionOnWriteErrorWithDisconnectBeforeConnectAysnc) {
6778 TestMigrationOnWriteErrorWithMultipleNotifications(
6779 ASYNC, /*disconnect_before_connect*/ true);
6780}
6781
6782// Migrate on synchronous write error, old network disconnects before alternate
6783// network connects.
6784TEST_P(QuicStreamFactoryTest,
6785 MigrateSessionOnWriteErrorWithDisconnectBeforeConnectSync) {
6786 TestMigrationOnWriteErrorWithMultipleNotifications(
6787 SYNCHRONOUS, /*disconnect_before_connect*/ true);
6788}
6789
6790// Setps up test which verifies that session successfully migrate to alternate
6791// network with signals delivered in the following order:
6792// *NOTE* Signal (A) and (B) can reverse order based on
6793// |disconnect_before_connect|.
6794// - (No alternate network is connected) session connects to
6795// kDefaultNetworkForTests.
6796// - An async/sync write error is encountered based on |write_error_mode|:
6797// session posted task to migrate session on write error.
6798// - Posted task is executed, miration moves to pending state due to lack of
6799// alternate network.
6800// - (A) An alternate network is connected, pending migration completes.
6801// - (B) Old default network disconnects, no migration will be attempted as
Zhongyi Shi329f5cbd2018-06-22 23:51:186802// session has already migrate to the alternate network.
Zhongyi Shi4ac9e1f2018-06-21 05:21:476803// - The alternate network is made default.
jri5b785512016-09-13 04:29:116804void QuicStreamFactoryTestBase::
Zhongyi Shi4ac9e1f2018-06-21 05:21:476805 TestMigrationOnWriteErrorWithMultipleNotifications(
jri5b785512016-09-13 04:29:116806 IoMode write_error_mode,
Zhongyi Shi4ac9e1f2018-06-21 05:21:476807 bool disconnect_before_connect) {
Zhongyi Shi329f5cbd2018-06-22 23:51:186808 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri5b785512016-09-13 04:29:116809 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6810 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6811 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6812
6813 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526814 quic::QuicStreamOffset header_stream_offset = 0;
jri5b785512016-09-13 04:29:116815 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
rch5cb522462017-04-25 20:18:366816 socket_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436817 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Zhongyi Shi4ac9e1f2018-06-21 05:21:476818 socket_data.AddWrite(write_error_mode, ERR_FAILED); // Write error.
Zhongyi Shi5f587cc2017-11-21 23:24:176819 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri5b785512016-09-13 04:29:116820
6821 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456822 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336823 EXPECT_EQ(ERR_IO_PENDING,
6824 request.Request(host_port_pair_, version_, privacy_mode_,
6825 DEFAULT_PRIORITY, SocketTag(),
6826 /*cert_verify_flags=*/0, url_, net_log_,
6827 &net_error_details_, callback_.callback()));
jri5b785512016-09-13 04:29:116828 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246829 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri5b785512016-09-13 04:29:116830 EXPECT_TRUE(stream.get());
6831
6832 // Cause QUIC stream to be created.
6833 HttpRequestInfo request_info;
6834 request_info.method = "GET";
6835 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396836 request_info.traffic_annotation =
6837 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276838 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396839 net_log_, CompletionOnceCallback()));
jri5b785512016-09-13 04:29:116840
6841 // Ensure that session is alive and active.
6842 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6843 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6844 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6845
6846 // Send GET request on stream. This should cause a write error, which triggers
6847 // a connection migration attempt.
6848 HttpResponseInfo response;
6849 HttpRequestHeaders request_headers;
6850 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6851 callback_.callback()));
Zhongyi Shi4ac9e1f2018-06-21 05:21:476852 // Run the message loop so that posted task to migrate to socket will be
6853 // executed. A new task will be posted to wait for a new network.
jri5b785512016-09-13 04:29:116854 base::RunLoop().RunUntilIdle();
6855
6856 // In this particular code path, the network will not yet be marked
6857 // as going away and the session will still be alive.
6858 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6859 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6860 EXPECT_EQ(1u, session->GetNumActiveStreams());
6861 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
6862
6863 // Set up second socket data provider that is used after
6864 // migration. The request is rewritten to this new socket, and the
6865 // response to the request is read on this new socket.
6866 MockQuicData socket_data1;
Zhongyi Shi32f2fd02018-04-16 18:23:436867 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
6868 2, GetNthClientInitiatedStreamId(0),
6869 true, true, &header_stream_offset));
6870 socket_data1.AddRead(
6871 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
6872 false, false));
jri5b785512016-09-13 04:29:116873 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436874 socket_data1.AddWrite(SYNCHRONOUS,
6875 client_maker_.MakeAckAndRstPacket(
6876 3, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:526877 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:176878 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri5b785512016-09-13 04:29:116879
6880 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6881 ->SetConnectedNetworksList(
6882 {kDefaultNetworkForTests, kNewNetworkForTests});
Zhongyi Shi4ac9e1f2018-06-21 05:21:476883 if (disconnect_before_connect) {
6884 // Now deliver a DISCONNECT notification.
jri5b785512016-09-13 04:29:116885 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6886 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
Zhongyi Shi4ac9e1f2018-06-21 05:21:476887
6888 // Now deliver a CONNECTED notification and completes migration.
jri5b785512016-09-13 04:29:116889 scoped_mock_network_change_notifier_->mock_network_change_notifier()
Zhongyi Shi4ac9e1f2018-06-21 05:21:476890 ->NotifyNetworkConnected(kNewNetworkForTests);
6891 } else {
6892 // Now deliver a CONNECTED notification and completes migration.
6893 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6894 ->NotifyNetworkConnected(kNewNetworkForTests);
6895
6896 // Now deliver a DISCONNECT notification.
6897 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6898 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
jri5b785512016-09-13 04:29:116899 }
jri5b785512016-09-13 04:29:116900 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shi329f5cbd2018-06-22 23:51:186901 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:116902 EXPECT_EQ(1u, session->GetNumActiveStreams());
6903
6904 // This is the callback for the response headers that returned
6905 // pending previously, because no result was available. Check that
6906 // the result is now available due to the successful migration.
6907 EXPECT_THAT(callback_.WaitForResult(), IsOk());
6908 EXPECT_EQ(200, response.headers->response_code());
6909
Zhongyi Shi4ac9e1f2018-06-21 05:21:476910 // Deliver a MADEDEFAULT notification.
jri5b785512016-09-13 04:29:116911 scoped_mock_network_change_notifier_->mock_network_change_notifier()
Zhongyi Shi4ac9e1f2018-06-21 05:21:476912 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri5b785512016-09-13 04:29:116913
zhongyi98d6a9262017-05-19 02:47:456914 QuicStreamRequest request2(factory_.get());
Zhongyi Shi329f5cbd2018-06-22 23:51:186915 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_, privacy_mode_,
6916 DEFAULT_PRIORITY, SocketTag(),
6917 /*cert_verify_flags=*/0, url_, net_log_,
6918 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:246919 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
jri5b785512016-09-13 04:29:116920 EXPECT_TRUE(stream2.get());
6921
6922 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi329f5cbd2018-06-22 23:51:186923 EXPECT_EQ(session, GetActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:116924
6925 stream.reset();
6926 stream2.reset();
6927
6928 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6929 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6930 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6931 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
jri5b785512016-09-13 04:29:116932}
6933
jri217455a12016-07-13 20:15:096934TEST_P(QuicStreamFactoryTest, ServerMigration) {
6935 allow_server_migration_ = true;
6936 Initialize();
6937
6938 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6939 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6940 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6941
rcha00569732016-08-27 11:09:366942 MockQuicData socket_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526943 quic::QuicStreamOffset header_stream_offset = 0;
rcha00569732016-08-27 11:09:366944 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
rch5cb522462017-04-25 20:18:366945 socket_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436946 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6947 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
6948 2, GetNthClientInitiatedStreamId(0),
6949 true, true, &header_stream_offset));
Zhongyi Shi5f587cc2017-11-21 23:24:176950 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri217455a12016-07-13 20:15:096951
6952 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456953 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336954 EXPECT_EQ(ERR_IO_PENDING,
6955 request.Request(host_port_pair_, version_, privacy_mode_,
6956 DEFAULT_PRIORITY, SocketTag(),
6957 /*cert_verify_flags=*/0, url_, net_log_,
6958 &net_error_details_, callback_.callback()));
jri217455a12016-07-13 20:15:096959 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246960 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri217455a12016-07-13 20:15:096961 EXPECT_TRUE(stream.get());
6962
6963 // Cause QUIC stream to be created.
6964 HttpRequestInfo request_info;
6965 request_info.method = "GET";
6966 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396967 request_info.traffic_annotation =
6968 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276969 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396970 net_log_, CompletionOnceCallback()));
jri217455a12016-07-13 20:15:096971
6972 // Ensure that session is alive and active.
6973 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6974 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6975 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6976
6977 // Send GET request on stream.
6978 HttpResponseInfo response;
6979 HttpRequestHeaders request_headers;
6980 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6981 callback_.callback()));
6982
6983 IPEndPoint ip;
6984 session->GetDefaultSocket()->GetPeerAddress(&ip);
6985 DVLOG(1) << "Socket connected to: " << ip.address().ToString() << " "
6986 << ip.port();
6987
6988 // Set up second socket data provider that is used after
6989 // migration. The request is rewritten to this new socket, and the
6990 // response to the request is read on this new socket.
rcha00569732016-08-27 11:09:366991 MockQuicData socket_data2;
6992 socket_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436993 SYNCHRONOUS, client_maker_.MakePingPacket(3, /*include_version=*/true));
6994 socket_data2.AddRead(
6995 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
6996 false, false));
rcha00569732016-08-27 11:09:366997 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436998 socket_data2.AddWrite(SYNCHRONOUS,
6999 client_maker_.MakeAckAndRstPacket(
7000 4, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:527001 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:177002 socket_data2.AddSocketDataToFactory(socket_factory_.get());
jri217455a12016-07-13 20:15:097003
7004 const uint8_t kTestIpAddress[] = {1, 2, 3, 4};
7005 const uint16_t kTestPort = 123;
Zhongyi Shif124a582017-11-02 00:15:047006 session->Migrate(NetworkChangeNotifier::kInvalidNetworkHandle,
7007 IPEndPoint(IPAddress(kTestIpAddress), kTestPort), true,
7008 net_log_);
jri217455a12016-07-13 20:15:097009
7010 session->GetDefaultSocket()->GetPeerAddress(&ip);
7011 DVLOG(1) << "Socket migrated to: " << ip.address().ToString() << " "
7012 << ip.port();
7013
7014 // The session should be alive and active.
7015 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7016 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7017 EXPECT_EQ(1u, session->GetNumActiveStreams());
7018
7019 // Run the message loop so that data queued in the new socket is read by the
7020 // packet reader.
7021 base::RunLoop().RunUntilIdle();
7022
7023 // Verify that response headers on the migrated socket were delivered to the
7024 // stream.
7025 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
7026 EXPECT_EQ(200, response.headers->response_code());
7027
7028 stream.reset();
7029
7030 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7031 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7032 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
7033 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
7034}
7035
jri053fdbd2016-08-19 02:33:057036TEST_P(QuicStreamFactoryTest, ServerMigrationIPv4ToIPv4) {
7037 // Add alternate IPv4 server address to config.
7038 IPEndPoint alt_address = IPEndPoint(IPAddress(1, 2, 3, 4), 123);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527039 quic::QuicConfig config;
fayang91ca2012016-11-22 07:42:467040 config.SetAlternateServerAddressToSend(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527041 quic::QuicSocketAddress(quic::QuicSocketAddressImpl(alt_address)));
jri053fdbd2016-08-19 02:33:057042 VerifyServerMigration(config, alt_address);
7043}
7044
7045TEST_P(QuicStreamFactoryTest, ServerMigrationIPv6ToIPv6) {
7046 // Add a resolver rule to make initial connection to an IPv6 address.
7047 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
7048 "fe80::aebc:32ff:febb:1e33", "");
7049 // Add alternate IPv6 server address to config.
7050 IPEndPoint alt_address = IPEndPoint(
7051 IPAddress(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), 123);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527052 quic::QuicConfig config;
fayang91ca2012016-11-22 07:42:467053 config.SetAlternateServerAddressToSend(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527054 quic::QuicSocketAddress(quic::QuicSocketAddressImpl(alt_address)));
jri053fdbd2016-08-19 02:33:057055 VerifyServerMigration(config, alt_address);
7056}
7057
7058TEST_P(QuicStreamFactoryTest, ServerMigrationIPv6ToIPv4) {
7059 // Add a resolver rule to make initial connection to an IPv6 address.
7060 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
7061 "fe80::aebc:32ff:febb:1e33", "");
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 IPEndPoint expected_address(
7068 ConvertIPv4ToIPv4MappedIPv6(alt_address.address()), alt_address.port());
7069 VerifyServerMigration(config, expected_address);
7070}
7071
7072TEST_P(QuicStreamFactoryTest, ServerMigrationIPv4ToIPv6Fails) {
7073 allow_server_migration_ = true;
7074 Initialize();
7075
7076 // Add a resolver rule to make initial connection to an IPv4 address.
7077 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(), "1.2.3.4",
7078 "");
7079 // Add alternate IPv6 server address to config.
7080 IPEndPoint alt_address = IPEndPoint(
7081 IPAddress(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), 123);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527082 quic::QuicConfig config;
fayang91ca2012016-11-22 07:42:467083 config.SetAlternateServerAddressToSend(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527084 quic::QuicSocketAddress(quic::QuicSocketAddressImpl(alt_address)));
jri053fdbd2016-08-19 02:33:057085
7086 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7087 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7088 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7089
7090 crypto_client_stream_factory_.SetConfig(config);
7091
7092 // Set up only socket data provider.
rcha00569732016-08-27 11:09:367093 MockQuicData socket_data1;
7094 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437095 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
7096 socket_data1.AddWrite(
7097 SYNCHRONOUS,
7098 client_maker_.MakeRstPacket(2, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:527099 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:177100 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri053fdbd2016-08-19 02:33:057101
7102 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:457103 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337104 EXPECT_EQ(ERR_IO_PENDING,
7105 request.Request(host_port_pair_, version_, privacy_mode_,
7106 DEFAULT_PRIORITY, SocketTag(),
7107 /*cert_verify_flags=*/0, url_, net_log_,
7108 &net_error_details_, callback_.callback()));
jri053fdbd2016-08-19 02:33:057109 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:247110 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri053fdbd2016-08-19 02:33:057111 EXPECT_TRUE(stream.get());
7112
7113 // Cause QUIC stream to be created.
7114 HttpRequestInfo request_info;
7115 request_info.method = "GET";
7116 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:397117 request_info.traffic_annotation =
7118 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:277119 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:397120 net_log_, CompletionOnceCallback()));
jri053fdbd2016-08-19 02:33:057121
7122 // Ensure that session is alive and active.
7123 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7124 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7125 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7126
7127 IPEndPoint actual_address;
7128 session->GetDefaultSocket()->GetPeerAddress(&actual_address);
7129 // No migration should have happened.
7130 IPEndPoint expected_address =
7131 IPEndPoint(IPAddress(1, 2, 3, 4), kDefaultServerPort);
7132 EXPECT_EQ(actual_address, expected_address);
7133 DVLOG(1) << "Socket connected to: " << actual_address.address().ToString()
7134 << " " << actual_address.port();
7135 DVLOG(1) << "Expected address: " << expected_address.address().ToString()
7136 << " " << expected_address.port();
7137
7138 stream.reset();
7139 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7140 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7141}
7142
rch02d87792015-09-09 09:05:537143TEST_P(QuicStreamFactoryTest, OnSSLConfigChanged) {
jri7046038f2015-10-22 00:29:267144 Initialize();
rch6faa4d42016-01-05 20:48:437145 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7146 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7147 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7148
rcha00569732016-08-27 11:09:367149 MockQuicData socket_data;
7150 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437151 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Ryan Hamilton8d9ee76e2018-05-29 23:52:527152 socket_data.AddWrite(
7153 SYNCHRONOUS, ConstructClientRstPacket(2, quic::QUIC_RST_ACKNOWLEDGEMENT));
Zhongyi Shi5f587cc2017-11-21 23:24:177154 socket_data.AddSocketDataToFactory(socket_factory_.get());
rch02d87792015-09-09 09:05:537155
rcha00569732016-08-27 11:09:367156 MockQuicData socket_data2;
7157 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437158 socket_data2.AddWrite(SYNCHRONOUS,
7159 ConstructInitialSettingsPacket(1, nullptr));
Zhongyi Shi5f587cc2017-11-21 23:24:177160 socket_data2.AddSocketDataToFactory(socket_factory_.get());
rch02d87792015-09-09 09:05:537161
zhongyi98d6a9262017-05-19 02:47:457162 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337163 EXPECT_EQ(ERR_IO_PENDING,
7164 request.Request(host_port_pair_, version_, privacy_mode_,
7165 DEFAULT_PRIORITY, SocketTag(),
7166 /*cert_verify_flags=*/0, url_, net_log_,
7167 &net_error_details_, callback_.callback()));
rch02d87792015-09-09 09:05:537168
robpercival214763f2016-07-01 23:27:017169 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:247170 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Cherie Shie615a0842018-02-28 02:01:137171 HttpRequestInfo request_info;
7172 request_info.traffic_annotation =
7173 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7174 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békyd8a21fc32018-06-27 18:29:587175 net_log_, CompletionOnceCallback()));
rch02d87792015-09-09 09:05:537176
nharper642ae4b2016-06-30 00:40:367177 ssl_config_service_->NotifySSLConfigChange();
Cherie Shie615a0842018-02-28 02:01:137178 EXPECT_EQ(ERR_CERT_DATABASE_CHANGED,
7179 stream->ReadResponseHeaders(callback_.callback()));
jri7046038f2015-10-22 00:29:267180 EXPECT_FALSE(factory_->require_confirmation());
rch02d87792015-09-09 09:05:537181
7182 // Now attempting to request a stream to the same origin should create
7183 // a new session.
Cherie Shie615a0842018-02-28 02:01:137184
zhongyi98d6a9262017-05-19 02:47:457185 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337186 EXPECT_EQ(ERR_IO_PENDING,
7187 request2.Request(host_port_pair_, version_, privacy_mode_,
7188 DEFAULT_PRIORITY, SocketTag(),
7189 /*cert_verify_flags=*/0, url_, net_log_,
7190 &net_error_details_, callback_.callback()));
rch02d87792015-09-09 09:05:537191
robpercival214763f2016-07-01 23:27:017192 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Cherie Shie615a0842018-02-28 02:01:137193 stream = CreateStream(&request2);
7194 stream.reset(); // Will reset stream 3.
rch02d87792015-09-09 09:05:537195
7196 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7197 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7198 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
7199 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
7200}
7201
rsleevi17784692016-10-12 01:36:207202TEST_P(QuicStreamFactoryTest, OnCertDBChanged) {
jri7046038f2015-10-22 00:29:267203 Initialize();
rch6faa4d42016-01-05 20:48:437204 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7205 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7206 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7207
rcha00569732016-08-27 11:09:367208 MockQuicData socket_data;
7209 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437210 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:177211 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]d7d1e50b2013-11-25 22:08:097212
rcha00569732016-08-27 11:09:367213 MockQuicData socket_data2;
7214 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437215 socket_data2.AddWrite(SYNCHRONOUS,
7216 ConstructInitialSettingsPacket(1, nullptr));
Zhongyi Shi5f587cc2017-11-21 23:24:177217 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]d7d1e50b2013-11-25 22:08:097218
zhongyi98d6a9262017-05-19 02:47:457219 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337220 EXPECT_EQ(ERR_IO_PENDING,
7221 request.Request(host_port_pair_, version_, privacy_mode_,
7222 DEFAULT_PRIORITY, SocketTag(),
7223 /*cert_verify_flags=*/0, url_, net_log_,
7224 &net_error_details_, callback_.callback()));
[email protected]d7d1e50b2013-11-25 22:08:097225
robpercival214763f2016-07-01 23:27:017226 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:247227 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Charles 'Buck' Krasic71763c9f2018-02-16 02:37:287228 EXPECT_TRUE(stream);
7229 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
[email protected]d7d1e50b2013-11-25 22:08:097230
7231 // Change the CA cert and verify that stream saw the event.
mattmfd05a1f2017-02-18 06:18:447232 factory_->OnCertDBChanged();
Charles 'Buck' Krasic71763c9f2018-02-16 02:37:287233
jri7046038f2015-10-22 00:29:267234 EXPECT_FALSE(factory_->require_confirmation());
Charles 'Buck' Krasic71763c9f2018-02-16 02:37:287235 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7236 EXPECT_FALSE(HasActiveSession(host_port_pair_));
[email protected]d7d1e50b2013-11-25 22:08:097237
7238 // Now attempting to request a stream to the same origin should create
7239 // a new session.
7240
zhongyi98d6a9262017-05-19 02:47:457241 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337242 EXPECT_EQ(ERR_IO_PENDING,
7243 request2.Request(host_port_pair_, version_, privacy_mode_,
7244 DEFAULT_PRIORITY, SocketTag(),
7245 /*cert_verify_flags=*/0, url_, net_log_,
7246 &net_error_details_, callback_.callback()));
[email protected]d7d1e50b2013-11-25 22:08:097247
robpercival214763f2016-07-01 23:27:017248 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Charles 'Buck' Krasic71763c9f2018-02-16 02:37:287249 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
7250 EXPECT_TRUE(stream2);
7251 QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
7252 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7253 EXPECT_NE(session, session2);
7254 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7255 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
7256
7257 stream2.reset();
7258 stream.reset();
[email protected]d7d1e50b2013-11-25 22:08:097259
rch37de576c2015-05-17 20:28:177260 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7261 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7262 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
7263 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]d7d1e50b2013-11-25 22:08:097264}
7265
[email protected]1e960032013-12-20 19:00:207266TEST_P(QuicStreamFactoryTest, SharedCryptoConfig) {
jri7046038f2015-10-22 00:29:267267 Initialize();
rch6faa4d42016-01-05 20:48:437268
rch872e00e2016-12-02 02:48:187269 std::vector<string> cannoncial_suffixes;
[email protected]6e12d702013-11-13 00:17:177270 cannoncial_suffixes.push_back(string(".c.youtube.com"));
7271 cannoncial_suffixes.push_back(string(".googlevideo.com"));
[email protected]c49ff182013-09-28 08:33:267272
[email protected]6e12d702013-11-13 00:17:177273 for (unsigned i = 0; i < cannoncial_suffixes.size(); ++i) {
7274 string r1_host_name("r1");
7275 string r2_host_name("r2");
7276 r1_host_name.append(cannoncial_suffixes[i]);
7277 r2_host_name.append(cannoncial_suffixes[i]);
[email protected]b70fdb792013-10-25 19:04:147278
[email protected]bf4ea2f2014-03-10 22:57:537279 HostPortPair host_port_pair1(r1_host_name, 80);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527280 quic::QuicCryptoClientConfig* crypto_config =
jri7046038f2015-10-22 00:29:267281 QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
Ryan Hamilton4f0b26e2018-06-27 23:52:327282 quic::QuicServerId server_id1(host_port_pair1.host(),
7283 host_port_pair1.port(), privacy_mode_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527284 quic::QuicCryptoClientConfig::CachedState* cached1 =
[email protected]257f24f2014-04-01 09:15:377285 crypto_config->LookupOrCreate(server_id1);
[email protected]6e12d702013-11-13 00:17:177286 EXPECT_FALSE(cached1->proof_valid());
7287 EXPECT_TRUE(cached1->source_address_token().empty());
7288
7289 // Mutate the cached1 to have different data.
7290 // TODO(rtenneti): mutate other members of CachedState.
7291 cached1->set_source_address_token(r1_host_name);
7292 cached1->SetProofValid();
7293
[email protected]bf4ea2f2014-03-10 22:57:537294 HostPortPair host_port_pair2(r2_host_name, 80);
Ryan Hamilton4f0b26e2018-06-27 23:52:327295 quic::QuicServerId server_id2(host_port_pair2.host(),
7296 host_port_pair2.port(), privacy_mode_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527297 quic::QuicCryptoClientConfig::CachedState* cached2 =
[email protected]257f24f2014-04-01 09:15:377298 crypto_config->LookupOrCreate(server_id2);
[email protected]6e12d702013-11-13 00:17:177299 EXPECT_EQ(cached1->source_address_token(), cached2->source_address_token());
7300 EXPECT_TRUE(cached2->proof_valid());
7301 }
[email protected]b70fdb792013-10-25 19:04:147302}
7303
[email protected]1e960032013-12-20 19:00:207304TEST_P(QuicStreamFactoryTest, CryptoConfigWhenProofIsInvalid) {
jri7046038f2015-10-22 00:29:267305 Initialize();
rch872e00e2016-12-02 02:48:187306 std::vector<string> cannoncial_suffixes;
[email protected]6e12d702013-11-13 00:17:177307 cannoncial_suffixes.push_back(string(".c.youtube.com"));
7308 cannoncial_suffixes.push_back(string(".googlevideo.com"));
[email protected]b70fdb792013-10-25 19:04:147309
[email protected]6e12d702013-11-13 00:17:177310 for (unsigned i = 0; i < cannoncial_suffixes.size(); ++i) {
7311 string r3_host_name("r3");
7312 string r4_host_name("r4");
7313 r3_host_name.append(cannoncial_suffixes[i]);
7314 r4_host_name.append(cannoncial_suffixes[i]);
[email protected]b70fdb792013-10-25 19:04:147315
[email protected]bf4ea2f2014-03-10 22:57:537316 HostPortPair host_port_pair1(r3_host_name, 80);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527317 quic::QuicCryptoClientConfig* crypto_config =
jri7046038f2015-10-22 00:29:267318 QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
Ryan Hamilton4f0b26e2018-06-27 23:52:327319 quic::QuicServerId server_id1(host_port_pair1.host(),
7320 host_port_pair1.port(), privacy_mode_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527321 quic::QuicCryptoClientConfig::CachedState* cached1 =
[email protected]257f24f2014-04-01 09:15:377322 crypto_config->LookupOrCreate(server_id1);
[email protected]6e12d702013-11-13 00:17:177323 EXPECT_FALSE(cached1->proof_valid());
7324 EXPECT_TRUE(cached1->source_address_token().empty());
7325
7326 // Mutate the cached1 to have different data.
7327 // TODO(rtenneti): mutate other members of CachedState.
7328 cached1->set_source_address_token(r3_host_name);
7329 cached1->SetProofInvalid();
7330
[email protected]bf4ea2f2014-03-10 22:57:537331 HostPortPair host_port_pair2(r4_host_name, 80);
Ryan Hamilton4f0b26e2018-06-27 23:52:327332 quic::QuicServerId server_id2(host_port_pair2.host(),
7333 host_port_pair2.port(), privacy_mode_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527334 quic::QuicCryptoClientConfig::CachedState* cached2 =
[email protected]257f24f2014-04-01 09:15:377335 crypto_config->LookupOrCreate(server_id2);
[email protected]6e12d702013-11-13 00:17:177336 EXPECT_NE(cached1->source_address_token(), cached2->source_address_token());
7337 EXPECT_TRUE(cached2->source_address_token().empty());
7338 EXPECT_FALSE(cached2->proof_valid());
7339 }
[email protected]c49ff182013-09-28 08:33:267340}
7341
rtenneti34dffe752015-02-24 23:27:327342TEST_P(QuicStreamFactoryTest, EnableNotLoadFromDiskCache) {
jri7046038f2015-10-22 00:29:267343 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:207344 factory_->set_require_confirmation(false);
rch6faa4d42016-01-05 20:48:437345 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7346 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7347
jri7046038f2015-10-22 00:29:267348 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
rtenneti34dffe752015-02-24 23:27:327349
rcha00569732016-08-27 11:09:367350 MockQuicData socket_data;
7351 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:177352 socket_data.AddSocketDataToFactory(socket_factory_.get());
rtenneti34dffe752015-02-24 23:27:327353
7354 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:277355 MockCryptoClientStream::ZERO_RTT);
rtenneti34dffe752015-02-24 23:27:327356 host_resolver_.set_synchronous_mode(true);
7357 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
7358 "192.168.0.1", "");
7359
zhongyi98d6a9262017-05-19 02:47:457360 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337361 EXPECT_EQ(OK, request.Request(host_port_pair_, version_, privacy_mode_,
7362 DEFAULT_PRIORITY, SocketTag(),
7363 /*cert_verify_flags=*/0, url_, net_log_,
7364 &net_error_details_, callback_.callback()));
rtenneti34dffe752015-02-24 23:27:327365
7366 // If we are waiting for disk cache, we would have posted a task. Verify that
7367 // the CancelWaitForDataReady task hasn't been posted.
7368 ASSERT_EQ(0u, runner_->GetPostedTasks().size());
7369
Yixin Wang7891a39d2017-11-08 20:59:247370 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rtenneti34dffe752015-02-24 23:27:327371 EXPECT_TRUE(stream.get());
rch37de576c2015-05-17 20:28:177372 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7373 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
rtenneti34dffe752015-02-24 23:27:327374}
7375
dmurph44ca4f42016-09-09 20:39:097376TEST_P(QuicStreamFactoryTest, ReducePingTimeoutOnConnectionTimeOutOpenStreams) {
7377 reduced_ping_timeout_seconds_ = 10;
dmurph44ca4f42016-09-09 20:39:097378 Initialize();
7379 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7380 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7381 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7382
7383 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
zhongyidd1439f62016-09-02 02:02:267384
7385 MockQuicData socket_data;
7386 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437387 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:177388 socket_data.AddSocketDataToFactory(socket_factory_.get());
zhongyidd1439f62016-09-02 02:02:267389
7390 MockQuicData socket_data2;
7391 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437392 socket_data2.AddWrite(SYNCHRONOUS,
7393 ConstructInitialSettingsPacket(1, nullptr));
Zhongyi Shi5f587cc2017-11-21 23:24:177394 socket_data2.AddSocketDataToFactory(socket_factory_.get());
zhongyidd1439f62016-09-02 02:02:267395
7396 HostPortPair server2(kServer2HostName, kDefaultServerPort);
7397
7398 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:277399 MockCryptoClientStream::CONFIRM_HANDSHAKE);
zhongyidd1439f62016-09-02 02:02:267400 host_resolver_.set_synchronous_mode(true);
7401 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
7402 "192.168.0.1", "");
7403 host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
7404
7405 // Quic should use default PING timeout when no previous connection times out
7406 // with open stream.
Ryan Hamilton8d9ee76e2018-05-29 23:52:527407 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(quic::kPingTimeoutSecs),
zhongyidd1439f62016-09-02 02:02:267408 QuicStreamFactoryPeer::GetPingTimeout(factory_.get()));
zhongyi98d6a9262017-05-19 02:47:457409 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337410 EXPECT_EQ(OK, request.Request(host_port_pair_, version_, privacy_mode_,
7411 DEFAULT_PRIORITY, SocketTag(),
7412 /*cert_verify_flags=*/0, url_, net_log_,
7413 &net_error_details_, callback_.callback()));
zhongyidd1439f62016-09-02 02:02:267414
7415 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527416 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(quic::kPingTimeoutSecs),
zhongyidd1439f62016-09-02 02:02:267417 session->connection()->ping_timeout());
7418
Yixin Wang7891a39d2017-11-08 20:59:247419 std::unique_ptr<HttpStream> stream = CreateStream(&request);
zhongyidd1439f62016-09-02 02:02:267420 EXPECT_TRUE(stream.get());
7421 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:397422 request_info.traffic_annotation =
7423 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:277424 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:397425 net_log_, CompletionOnceCallback()));
zhongyidd1439f62016-09-02 02:02:267426
7427 DVLOG(1)
7428 << "Created 1st session and initialized a stream. Now trigger timeout";
Ryan Hamilton8d9ee76e2018-05-29 23:52:527429 session->connection()->CloseConnection(
7430 quic::QUIC_NETWORK_IDLE_TIMEOUT, "test",
7431 quic::ConnectionCloseBehavior::SILENT_CLOSE);
zhongyidd1439f62016-09-02 02:02:267432 // Need to spin the loop now to ensure that
7433 // QuicStreamFactory::OnSessionClosed() runs.
7434 base::RunLoop run_loop;
7435 run_loop.RunUntilIdle();
7436
zhongyidd1439f62016-09-02 02:02:267437 // The first connection times out with open stream, QUIC should reduce initial
7438 // PING time for subsequent connections.
Ryan Hamilton8d9ee76e2018-05-29 23:52:527439 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(10),
zhongyidd1439f62016-09-02 02:02:267440 QuicStreamFactoryPeer::GetPingTimeout(factory_.get()));
7441
7442 // Test two-in-a-row timeouts with open streams.
7443 DVLOG(1) << "Create 2nd session and timeout with open stream";
7444 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:457445 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337446 EXPECT_EQ(OK, request2.Request(server2, version_, privacy_mode_,
7447 DEFAULT_PRIORITY, SocketTag(),
7448 /*cert_verify_flags=*/0, url2_, net_log_,
7449 &net_error_details_, callback2.callback()));
zhongyidd1439f62016-09-02 02:02:267450 QuicChromiumClientSession* session2 = GetActiveSession(server2);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527451 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(10),
zhongyidd1439f62016-09-02 02:02:267452 session2->connection()->ping_timeout());
7453
Yixin Wang7891a39d2017-11-08 20:59:247454 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
zhongyidd1439f62016-09-02 02:02:267455 EXPECT_TRUE(stream2.get());
Steven Valdezb4ff0412018-01-18 22:39:277456 EXPECT_EQ(OK,
7457 stream2->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:397458 net_log_, CompletionOnceCallback()));
zhongyidd1439f62016-09-02 02:02:267459 session2->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527460 quic::QUIC_NETWORK_IDLE_TIMEOUT, "test",
7461 quic::ConnectionCloseBehavior::SILENT_CLOSE);
zhongyidd1439f62016-09-02 02:02:267462 // Need to spin the loop now to ensure that
7463 // QuicStreamFactory::OnSessionClosed() runs.
7464 base::RunLoop run_loop2;
7465 run_loop2.RunUntilIdle();
zhongyidd1439f62016-09-02 02:02:267466
7467 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7468 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7469 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
7470 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
7471}
7472
tbansal3b966952016-10-25 23:25:147473// Verifies that the QUIC stream factory is initialized correctly.
rtenneticd2aaa15b2015-10-10 20:29:337474TEST_P(QuicStreamFactoryTest, MaybeInitialize) {
tbansal9b1cdf32017-05-10 17:28:397475 VerifyInitialization();
rtenneti8a80a6dc2015-09-21 19:51:137476}
7477
rtennetid073dd22016-08-04 01:58:337478TEST_P(QuicStreamFactoryTest, StartCertVerifyJob) {
7479 Initialize();
7480
rcha00569732016-08-27 11:09:367481 MockQuicData socket_data;
7482 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437483 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:177484 socket_data.AddSocketDataToFactory(socket_factory_.get());
rtennetid073dd22016-08-04 01:58:337485
7486 // Save current state of |race_cert_verification|.
7487 bool race_cert_verification =
7488 QuicStreamFactoryPeer::GetRaceCertVerification(factory_.get());
7489
7490 // Load server config.
7491 HostPortPair host_port_pair(kDefaultServerHostName, kDefaultServerPort);
Ryan Hamilton4f0b26e2018-06-27 23:52:327492 quic::QuicServerId quic_server_id(host_port_pair_.host(),
7493 host_port_pair_.port(),
7494 privacy_mode_ == PRIVACY_MODE_ENABLED);
rtennetid073dd22016-08-04 01:58:337495 QuicStreamFactoryPeer::CacheDummyServerConfig(factory_.get(), quic_server_id);
7496
7497 QuicStreamFactoryPeer::SetRaceCertVerification(factory_.get(), true);
7498 EXPECT_FALSE(HasActiveCertVerifierJob(quic_server_id));
7499
7500 // Start CertVerifyJob.
Ryan Hamilton8d9ee76e2018-05-29 23:52:527501 quic::QuicAsyncStatus status = QuicStreamFactoryPeer::StartCertVerifyJob(
rtennetid073dd22016-08-04 01:58:337502 factory_.get(), quic_server_id, /*cert_verify_flags=*/0, net_log_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527503 if (status == quic::QUIC_PENDING) {
rtennetid073dd22016-08-04 01:58:337504 // Verify CertVerifierJob has started.
7505 EXPECT_TRUE(HasActiveCertVerifierJob(quic_server_id));
7506
7507 while (HasActiveCertVerifierJob(quic_server_id)) {
7508 base::RunLoop().RunUntilIdle();
7509 }
7510 }
7511 // Verify CertVerifierJob has finished.
7512 EXPECT_FALSE(HasActiveCertVerifierJob(quic_server_id));
7513
7514 // Start a QUIC request.
zhongyi98d6a9262017-05-19 02:47:457515 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337516 EXPECT_EQ(ERR_IO_PENDING,
7517 request.Request(host_port_pair_, version_, privacy_mode_,
7518 DEFAULT_PRIORITY, SocketTag(),
7519 /*cert_verify_flags=*/0, url_, net_log_,
7520 &net_error_details_, callback_.callback()));
rtennetid073dd22016-08-04 01:58:337521
7522 EXPECT_EQ(OK, callback_.WaitForResult());
7523
Yixin Wang7891a39d2017-11-08 20:59:247524 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rtennetid073dd22016-08-04 01:58:337525 EXPECT_TRUE(stream.get());
7526
7527 // Restore |race_cert_verification|.
7528 QuicStreamFactoryPeer::SetRaceCertVerification(factory_.get(),
7529 race_cert_verification);
7530
7531 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7532 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7533
7534 // Verify there are no outstanding CertVerifierJobs after request has
7535 // finished.
7536 EXPECT_FALSE(HasActiveCertVerifierJob(quic_server_id));
7537}
7538
rtenneti1cd3b162015-09-29 02:58:287539TEST_P(QuicStreamFactoryTest, YieldAfterPackets) {
jri7046038f2015-10-22 00:29:267540 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:207541 factory_->set_require_confirmation(false);
rch6faa4d42016-01-05 20:48:437542 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7543 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:267544 QuicStreamFactoryPeer::SetYieldAfterPackets(factory_.get(), 0);
rtenneti1cd3b162015-09-29 02:58:287545
rcha00569732016-08-27 11:09:367546 MockQuicData socket_data;
Zhongyi Shi32f2fd02018-04-16 18:23:437547 socket_data.AddRead(SYNCHRONOUS, ConstructClientConnectionClosePacket(0));
rcha00569732016-08-27 11:09:367548 socket_data.AddRead(ASYNC, OK);
Zhongyi Shi5f587cc2017-11-21 23:24:177549 socket_data.AddSocketDataToFactory(socket_factory_.get());
rtenneti1cd3b162015-09-29 02:58:287550
7551 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:277552 MockCryptoClientStream::ZERO_RTT);
rtenneti1cd3b162015-09-29 02:58:287553 host_resolver_.set_synchronous_mode(true);
7554 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
7555 "192.168.0.1", "");
7556
rcha02807b42016-01-29 21:56:157557 // Set up the TaskObserver to verify QuicChromiumPacketReader::StartReading
7558 // posts a task.
rtenneti1cd3b162015-09-29 02:58:287559 // TODO(rtenneti): Change SpdySessionTestTaskObserver to NetTestTaskObserver??
rcha02807b42016-01-29 21:56:157560 SpdySessionTestTaskObserver observer("quic_chromium_packet_reader.cc",
7561 "StartReading");
rtenneti1cd3b162015-09-29 02:58:287562
zhongyi98d6a9262017-05-19 02:47:457563 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337564 EXPECT_EQ(OK, request.Request(host_port_pair_, version_, privacy_mode_,
7565 DEFAULT_PRIORITY, SocketTag(),
7566 /*cert_verify_flags=*/0, url_, net_log_,
7567 &net_error_details_, callback_.callback()));
rtenneti1cd3b162015-09-29 02:58:287568
rcha02807b42016-01-29 21:56:157569 // Call run_loop so that QuicChromiumPacketReader::OnReadComplete() gets
7570 // called.
rtenneti1cd3b162015-09-29 02:58:287571 base::RunLoop run_loop;
7572 run_loop.RunUntilIdle();
7573
7574 // Verify task that the observer's executed_count is 1, which indicates
rcha02807b42016-01-29 21:56:157575 // QuicChromiumPacketReader::StartReading() has posted only one task and
7576 // yielded the read.
rtenneti1cd3b162015-09-29 02:58:287577 EXPECT_EQ(1u, observer.executed_count());
7578
Yixin Wang7891a39d2017-11-08 20:59:247579 std::unique_ptr<HttpStream> stream = CreateStream(&request);
xunjieli2608f9b2016-03-14 13:39:237580 EXPECT_FALSE(stream.get()); // Session is already closed.
rtenneti1cd3b162015-09-29 02:58:287581 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7582 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7583}
7584
7585TEST_P(QuicStreamFactoryTest, YieldAfterDuration) {
jri7046038f2015-10-22 00:29:267586 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:207587 factory_->set_require_confirmation(false);
rch6faa4d42016-01-05 20:48:437588 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7589 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rtenneti1cd3b162015-09-29 02:58:287590 QuicStreamFactoryPeer::SetYieldAfterDuration(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527591 factory_.get(), quic::QuicTime::Delta::FromMilliseconds(-1));
rtenneti1cd3b162015-09-29 02:58:287592
rcha00569732016-08-27 11:09:367593 MockQuicData socket_data;
Zhongyi Shi32f2fd02018-04-16 18:23:437594 socket_data.AddRead(SYNCHRONOUS, ConstructClientConnectionClosePacket(0));
rcha00569732016-08-27 11:09:367595 socket_data.AddRead(ASYNC, OK);
Zhongyi Shi5f587cc2017-11-21 23:24:177596 socket_data.AddSocketDataToFactory(socket_factory_.get());
rtenneti1cd3b162015-09-29 02:58:287597
7598 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:277599 MockCryptoClientStream::ZERO_RTT);
rtenneti1cd3b162015-09-29 02:58:287600 host_resolver_.set_synchronous_mode(true);
7601 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
7602 "192.168.0.1", "");
7603
rcha02807b42016-01-29 21:56:157604 // Set up the TaskObserver to verify QuicChromiumPacketReader::StartReading
7605 // posts a task.
rtenneti1cd3b162015-09-29 02:58:287606 // TODO(rtenneti): Change SpdySessionTestTaskObserver to NetTestTaskObserver??
rcha02807b42016-01-29 21:56:157607 SpdySessionTestTaskObserver observer("quic_chromium_packet_reader.cc",
7608 "StartReading");
rtenneti1cd3b162015-09-29 02:58:287609
zhongyi98d6a9262017-05-19 02:47:457610 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337611 EXPECT_EQ(OK, request.Request(host_port_pair_, version_, privacy_mode_,
7612 DEFAULT_PRIORITY, SocketTag(),
7613 /*cert_verify_flags=*/0, url_, net_log_,
7614 &net_error_details_, callback_.callback()));
rtenneti1cd3b162015-09-29 02:58:287615
rcha02807b42016-01-29 21:56:157616 // Call run_loop so that QuicChromiumPacketReader::OnReadComplete() gets
7617 // called.
rtenneti1cd3b162015-09-29 02:58:287618 base::RunLoop run_loop;
7619 run_loop.RunUntilIdle();
7620
7621 // Verify task that the observer's executed_count is 1, which indicates
rcha02807b42016-01-29 21:56:157622 // QuicChromiumPacketReader::StartReading() has posted only one task and
7623 // yielded the read.
rtenneti1cd3b162015-09-29 02:58:287624 EXPECT_EQ(1u, observer.executed_count());
7625
Yixin Wang7891a39d2017-11-08 20:59:247626 std::unique_ptr<HttpStream> stream = CreateStream(&request);
xunjieli2608f9b2016-03-14 13:39:237627 EXPECT_FALSE(stream.get()); // Session is already closed.
rtenneti1cd3b162015-09-29 02:58:287628 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7629 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7630}
7631
ckrasic3865ee0f2016-02-29 22:04:567632TEST_P(QuicStreamFactoryTest, ServerPushSessionAffinity) {
7633 Initialize();
7634 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7635 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7636
rcha00569732016-08-27 11:09:367637 MockQuicData socket_data;
7638 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437639 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:177640 socket_data.AddSocketDataToFactory(socket_factory_.get());
ckrasic3865ee0f2016-02-29 22:04:567641
zhongyi98d6a9262017-05-19 02:47:457642 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337643 EXPECT_EQ(ERR_IO_PENDING,
7644 request.Request(host_port_pair_, version_, privacy_mode_,
7645 DEFAULT_PRIORITY, SocketTag(),
7646 /*cert_verify_flags=*/0, url_, net_log_,
7647 &net_error_details_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:567648
robpercival214763f2016-07-01 23:27:017649 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:247650 std::unique_ptr<HttpStream> stream = CreateStream(&request);
ckrasic3865ee0f2016-02-29 22:04:567651 EXPECT_TRUE(stream.get());
7652
7653 EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumPushStreamsCreated(factory_.get()));
7654
bnc5fdc07162016-05-23 17:36:037655 string url = "https://www.example.org/";
ckrasic3865ee0f2016-02-29 22:04:567656
bnc912a04b2016-04-20 14:19:507657 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
ckrasic3865ee0f2016-02-29 22:04:567658
Ryan Hamilton8d9ee76e2018-05-29 23:52:527659 quic::QuicClientPromisedInfo promised(
7660 session, GetNthServerInitiatedStreamId(0), kDefaultUrl);
ckrasic3865ee0f2016-02-29 22:04:567661 (*QuicStreamFactoryPeer::GetPushPromiseIndex(factory_.get())
bnc3d9035b32016-06-30 18:18:487662 ->promised_by_url())[kDefaultUrl] = &promised;
ckrasic3865ee0f2016-02-29 22:04:567663
zhongyi98d6a9262017-05-19 02:47:457664 QuicStreamRequest request2(factory_.get());
zhongyia00ca012017-07-06 23:36:397665 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_, privacy_mode_,
Paul Jensen8e3c5d32018-02-19 17:06:337666 DEFAULT_PRIORITY, SocketTag(),
7667 /*cert_verify_flags=*/0, url_, net_log_,
7668 &net_error_details_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:567669
7670 EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumPushStreamsCreated(factory_.get()));
7671}
7672
7673TEST_P(QuicStreamFactoryTest, ServerPushPrivacyModeMismatch) {
7674 Initialize();
7675 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7676 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7677 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7678
rcha00569732016-08-27 11:09:367679 MockQuicData socket_data1;
7680 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437681 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
7682 socket_data1.AddWrite(
7683 SYNCHRONOUS,
7684 client_maker_.MakeRstPacket(2, true, GetNthServerInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:527685 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:177686 socket_data1.AddSocketDataToFactory(socket_factory_.get());
ckrasic3865ee0f2016-02-29 22:04:567687
rcha00569732016-08-27 11:09:367688 MockQuicData socket_data2;
7689 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437690 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:177691 socket_data2.AddSocketDataToFactory(socket_factory_.get());
ckrasic3865ee0f2016-02-29 22:04:567692
zhongyi98d6a9262017-05-19 02:47:457693 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337694 EXPECT_EQ(ERR_IO_PENDING,
7695 request.Request(host_port_pair_, version_, privacy_mode_,
7696 DEFAULT_PRIORITY, SocketTag(),
7697 /*cert_verify_flags=*/0, url_, net_log_,
7698 &net_error_details_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:567699
robpercival214763f2016-07-01 23:27:017700 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:247701 std::unique_ptr<HttpStream> stream = CreateStream(&request);
ckrasic3865ee0f2016-02-29 22:04:567702 EXPECT_TRUE(stream.get());
7703
7704 EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumPushStreamsCreated(factory_.get()));
7705
bnc5fdc07162016-05-23 17:36:037706 string url = "https://www.example.org/";
bnc912a04b2016-04-20 14:19:507707 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
ckrasic3865ee0f2016-02-29 22:04:567708
Ryan Hamilton8d9ee76e2018-05-29 23:52:527709 quic::QuicClientPromisedInfo promised(
7710 session, GetNthServerInitiatedStreamId(0), kDefaultUrl);
ckrasic3865ee0f2016-02-29 22:04:567711
Ryan Hamilton8d9ee76e2018-05-29 23:52:527712 quic::QuicClientPushPromiseIndex* index =
ckrasic3865ee0f2016-02-29 22:04:567713 QuicStreamFactoryPeer::GetPushPromiseIndex(factory_.get());
7714
bnc3d9035b32016-06-30 18:18:487715 (*index->promised_by_url())[kDefaultUrl] = &promised;
7716 EXPECT_EQ(index->GetPromised(kDefaultUrl), &promised);
ckrasic3865ee0f2016-02-29 22:04:567717
7718 // Doing the request should not use the push stream, but rather
7719 // cancel it because the privacy modes do not match.
zhongyi98d6a9262017-05-19 02:47:457720 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337721 EXPECT_EQ(ERR_IO_PENDING,
7722 request2.Request(host_port_pair_, version_, PRIVACY_MODE_ENABLED,
7723 DEFAULT_PRIORITY, SocketTag(),
7724 /*cert_verify_flags=*/0, url_, net_log_,
7725 &net_error_details_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:567726
7727 EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumPushStreamsCreated(factory_.get()));
bnc3d9035b32016-06-30 18:18:487728 EXPECT_EQ(index->GetPromised(kDefaultUrl), nullptr);
ckrasic3865ee0f2016-02-29 22:04:567729
robpercival214763f2016-07-01 23:27:017730 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:247731 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
ckrasic3865ee0f2016-02-29 22:04:567732 EXPECT_TRUE(stream2.get());
7733
7734 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7735 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7736 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
7737 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
7738}
7739
Ryan Hamilton8d9ee76e2018-05-29 23:52:527740// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:457741// even if destination is different.
7742TEST_P(QuicStreamFactoryTest, PoolByOrigin) {
7743 Initialize();
7744
7745 HostPortPair destination1("first.example.com", 443);
7746 HostPortPair destination2("second.example.com", 443);
7747
7748 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7749 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7750
rcha00569732016-08-27 11:09:367751 MockQuicData socket_data;
7752 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437753 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:177754 socket_data.AddSocketDataToFactory(socket_factory_.get());
bnc359ed2a2016-04-29 20:43:457755
zhongyi98d6a9262017-05-19 02:47:457756 QuicStreamRequest request1(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337757 EXPECT_EQ(ERR_IO_PENDING,
7758 request1.Request(destination1, version_, privacy_mode_,
7759 DEFAULT_PRIORITY, SocketTag(),
7760 /*cert_verify_flags=*/0, url_, net_log_,
7761 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:017762 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:247763 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
bnc359ed2a2016-04-29 20:43:457764 EXPECT_TRUE(stream1.get());
7765 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7766
7767 // Second request returns synchronously because it pools to existing session.
7768 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:457769 QuicStreamRequest request2(factory_.get());
zhongyia00ca012017-07-06 23:36:397770 EXPECT_EQ(OK, request2.Request(destination2, version_, privacy_mode_,
Paul Jensen8e3c5d32018-02-19 17:06:337771 DEFAULT_PRIORITY, SocketTag(),
7772 /*cert_verify_flags=*/0, url_, net_log_,
7773 &net_error_details_, callback2.callback()));
Yixin Wang7891a39d2017-11-08 20:59:247774 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
bnc359ed2a2016-04-29 20:43:457775 EXPECT_TRUE(stream2.get());
7776
rchf0b18c8a2017-05-05 19:31:577777 QuicChromiumClientSession::Handle* session1 =
7778 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
7779 QuicChromiumClientSession::Handle* session2 =
7780 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
7781 EXPECT_TRUE(session1->SharesSameSession(*session2));
Ryan Hamilton4f0b26e2018-06-27 23:52:327782 EXPECT_EQ(quic::QuicServerId(host_port_pair_.host(), host_port_pair_.port(),
7783 privacy_mode_ == PRIVACY_MODE_ENABLED),
bnc359ed2a2016-04-29 20:43:457784 session1->server_id());
7785
7786 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7787 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7788}
7789
7790class QuicStreamFactoryWithDestinationTest
7791 : public QuicStreamFactoryTestBase,
7792 public ::testing::TestWithParam<PoolingTestParams> {
7793 protected:
7794 QuicStreamFactoryWithDestinationTest()
Yixin Wang079ad542018-01-11 04:06:057795 : QuicStreamFactoryTestBase(
7796 GetParam().version,
7797 GetParam().client_headers_include_h2_stream_dependency),
bnc359ed2a2016-04-29 20:43:457798 destination_type_(GetParam().destination_type),
7799 hanging_read_(SYNCHRONOUS, ERR_IO_PENDING, 0) {}
7800
7801 HostPortPair GetDestination() {
7802 switch (destination_type_) {
7803 case SAME_AS_FIRST:
7804 return origin1_;
7805 case SAME_AS_SECOND:
7806 return origin2_;
7807 case DIFFERENT:
7808 return HostPortPair(kDifferentHostname, 443);
7809 default:
7810 NOTREACHED();
7811 return HostPortPair();
7812 }
7813 }
7814
7815 void AddHangingSocketData() {
7816 std::unique_ptr<SequencedSocketData> sequenced_socket_data(
Ryan Sleevib8d7ea02018-05-07 20:01:017817 new SequencedSocketData(base::make_span(&hanging_read_, 1),
7818 base::span<MockWrite>()));
Zhongyi Shi5f587cc2017-11-21 23:24:177819 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
bnc359ed2a2016-04-29 20:43:457820 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
7821 }
7822
7823 bool AllDataConsumed() {
7824 for (const auto& socket_data_ptr : sequenced_socket_data_vector_) {
7825 if (!socket_data_ptr->AllReadDataConsumed() ||
7826 !socket_data_ptr->AllWriteDataConsumed()) {
7827 return false;
7828 }
7829 }
7830 return true;
7831 }
7832
7833 DestinationType destination_type_;
7834 HostPortPair origin1_;
7835 HostPortPair origin2_;
7836 MockRead hanging_read_;
rch872e00e2016-12-02 02:48:187837 std::vector<std::unique_ptr<SequencedSocketData>>
7838 sequenced_socket_data_vector_;
bnc359ed2a2016-04-29 20:43:457839};
7840
Bence Békyce380cb2018-04-26 23:39:557841INSTANTIATE_TEST_CASE_P(VersionIncludeStreamDependencySequence,
bnc359ed2a2016-04-29 20:43:457842 QuicStreamFactoryWithDestinationTest,
7843 ::testing::ValuesIn(GetPoolingTestParams()));
7844
7845// A single QUIC request fails because the certificate does not match the origin
7846// hostname, regardless of whether it matches the alternative service hostname.
7847TEST_P(QuicStreamFactoryWithDestinationTest, InvalidCertificate) {
7848 if (destination_type_ == DIFFERENT)
7849 return;
7850
7851 Initialize();
7852
7853 GURL url("https://mail.example.com/");
7854 origin1_ = HostPortPair::FromURL(url);
7855
7856 // Not used for requests, but this provides a test case where the certificate
7857 // is valid for the hostname of the alternative service.
7858 origin2_ = HostPortPair("mail.example.org", 433);
7859
7860 HostPortPair destination = GetDestination();
7861
7862 scoped_refptr<X509Certificate> cert(
7863 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247864 ASSERT_FALSE(cert->VerifyNameMatch(origin1_.host()));
7865 ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host()));
bnc359ed2a2016-04-29 20:43:457866
7867 ProofVerifyDetailsChromium verify_details;
7868 verify_details.cert_verify_result.verified_cert = cert;
7869 verify_details.cert_verify_result.is_issued_by_known_root = true;
7870 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7871
7872 AddHangingSocketData();
7873
zhongyi98d6a9262017-05-19 02:47:457874 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337875 EXPECT_EQ(ERR_IO_PENDING,
7876 request.Request(destination, version_, privacy_mode_,
7877 DEFAULT_PRIORITY, SocketTag(),
7878 /*cert_verify_flags=*/0, url, net_log_,
7879 &net_error_details_, callback_.callback()));
bnc359ed2a2016-04-29 20:43:457880
robpercival214763f2016-07-01 23:27:017881 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_QUIC_HANDSHAKE_FAILED));
bnc359ed2a2016-04-29 20:43:457882
7883 EXPECT_TRUE(AllDataConsumed());
7884}
7885
7886// QuicStreamRequest is pooled based on |destination| if certificate matches.
7887TEST_P(QuicStreamFactoryWithDestinationTest, SharedCertificate) {
7888 Initialize();
7889
7890 GURL url1("https://www.example.org/");
7891 GURL url2("https://mail.example.org/");
7892 origin1_ = HostPortPair::FromURL(url1);
7893 origin2_ = HostPortPair::FromURL(url2);
7894
7895 HostPortPair destination = GetDestination();
7896
7897 scoped_refptr<X509Certificate> cert(
7898 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247899 ASSERT_TRUE(cert->VerifyNameMatch(origin1_.host()));
7900 ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host()));
7901 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457902
7903 ProofVerifyDetailsChromium verify_details;
7904 verify_details.cert_verify_result.verified_cert = cert;
7905 verify_details.cert_verify_result.is_issued_by_known_root = true;
7906 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7907
fayang3bcb8b502016-12-07 21:44:377908 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:527909 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:367910 client_maker_.MakeInitialSettingsPacket(1, nullptr));
bnceb9aa7112017-01-05 01:03:467911 MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(),
7912 settings_packet->length(), 1)};
fayang3bcb8b502016-12-07 21:44:377913 std::unique_ptr<SequencedSocketData> sequenced_socket_data(
Ryan Sleevib8d7ea02018-05-07 20:01:017914 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:177915 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
fayang3bcb8b502016-12-07 21:44:377916 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
bnc359ed2a2016-04-29 20:43:457917
zhongyi98d6a9262017-05-19 02:47:457918 QuicStreamRequest request1(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337919 EXPECT_EQ(ERR_IO_PENDING,
7920 request1.Request(destination, version_, privacy_mode_,
7921 DEFAULT_PRIORITY, SocketTag(),
7922 /*cert_verify_flags=*/0, url1, net_log_,
7923 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:017924 EXPECT_THAT(callback_.WaitForResult(), IsOk());
fayang3bcb8b502016-12-07 21:44:377925
Yixin Wang7891a39d2017-11-08 20:59:247926 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
bnc359ed2a2016-04-29 20:43:457927 EXPECT_TRUE(stream1.get());
7928 EXPECT_TRUE(HasActiveSession(origin1_));
7929
7930 // Second request returns synchronously because it pools to existing session.
7931 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:457932 QuicStreamRequest request2(factory_.get());
zhongyia00ca012017-07-06 23:36:397933 EXPECT_EQ(OK, request2.Request(destination, version_, privacy_mode_,
Paul Jensen8e3c5d32018-02-19 17:06:337934 DEFAULT_PRIORITY, SocketTag(),
7935 /*cert_verify_flags=*/0, url2, net_log_,
7936 &net_error_details_, callback2.callback()));
Yixin Wang7891a39d2017-11-08 20:59:247937 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
bnc359ed2a2016-04-29 20:43:457938 EXPECT_TRUE(stream2.get());
7939
rchf0b18c8a2017-05-05 19:31:577940 QuicChromiumClientSession::Handle* session1 =
7941 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
7942 QuicChromiumClientSession::Handle* session2 =
7943 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
7944 EXPECT_TRUE(session1->SharesSameSession(*session2));
bnc359ed2a2016-04-29 20:43:457945
Ryan Hamilton4f0b26e2018-06-27 23:52:327946 EXPECT_EQ(quic::QuicServerId(origin1_.host(), origin1_.port(),
7947 privacy_mode_ == PRIVACY_MODE_ENABLED),
7948 session1->server_id());
bnc359ed2a2016-04-29 20:43:457949
7950 EXPECT_TRUE(AllDataConsumed());
7951}
7952
bnc47eba7d2016-07-01 00:43:387953// QuicStreamRequest is not pooled if PrivacyMode differs.
7954TEST_P(QuicStreamFactoryWithDestinationTest, DifferentPrivacyMode) {
7955 Initialize();
7956
7957 GURL url1("https://www.example.org/");
7958 GURL url2("https://mail.example.org/");
7959 origin1_ = HostPortPair::FromURL(url1);
7960 origin2_ = HostPortPair::FromURL(url2);
7961
7962 HostPortPair destination = GetDestination();
7963
7964 scoped_refptr<X509Certificate> cert(
7965 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247966 ASSERT_TRUE(cert->VerifyNameMatch(origin1_.host()));
7967 ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host()));
7968 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc47eba7d2016-07-01 00:43:387969
7970 ProofVerifyDetailsChromium verify_details1;
7971 verify_details1.cert_verify_result.verified_cert = cert;
7972 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7973 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7974
7975 ProofVerifyDetailsChromium verify_details2;
7976 verify_details2.cert_verify_result.verified_cert = cert;
7977 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7978 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7979
fayang3bcb8b502016-12-07 21:44:377980 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:527981 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:367982 client_maker_.MakeInitialSettingsPacket(1, nullptr));
bnceb9aa7112017-01-05 01:03:467983 MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(),
7984 settings_packet->length(), 1)};
fayang3bcb8b502016-12-07 21:44:377985 std::unique_ptr<SequencedSocketData> sequenced_socket_data(
Ryan Sleevib8d7ea02018-05-07 20:01:017986 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:177987 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
fayang3bcb8b502016-12-07 21:44:377988 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
7989 std::unique_ptr<SequencedSocketData> sequenced_socket_data1(
Ryan Sleevib8d7ea02018-05-07 20:01:017990 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:177991 socket_factory_->AddSocketDataProvider(sequenced_socket_data1.get());
fayang3bcb8b502016-12-07 21:44:377992 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data1));
bnc47eba7d2016-07-01 00:43:387993
zhongyi98d6a9262017-05-19 02:47:457994 QuicStreamRequest request1(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337995 EXPECT_EQ(ERR_IO_PENDING,
7996 request1.Request(destination, version_, PRIVACY_MODE_DISABLED,
7997 DEFAULT_PRIORITY, SocketTag(),
7998 /*cert_verify_flags=*/0, url1, net_log_,
7999 &net_error_details_, callback_.callback()));
bnc47eba7d2016-07-01 00:43:388000 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:248001 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
bnc47eba7d2016-07-01 00:43:388002 EXPECT_TRUE(stream1.get());
8003 EXPECT_TRUE(HasActiveSession(origin1_));
8004
8005 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:458006 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338007 EXPECT_EQ(ERR_IO_PENDING,
8008 request2.Request(destination, version_, PRIVACY_MODE_ENABLED,
8009 DEFAULT_PRIORITY, SocketTag(),
8010 /*cert_verify_flags=*/0, url2, net_log_,
8011 &net_error_details_, callback2.callback()));
bnc47eba7d2016-07-01 00:43:388012 EXPECT_EQ(OK, callback2.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:248013 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
bnc47eba7d2016-07-01 00:43:388014 EXPECT_TRUE(stream2.get());
8015
8016 // |request2| does not pool to the first session, because PrivacyMode does not
8017 // match. Instead, another session is opened to the same destination, but
Ryan Hamilton8d9ee76e2018-05-29 23:52:528018 // with a different quic::QuicServerId.
rchf0b18c8a2017-05-05 19:31:578019 QuicChromiumClientSession::Handle* session1 =
8020 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
8021 QuicChromiumClientSession::Handle* session2 =
8022 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
8023 EXPECT_FALSE(session1->SharesSameSession(*session2));
bnc47eba7d2016-07-01 00:43:388024
Ryan Hamilton4f0b26e2018-06-27 23:52:328025 EXPECT_EQ(quic::QuicServerId(origin1_.host(), origin1_.port(), false),
bnc47eba7d2016-07-01 00:43:388026 session1->server_id());
Ryan Hamilton4f0b26e2018-06-27 23:52:328027 EXPECT_EQ(quic::QuicServerId(origin2_.host(), origin2_.port(), true),
bnc47eba7d2016-07-01 00:43:388028 session2->server_id());
8029
8030 EXPECT_TRUE(AllDataConsumed());
8031}
8032
bnc359ed2a2016-04-29 20:43:458033// QuicStreamRequest is not pooled if certificate does not match its origin.
8034TEST_P(QuicStreamFactoryWithDestinationTest, DisjointCertificate) {
8035 Initialize();
8036
8037 GURL url1("https://news.example.org/");
8038 GURL url2("https://mail.example.com/");
8039 origin1_ = HostPortPair::FromURL(url1);
8040 origin2_ = HostPortPair::FromURL(url2);
8041
8042 HostPortPair destination = GetDestination();
8043
8044 scoped_refptr<X509Certificate> cert1(
8045 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:248046 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_.host()));
8047 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_.host()));
8048 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:458049
8050 ProofVerifyDetailsChromium verify_details1;
8051 verify_details1.cert_verify_result.verified_cert = cert1;
8052 verify_details1.cert_verify_result.is_issued_by_known_root = true;
8053 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
8054
8055 scoped_refptr<X509Certificate> cert2(
8056 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:248057 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_.host()));
8058 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:458059
8060 ProofVerifyDetailsChromium verify_details2;
8061 verify_details2.cert_verify_result.verified_cert = cert2;
8062 verify_details2.cert_verify_result.is_issued_by_known_root = true;
8063 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
8064
fayang3bcb8b502016-12-07 21:44:378065 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:528066 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:368067 client_maker_.MakeInitialSettingsPacket(1, nullptr));
bnceb9aa7112017-01-05 01:03:468068 MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(),
8069 settings_packet->length(), 1)};
fayang3bcb8b502016-12-07 21:44:378070 std::unique_ptr<SequencedSocketData> sequenced_socket_data(
Ryan Sleevib8d7ea02018-05-07 20:01:018071 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:178072 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
fayang3bcb8b502016-12-07 21:44:378073 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
8074 std::unique_ptr<SequencedSocketData> sequenced_socket_data1(
Ryan Sleevib8d7ea02018-05-07 20:01:018075 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:178076 socket_factory_->AddSocketDataProvider(sequenced_socket_data1.get());
fayang3bcb8b502016-12-07 21:44:378077 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data1));
bnc359ed2a2016-04-29 20:43:458078
zhongyi98d6a9262017-05-19 02:47:458079 QuicStreamRequest request1(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338080 EXPECT_EQ(ERR_IO_PENDING,
8081 request1.Request(destination, version_, privacy_mode_,
8082 DEFAULT_PRIORITY, SocketTag(),
8083 /*cert_verify_flags=*/0, url1, net_log_,
8084 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:018085 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:248086 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
bnc359ed2a2016-04-29 20:43:458087 EXPECT_TRUE(stream1.get());
8088 EXPECT_TRUE(HasActiveSession(origin1_));
8089
8090 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:458091 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338092 EXPECT_EQ(ERR_IO_PENDING,
8093 request2.Request(destination, version_, privacy_mode_,
8094 DEFAULT_PRIORITY, SocketTag(),
8095 /*cert_verify_flags=*/0, url2, net_log_,
8096 &net_error_details_, callback2.callback()));
robpercival214763f2016-07-01 23:27:018097 EXPECT_THAT(callback2.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:248098 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
bnc359ed2a2016-04-29 20:43:458099 EXPECT_TRUE(stream2.get());
8100
8101 // |request2| does not pool to the first session, because the certificate does
8102 // not match. Instead, another session is opened to the same destination, but
Ryan Hamilton8d9ee76e2018-05-29 23:52:528103 // with a different quic::QuicServerId.
rchf0b18c8a2017-05-05 19:31:578104 QuicChromiumClientSession::Handle* session1 =
8105 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
8106 QuicChromiumClientSession::Handle* session2 =
8107 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
8108 EXPECT_FALSE(session1->SharesSameSession(*session2));
bnc359ed2a2016-04-29 20:43:458109
Ryan Hamilton4f0b26e2018-06-27 23:52:328110 EXPECT_EQ(quic::QuicServerId(origin1_.host(), origin1_.port(),
8111 privacy_mode_ == PRIVACY_MODE_ENABLED),
8112 session1->server_id());
8113 EXPECT_EQ(quic::QuicServerId(origin2_.host(), origin2_.port(),
8114 privacy_mode_ == PRIVACY_MODE_ENABLED),
8115 session2->server_id());
bnc359ed2a2016-04-29 20:43:458116
8117 EXPECT_TRUE(AllDataConsumed());
8118}
8119
msramek992625ec2016-08-04 18:33:588120// This test verifies that QuicStreamFactory::ClearCachedStatesInCryptoConfig
8121// correctly transform an origin filter to a ServerIdFilter. Whether the
8122// deletion itself works correctly is tested in QuicCryptoClientConfigTest.
8123TEST_P(QuicStreamFactoryTest, ClearCachedStatesInCryptoConfig) {
8124 Initialize();
Ryan Hamilton8d9ee76e2018-05-29 23:52:528125 quic::QuicCryptoClientConfig* crypto_config =
msramek992625ec2016-08-04 18:33:588126 QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
8127
8128 struct TestCase {
8129 TestCase(const std::string& host,
8130 int port,
8131 PrivacyMode privacy_mode,
Ryan Hamilton8d9ee76e2018-05-29 23:52:528132 quic::QuicCryptoClientConfig* crypto_config)
msramek992625ec2016-08-04 18:33:588133 : server_id(host, port, privacy_mode),
8134 state(crypto_config->LookupOrCreate(server_id)) {
rch872e00e2016-12-02 02:48:188135 std::vector<string> certs(1);
msramek992625ec2016-08-04 18:33:588136 certs[0] = "cert";
8137 state->SetProof(certs, "cert_sct", "chlo_hash", "signature");
8138 state->set_source_address_token("TOKEN");
8139 state->SetProofValid();
8140
8141 EXPECT_FALSE(state->certs().empty());
8142 }
8143
Ryan Hamilton8d9ee76e2018-05-29 23:52:528144 quic::QuicServerId server_id;
8145 quic::QuicCryptoClientConfig::CachedState* state;
msramek992625ec2016-08-04 18:33:588146 } test_cases[] = {
8147 TestCase("www.google.com", 443, privacy_mode_, crypto_config),
8148 TestCase("www.example.com", 443, privacy_mode_, crypto_config),
8149 TestCase("www.example.com", 4433, privacy_mode_, crypto_config)};
8150
8151 // Clear cached states for the origin https://www.example.com:4433.
8152 GURL origin("https://www.example.com:4433");
csharrisonebeca8e2016-10-18 02:35:368153 factory_->ClearCachedStatesInCryptoConfig(base::Bind(
8154 static_cast<bool (*)(const GURL&, const GURL&)>(::operator==), origin));
msramek992625ec2016-08-04 18:33:588155 EXPECT_FALSE(test_cases[0].state->certs().empty());
8156 EXPECT_FALSE(test_cases[1].state->certs().empty());
8157 EXPECT_TRUE(test_cases[2].state->certs().empty());
8158
8159 // Clear all cached states.
8160 factory_->ClearCachedStatesInCryptoConfig(
8161 base::Callback<bool(const GURL&)>());
8162 EXPECT_TRUE(test_cases[0].state->certs().empty());
8163 EXPECT_TRUE(test_cases[1].state->certs().empty());
8164 EXPECT_TRUE(test_cases[2].state->certs().empty());
8165}
8166
Yixin Wang46a425f2017-08-10 23:02:208167// Passes connection options and client connection options to QuicStreamFactory,
Ryan Hamilton8d9ee76e2018-05-29 23:52:528168// then checks that its internal quic::QuicConfig is correct.
Yixin Wang46a425f2017-08-10 23:02:208169TEST_P(QuicStreamFactoryTest, ConfigConnectionOptions) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:528170 connection_options_.push_back(quic::kTIME);
8171 connection_options_.push_back(quic::kTBBR);
8172 connection_options_.push_back(quic::kREJ);
Yixin Wang46a425f2017-08-10 23:02:208173
Ryan Hamilton8d9ee76e2018-05-29 23:52:528174 client_connection_options_.push_back(quic::kTBBR);
8175 client_connection_options_.push_back(quic::k1RTT);
Yixin Wang46a425f2017-08-10 23:02:208176
8177 Initialize();
8178
Ryan Hamilton8d9ee76e2018-05-29 23:52:528179 const quic::QuicConfig* config =
8180 QuicStreamFactoryPeer::GetConfig(factory_.get());
Yixin Wang46a425f2017-08-10 23:02:208181 EXPECT_EQ(connection_options_, config->SendConnectionOptions());
8182 EXPECT_TRUE(config->HasClientRequestedIndependentOption(
Ryan Hamilton8d9ee76e2018-05-29 23:52:528183 quic::kTBBR, quic::Perspective::IS_CLIENT));
Yixin Wang46a425f2017-08-10 23:02:208184 EXPECT_TRUE(config->HasClientRequestedIndependentOption(
Ryan Hamilton8d9ee76e2018-05-29 23:52:528185 quic::k1RTT, quic::Perspective::IS_CLIENT));
Yixin Wang46a425f2017-08-10 23:02:208186}
8187
Yixin Wang247ea642017-11-15 01:15:508188// Verifies that the host resolver uses the request priority passed to
8189// QuicStreamRequest::Request().
8190TEST_P(QuicStreamFactoryTest, HostResolverUsesRequestPriority) {
8191 Initialize();
8192 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8193 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8194
8195 MockQuicData socket_data;
8196 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:438197 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:178198 socket_data.AddSocketDataToFactory(socket_factory_.get());
Yixin Wang247ea642017-11-15 01:15:508199
8200 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338201 EXPECT_EQ(ERR_IO_PENDING,
8202 request.Request(host_port_pair_, version_, privacy_mode_,
8203 MAXIMUM_PRIORITY, SocketTag(),
8204 /*cert_verify_flags=*/0, url_, net_log_,
8205 &net_error_details_, callback_.callback()));
Yixin Wang247ea642017-11-15 01:15:508206
8207 EXPECT_THAT(callback_.WaitForResult(), IsOk());
8208 std::unique_ptr<HttpStream> stream = CreateStream(&request);
8209 EXPECT_TRUE(stream.get());
8210
8211 EXPECT_EQ(MAXIMUM_PRIORITY, host_resolver_.last_request_priority());
8212
8213 EXPECT_TRUE(socket_data.AllReadDataConsumed());
8214 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
8215}
8216
Yixin Wang469da562017-11-15 21:34:588217// Passes |max_time_before_crypto_handshake_seconds| and
8218// |max_idle_time_before_crypto_handshake_seconds| to QuicStreamFactory, then
Ryan Hamilton8d9ee76e2018-05-29 23:52:528219// checks that its internal quic::QuicConfig is correct.
Yixin Wang469da562017-11-15 21:34:588220TEST_P(QuicStreamFactoryTest, ConfigMaxTimeBeforeCryptoHandshake) {
8221 max_time_before_crypto_handshake_seconds_ = 11;
8222 max_idle_time_before_crypto_handshake_seconds_ = 13;
8223
8224 Initialize();
8225
Ryan Hamilton8d9ee76e2018-05-29 23:52:528226 const quic::QuicConfig* config =
8227 QuicStreamFactoryPeer::GetConfig(factory_.get());
8228 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(11),
Yixin Wang469da562017-11-15 21:34:588229 config->max_time_before_crypto_handshake());
Ryan Hamilton8d9ee76e2018-05-29 23:52:528230 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(13),
Yixin Wang469da562017-11-15 21:34:588231 config->max_idle_time_before_crypto_handshake());
8232}
8233
Yixin Wang7c5d11a82017-12-21 02:40:008234// Verify ResultAfterHostResolutionCallback behavior when host resolution
8235// succeeds asynchronously, then crypto handshake fails synchronously.
8236TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackAsyncSync) {
8237 Initialize();
8238 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8239 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8240
8241 host_resolver_.set_ondemand_mode(true);
8242
8243 MockQuicData socket_data;
8244 socket_data.AddRead(SYNCHRONOUS, ERR_FAILED);
8245 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
8246 socket_data.AddSocketDataToFactory(socket_factory_.get());
8247
8248 QuicStreamRequest request(factory_.get());
8249 EXPECT_EQ(ERR_IO_PENDING,
8250 request.Request(host_port_pair_, version_, privacy_mode_,
Paul Jensen8e3c5d32018-02-19 17:06:338251 DEFAULT_PRIORITY, SocketTag(),
Yixin Wang7c5d11a82017-12-21 02:40:008252 /*cert_verify_flags=*/0, url_, net_log_,
8253 &net_error_details_, callback_.callback()));
8254
8255 TestCompletionCallback host_resolution_callback;
8256 EXPECT_TRUE(
8257 request.WaitForHostResolution(host_resolution_callback.callback()));
8258
8259 // |host_resolver_| has not finished host resolution at this point, so
8260 // |host_resolution_callback| should not have a result.
8261 base::RunLoop().RunUntilIdle();
8262 EXPECT_FALSE(host_resolution_callback.have_result());
8263
8264 // Allow |host_resolver_| to finish host resolution.
8265 // Since the request fails immediately after host resolution (getting
8266 // ERR_FAILED from socket reads/writes), |host_resolution_callback| should be
8267 // called with ERR_QUIC_PROTOCOL_ERROR since that's the next result in
8268 // forming the connection.
8269 host_resolver_.ResolveAllPending();
8270 base::RunLoop().RunUntilIdle();
8271 EXPECT_TRUE(host_resolution_callback.have_result());
8272 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, host_resolution_callback.WaitForResult());
8273
8274 // Calling WaitForHostResolution() a second time should return
8275 // false since host resolution has finished already.
8276 EXPECT_FALSE(
8277 request.WaitForHostResolution(host_resolution_callback.callback()));
8278
8279 EXPECT_TRUE(callback_.have_result());
8280 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
8281}
8282
8283// Verify ResultAfterHostResolutionCallback behavior when host resolution
8284// succeeds asynchronously, then crypto handshake fails asynchronously.
8285TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackAsyncAsync) {
8286 Initialize();
8287 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8288 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8289
8290 host_resolver_.set_ondemand_mode(true);
8291 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:278292 MockCryptoClientStream::ZERO_RTT);
Yixin Wang7c5d11a82017-12-21 02:40:008293 factory_->set_require_confirmation(true);
8294
8295 MockQuicData socket_data;
8296 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
8297 socket_data.AddRead(ASYNC, ERR_FAILED);
8298 socket_data.AddWrite(ASYNC, ERR_FAILED);
8299 socket_data.AddSocketDataToFactory(socket_factory_.get());
8300
8301 QuicStreamRequest request(factory_.get());
8302 EXPECT_EQ(ERR_IO_PENDING,
8303 request.Request(host_port_pair_, version_, privacy_mode_,
Paul Jensen8e3c5d32018-02-19 17:06:338304 DEFAULT_PRIORITY, SocketTag(),
Yixin Wang7c5d11a82017-12-21 02:40:008305 /*cert_verify_flags=*/0, url_, net_log_,
8306 &net_error_details_, callback_.callback()));
8307
8308 TestCompletionCallback host_resolution_callback;
8309 EXPECT_TRUE(
8310 request.WaitForHostResolution(host_resolution_callback.callback()));
8311
8312 // |host_resolver_| has not finished host resolution at this point, so
8313 // |host_resolution_callback| should not have a result.
8314 base::RunLoop().RunUntilIdle();
8315 EXPECT_FALSE(host_resolution_callback.have_result());
8316
8317 // Allow |host_resolver_| to finish host resolution. Since crypto handshake
8318 // will hang after host resolution, |host_resolution_callback| should run with
8319 // ERR_IO_PENDING since that's the next result in forming the connection.
8320 host_resolver_.ResolveAllPending();
8321 base::RunLoop().RunUntilIdle();
8322 EXPECT_TRUE(host_resolution_callback.have_result());
8323 EXPECT_EQ(ERR_IO_PENDING, host_resolution_callback.WaitForResult());
8324
8325 // Calling WaitForHostResolution() a second time should return
8326 // false since host resolution has finished already.
8327 EXPECT_FALSE(
8328 request.WaitForHostResolution(host_resolution_callback.callback()));
8329
8330 EXPECT_FALSE(callback_.have_result());
8331 socket_data.GetSequencedSocketData()->Resume();
8332 base::RunLoop().RunUntilIdle();
8333 EXPECT_TRUE(callback_.have_result());
8334 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
8335}
8336
8337// Verify ResultAfterHostResolutionCallback behavior when host resolution
8338// succeeds synchronously, then crypto handshake fails synchronously.
8339TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackSyncSync) {
8340 Initialize();
8341 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8342 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8343
8344 host_resolver_.set_synchronous_mode(true);
8345
8346 MockQuicData socket_data;
8347 socket_data.AddRead(SYNCHRONOUS, ERR_FAILED);
8348 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
8349 socket_data.AddSocketDataToFactory(socket_factory_.get());
8350
8351 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338352 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR,
8353 request.Request(host_port_pair_, version_, privacy_mode_,
8354 DEFAULT_PRIORITY, SocketTag(),
8355 /*cert_verify_flags=*/0, url_, net_log_,
8356 &net_error_details_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:008357
8358 // WaitForHostResolution() should return false since host
8359 // resolution has finished already.
8360 TestCompletionCallback host_resolution_callback;
8361 EXPECT_FALSE(
8362 request.WaitForHostResolution(host_resolution_callback.callback()));
8363 base::RunLoop().RunUntilIdle();
8364 EXPECT_FALSE(host_resolution_callback.have_result());
8365 EXPECT_FALSE(callback_.have_result());
8366}
8367
8368// Verify ResultAfterHostResolutionCallback behavior when host resolution
8369// succeeds synchronously, then crypto handshake fails asynchronously.
8370TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackSyncAsync) {
8371 Initialize();
8372 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8373 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8374
8375 // Host resolution will succeed synchronously, but Request() as a whole
8376 // will fail asynchronously.
8377 host_resolver_.set_synchronous_mode(true);
8378 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:278379 MockCryptoClientStream::ZERO_RTT);
Yixin Wang7c5d11a82017-12-21 02:40:008380 factory_->set_require_confirmation(true);
8381
8382 MockQuicData socket_data;
8383 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
8384 socket_data.AddRead(ASYNC, ERR_FAILED);
8385 socket_data.AddWrite(ASYNC, ERR_FAILED);
8386 socket_data.AddSocketDataToFactory(socket_factory_.get());
8387
8388 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338389 EXPECT_EQ(ERR_IO_PENDING,
8390 request.Request(host_port_pair_, version_, privacy_mode_,
8391 DEFAULT_PRIORITY, SocketTag(),
8392 /*cert_verify_flags=*/0, url_, net_log_,
8393 &net_error_details_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:008394
8395 // WaitForHostResolution() should return false since host
8396 // resolution has finished already.
8397 TestCompletionCallback host_resolution_callback;
8398 EXPECT_FALSE(
8399 request.WaitForHostResolution(host_resolution_callback.callback()));
8400 base::RunLoop().RunUntilIdle();
8401 EXPECT_FALSE(host_resolution_callback.have_result());
8402
8403 EXPECT_FALSE(callback_.have_result());
8404 socket_data.GetSequencedSocketData()->Resume();
8405 base::RunLoop().RunUntilIdle();
8406 EXPECT_TRUE(callback_.have_result());
8407 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
8408}
8409
8410// Verify ResultAfterHostResolutionCallback behavior when host resolution fails
8411// synchronously.
8412TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackFailSync) {
8413 Initialize();
8414 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8415 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8416
8417 // Host resolution will fail synchronously.
8418 host_resolver_.rules()->AddSimulatedFailure(host_port_pair_.host());
8419 host_resolver_.set_synchronous_mode(true);
8420
8421 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338422 EXPECT_EQ(ERR_NAME_NOT_RESOLVED,
8423 request.Request(host_port_pair_, version_, privacy_mode_,
8424 DEFAULT_PRIORITY, SocketTag(),
8425 /*cert_verify_flags=*/0, url_, net_log_,
8426 &net_error_details_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:008427
8428 // WaitForHostResolution() should return false since host
8429 // resolution has failed already.
8430 TestCompletionCallback host_resolution_callback;
8431 EXPECT_FALSE(
8432 request.WaitForHostResolution(host_resolution_callback.callback()));
8433 base::RunLoop().RunUntilIdle();
8434 EXPECT_FALSE(host_resolution_callback.have_result());
8435}
8436
8437// Verify ResultAfterHostResolutionCallback behavior when host resolution fails
8438// asynchronously.
8439TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackFailAsync) {
8440 Initialize();
8441 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8442 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8443
8444 host_resolver_.rules()->AddSimulatedFailure(host_port_pair_.host());
8445
8446 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338447 EXPECT_EQ(ERR_IO_PENDING,
8448 request.Request(host_port_pair_, version_, privacy_mode_,
8449 DEFAULT_PRIORITY, SocketTag(),
8450 /*cert_verify_flags=*/0, url_, net_log_,
8451 &net_error_details_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:008452
8453 TestCompletionCallback host_resolution_callback;
8454 EXPECT_TRUE(
8455 request.WaitForHostResolution(host_resolution_callback.callback()));
8456
8457 // Allow |host_resolver_| to fail host resolution. |host_resolution_callback|
8458 // Should run with ERR_NAME_NOT_RESOLVED since that's the error host
8459 // resolution failed with.
8460 base::RunLoop().RunUntilIdle();
8461 EXPECT_TRUE(host_resolution_callback.have_result());
8462 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, host_resolution_callback.WaitForResult());
8463
8464 EXPECT_TRUE(callback_.have_result());
8465 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, callback_.WaitForResult());
8466}
8467
Paul Jensen8e3c5d32018-02-19 17:06:338468// Test that QuicStreamRequests with similar and different tags results in
8469// reused and unique QUIC streams using appropriately tagged sockets.
8470TEST_P(QuicStreamFactoryTest, Tag) {
8471 MockTaggingClientSocketFactory* socket_factory =
8472 new MockTaggingClientSocketFactory();
8473 socket_factory_.reset(socket_factory);
8474 Initialize();
8475 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8476 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8477
8478 // Prepare to establish two QUIC sessions.
8479 MockQuicData socket_data;
8480 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:438481 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Paul Jensen8e3c5d32018-02-19 17:06:338482 socket_data.AddSocketDataToFactory(socket_factory_.get());
8483 MockQuicData socket_data2;
8484 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:438485 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Paul Jensen8e3c5d32018-02-19 17:06:338486 socket_data2.AddSocketDataToFactory(socket_factory_.get());
8487
8488#if defined(OS_ANDROID)
8489 SocketTag tag1(SocketTag::UNSET_UID, 0x12345678);
8490 SocketTag tag2(getuid(), 0x87654321);
8491#else
8492 // On non-Android platforms we can only use the default constructor.
8493 SocketTag tag1, tag2;
8494#endif
8495
8496 // Request a stream with |tag1|.
8497 QuicStreamRequest request1(factory_.get());
8498 int rv =
8499 request1.Request(host_port_pair_, version_, privacy_mode_,
8500 DEFAULT_PRIORITY, tag1, /*cert_verify_flags=*/0, url_,
8501 net_log_, &net_error_details_, callback_.callback());
8502 EXPECT_THAT(callback_.GetResult(rv), IsOk());
8503 EXPECT_EQ(socket_factory->GetLastProducedUDPSocket()->tag(), tag1);
8504 EXPECT_TRUE(socket_factory->GetLastProducedUDPSocket()
8505 ->tagged_before_data_transferred());
8506 std::unique_ptr<QuicChromiumClientSession::Handle> stream1 =
8507 request1.ReleaseSessionHandle();
8508 EXPECT_TRUE(stream1);
8509 EXPECT_TRUE(stream1->IsConnected());
8510
8511 // Request a stream with |tag1| and verify underlying session is reused.
8512 QuicStreamRequest request2(factory_.get());
8513 rv = request2.Request(host_port_pair_, version_, privacy_mode_,
8514 DEFAULT_PRIORITY, tag1,
8515 /*cert_verify_flags=*/0, url_, net_log_,
8516 &net_error_details_, callback_.callback());
8517 EXPECT_THAT(callback_.GetResult(rv), IsOk());
8518 std::unique_ptr<QuicChromiumClientSession::Handle> stream2 =
8519 request2.ReleaseSessionHandle();
8520 EXPECT_TRUE(stream2);
8521 EXPECT_TRUE(stream2->IsConnected());
8522 EXPECT_TRUE(stream2->SharesSameSession(*stream1));
8523
8524 // Request a stream with |tag2| and verify a new session is created.
8525 QuicStreamRequest request3(factory_.get());
8526 rv = request3.Request(host_port_pair_, version_, privacy_mode_,
8527 DEFAULT_PRIORITY, tag2,
8528 /*cert_verify_flags=*/0, url_, net_log_,
8529 &net_error_details_, callback_.callback());
8530 EXPECT_THAT(callback_.GetResult(rv), IsOk());
8531 EXPECT_EQ(socket_factory->GetLastProducedUDPSocket()->tag(), tag2);
8532 EXPECT_TRUE(socket_factory->GetLastProducedUDPSocket()
8533 ->tagged_before_data_transferred());
8534 std::unique_ptr<QuicChromiumClientSession::Handle> stream3 =
8535 request3.ReleaseSessionHandle();
8536 EXPECT_TRUE(stream3);
8537 EXPECT_TRUE(stream3->IsConnected());
8538#if defined(OS_ANDROID)
8539 EXPECT_FALSE(stream3->SharesSameSession(*stream1));
8540#else
8541 // Same tag should reuse session.
8542 EXPECT_TRUE(stream3->SharesSameSession(*stream1));
8543#endif
8544}
8545
[email protected]e13201d82012-12-12 05:00:328546} // namespace test
[email protected]e13201d82012-12-12 05:00:328547} // namespace net