blob: fe535e8193c21d8c99152d0d506dd3124ab87c2b [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 Shi8de43832018-08-15 23:40:00818 void TestNewConnectionOnAlternateNetworkBeforeHandshake(
819 quic::QuicErrorCode error);
jri9f303712016-09-13 01:10:22820
Jana Iyengarf6b13d82017-09-04 02:09:10821 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
[email protected]e13201d82012-12-12 05:00:32822 MockHostResolver host_resolver_;
Ryan Sleevib8449e02018-07-15 04:31:07823 std::unique_ptr<SSLConfigService> ssl_config_service_;
Zhongyi Shi5f587cc2017-11-21 23:24:17824 std::unique_ptr<MockClientSocketFactory> socket_factory_;
[email protected]e8ff26842013-03-22 21:02:05825 MockCryptoClientStreamFactory crypto_client_stream_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52826 quic::test::MockRandom random_generator_;
827 quic::MockClock clock_;
rtenneti38f5cd52014-10-28 20:28:28828 scoped_refptr<TestTaskRunner> runner_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52829 const quic::QuicTransportVersion version_;
Yixin Wang079ad542018-01-11 04:06:05830 const bool client_headers_include_h2_stream_dependency_;
alyssar2adf3ac2016-05-03 17:12:58831 QuicTestPacketMaker client_maker_;
832 QuicTestPacketMaker server_maker_;
rtenneticcab42b2015-10-09 06:38:16833 HttpServerPropertiesImpl http_server_properties_;
danakjad1777e2016-04-16 00:56:42834 std::unique_ptr<CertVerifier> cert_verifier_;
835 std::unique_ptr<ChannelIDService> channel_id_service_;
[email protected]080b77932014-08-04 01:22:46836 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42837 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:23838 DefaultCTPolicyEnforcer ct_policy_enforcer_;
danakjad1777e2016-04-16 00:56:42839 std::unique_ptr<ScopedMockNetworkChangeNotifier>
jri7e636642016-01-14 06:57:08840 scoped_mock_network_change_notifier_;
danakjad1777e2016-04-16 00:56:42841 std::unique_ptr<QuicStreamFactory> factory_;
[email protected]bf4ea2f2014-03-10 22:57:53842 HostPortPair host_port_pair_;
ckrasic3865ee0f2016-02-29 22:04:56843 GURL url_;
844 GURL url2_;
845 GURL url3_;
846 GURL url4_;
847
[email protected]9dd3ff0f2014-03-26 09:51:28848 PrivacyMode privacy_mode_;
tfarina42834112016-09-22 13:38:20849 NetLogWithSource net_log_;
[email protected]e13201d82012-12-12 05:00:32850 TestCompletionCallback callback_;
Ryan Hamilton75f197262017-08-17 14:00:07851 NetErrorDetails net_error_details_;
jri7046038f2015-10-22 00:29:26852
853 // Variables to configure QuicStreamFactory.
rch431dd4452017-04-19 15:22:35854 bool store_server_configs_in_properties_;
Jana Iyengar903dec22017-11-28 00:44:23855 bool close_sessions_on_ip_change_;
Zhongyi Shi63574b72018-06-01 20:22:25856 bool goaway_sessions_on_ip_change_;
rtenneti41c09992015-11-30 18:24:01857 int idle_connection_timeout_seconds_;
zhongyidd1439f62016-09-02 02:02:26858 int reduced_ping_timeout_seconds_;
Yixin Wang469da562017-11-15 21:34:58859 int max_time_before_crypto_handshake_seconds_;
860 int max_idle_time_before_crypto_handshake_seconds_;
Zhongyi Shif4683a32017-12-01 00:03:28861 bool migrate_sessions_on_network_change_v2_;
862 bool migrate_sessions_early_v2_;
Zhongyi Shi8de43832018-08-15 23:40:00863 bool retry_on_alternate_network_before_handshake_;
Renjiea5722ccf2018-08-10 00:18:49864 bool go_away_on_path_degrading_;
jri217455a12016-07-13 20:15:09865 bool allow_server_migration_;
rtennetid073dd22016-08-04 01:58:33866 bool race_cert_verification_;
rchd6163f32017-01-30 23:50:38867 bool estimate_initial_rtt_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52868 quic::QuicTagVector connection_options_;
869 quic::QuicTagVector client_connection_options_;
[email protected]e13201d82012-12-12 05:00:32870};
871
bnc359ed2a2016-04-29 20:43:45872class QuicStreamFactoryTest : public QuicStreamFactoryTestBase,
873 public ::testing::TestWithParam<TestParams> {
874 protected:
Yixin Wang079ad542018-01-11 04:06:05875 QuicStreamFactoryTest()
876 : QuicStreamFactoryTestBase(
877 GetParam().version,
878 GetParam().client_headers_include_h2_stream_dependency) {}
bnc359ed2a2016-04-29 20:43:45879};
880
Bence Békyce380cb2018-04-26 23:39:55881INSTANTIATE_TEST_CASE_P(VersionIncludeStreamDependencySequence,
rtenneti14abd312015-02-06 21:56:01882 QuicStreamFactoryTest,
883 ::testing::ValuesIn(GetTestParams()));
[email protected]1e960032013-12-20 19:00:20884
[email protected]1e960032013-12-20 19:00:20885TEST_P(QuicStreamFactoryTest, Create) {
jri7046038f2015-10-22 00:29:26886 Initialize();
rch6faa4d42016-01-05 20:48:43887 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
888 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:26889
rcha00569732016-08-27 11:09:36890 MockQuicData socket_data;
891 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:43892 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:17893 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]e13201d82012-12-12 05:00:32894
zhongyi98d6a9262017-05-19 02:47:45895 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:33896 EXPECT_EQ(ERR_IO_PENDING,
897 request.Request(host_port_pair_, version_, privacy_mode_,
898 DEFAULT_PRIORITY, SocketTag(),
899 /*cert_verify_flags=*/0, url_, net_log_,
900 &net_error_details_, callback_.callback()));
[email protected]e13201d82012-12-12 05:00:32901
robpercival214763f2016-07-01 23:27:01902 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:24903 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0edce6a2013-05-08 18:02:40904 EXPECT_TRUE(stream.get());
[email protected]e13201d82012-12-12 05:00:32905
Yixin Wang247ea642017-11-15 01:15:50906 EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_.last_request_priority());
907
zhongyi98d6a9262017-05-19 02:47:45908 QuicStreamRequest request2(factory_.get());
zhongyia00ca012017-07-06 23:36:39909 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_, privacy_mode_,
Paul Jensen8e3c5d32018-02-19 17:06:33910 DEFAULT_PRIORITY, SocketTag(),
911 /*cert_verify_flags=*/0, url_, net_log_,
912 &net_error_details_, callback_.callback()));
rch68a80eb2017-04-25 05:24:24913 // Will reset stream 3.
Yixin Wang7891a39d2017-11-08 20:59:24914 stream = CreateStream(&request2);
rch68a80eb2017-04-25 05:24:24915
916 EXPECT_TRUE(stream.get());
917
918 // TODO(rtenneti): We should probably have a tests that HTTP and HTTPS result
919 // in streams on different sessions.
zhongyi98d6a9262017-05-19 02:47:45920 QuicStreamRequest request3(factory_.get());
zhongyia00ca012017-07-06 23:36:39921 EXPECT_EQ(OK, request3.Request(host_port_pair_, version_, privacy_mode_,
Paul Jensen8e3c5d32018-02-19 17:06:33922 DEFAULT_PRIORITY, SocketTag(),
923 /*cert_verify_flags=*/0, url_, net_log_,
924 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:24925 stream = CreateStream(&request3); // Will reset stream 5.
Ryan Hamiltona12722b2017-08-12 02:23:20926 stream.reset(); // Will reset stream 7.
[email protected]e13201d82012-12-12 05:00:32927
rch37de576c2015-05-17 20:28:17928 EXPECT_TRUE(socket_data.AllReadDataConsumed());
929 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]e13201d82012-12-12 05:00:32930}
931
[email protected]8bd2b812014-03-26 04:01:17932TEST_P(QuicStreamFactoryTest, CreateZeroRtt) {
jri7046038f2015-10-22 00:29:26933 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:20934 factory_->set_require_confirmation(false);
rch6faa4d42016-01-05 20:48:43935 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
936 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:26937
rcha00569732016-08-27 11:09:36938 MockQuicData socket_data;
939 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:17940 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]8bd2b812014-03-26 04:01:17941
942 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:27943 MockCryptoClientStream::ZERO_RTT);
[email protected]8bd2b812014-03-26 04:01:17944 host_resolver_.set_synchronous_mode(true);
945 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
946 "192.168.0.1", "");
947
zhongyi98d6a9262017-05-19 02:47:45948 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:33949 EXPECT_EQ(OK, request.Request(host_port_pair_, version_, privacy_mode_,
950 DEFAULT_PRIORITY, SocketTag(),
951 /*cert_verify_flags=*/0, url_, net_log_,
952 &net_error_details_, callback_.callback()));
[email protected]8bd2b812014-03-26 04:01:17953
Yixin Wang7891a39d2017-11-08 20:59:24954 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]8bd2b812014-03-26 04:01:17955 EXPECT_TRUE(stream.get());
rch37de576c2015-05-17 20:28:17956 EXPECT_TRUE(socket_data.AllReadDataConsumed());
957 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]8bd2b812014-03-26 04:01:17958}
959
rchd6163f32017-01-30 23:50:38960TEST_P(QuicStreamFactoryTest, DefaultInitialRtt) {
961 Initialize();
962 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
963 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
964
965 MockQuicData socket_data;
966 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:43967 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:17968 socket_data.AddSocketDataToFactory(socket_factory_.get());
rchd6163f32017-01-30 23:50:38969
zhongyi98d6a9262017-05-19 02:47:45970 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:33971 EXPECT_EQ(ERR_IO_PENDING,
972 request.Request(host_port_pair_, version_, privacy_mode_,
973 DEFAULT_PRIORITY, SocketTag(),
974 /*cert_verify_flags=*/0, url_, net_log_,
975 &net_error_details_, callback_.callback()));
rchd6163f32017-01-30 23:50:38976
977 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:24978 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rchd6163f32017-01-30 23:50:38979 EXPECT_TRUE(stream.get());
980
981 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Ryan Hamiltona12722b2017-08-12 02:23:20982 EXPECT_TRUE(session->require_confirmation());
rchd6163f32017-01-30 23:50:38983 EXPECT_EQ(100000u, session->connection()->GetStats().srtt_us);
984 ASSERT_FALSE(session->config()->HasInitialRoundTripTimeUsToSend());
985}
986
Helen Li0e823912017-09-25 19:48:30987TEST_P(QuicStreamFactoryTest, FactoryDestroyedWhenJobPending) {
988 Initialize();
989 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
990 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
991
992 MockQuicData socket_data;
993 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:43994 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:17995 socket_data.AddSocketDataToFactory(socket_factory_.get());
Helen Li0e823912017-09-25 19:48:30996
997 auto request = std::make_unique<QuicStreamRequest>(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:33998 EXPECT_EQ(ERR_IO_PENDING,
999 request->Request(host_port_pair_, version_, privacy_mode_,
1000 DEFAULT_PRIORITY, SocketTag(),
1001 /*cert_verify_flags=*/0, url_, net_log_,
1002 &net_error_details_, callback_.callback()));
Helen Li0e823912017-09-25 19:48:301003 request.reset();
1004 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
1005 // Tearing down a QuicStreamFactory with a pending Job should not cause any
1006 // crash. crbug.com/768343.
1007 factory_.reset();
1008}
1009
Ryan Hamiltona12722b2017-08-12 02:23:201010TEST_P(QuicStreamFactoryTest, RequireConfirmation) {
1011 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271012 MockCryptoClientStream::ZERO_RTT);
Ryan Hamiltona12722b2017-08-12 02:23:201013 host_resolver_.set_synchronous_mode(true);
1014 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
1015 "192.168.0.1", "");
1016 Initialize();
1017 factory_->set_require_confirmation(true);
1018 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1019 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1020
1021 MockQuicData socket_data;
1022 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431023 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171024 socket_data.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamiltona12722b2017-08-12 02:23:201025
1026 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331027 EXPECT_EQ(ERR_IO_PENDING,
1028 request.Request(host_port_pair_, version_, privacy_mode_,
1029 DEFAULT_PRIORITY, SocketTag(),
1030 /*cert_verify_flags=*/0, url_, net_log_,
1031 &net_error_details_, callback_.callback()));
Ryan Hamiltona12722b2017-08-12 02:23:201032
Ryan Hamilton8e32a2b2017-08-28 20:06:521033 IPAddress last_address;
1034 EXPECT_FALSE(http_server_properties_.GetSupportsQuic(&last_address));
1035
Ryan Hamiltona12722b2017-08-12 02:23:201036 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521037 quic::QuicSession::HANDSHAKE_CONFIRMED);
Ryan Hamiltona12722b2017-08-12 02:23:201038
Ryan Hamilton8e32a2b2017-08-28 20:06:521039 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
1040
Ryan Hamiltona12722b2017-08-12 02:23:201041 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241042 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Ryan Hamiltona12722b2017-08-12 02:23:201043 EXPECT_TRUE(stream.get());
1044
1045 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1046 EXPECT_TRUE(session->require_confirmation());
1047}
1048
1049TEST_P(QuicStreamFactoryTest, DontRequireConfirmationFromSameIP) {
1050 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271051 MockCryptoClientStream::ZERO_RTT);
Ryan Hamiltona12722b2017-08-12 02:23:201052 host_resolver_.set_synchronous_mode(true);
1053 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
1054 "192.168.0.1", "");
1055 Initialize();
1056 factory_->set_require_confirmation(true);
1057 http_server_properties_.SetSupportsQuic(IPAddress(192, 0, 2, 33));
1058
1059 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1060 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1061
1062 MockQuicData socket_data;
1063 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431064 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171065 socket_data.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamiltona12722b2017-08-12 02:23:201066
1067 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331068 EXPECT_THAT(request.Request(host_port_pair_, version_, privacy_mode_,
1069 DEFAULT_PRIORITY, SocketTag(),
1070 /*cert_verify_flags=*/0, url_, net_log_,
1071 &net_error_details_, callback_.callback()),
1072 IsOk());
Ryan Hamiltona12722b2017-08-12 02:23:201073
Ryan Hamilton8e32a2b2017-08-28 20:06:521074 IPAddress last_address;
1075 EXPECT_FALSE(http_server_properties_.GetSupportsQuic(&last_address));
1076
Yixin Wang7891a39d2017-11-08 20:59:241077 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Ryan Hamiltona12722b2017-08-12 02:23:201078 EXPECT_TRUE(stream.get());
1079
1080 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1081 EXPECT_FALSE(session->require_confirmation());
Ryan Hamilton8e32a2b2017-08-28 20:06:521082
1083 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521084 quic::QuicSession::HANDSHAKE_CONFIRMED);
Ryan Hamilton8e32a2b2017-08-28 20:06:521085
1086 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
Ryan Hamiltona12722b2017-08-12 02:23:201087}
1088
rchd6163f32017-01-30 23:50:381089TEST_P(QuicStreamFactoryTest, CachedInitialRtt) {
1090 ServerNetworkStats stats;
1091 stats.srtt = base::TimeDelta::FromMilliseconds(10);
1092 http_server_properties_.SetServerNetworkStats(url::SchemeHostPort(url_),
1093 stats);
1094 estimate_initial_rtt_ = true;
1095
1096 Initialize();
1097 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1098 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1099
1100 MockQuicData socket_data;
1101 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431102 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171103 socket_data.AddSocketDataToFactory(socket_factory_.get());
rchd6163f32017-01-30 23:50:381104
zhongyi98d6a9262017-05-19 02:47:451105 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331106 EXPECT_EQ(ERR_IO_PENDING,
1107 request.Request(host_port_pair_, version_, privacy_mode_,
1108 DEFAULT_PRIORITY, SocketTag(),
1109 /*cert_verify_flags=*/0, url_, net_log_,
1110 &net_error_details_, callback_.callback()));
rchd6163f32017-01-30 23:50:381111
1112 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241113 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rchd6163f32017-01-30 23:50:381114 EXPECT_TRUE(stream.get());
1115
1116 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1117 EXPECT_EQ(10000u, session->connection()->GetStats().srtt_us);
1118 ASSERT_TRUE(session->config()->HasInitialRoundTripTimeUsToSend());
1119 EXPECT_EQ(10000u, session->config()->GetInitialRoundTripTimeUsToSend());
1120}
1121
1122TEST_P(QuicStreamFactoryTest, 2gInitialRtt) {
1123 ScopedMockNetworkChangeNotifier notifier;
1124 notifier.mock_network_change_notifier()->SetConnectionType(
1125 NetworkChangeNotifier::CONNECTION_2G);
1126 estimate_initial_rtt_ = true;
1127
1128 Initialize();
1129 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1130 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1131
1132 MockQuicData socket_data;
1133 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431134 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171135 socket_data.AddSocketDataToFactory(socket_factory_.get());
rchd6163f32017-01-30 23:50:381136
zhongyi98d6a9262017-05-19 02:47:451137 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331138 EXPECT_EQ(ERR_IO_PENDING,
1139 request.Request(host_port_pair_, version_, privacy_mode_,
1140 DEFAULT_PRIORITY, SocketTag(),
1141 /*cert_verify_flags=*/0, url_, net_log_,
1142 &net_error_details_, callback_.callback()));
rchd6163f32017-01-30 23:50:381143
1144 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241145 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rchd6163f32017-01-30 23:50:381146 EXPECT_TRUE(stream.get());
1147
1148 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1149 EXPECT_EQ(1200000u, session->connection()->GetStats().srtt_us);
1150 ASSERT_TRUE(session->config()->HasInitialRoundTripTimeUsToSend());
1151 EXPECT_EQ(1200000u, session->config()->GetInitialRoundTripTimeUsToSend());
1152}
1153
1154TEST_P(QuicStreamFactoryTest, 3gInitialRtt) {
1155 ScopedMockNetworkChangeNotifier notifier;
1156 notifier.mock_network_change_notifier()->SetConnectionType(
1157 NetworkChangeNotifier::CONNECTION_3G);
1158 estimate_initial_rtt_ = true;
1159
1160 Initialize();
1161 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1162 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1163
1164 MockQuicData socket_data;
1165 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431166 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171167 socket_data.AddSocketDataToFactory(socket_factory_.get());
rchd6163f32017-01-30 23:50:381168
zhongyi98d6a9262017-05-19 02:47:451169 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331170 EXPECT_EQ(ERR_IO_PENDING,
1171 request.Request(host_port_pair_, version_, privacy_mode_,
1172 DEFAULT_PRIORITY, SocketTag(),
1173 /*cert_verify_flags=*/0, url_, net_log_,
1174 &net_error_details_, callback_.callback()));
rchd6163f32017-01-30 23:50:381175
1176 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241177 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rchd6163f32017-01-30 23:50:381178 EXPECT_TRUE(stream.get());
1179
1180 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1181 EXPECT_EQ(400000u, session->connection()->GetStats().srtt_us);
1182 ASSERT_TRUE(session->config()->HasInitialRoundTripTimeUsToSend());
1183 EXPECT_EQ(400000u, session->config()->GetInitialRoundTripTimeUsToSend());
1184}
1185
rch68955482015-09-24 00:14:391186TEST_P(QuicStreamFactoryTest, GoAway) {
jri7046038f2015-10-22 00:29:261187 Initialize();
rch6faa4d42016-01-05 20:48:431188 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1189 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:261190
rcha00569732016-08-27 11:09:361191 MockQuicData socket_data;
1192 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431193 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171194 socket_data.AddSocketDataToFactory(socket_factory_.get());
rch68955482015-09-24 00:14:391195
zhongyi98d6a9262017-05-19 02:47:451196 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331197 EXPECT_EQ(ERR_IO_PENDING,
1198 request.Request(host_port_pair_, version_, privacy_mode_,
1199 DEFAULT_PRIORITY, SocketTag(),
1200 /*cert_verify_flags=*/0, url_, net_log_,
1201 &net_error_details_, callback_.callback()));
rch68955482015-09-24 00:14:391202
robpercival214763f2016-07-01 23:27:011203 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241204 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rch68955482015-09-24 00:14:391205 EXPECT_TRUE(stream.get());
1206
bnc912a04b2016-04-20 14:19:501207 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
rch68955482015-09-24 00:14:391208
Ryan Hamilton8d9ee76e2018-05-29 23:52:521209 session->OnGoAway(quic::QuicGoAwayFrame());
rch68955482015-09-24 00:14:391210
bnc912a04b2016-04-20 14:19:501211 EXPECT_FALSE(HasActiveSession(host_port_pair_));
rch68955482015-09-24 00:14:391212
1213 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1214 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1215}
1216
zhongyi6b5a3892016-03-12 04:46:201217TEST_P(QuicStreamFactoryTest, GoAwayForConnectionMigrationWithPortOnly) {
1218 Initialize();
1219 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1220 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1221
rcha00569732016-08-27 11:09:361222 MockQuicData socket_data;
1223 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431224 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171225 socket_data.AddSocketDataToFactory(socket_factory_.get());
zhongyi6b5a3892016-03-12 04:46:201226
zhongyi98d6a9262017-05-19 02:47:451227 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331228 EXPECT_EQ(ERR_IO_PENDING,
1229 request.Request(host_port_pair_, version_, privacy_mode_,
1230 DEFAULT_PRIORITY, SocketTag(),
1231 /*cert_verify_flags=*/0, url_, net_log_,
1232 &net_error_details_, callback_.callback()));
zhongyi6b5a3892016-03-12 04:46:201233
robpercival214763f2016-07-01 23:27:011234 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241235 std::unique_ptr<HttpStream> stream = CreateStream(&request);
zhongyi6b5a3892016-03-12 04:46:201236 EXPECT_TRUE(stream.get());
1237
bnc912a04b2016-04-20 14:19:501238 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
zhongyi6b5a3892016-03-12 04:46:201239
Ryan Hamilton8d9ee76e2018-05-29 23:52:521240 session->OnGoAway(quic::QuicGoAwayFrame(
1241 quic::kInvalidControlFrameId, quic::QUIC_ERROR_MIGRATING_PORT, 0,
1242 "peer connection migration due to port change only"));
zhongyi6b5a3892016-03-12 04:46:201243 NetErrorDetails details;
1244 EXPECT_FALSE(details.quic_port_migration_detected);
1245 session->PopulateNetErrorDetails(&details);
1246 EXPECT_TRUE(details.quic_port_migration_detected);
1247 details.quic_port_migration_detected = false;
1248 stream->PopulateNetErrorDetails(&details);
1249 EXPECT_TRUE(details.quic_port_migration_detected);
1250
bnc912a04b2016-04-20 14:19:501251 EXPECT_FALSE(HasActiveSession(host_port_pair_));
zhongyi6b5a3892016-03-12 04:46:201252
1253 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1254 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1255}
1256
[email protected]5db452202014-08-19 05:22:151257TEST_P(QuicStreamFactoryTest, Pooling) {
jri7046038f2015-10-22 00:29:261258 Initialize();
rch6faa4d42016-01-05 20:48:431259 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1260 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:261261
rcha00569732016-08-27 11:09:361262 MockQuicData socket_data;
1263 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431264 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171265 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]eed749f92013-12-23 18:57:381266
rch6faa4d42016-01-05 20:48:431267 HostPortPair server2(kServer2HostName, kDefaultServerPort);
[email protected]eed749f92013-12-23 18:57:381268 host_resolver_.set_synchronous_mode(true);
rch6faa4d42016-01-05 20:48:431269 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
rjshaded5ced072015-12-18 19:26:021270 "192.168.0.1", "");
rch6faa4d42016-01-05 20:48:431271 host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]eed749f92013-12-23 18:57:381272
zhongyi98d6a9262017-05-19 02:47:451273 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331274 EXPECT_EQ(OK, request.Request(host_port_pair_, version_, privacy_mode_,
1275 DEFAULT_PRIORITY, SocketTag(),
1276 /*cert_verify_flags=*/0, url_, net_log_,
1277 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241278 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]eed749f92013-12-23 18:57:381279 EXPECT_TRUE(stream.get());
1280
1281 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451282 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331283 EXPECT_EQ(OK, request2.Request(server2, version_, privacy_mode_,
1284 DEFAULT_PRIORITY, SocketTag(),
1285 /*cert_verify_flags=*/0, url2_, net_log_,
1286 &net_error_details_, callback.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241287 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]eed749f92013-12-23 18:57:381288 EXPECT_TRUE(stream2.get());
1289
bnc912a04b2016-04-20 14:19:501290 EXPECT_EQ(GetActiveSession(host_port_pair_), GetActiveSession(server2));
[email protected]eed749f92013-12-23 18:57:381291
rch37de576c2015-05-17 20:28:171292 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1293 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]eed749f92013-12-23 18:57:381294}
1295
jri94ddc3142016-08-26 01:32:431296TEST_P(QuicStreamFactoryTest, PoolingWithServerMigration) {
1297 // Set up session to migrate.
1298 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
1299 "192.168.0.1", "");
1300 IPEndPoint alt_address = IPEndPoint(IPAddress(1, 2, 3, 4), 443);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521301 quic::QuicConfig config;
fayang91ca2012016-11-22 07:42:461302 config.SetAlternateServerAddressToSend(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521303 quic::QuicSocketAddress(quic::QuicSocketAddressImpl(alt_address)));
jri94ddc3142016-08-26 01:32:431304
1305 VerifyServerMigration(config, alt_address);
1306
1307 // Close server-migrated session.
1308 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521309 session->CloseSessionOnError(0u, quic::QUIC_NO_ERROR);
jri94ddc3142016-08-26 01:32:431310
1311 // Set up server IP, socket, proof, and config for new session.
1312 HostPortPair server2(kServer2HostName, kDefaultServerPort);
1313 host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
1314
1315 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521316 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361317 client_maker_.MakeInitialSettingsPacket(1, nullptr));
bnceb9aa7112017-01-05 01:03:461318 MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(),
1319 settings_packet->length(), 1)};
fayang3bcb8b502016-12-07 21:44:371320
Ryan Sleevib8d7ea02018-05-07 20:01:011321 SequencedSocketData socket_data(reads, writes);
Zhongyi Shi5f587cc2017-11-21 23:24:171322 socket_factory_->AddSocketDataProvider(&socket_data);
jri94ddc3142016-08-26 01:32:431323
1324 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1325 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521326 quic::QuicConfig config2;
jri94ddc3142016-08-26 01:32:431327 crypto_client_stream_factory_.SetConfig(config2);
1328
1329 // Create new request to cause new session creation.
1330 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451331 QuicStreamRequest request2(factory_.get());
jri94ddc3142016-08-26 01:32:431332 EXPECT_EQ(ERR_IO_PENDING,
Yixin Wang247ea642017-11-15 01:15:501333 request2.Request(server2, version_, privacy_mode_, DEFAULT_PRIORITY,
Paul Jensen8e3c5d32018-02-19 17:06:331334 SocketTag(),
Yixin Wang7f3cdc3f2017-11-10 01:44:141335 /*cert_verify_flags=*/0, url2_, net_log_,
Ryan Hamilton75f197262017-08-17 14:00:071336 &net_error_details_, callback.callback()));
jri94ddc3142016-08-26 01:32:431337 EXPECT_EQ(OK, callback.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:241338 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
jri94ddc3142016-08-26 01:32:431339 EXPECT_TRUE(stream2.get());
1340
1341 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1342 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1343 // EXPECT_EQ(GetActiveSession(host_port_pair_), GetActiveSession(server2));
1344}
1345
[email protected]eed749f92013-12-23 18:57:381346TEST_P(QuicStreamFactoryTest, NoPoolingAfterGoAway) {
jri7046038f2015-10-22 00:29:261347 Initialize();
rch6faa4d42016-01-05 20:48:431348 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1349 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1350 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:261351
rcha00569732016-08-27 11:09:361352 MockQuicData socket_data1;
1353 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431354 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171355 socket_data1.AddSocketDataToFactory(socket_factory_.get());
rcha00569732016-08-27 11:09:361356 MockQuicData socket_data2;
1357 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431358 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171359 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]eed749f92013-12-23 18:57:381360
rch6faa4d42016-01-05 20:48:431361 HostPortPair server2(kServer2HostName, kDefaultServerPort);
[email protected]eed749f92013-12-23 18:57:381362 host_resolver_.set_synchronous_mode(true);
rch6faa4d42016-01-05 20:48:431363 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
rjshaded5ced072015-12-18 19:26:021364 "192.168.0.1", "");
rch6faa4d42016-01-05 20:48:431365 host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]eed749f92013-12-23 18:57:381366
zhongyi98d6a9262017-05-19 02:47:451367 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331368 EXPECT_EQ(OK, request.Request(host_port_pair_, version_, privacy_mode_,
1369 DEFAULT_PRIORITY, SocketTag(),
1370 /*cert_verify_flags=*/0, url_, net_log_,
1371 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241372 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]eed749f92013-12-23 18:57:381373 EXPECT_TRUE(stream.get());
1374
1375 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451376 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331377 EXPECT_EQ(OK, request2.Request(server2, version_, privacy_mode_,
1378 DEFAULT_PRIORITY, SocketTag(),
1379 /*cert_verify_flags=*/0, url2_, net_log_,
1380 &net_error_details_, callback.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241381 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]eed749f92013-12-23 18:57:381382 EXPECT_TRUE(stream2.get());
1383
bnc912a04b2016-04-20 14:19:501384 factory_->OnSessionGoingAway(GetActiveSession(host_port_pair_));
1385 EXPECT_FALSE(HasActiveSession(host_port_pair_));
1386 EXPECT_FALSE(HasActiveSession(server2));
[email protected]eed749f92013-12-23 18:57:381387
1388 TestCompletionCallback callback3;
zhongyi98d6a9262017-05-19 02:47:451389 QuicStreamRequest request3(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331390 EXPECT_EQ(OK, request3.Request(server2, version_, privacy_mode_,
1391 DEFAULT_PRIORITY, SocketTag(),
1392 /*cert_verify_flags=*/0, url2_, net_log_,
1393 &net_error_details_, callback3.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241394 std::unique_ptr<HttpStream> stream3 = CreateStream(&request3);
[email protected]eed749f92013-12-23 18:57:381395 EXPECT_TRUE(stream3.get());
1396
bnc912a04b2016-04-20 14:19:501397 EXPECT_TRUE(HasActiveSession(server2));
[email protected]eed749f92013-12-23 18:57:381398
rch37de576c2015-05-17 20:28:171399 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
1400 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
1401 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1402 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]eed749f92013-12-23 18:57:381403}
1404
[email protected]5db452202014-08-19 05:22:151405TEST_P(QuicStreamFactoryTest, HttpsPooling) {
jri7046038f2015-10-22 00:29:261406 Initialize();
rch6faa4d42016-01-05 20:48:431407
rcha00569732016-08-27 11:09:361408 MockQuicData socket_data;
1409 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431410 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171411 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]eed749f92013-12-23 18:57:381412
rch6faa4d42016-01-05 20:48:431413 HostPortPair server1(kDefaultServerHostName, 443);
1414 HostPortPair server2(kServer2HostName, 443);
[email protected]eed749f92013-12-23 18:57:381415
bncf8bf0722015-05-19 20:04:131416 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
bnc20daf9a2015-05-15 17:11:011417 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
[email protected]eed749f92013-12-23 18:57:381418
1419 host_resolver_.set_synchronous_mode(true);
[email protected]bf4ea2f2014-03-10 22:57:531420 host_resolver_.rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
1421 host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]eed749f92013-12-23 18:57:381422
zhongyi98d6a9262017-05-19 02:47:451423 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331424 EXPECT_EQ(OK, request.Request(server1, version_, privacy_mode_,
1425 DEFAULT_PRIORITY, SocketTag(),
1426 /*cert_verify_flags=*/0, url_, net_log_,
1427 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241428 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]eed749f92013-12-23 18:57:381429 EXPECT_TRUE(stream.get());
1430
1431 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451432 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331433 EXPECT_EQ(OK, request2.Request(server2, version_, privacy_mode_,
1434 DEFAULT_PRIORITY, SocketTag(),
1435 /*cert_verify_flags=*/0, url2_, net_log_,
1436 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241437 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]eed749f92013-12-23 18:57:381438 EXPECT_TRUE(stream2.get());
1439
bnc912a04b2016-04-20 14:19:501440 EXPECT_EQ(GetActiveSession(server1), GetActiveSession(server2));
[email protected]eed749f92013-12-23 18:57:381441
rch37de576c2015-05-17 20:28:171442 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1443 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]eed749f92013-12-23 18:57:381444}
1445
[email protected]5db452202014-08-19 05:22:151446TEST_P(QuicStreamFactoryTest, HttpsPoolingWithMatchingPins) {
jri7046038f2015-10-22 00:29:261447 Initialize();
rcha00569732016-08-27 11:09:361448 MockQuicData socket_data;
1449 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431450 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171451 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]5db452202014-08-19 05:22:151452
rch6faa4d42016-01-05 20:48:431453 HostPortPair server1(kDefaultServerHostName, 443);
1454 HostPortPair server2(kServer2HostName, 443);
Avi Drissman13fc8932015-12-20 04:40:461455 uint8_t primary_pin = 1;
1456 uint8_t backup_pin = 2;
rch6faa4d42016-01-05 20:48:431457 test::AddPin(&transport_security_state_, kServer2HostName, primary_pin,
[email protected]5db452202014-08-19 05:22:151458 backup_pin);
1459
bncf8bf0722015-05-19 20:04:131460 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
[email protected]5db452202014-08-19 05:22:151461 verify_details.cert_verify_result.public_key_hashes.push_back(
1462 test::GetTestHashValue(primary_pin));
bnc20daf9a2015-05-15 17:11:011463 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
[email protected]5db452202014-08-19 05:22:151464
1465 host_resolver_.set_synchronous_mode(true);
1466 host_resolver_.rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
1467 host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
1468
zhongyi98d6a9262017-05-19 02:47:451469 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331470 EXPECT_EQ(OK, request.Request(server1, version_, privacy_mode_,
1471 DEFAULT_PRIORITY, SocketTag(),
1472 /*cert_verify_flags=*/0, url_, net_log_,
1473 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241474 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]5db452202014-08-19 05:22:151475 EXPECT_TRUE(stream.get());
1476
1477 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451478 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331479 EXPECT_EQ(OK, request2.Request(server2, version_, privacy_mode_,
1480 DEFAULT_PRIORITY, SocketTag(),
1481 /*cert_verify_flags=*/0, url2_, net_log_,
1482 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241483 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]5db452202014-08-19 05:22:151484 EXPECT_TRUE(stream2.get());
1485
bnc912a04b2016-04-20 14:19:501486 EXPECT_EQ(GetActiveSession(server1), GetActiveSession(server2));
[email protected]5db452202014-08-19 05:22:151487
rch37de576c2015-05-17 20:28:171488 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1489 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]5db452202014-08-19 05:22:151490}
1491
1492TEST_P(QuicStreamFactoryTest, NoHttpsPoolingWithDifferentPins) {
jri7046038f2015-10-22 00:29:261493 Initialize();
rcha00569732016-08-27 11:09:361494
1495 MockQuicData socket_data1;
1496 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431497 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171498 socket_data1.AddSocketDataToFactory(socket_factory_.get());
rcha00569732016-08-27 11:09:361499 MockQuicData socket_data2;
1500 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431501 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171502 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]5db452202014-08-19 05:22:151503
rch6faa4d42016-01-05 20:48:431504 HostPortPair server1(kDefaultServerHostName, 443);
1505 HostPortPair server2(kServer2HostName, 443);
Avi Drissman13fc8932015-12-20 04:40:461506 uint8_t primary_pin = 1;
1507 uint8_t backup_pin = 2;
1508 uint8_t bad_pin = 3;
rch6faa4d42016-01-05 20:48:431509 test::AddPin(&transport_security_state_, kServer2HostName, primary_pin,
[email protected]5db452202014-08-19 05:22:151510 backup_pin);
1511
bncf8bf0722015-05-19 20:04:131512 ProofVerifyDetailsChromium verify_details1 = DefaultProofVerifyDetails();
bnc20daf9a2015-05-15 17:11:011513 verify_details1.cert_verify_result.public_key_hashes.push_back(
1514 test::GetTestHashValue(bad_pin));
1515 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
1516
bncf8bf0722015-05-19 20:04:131517 ProofVerifyDetailsChromium verify_details2 = DefaultProofVerifyDetails();
bnc20daf9a2015-05-15 17:11:011518 verify_details2.cert_verify_result.public_key_hashes.push_back(
1519 test::GetTestHashValue(primary_pin));
1520 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
[email protected]5db452202014-08-19 05:22:151521
1522 host_resolver_.set_synchronous_mode(true);
1523 host_resolver_.rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
1524 host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
1525
zhongyi98d6a9262017-05-19 02:47:451526 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331527 EXPECT_EQ(OK, request.Request(server1, version_, privacy_mode_,
1528 DEFAULT_PRIORITY, SocketTag(),
1529 /*cert_verify_flags=*/0, url_, net_log_,
1530 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241531 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]5db452202014-08-19 05:22:151532 EXPECT_TRUE(stream.get());
1533
1534 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451535 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331536 EXPECT_EQ(OK, request2.Request(server2, version_, privacy_mode_,
1537 DEFAULT_PRIORITY, SocketTag(),
1538 /*cert_verify_flags=*/0, url2_, net_log_,
1539 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241540 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]5db452202014-08-19 05:22:151541 EXPECT_TRUE(stream2.get());
1542
bnc912a04b2016-04-20 14:19:501543 EXPECT_NE(GetActiveSession(server1), GetActiveSession(server2));
[email protected]5db452202014-08-19 05:22:151544
rch37de576c2015-05-17 20:28:171545 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
1546 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
1547 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1548 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]5db452202014-08-19 05:22:151549}
1550
[email protected]1e960032013-12-20 19:00:201551TEST_P(QuicStreamFactoryTest, Goaway) {
jri7046038f2015-10-22 00:29:261552 Initialize();
rch6faa4d42016-01-05 20:48:431553 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1554 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1555 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1556
rcha00569732016-08-27 11:09:361557 MockQuicData socket_data;
1558 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431559 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171560 socket_data.AddSocketDataToFactory(socket_factory_.get());
rcha00569732016-08-27 11:09:361561 MockQuicData socket_data2;
1562 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431563 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171564 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]4d283b32013-10-17 12:57:271565
zhongyi98d6a9262017-05-19 02:47:451566 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331567 EXPECT_EQ(ERR_IO_PENDING,
1568 request.Request(host_port_pair_, version_, privacy_mode_,
1569 DEFAULT_PRIORITY, SocketTag(),
1570 /*cert_verify_flags=*/0, url_, net_log_,
1571 &net_error_details_, callback_.callback()));
[email protected]4d283b32013-10-17 12:57:271572
robpercival214763f2016-07-01 23:27:011573 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241574 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]4d283b32013-10-17 12:57:271575 EXPECT_TRUE(stream.get());
1576
1577 // Mark the session as going away. Ensure that while it is still alive
1578 // that it is no longer active.
bnc912a04b2016-04-20 14:19:501579 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri7046038f2015-10-22 00:29:261580 factory_->OnSessionGoingAway(session);
1581 EXPECT_EQ(true,
1582 QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
bnc912a04b2016-04-20 14:19:501583 EXPECT_FALSE(HasActiveSession(host_port_pair_));
[email protected]4d283b32013-10-17 12:57:271584
1585 // Create a new request for the same destination and verify that a
1586 // new session is created.
zhongyi98d6a9262017-05-19 02:47:451587 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331588 EXPECT_EQ(ERR_IO_PENDING,
1589 request2.Request(host_port_pair_, version_, privacy_mode_,
1590 DEFAULT_PRIORITY, SocketTag(),
1591 /*cert_verify_flags=*/0, url_, net_log_,
1592 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:011593 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241594 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]4d283b32013-10-17 12:57:271595 EXPECT_TRUE(stream2.get());
1596
bnc912a04b2016-04-20 14:19:501597 EXPECT_TRUE(HasActiveSession(host_port_pair_));
1598 EXPECT_NE(session, GetActiveSession(host_port_pair_));
jri7046038f2015-10-22 00:29:261599 EXPECT_EQ(true,
1600 QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
[email protected]4d283b32013-10-17 12:57:271601
1602 stream2.reset();
1603 stream.reset();
1604
rch37de576c2015-05-17 20:28:171605 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1606 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1607 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1608 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]4d283b32013-10-17 12:57:271609}
1610
[email protected]1e960032013-12-20 19:00:201611TEST_P(QuicStreamFactoryTest, MaxOpenStream) {
jri7046038f2015-10-22 00:29:261612 Initialize();
rch6faa4d42016-01-05 20:48:431613 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1614 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1615
Ryan Hamilton8d9ee76e2018-05-29 23:52:521616 quic::QuicStreamId stream_id = GetNthClientInitiatedStreamId(0);
rcha00569732016-08-27 11:09:361617 MockQuicData socket_data;
Zhongyi Shi32f2fd02018-04-16 18:23:431618 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
fayang3bcb8b502016-12-07 21:44:371619 socket_data.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521620 SYNCHRONOUS, client_maker_.MakeRstPacket(2, true, stream_id,
1621 quic::QUIC_STREAM_CANCELLED));
1622 socket_data.AddRead(ASYNC,
1623 server_maker_.MakeRstPacket(1, false, stream_id,
1624 quic::QUIC_STREAM_CANCELLED));
rcha00569732016-08-27 11:09:361625 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:171626 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]0b2294d32013-08-02 00:46:361627
1628 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:391629 request_info.traffic_annotation =
1630 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1631
xunjieli1d2b4272017-04-25 22:37:171632 std::vector<std::unique_ptr<HttpStream>> streams;
Ryan Hamilton9835e662018-08-02 05:36:271633 // The MockCryptoClientStream sets max_open_streams to be
Ryan Hamilton8d9ee76e2018-05-29 23:52:521634 // quic::kDefaultMaxStreamsPerConnection / 2.
1635 for (size_t i = 0; i < quic::kDefaultMaxStreamsPerConnection / 2; i++) {
zhongyi98d6a9262017-05-19 02:47:451636 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331637 int rv = request.Request(host_port_pair_, version_, privacy_mode_,
1638 DEFAULT_PRIORITY, SocketTag(),
1639 /*cert_verify_flags=*/0, url_, net_log_,
1640 &net_error_details_, callback_.callback());
[email protected]0b2294d32013-08-02 00:46:361641 if (i == 0) {
robpercival214763f2016-07-01 23:27:011642 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1643 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]0b2294d32013-08-02 00:46:361644 } else {
robpercival214763f2016-07-01 23:27:011645 EXPECT_THAT(rv, IsOk());
[email protected]0b2294d32013-08-02 00:46:361646 }
Yixin Wang7891a39d2017-11-08 20:59:241647 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0b2294d32013-08-02 00:46:361648 EXPECT_TRUE(stream);
Steven Valdezb4ff0412018-01-18 22:39:271649 EXPECT_EQ(OK,
1650 stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:391651 net_log_, CompletionOnceCallback()));
avib3635452016-10-21 18:33:531652 streams.push_back(std::move(stream));
[email protected]0b2294d32013-08-02 00:46:361653 }
1654
zhongyi98d6a9262017-05-19 02:47:451655 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331656 EXPECT_EQ(OK, request.Request(host_port_pair_, version_, privacy_mode_,
1657 DEFAULT_PRIORITY, SocketTag(),
1658 /*cert_verify_flags=*/0, url_, net_log_,
Bence Békyd8a21fc32018-06-27 18:29:581659 &net_error_details_, CompletionOnceCallback()));
Yixin Wang7891a39d2017-11-08 20:59:241660 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0b2294d32013-08-02 00:46:361661 EXPECT_TRUE(stream);
rjshaded5ced072015-12-18 19:26:021662 EXPECT_EQ(ERR_IO_PENDING,
Steven Valdezb4ff0412018-01-18 22:39:271663 stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
1664 net_log_, callback_.callback()));
[email protected]0b2294d32013-08-02 00:46:361665
1666 // Close the first stream.
1667 streams.front()->Close(false);
ckrasicea295fe2015-10-31 05:03:271668 // Trigger exchange of RSTs that in turn allow progress for the last
1669 // stream.
robpercival214763f2016-07-01 23:27:011670 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]0b2294d32013-08-02 00:46:361671
rch37de576c2015-05-17 20:28:171672 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1673 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
ckrasicea295fe2015-10-31 05:03:271674
1675 // Force close of the connection to suppress the generation of RST
1676 // packets when streams are torn down, which wouldn't be relevant to
1677 // this test anyway.
bnc912a04b2016-04-20 14:19:501678 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521679 session->connection()->CloseConnection(
1680 quic::QUIC_PUBLIC_RESET, "test",
1681 quic::ConnectionCloseBehavior::SILENT_CLOSE);
[email protected]0b2294d32013-08-02 00:46:361682}
1683
[email protected]1e960032013-12-20 19:00:201684TEST_P(QuicStreamFactoryTest, ResolutionErrorInCreate) {
jri7046038f2015-10-22 00:29:261685 Initialize();
rcha00569732016-08-27 11:09:361686 MockQuicData socket_data;
Zhongyi Shi5f587cc2017-11-21 23:24:171687 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]e13201d82012-12-12 05:00:321688
[email protected]3c772402013-12-18 21:38:111689 host_resolver_.rules()->AddSimulatedFailure(kDefaultServerHostName);
[email protected]e13201d82012-12-12 05:00:321690
zhongyi98d6a9262017-05-19 02:47:451691 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331692 EXPECT_EQ(ERR_IO_PENDING,
1693 request.Request(host_port_pair_, version_, privacy_mode_,
1694 DEFAULT_PRIORITY, SocketTag(),
1695 /*cert_verify_flags=*/0, url_, net_log_,
1696 &net_error_details_, callback_.callback()));
[email protected]e13201d82012-12-12 05:00:321697
robpercival214763f2016-07-01 23:27:011698 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
[email protected]e13201d82012-12-12 05:00:321699
rch37de576c2015-05-17 20:28:171700 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1701 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]e13201d82012-12-12 05:00:321702}
1703
[email protected]1e960032013-12-20 19:00:201704TEST_P(QuicStreamFactoryTest, ConnectErrorInCreate) {
jri7046038f2015-10-22 00:29:261705 Initialize();
rcha00569732016-08-27 11:09:361706
1707 MockQuicData socket_data;
1708 socket_data.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
Zhongyi Shi5f587cc2017-11-21 23:24:171709 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]3c772402013-12-18 21:38:111710
zhongyi98d6a9262017-05-19 02:47:451711 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331712 EXPECT_EQ(ERR_IO_PENDING,
1713 request.Request(host_port_pair_, version_, privacy_mode_,
1714 DEFAULT_PRIORITY, SocketTag(),
1715 /*cert_verify_flags=*/0, url_, net_log_,
1716 &net_error_details_, callback_.callback()));
[email protected]3c772402013-12-18 21:38:111717
robpercival214763f2016-07-01 23:27:011718 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_ADDRESS_IN_USE));
[email protected]3c772402013-12-18 21:38:111719
rch37de576c2015-05-17 20:28:171720 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1721 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]3c772402013-12-18 21:38:111722}
1723
[email protected]1e960032013-12-20 19:00:201724TEST_P(QuicStreamFactoryTest, CancelCreate) {
jri7046038f2015-10-22 00:29:261725 Initialize();
rcha00569732016-08-27 11:09:361726 MockQuicData socket_data;
1727 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431728 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171729 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]e13201d82012-12-12 05:00:321730 {
zhongyi98d6a9262017-05-19 02:47:451731 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331732 EXPECT_EQ(ERR_IO_PENDING,
1733 request.Request(host_port_pair_, version_, privacy_mode_,
1734 DEFAULT_PRIORITY, SocketTag(),
1735 /*cert_verify_flags=*/0, url_, net_log_,
1736 &net_error_details_, callback_.callback()));
[email protected]e13201d82012-12-12 05:00:321737 }
1738
mmenke651bae7f2015-12-18 21:26:451739 base::RunLoop().RunUntilIdle();
[email protected]e13201d82012-12-12 05:00:321740
zhongyi98d6a9262017-05-19 02:47:451741 QuicStreamRequest request2(factory_.get());
zhongyia00ca012017-07-06 23:36:391742 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_, privacy_mode_,
Paul Jensen8e3c5d32018-02-19 17:06:331743 DEFAULT_PRIORITY, SocketTag(),
1744 /*cert_verify_flags=*/0, url_, net_log_,
1745 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241746 std::unique_ptr<HttpStream> stream = CreateStream(&request2);
rch68a80eb2017-04-25 05:24:241747
[email protected]e13201d82012-12-12 05:00:321748 EXPECT_TRUE(stream.get());
1749 stream.reset();
1750
rch37de576c2015-05-17 20:28:171751 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1752 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]e13201d82012-12-12 05:00:321753}
1754
[email protected]1e960032013-12-20 19:00:201755TEST_P(QuicStreamFactoryTest, CloseAllSessions) {
jri7046038f2015-10-22 00:29:261756 Initialize();
rch6faa4d42016-01-05 20:48:431757 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1758 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1759 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1760
rcha00569732016-08-27 11:09:361761 MockQuicData socket_data;
1762 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431763 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Ryan Hamilton8d9ee76e2018-05-29 23:52:521764 socket_data.AddWrite(
1765 SYNCHRONOUS, ConstructClientRstPacket(2, quic::QUIC_RST_ACKNOWLEDGEMENT));
Zhongyi Shi5f587cc2017-11-21 23:24:171766 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]56dfb902013-01-03 23:17:551767
rcha00569732016-08-27 11:09:361768 MockQuicData socket_data2;
1769 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431770 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171771 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]56dfb902013-01-03 23:17:551772
zhongyi98d6a9262017-05-19 02:47:451773 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331774 EXPECT_EQ(ERR_IO_PENDING,
1775 request.Request(host_port_pair_, version_, privacy_mode_,
1776 DEFAULT_PRIORITY, SocketTag(),
1777 /*cert_verify_flags=*/0, url_, net_log_,
1778 &net_error_details_, callback_.callback()));
[email protected]56dfb902013-01-03 23:17:551779
robpercival214763f2016-07-01 23:27:011780 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241781 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0b2294d32013-08-02 00:46:361782 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:391783 request_info.traffic_annotation =
1784 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:271785 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:391786 net_log_, CompletionOnceCallback()));
[email protected]56dfb902013-01-03 23:17:551787
1788 // Close the session and verify that stream saw the error.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521789 factory_->CloseAllSessions(ERR_INTERNET_DISCONNECTED,
1790 quic::QUIC_INTERNAL_ERROR);
[email protected]56dfb902013-01-03 23:17:551791 EXPECT_EQ(ERR_INTERNET_DISCONNECTED,
1792 stream->ReadResponseHeaders(callback_.callback()));
1793
1794 // Now attempting to request a stream to the same origin should create
1795 // a new session.
1796
zhongyi98d6a9262017-05-19 02:47:451797 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331798 EXPECT_EQ(ERR_IO_PENDING,
1799 request2.Request(host_port_pair_, version_, privacy_mode_,
1800 DEFAULT_PRIORITY, SocketTag(),
1801 /*cert_verify_flags=*/0, url_, net_log_,
1802 &net_error_details_, callback_.callback()));
[email protected]56dfb902013-01-03 23:17:551803
robpercival214763f2016-07-01 23:27:011804 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241805 stream = CreateStream(&request2);
[email protected]56dfb902013-01-03 23:17:551806 stream.reset(); // Will reset stream 3.
1807
rch37de576c2015-05-17 20:28:171808 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1809 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1810 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1811 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]56dfb902013-01-03 23:17:551812}
1813
zhongyi363c91c2017-03-23 23:16:081814// Regression test for crbug.com/700617. Test a write error during the
1815// crypto handshake will not hang QuicStreamFactory::Job and should
1816// report QUIC_HANDSHAKE_FAILED to upper layers. Subsequent
1817// QuicStreamRequest should succeed without hanging.
1818TEST_P(QuicStreamFactoryTest,
1819 WriteErrorInCryptoConnectWithAsyncHostResolution) {
1820 Initialize();
1821 // Use unmocked crypto stream to do crypto connect.
1822 crypto_client_stream_factory_.set_handshake_mode(
Zhongyi Shi879659422018-08-02 17:58:251823 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
zhongyi363c91c2017-03-23 23:16:081824
1825 MockQuicData socket_data;
1826 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1827 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
1828 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:171829 socket_data.AddSocketDataToFactory(socket_factory_.get());
zhongyi363c91c2017-03-23 23:16:081830
1831 // Create request, should fail after the write of the CHLO fails.
zhongyi98d6a9262017-05-19 02:47:451832 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331833 EXPECT_EQ(ERR_IO_PENDING,
1834 request.Request(host_port_pair_, version_, privacy_mode_,
1835 DEFAULT_PRIORITY, SocketTag(),
1836 /*cert_verify_flags=*/0, url_, net_log_,
1837 &net_error_details_, callback_.callback()));
zhongyi363c91c2017-03-23 23:16:081838 EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED, callback_.WaitForResult());
1839 EXPECT_FALSE(HasActiveSession(host_port_pair_));
1840 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
1841
1842 // Verify new requests can be sent normally without hanging.
1843 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271844 MockCryptoClientStream::COLD_START);
zhongyi363c91c2017-03-23 23:16:081845 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1846 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1847 MockQuicData socket_data2;
1848 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431849 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171850 socket_data2.AddSocketDataToFactory(socket_factory_.get());
zhongyi363c91c2017-03-23 23:16:081851
zhongyi98d6a9262017-05-19 02:47:451852 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331853 EXPECT_EQ(ERR_IO_PENDING,
1854 request2.Request(host_port_pair_, version_, privacy_mode_,
1855 DEFAULT_PRIORITY, SocketTag(),
1856 /*cert_verify_flags=*/0, url_, net_log_,
1857 &net_error_details_, callback_.callback()));
zhongyi363c91c2017-03-23 23:16:081858 EXPECT_FALSE(HasActiveSession(host_port_pair_));
1859 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
1860 // Run the message loop to complete host resolution.
1861 base::RunLoop().RunUntilIdle();
1862
1863 // Complete handshake. QuicStreamFactory::Job should complete and succeed.
1864 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521865 quic::QuicSession::HANDSHAKE_CONFIRMED);
zhongyi363c91c2017-03-23 23:16:081866 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1867 EXPECT_TRUE(HasActiveSession(host_port_pair_));
1868 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
1869
1870 // Create QuicHttpStream.
Yixin Wang7891a39d2017-11-08 20:59:241871 std::unique_ptr<HttpStream> stream = CreateStream(&request2);
zhongyi363c91c2017-03-23 23:16:081872 EXPECT_TRUE(stream.get());
1873 stream.reset();
1874 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1875 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1876 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1877 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
1878}
1879
1880TEST_P(QuicStreamFactoryTest, WriteErrorInCryptoConnectWithSyncHostResolution) {
1881 Initialize();
1882 // Use unmocked crypto stream to do crypto connect.
1883 crypto_client_stream_factory_.set_handshake_mode(
Zhongyi Shi879659422018-08-02 17:58:251884 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
zhongyi363c91c2017-03-23 23:16:081885 host_resolver_.set_synchronous_mode(true);
1886 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
1887 "192.168.0.1", "");
1888
1889 MockQuicData socket_data;
1890 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1891 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
1892 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:171893 socket_data.AddSocketDataToFactory(socket_factory_.get());
zhongyi363c91c2017-03-23 23:16:081894
1895 // Create request, should fail immediately.
zhongyi98d6a9262017-05-19 02:47:451896 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331897 EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED,
1898 request.Request(host_port_pair_, version_, privacy_mode_,
1899 DEFAULT_PRIORITY, SocketTag(),
1900 /*cert_verify_flags=*/0, url_, net_log_,
1901 &net_error_details_, callback_.callback()));
zhongyi363c91c2017-03-23 23:16:081902 // Check no active session, or active jobs left for this server.
1903 EXPECT_FALSE(HasActiveSession(host_port_pair_));
1904 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
1905
1906 // Verify new requests can be sent normally without hanging.
1907 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271908 MockCryptoClientStream::COLD_START);
zhongyi363c91c2017-03-23 23:16:081909 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1910 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1911 MockQuicData socket_data2;
1912 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431913 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171914 socket_data2.AddSocketDataToFactory(socket_factory_.get());
zhongyi363c91c2017-03-23 23:16:081915
zhongyi98d6a9262017-05-19 02:47:451916 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331917 EXPECT_EQ(ERR_IO_PENDING,
1918 request2.Request(host_port_pair_, version_, privacy_mode_,
1919 DEFAULT_PRIORITY, SocketTag(),
1920 /*cert_verify_flags=*/0, url_, net_log_,
1921 &net_error_details_, callback_.callback()));
zhongyi363c91c2017-03-23 23:16:081922 EXPECT_FALSE(HasActiveSession(host_port_pair_));
1923 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
1924
1925 // Complete handshake.
1926 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521927 quic::QuicSession::HANDSHAKE_CONFIRMED);
zhongyi363c91c2017-03-23 23:16:081928 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1929 EXPECT_TRUE(HasActiveSession(host_port_pair_));
1930 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
1931
1932 // Create QuicHttpStream.
Yixin Wang7891a39d2017-11-08 20:59:241933 std::unique_ptr<HttpStream> stream = CreateStream(&request2);
zhongyi363c91c2017-03-23 23:16:081934 EXPECT_TRUE(stream.get());
1935 stream.reset();
1936 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1937 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1938 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1939 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
1940}
1941
Zhongyi Shi63574b72018-06-01 20:22:251942TEST_P(QuicStreamFactoryTest, CloseSessionsOnIPAddressChanged) {
Jana Iyengar903dec22017-11-28 00:44:231943 close_sessions_on_ip_change_ = true;
jri7046038f2015-10-22 00:29:261944 Initialize();
rch6faa4d42016-01-05 20:48:431945 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1946 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1947 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri8c44d692015-10-23 23:53:411948
rcha00569732016-08-27 11:09:361949 MockQuicData socket_data;
1950 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431951 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Ryan Hamilton8d9ee76e2018-05-29 23:52:521952 socket_data.AddWrite(
1953 SYNCHRONOUS, ConstructClientRstPacket(2, quic::QUIC_RST_ACKNOWLEDGEMENT));
Zhongyi Shi5f587cc2017-11-21 23:24:171954 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]f698a012013-05-06 20:18:591955
rcha00569732016-08-27 11:09:361956 MockQuicData socket_data2;
1957 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431958 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171959 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]f698a012013-05-06 20:18:591960
zhongyi98d6a9262017-05-19 02:47:451961 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331962 EXPECT_EQ(ERR_IO_PENDING,
1963 request.Request(host_port_pair_, version_, privacy_mode_,
1964 DEFAULT_PRIORITY, SocketTag(),
1965 /*cert_verify_flags=*/0, url_, net_log_,
1966 &net_error_details_, callback_.callback()));
[email protected]f698a012013-05-06 20:18:591967
robpercival214763f2016-07-01 23:27:011968 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241969 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0b2294d32013-08-02 00:46:361970 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:391971 request_info.traffic_annotation =
1972 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:271973 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:391974 net_log_, CompletionOnceCallback()));
[email protected]f698a012013-05-06 20:18:591975
Zhongyi Shi63574b72018-06-01 20:22:251976 // Check an active session exisits for the destination.
1977 EXPECT_TRUE(HasActiveSession(host_port_pair_));
1978 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1979 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
1980
Ryan Hamilton8e32a2b2017-08-28 20:06:521981 IPAddress last_address;
1982 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
Zhongyi Shi63574b72018-06-01 20:22:251983 // Change the IP address and verify that stream saw the error and the active
1984 // session is closed.
jri8c44d692015-10-23 23:53:411985 NotifyIPAddressChanged();
[email protected]f698a012013-05-06 20:18:591986 EXPECT_EQ(ERR_NETWORK_CHANGED,
1987 stream->ReadResponseHeaders(callback_.callback()));
jri7046038f2015-10-22 00:29:261988 EXPECT_TRUE(factory_->require_confirmation());
Ryan Hamilton8e32a2b2017-08-28 20:06:521989 EXPECT_FALSE(http_server_properties_.GetSupportsQuic(&last_address));
Zhongyi Shi63574b72018-06-01 20:22:251990 // Check no active session exists for the destination.
1991 EXPECT_FALSE(HasActiveSession(host_port_pair_));
[email protected]f698a012013-05-06 20:18:591992
1993 // Now attempting to request a stream to the same origin should create
1994 // a new session.
zhongyi98d6a9262017-05-19 02:47:451995 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331996 EXPECT_EQ(ERR_IO_PENDING,
1997 request2.Request(host_port_pair_, version_, privacy_mode_,
1998 DEFAULT_PRIORITY, SocketTag(),
1999 /*cert_verify_flags=*/0, url_, net_log_,
2000 &net_error_details_, callback_.callback()));
[email protected]f698a012013-05-06 20:18:592001
robpercival214763f2016-07-01 23:27:012002 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242003 stream = CreateStream(&request2);
[email protected]f698a012013-05-06 20:18:592004
Zhongyi Shi63574b72018-06-01 20:22:252005 // Check a new active session exisits for the destination and the old session
2006 // is no longer live.
2007 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2008 QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
2009 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
2010
2011 stream.reset(); // Will reset stream 3.
rch37de576c2015-05-17 20:28:172012 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2013 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2014 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
2015 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]f698a012013-05-06 20:18:592016}
2017
Zhongyi Shi63574b72018-06-01 20:22:252018// Test that if goaway_session_on_ip_change is set, old sessions will be marked
2019// as going away on IP address change instead of being closed. New requests will
2020// go to a new connection.
2021TEST_P(QuicStreamFactoryTest, GoAwaySessionsOnIPAddressChanged) {
2022 goaway_sessions_on_ip_change_ = true;
2023 Initialize();
2024 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2025 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2026 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2027
2028 MockQuicData quic_data1;
2029 quic::QuicStreamOffset header_stream_offset = 0;
2030 quic_data1.AddWrite(SYNCHRONOUS,
2031 ConstructInitialSettingsPacket(1, &header_stream_offset));
2032 quic_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
2033 2, GetNthClientInitiatedStreamId(0),
2034 true, true, &header_stream_offset));
2035 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
2036 quic_data1.AddRead(
2037 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
2038 false, true));
2039 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
2040 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2041
2042 MockQuicData quic_data2;
2043 quic::QuicStreamOffset header_stream_offset2 = 0;
2044 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
2045 quic_data2.AddWrite(
2046 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset2));
2047 quic_data2.AddSocketDataToFactory(socket_factory_.get());
2048
2049 // Create request and QuicHttpStream.
2050 QuicStreamRequest request(factory_.get());
2051 EXPECT_EQ(ERR_IO_PENDING,
2052 request.Request(host_port_pair_, version_, privacy_mode_,
2053 DEFAULT_PRIORITY, SocketTag(),
2054 /*cert_verify_flags=*/0, url_, net_log_,
2055 &net_error_details_, callback_.callback()));
2056 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2057 std::unique_ptr<HttpStream> stream = CreateStream(&request);
2058 EXPECT_TRUE(stream.get());
2059
2060 // Cause QUIC stream to be created.
2061 HttpRequestInfo request_info;
2062 request_info.method = "GET";
2063 request_info.url = url_;
2064 request_info.traffic_annotation =
2065 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2066 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
2067 net_log_, CompletionOnceCallback()));
2068
2069 // Ensure that session is alive and active.
2070 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
2071 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2072 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2073
2074 // Send GET request on stream.
2075 HttpResponseInfo response;
2076 HttpRequestHeaders request_headers;
2077 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
2078 callback_.callback()));
2079
2080 // Receive an IP address change notification.
2081 NotifyIPAddressChanged();
2082
2083 // The connection should still be alive, but marked as going away.
2084 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2085 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2086 EXPECT_EQ(1u, session->GetNumActiveStreams());
2087
2088 // Resume the data, response should be read from the original connection.
2089 quic_data1.Resume();
2090 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
2091 EXPECT_EQ(200, response.headers->response_code());
2092 EXPECT_EQ(0u, session->GetNumActiveStreams());
2093
2094 // Second request should be sent on a new connection.
2095 QuicStreamRequest request2(factory_.get());
2096 EXPECT_EQ(ERR_IO_PENDING,
2097 request2.Request(host_port_pair_, version_, privacy_mode_,
2098 DEFAULT_PRIORITY, SocketTag(),
2099 /*cert_verify_flags=*/0, url_, net_log_,
2100 &net_error_details_, callback_.callback()));
2101 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2102 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
2103 EXPECT_TRUE(stream2.get());
2104
2105 // Check an active session exisits for the destination.
2106 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2107 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2108 QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
2109 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
2110
2111 stream.reset();
2112 stream2.reset();
2113 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
2114 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
2115 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
2116 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
2117}
2118
Jana Iyengarba355772017-09-21 22:03:212119TEST_P(QuicStreamFactoryTest, OnIPAddressChangedWithConnectionMigration) {
Zhongyi Shi1a054612018-06-14 04:59:082120 InitializeConnectionMigrationV2Test(
Jana Iyengarba355772017-09-21 22:03:212121 {kDefaultNetworkForTests, kNewNetworkForTests});
2122 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2123 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2124 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2125
2126 MockQuicData socket_data;
2127 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432128 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Ryan Hamilton8d9ee76e2018-05-29 23:52:522129 socket_data.AddWrite(
2130 SYNCHRONOUS, ConstructClientRstPacket(2, quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:172131 socket_data.AddSocketDataToFactory(socket_factory_.get());
Jana Iyengarba355772017-09-21 22:03:212132
2133 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332134 EXPECT_EQ(ERR_IO_PENDING,
2135 request.Request(host_port_pair_, version_, privacy_mode_,
2136 DEFAULT_PRIORITY, SocketTag(),
2137 /*cert_verify_flags=*/0, url_, net_log_,
2138 &net_error_details_, callback_.callback()));
Jana Iyengarba355772017-09-21 22:03:212139
2140 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242141 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Jana Iyengarba355772017-09-21 22:03:212142 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392143 request_info.traffic_annotation =
2144 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272145 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392146 net_log_, CompletionOnceCallback()));
Jana Iyengarba355772017-09-21 22:03:212147
2148 IPAddress last_address;
2149 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
2150
2151 // Change the IP address and verify that the connection is unaffected.
2152 NotifyIPAddressChanged();
2153 EXPECT_FALSE(factory_->require_confirmation());
2154 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
2155
2156 // Attempting a new request to the same origin uses the same connection.
2157 QuicStreamRequest request2(factory_.get());
2158 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_, privacy_mode_,
Paul Jensen8e3c5d32018-02-19 17:06:332159 DEFAULT_PRIORITY, SocketTag(),
2160 /*cert_verify_flags=*/0, url_, net_log_,
2161 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:242162 stream = CreateStream(&request2);
Jana Iyengarba355772017-09-21 22:03:212163
2164 stream.reset();
2165 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2166 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2167}
2168
Zhongyi Shia0644e32018-06-21 05:19:522169TEST_P(QuicStreamFactoryTest, MigrateOnNetworkMadeDefaultWithSynchronousWrite) {
2170 TestMigrationOnNetworkMadeDefault(SYNCHRONOUS);
jri9f303712016-09-13 01:10:222171}
2172
Zhongyi Shia0644e32018-06-21 05:19:522173TEST_P(QuicStreamFactoryTest, MigrateOnNetworkMadeDefaultWithAsyncWrite) {
2174 TestMigrationOnNetworkMadeDefault(ASYNC);
jri9f303712016-09-13 01:10:222175}
2176
Zhongyi Shia0644e32018-06-21 05:19:522177// Sets up a test which attempts connection migration successfully after probing
2178// when a new network is made as default and the old default is still available.
2179// |write_mode| specifies the write mode for the last write before
2180// OnNetworkMadeDefault is delivered to session.
2181void QuicStreamFactoryTestBase::TestMigrationOnNetworkMadeDefault(
2182 IoMode write_mode) {
2183 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri7e636642016-01-14 06:57:082184 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2185 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2186 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2187
Zhongyi Shia0644e32018-06-21 05:19:522188 // Using a testing task runner so that we can control time.
2189 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
2190 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
2191
2192 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2193 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
2194
2195 MockQuicData quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522196 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shia0644e32018-06-21 05:19:522197 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
2198 quic_data1.AddWrite(SYNCHRONOUS,
2199 ConstructInitialSettingsPacket(1, &header_stream_offset));
2200 quic_data1.AddWrite(
2201 write_mode, ConstructGetRequestPacket(2, GetNthClientInitiatedStreamId(0),
2202 true, true, &header_stream_offset));
2203 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2204
2205 // Set up the second socket data provider that is used after migration.
2206 // The response to the earlier request is read on the new socket.
2207 MockQuicData quic_data2;
2208 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:252209 quic_data2.AddWrite(SYNCHRONOUS,
2210 client_maker_.MakeConnectivityProbingPacket(3, true));
Zhongyi Shia0644e32018-06-21 05:19:522211 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
2212 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:252213 quic_data2.AddRead(ASYNC,
2214 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shia0644e32018-06-21 05:19:522215 // Ping packet to send after migration is completed.
2216 quic_data2.AddWrite(ASYNC,
2217 client_maker_.MakeAckAndPingPacket(4, false, 1, 1, 1));
2218 quic_data2.AddRead(
2219 ASYNC, ConstructOkResponsePacket(2, GetNthClientInitiatedStreamId(0),
2220 false, false));
2221 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2222 quic_data2.AddWrite(SYNCHRONOUS,
2223 client_maker_.MakeAckAndRstPacket(
2224 5, false, GetNthClientInitiatedStreamId(0),
2225 quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true));
2226 quic_data2.AddSocketDataToFactory(socket_factory_.get());
jri7e636642016-01-14 06:57:082227
2228 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452229 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332230 EXPECT_EQ(ERR_IO_PENDING,
2231 request.Request(host_port_pair_, version_, privacy_mode_,
2232 DEFAULT_PRIORITY, SocketTag(),
2233 /*cert_verify_flags=*/0, url_, net_log_,
2234 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012235 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242236 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri7e636642016-01-14 06:57:082237 EXPECT_TRUE(stream.get());
2238
2239 // Cause QUIC stream to be created.
2240 HttpRequestInfo request_info;
2241 request_info.method = "GET";
bnc3d9035b32016-06-30 18:18:482242 request_info.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:392243 request_info.traffic_annotation =
2244 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272245 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392246 net_log_, CompletionOnceCallback()));
jri7e636642016-01-14 06:57:082247
2248 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502249 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri7e636642016-01-14 06:57:082250 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2251 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2252
2253 // Send GET request on stream.
2254 HttpResponseInfo response;
2255 HttpRequestHeaders request_headers;
2256 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
2257 callback_.callback()));
2258
Zhongyi Shia0644e32018-06-21 05:19:522259 // Deliver a signal that a alternate network is connected now, this should
2260 // cause the connection to start early migration on path degrading.
2261 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2262 ->SetConnectedNetworksList(
2263 {kDefaultNetworkForTests, kNewNetworkForTests});
2264 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2265 ->NotifyNetworkConnected(kNewNetworkForTests);
jri9f303712016-09-13 01:10:222266
Zhongyi Shia0644e32018-06-21 05:19:522267 // Cause the connection to report path degrading to the session.
2268 // Due to lack of alternate network, session will not mgirate connection.
2269 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
jri7e636642016-01-14 06:57:082270 scoped_mock_network_change_notifier_->mock_network_change_notifier()
jrie2661982016-08-20 08:24:342271 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri7e636642016-01-14 06:57:082272
Zhongyi Shia0644e32018-06-21 05:19:522273 // A task will be posted to migrate to the new default network.
2274 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2275 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
2276
2277 // Execute the posted task to migrate back to the default network.
2278 task_runner->RunUntilIdle();
2279 // Another task to try send a new connectivity probe is posted. And a task to
2280 // retry migrate back to default network is scheduled.
2281 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
2282 // Next connectivity probe is scheduled to be sent in 2 *
2283 // kDefaultRTTMilliSecs.
2284 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
2285 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
2286 next_task_delay);
2287
2288 // The connection should still be alive, and not marked as going away.
jri7e636642016-01-14 06:57:082289 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia0644e32018-06-21 05:19:522290 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2291 EXPECT_EQ(1u, session->GetNumActiveStreams());
2292 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
2293
2294 // Resume quic data and a connectivity probe response will be read on the new
2295 // socket, declare probing as successful. And a new task to WriteToNewSocket
2296 // will be posted to complete migration.
2297 quic_data2.Resume();
2298
2299 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2300 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri7e636642016-01-14 06:57:082301 EXPECT_EQ(1u, session->GetNumActiveStreams());
2302
Zhongyi Shia0644e32018-06-21 05:19:522303 // There should be three pending tasks, the nearest one will complete
2304 // migration to the new network.
2305 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
2306 next_task_delay = task_runner->NextPendingTaskDelay();
2307 EXPECT_EQ(base::TimeDelta(), next_task_delay);
2308 task_runner->FastForwardBy(next_task_delay);
2309
2310 // Response headers are received over the new network.
2311 EXPECT_THAT(callback_.WaitForResult(), IsOk());
jri7e636642016-01-14 06:57:082312 EXPECT_EQ(200, response.headers->response_code());
2313
Zhongyi Shia0644e32018-06-21 05:19:522314 // Now there are two pending tasks, the nearest one was to send connectivity
2315 // probe and has been cancelled due to successful migration.
2316 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
2317 next_task_delay = task_runner->NextPendingTaskDelay();
2318 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
2319 next_task_delay);
2320 task_runner->FastForwardBy(next_task_delay);
jri7e636642016-01-14 06:57:082321
Zhongyi Shia0644e32018-06-21 05:19:522322 // There's one more task to mgirate back to the default network in 0.4s, which
2323 // is also cancelled due to the success migration on the previous trial.
2324 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2325 next_task_delay = task_runner->NextPendingTaskDelay();
2326 base::TimeDelta expected_delay =
2327 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
2328 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
2329 EXPECT_EQ(expected_delay, next_task_delay);
2330 task_runner->FastForwardBy(next_task_delay);
2331 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
jri7e636642016-01-14 06:57:082332
Zhongyi Shia0644e32018-06-21 05:19:522333 // Verify that the session is still alive.
jri7e636642016-01-14 06:57:082334 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia0644e32018-06-21 05:19:522335 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri7e636642016-01-14 06:57:082336
Zhongyi Shia0644e32018-06-21 05:19:522337 stream.reset();
2338 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
2339 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
2340 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
2341 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
jri7e636642016-01-14 06:57:082342}
2343
Zhongyi Shib3bc982c2018-07-10 19:59:242344// Regression test for http://859674.
2345// This test veries that a writer will not attempt to write packets until being
2346// unblocked on both socket level and network level. In this test, a probing
2347// writer is used to send two connectivity probes to the peer: where the first
2348// one completes successfully, while a connectivity response is received before
2349// completes sending the second one. The connection migration attempt will
2350// proceed while the probing writer is blocked at the socket level, which will
2351// block the writer on the network level. Once connection migration completes
2352// successfully, the probing writer will be unblocked on the network level, it
2353// will not attempt to write new packets until the socket level is unblocked.
2354TEST_P(QuicStreamFactoryTest, MigratedToBlockedSocketAfterProbing) {
2355 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
2356 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2357 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2358 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2359
2360 // Using a testing task runner so that we can control time.
2361 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
2362 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
2363
2364 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2365 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
2366
2367 MockQuicData quic_data1;
2368 quic::QuicStreamOffset header_stream_offset = 0;
2369 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
2370 quic_data1.AddWrite(SYNCHRONOUS,
2371 ConstructInitialSettingsPacket(1, &header_stream_offset));
2372 quic_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
2373 2, GetNthClientInitiatedStreamId(0),
2374 true, true, &header_stream_offset));
2375 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2376
2377 // Set up the second socket data provider that is used after migration.
2378 // The response to the earlier request is read on the new socket.
2379 MockQuicData quic_data2;
2380 // First connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:252381 quic_data2.AddWrite(SYNCHRONOUS,
2382 client_maker_.MakeConnectivityProbingPacket(3, true));
Zhongyi Shib3bc982c2018-07-10 19:59:242383 quic_data2.AddRead(ASYNC,
2384 ERR_IO_PENDING); // Pause so that we can control time.
2385 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:252386 quic_data2.AddRead(ASYNC,
2387 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shib3bc982c2018-07-10 19:59:242388 // Second connectivity probe which will complete asynchronously.
Zhongyi Shi879659422018-08-02 17:58:252389 quic_data2.AddWrite(ASYNC,
2390 client_maker_.MakeConnectivityProbingPacket(4, true));
Zhongyi Shib3bc982c2018-07-10 19:59:242391 quic_data2.AddRead(
2392 ASYNC, ConstructOkResponsePacket(2, GetNthClientInitiatedStreamId(0),
2393 false, false));
2394 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2395 quic_data2.AddWrite(ASYNC,
2396 client_maker_.MakeAckAndPingPacket(5, false, 1, 1, 1));
2397 quic_data2.AddWrite(SYNCHRONOUS,
2398 client_maker_.MakeAckAndRstPacket(
2399 6, false, GetNthClientInitiatedStreamId(0),
2400 quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true));
2401
2402 quic_data2.AddSocketDataToFactory(socket_factory_.get());
2403
2404 // Create request and QuicHttpStream.
2405 QuicStreamRequest request(factory_.get());
2406 EXPECT_EQ(ERR_IO_PENDING,
2407 request.Request(host_port_pair_, version_, privacy_mode_,
2408 DEFAULT_PRIORITY, SocketTag(),
2409 /*cert_verify_flags=*/0, url_, net_log_,
2410 &net_error_details_, callback_.callback()));
2411 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2412 std::unique_ptr<HttpStream> stream = CreateStream(&request);
2413 EXPECT_TRUE(stream.get());
2414
2415 // Cause QUIC stream to be created.
2416 HttpRequestInfo request_info;
2417 request_info.method = "GET";
2418 request_info.url = url_;
2419 request_info.traffic_annotation =
2420 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2421 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
2422 net_log_, CompletionOnceCallback()));
2423
2424 // Ensure that session is alive and active.
2425 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
2426 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2427 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2428
2429 // Send GET request on stream.
2430 HttpResponseInfo response;
2431 HttpRequestHeaders request_headers;
2432 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
2433 callback_.callback()));
2434
2435 // Deliver a signal that a alternate network is connected now, this should
2436 // cause the connection to start early migration on path degrading.
2437 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2438 ->SetConnectedNetworksList(
2439 {kDefaultNetworkForTests, kNewNetworkForTests});
2440 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2441 ->NotifyNetworkConnected(kNewNetworkForTests);
2442
2443 // Cause the connection to report path degrading to the session.
2444 // Due to lack of alternate network, session will not mgirate connection.
2445 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
2446 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2447 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2448
2449 // A task will be posted to migrate to the new default network.
2450 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2451 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
2452
2453 // Execute the posted task to migrate back to the default network.
2454 task_runner->RunUntilIdle();
2455 // Another task to resend a new connectivity probe is posted. And a task to
2456 // retry migrate back to default network is scheduled.
2457 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
2458 // Next connectivity probe is scheduled to be sent in 2 *
2459 // kDefaultRTTMilliSecs.
2460 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
2461 base::TimeDelta expected_delay =
2462 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
2463 EXPECT_EQ(expected_delay, next_task_delay);
2464
2465 // Fast forward to send the second connectivity probe. The write will be
2466 // asynchronous and complete after the read completes.
2467 task_runner->FastForwardBy(next_task_delay);
2468
2469 // Resume quic data and a connectivity probe response will be read on the new
2470 // socket, declare probing as successful.
2471 quic_data2.Resume();
2472
2473 // The connection should still be alive, and not marked as going away.
2474 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2475 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2476 EXPECT_EQ(1u, session->GetNumActiveStreams());
2477 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
2478
2479 // There should be three pending tasks, the nearest one will complete
2480 // migration to the new network. Second task will retry migrate back to
2481 // default but cancelled, and the third task will retry send connectivity
2482 // probe but also cancelled.
2483 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
2484 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
2485 task_runner->RunUntilIdle();
2486
2487 // Response headers are received over the new network.
2488 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2489 EXPECT_EQ(200, response.headers->response_code());
2490
2491 // Run the message loop to complete the asynchronous write of ack and ping.
2492 base::RunLoop().RunUntilIdle();
2493
2494 // Now there are two pending tasks, the nearest one was to retry migrate back
2495 // to default network and has been cancelled due to successful migration.
2496 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
2497 expected_delay =
2498 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
2499 expected_delay;
2500 next_task_delay = task_runner->NextPendingTaskDelay();
2501 EXPECT_EQ(expected_delay, next_task_delay);
2502 task_runner->FastForwardBy(next_task_delay);
2503
2504 // There's one more task to retry sending connectivity probe in 0.4s and has
2505 // also been cancelled due to the successful probing.
2506 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2507 next_task_delay = task_runner->NextPendingTaskDelay();
2508 expected_delay =
2509 base::TimeDelta::FromMilliseconds(3 * 2 * kDefaultRTTMilliSecs) -
2510 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs);
2511 EXPECT_EQ(expected_delay, next_task_delay);
2512 task_runner->FastForwardBy(next_task_delay);
2513 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
2514
2515 // Verify that the session is still alive.
2516 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2517 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2518
2519 stream.reset();
2520 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
2521 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
2522 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
2523 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
2524}
2525
Zhongyi Shib1b1fa42018-06-19 23:13:472526// This test verifies that session times out connection migration attempt
2527// with signals delivered in the following order (no alternate network is
2528// available):
2529// - default network disconnected is delivered: session attempts connection
2530// migration but found not alternate network. Session waits for a new network
2531// comes up in the next kWaitTimeForNewNetworkSecs seonds.
2532// - no new network is connected, migration times out. Session is closed.
2533TEST_P(QuicStreamFactoryTest, MigrationTimeoutWithNoNewNetwork) {
2534 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri7e636642016-01-14 06:57:082535 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2536 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2537
Zhongyi Shib1b1fa42018-06-19 23:13:472538 // Using a testing task runner so that we can control time.
2539 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
2540 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
jri5b785512016-09-13 04:29:112541
rcha00569732016-08-27 11:09:362542 MockQuicData socket_data;
2543 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432544 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:172545 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri7e636642016-01-14 06:57:082546
2547 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452548 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332549 EXPECT_EQ(ERR_IO_PENDING,
2550 request.Request(host_port_pair_, version_, privacy_mode_,
2551 DEFAULT_PRIORITY, SocketTag(),
2552 /*cert_verify_flags=*/0, url_, net_log_,
2553 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012554 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242555 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri7e636642016-01-14 06:57:082556 EXPECT_TRUE(stream.get());
2557
2558 // Cause QUIC stream to be created.
2559 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392560 request_info.traffic_annotation =
2561 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272562 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392563 net_log_, CompletionOnceCallback()));
jri7e636642016-01-14 06:57:082564
2565 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502566 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri7e636642016-01-14 06:57:082567 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2568 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2569
2570 // Trigger connection migration. Since there are no networks
jri5b785512016-09-13 04:29:112571 // to migrate to, this should cause the session to wait for a new network.
jri7e636642016-01-14 06:57:082572 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2573 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
2574
jri5b785512016-09-13 04:29:112575 // The migration will not fail until the migration alarm timeout.
2576 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shib1b1fa42018-06-19 23:13:472577 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:112578 EXPECT_EQ(1u, session->GetNumActiveStreams());
2579 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
2580 EXPECT_EQ(true, session->connection()->writer()->IsWriteBlocked());
2581
Zhongyi Shib1b1fa42018-06-19 23:13:472582 // Migration will be timed out after kWaitTimeForNewNetwokSecs.
2583 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2584 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
2585 EXPECT_EQ(base::TimeDelta::FromSeconds(kWaitTimeForNewNetworkSecs),
2586 next_task_delay);
2587 task_runner->FastForwardBy(next_task_delay);
jri5b785512016-09-13 04:29:112588
2589 // The connection should now be closed. A request for response
2590 // headers should fail.
jri7e636642016-01-14 06:57:082591 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2592 EXPECT_FALSE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:112593 EXPECT_EQ(ERR_NETWORK_CHANGED, callback_.WaitForResult());
jri7e636642016-01-14 06:57:082594
2595 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2596 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2597}
2598
Zhongyi Shi21e99532018-07-17 22:23:072599// This test verifies that connectivity probes will be sent even if there is
2600// a non-migratable stream. However, when connection migrates to the
2601// successfully probed path, any non-migratable stream will be reset. And if
2602// the connection becomes idle then, close the connection.
jri9f303712016-09-13 01:10:222603TEST_P(QuicStreamFactoryTest, OnNetworkMadeDefaultNonMigratableStream) {
Zhongyi Shi5f587cc2017-11-21 23:24:172604 InitializeConnectionMigrationV2Test(
2605 {kDefaultNetworkForTests, kNewNetworkForTests});
2606 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2607 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2608
2609 MockQuicData socket_data;
2610 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432611 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:172612 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri231c2972016-03-08 19:50:112613
Zhongyi Shi21e99532018-07-17 22:23:072614 // Set up the second socket data provider that is used for probing.
2615 MockQuicData quic_data1;
2616 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:252617 quic_data1.AddWrite(SYNCHRONOUS,
2618 client_maker_.MakeConnectivityProbingPacket(2, true));
Zhongyi Shi21e99532018-07-17 22:23:072619 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
2620 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:252621 quic_data1.AddRead(ASYNC,
2622 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shi21e99532018-07-17 22:23:072623 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2624
jri231c2972016-03-08 19:50:112625 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452626 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332627 EXPECT_EQ(ERR_IO_PENDING,
2628 request.Request(host_port_pair_, version_, privacy_mode_,
2629 DEFAULT_PRIORITY, SocketTag(),
2630 /*cert_verify_flags=*/0, url_, net_log_,
2631 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012632 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242633 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri231c2972016-03-08 19:50:112634 EXPECT_TRUE(stream.get());
2635
2636 // Cause QUIC stream to be created, but marked as non-migratable.
2637 HttpRequestInfo request_info;
Zhongyi Shibb28b1f2018-07-18 02:41:262638 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Ramin Halavati683bcaa92018-02-14 08:42:392639 request_info.traffic_annotation =
2640 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272641 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392642 net_log_, CompletionOnceCallback()));
jri231c2972016-03-08 19:50:112643
2644 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502645 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri231c2972016-03-08 19:50:112646 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2647 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2648
Zhongyi Shi21e99532018-07-17 22:23:072649 // Trigger connection migration. Session will start to probe the alternative
2650 // network. Although there is a non-migratable stream, session will still be
2651 // active until probing is declared as successful.
jri231c2972016-03-08 19:50:112652 scoped_mock_network_change_notifier_->mock_network_change_notifier()
jrie2661982016-08-20 08:24:342653 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri231c2972016-03-08 19:50:112654
2655 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shi21e99532018-07-17 22:23:072656 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri231c2972016-03-08 19:50:112657 EXPECT_EQ(1u, session->GetNumActiveStreams());
2658
Zhongyi Shi21e99532018-07-17 22:23:072659 // Resume data to read a connectivity probing response, which will cause
2660 // non-migtable streams to be closed. As session becomes idle, connection will
2661 // be closed.
2662 quic_data1.Resume();
2663 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2664 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2665 EXPECT_EQ(0u, session->GetNumActiveStreams());
jri231c2972016-03-08 19:50:112666
Zhongyi Shi21e99532018-07-17 22:23:072667 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
2668 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
jri231c2972016-03-08 19:50:112669 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2670 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2671}
2672
jri9f303712016-09-13 01:10:222673TEST_P(QuicStreamFactoryTest, OnNetworkMadeDefaultConnectionMigrationDisabled) {
Zhongyi Shi5f587cc2017-11-21 23:24:172674 InitializeConnectionMigrationV2Test(
2675 {kDefaultNetworkForTests, kNewNetworkForTests});
2676 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2677 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2678
2679 MockQuicData socket_data;
2680 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432681 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
2682 socket_data.AddWrite(
2683 SYNCHRONOUS,
2684 client_maker_.MakeRstPacket(2, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:522685 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:172686 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9c541572016-03-29 17:51:482687
2688 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452689 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332690 EXPECT_EQ(ERR_IO_PENDING,
2691 request.Request(host_port_pair_, version_, privacy_mode_,
2692 DEFAULT_PRIORITY, SocketTag(),
2693 /*cert_verify_flags=*/0, url_, net_log_,
2694 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012695 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242696 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9c541572016-03-29 17:51:482697 EXPECT_TRUE(stream.get());
2698
2699 // Cause QUIC stream to be created.
2700 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392701 request_info.traffic_annotation =
2702 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272703 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392704 net_log_, CompletionOnceCallback()));
jri9c541572016-03-29 17:51:482705
2706 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502707 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri9c541572016-03-29 17:51:482708 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2709 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2710
2711 // Set session config to have connection migration disabled.
Ryan Hamilton8d9ee76e2018-05-29 23:52:522712 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
2713 session->config());
jri9c541572016-03-29 17:51:482714 EXPECT_TRUE(session->config()->DisableConnectionMigration());
2715
2716 // Trigger connection migration. Since there is a non-migratable stream,
2717 // this should cause session to continue but be marked as going away.
2718 scoped_mock_network_change_notifier_->mock_network_change_notifier()
jrie2661982016-08-20 08:24:342719 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri9c541572016-03-29 17:51:482720
2721 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2722 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2723 EXPECT_EQ(1u, session->GetNumActiveStreams());
2724
2725 stream.reset();
2726
2727 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2728 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2729}
2730
jri9f303712016-09-13 01:10:222731TEST_P(QuicStreamFactoryTest, OnNetworkDisconnectedNonMigratableStream) {
Zhongyi Shi5f587cc2017-11-21 23:24:172732 InitializeConnectionMigrationV2Test(
2733 {kDefaultNetworkForTests, kNewNetworkForTests});
2734 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2735 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2736
2737 MockQuicData socket_data;
2738 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432739 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
2740 socket_data.AddWrite(
2741 SYNCHRONOUS,
2742 client_maker_.MakeRstPacket(2, true, GetNthClientInitiatedStreamId(0),
Zhongyi Shi0439ecc72018-07-11 04:41:262743 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:172744 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri231c2972016-03-08 19:50:112745
2746 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452747 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332748 EXPECT_EQ(ERR_IO_PENDING,
2749 request.Request(host_port_pair_, version_, privacy_mode_,
2750 DEFAULT_PRIORITY, SocketTag(),
2751 /*cert_verify_flags=*/0, url_, net_log_,
2752 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012753 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242754 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri231c2972016-03-08 19:50:112755 EXPECT_TRUE(stream.get());
2756
2757 // Cause QUIC stream to be created, but marked as non-migratable.
2758 HttpRequestInfo request_info;
Zhongyi Shibb28b1f2018-07-18 02:41:262759 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Ramin Halavati683bcaa92018-02-14 08:42:392760 request_info.traffic_annotation =
2761 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272762 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392763 net_log_, CompletionOnceCallback()));
jri231c2972016-03-08 19:50:112764
2765 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502766 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri231c2972016-03-08 19:50:112767 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2768 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2769
2770 // Trigger connection migration. Since there is a non-migratable stream,
2771 // this should cause a RST_STREAM frame to be emitted with
Zhongyi Shi0439ecc72018-07-11 04:41:262772 // quic::QUIC_STREAM_CANCELLED error code, and the session will be closed.
jri231c2972016-03-08 19:50:112773 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2774 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
2775
2776 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2777 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2778
2779 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2780 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2781}
2782
jri9c541572016-03-29 17:51:482783TEST_P(QuicStreamFactoryTest,
jri9f303712016-09-13 01:10:222784 OnNetworkDisconnectedConnectionMigrationDisabled) {
Zhongyi Shi5f587cc2017-11-21 23:24:172785 InitializeConnectionMigrationV2Test(
2786 {kDefaultNetworkForTests, kNewNetworkForTests});
2787 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2788 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2789
2790 MockQuicData socket_data;
2791 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432792 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
2793 socket_data.AddWrite(
2794 SYNCHRONOUS,
2795 client_maker_.MakeRstPacket(2, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:522796 quic::QUIC_RST_ACKNOWLEDGEMENT));
Zhongyi Shi5f587cc2017-11-21 23:24:172797 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9c541572016-03-29 17:51:482798
2799 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452800 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332801 EXPECT_EQ(ERR_IO_PENDING,
2802 request.Request(host_port_pair_, version_, privacy_mode_,
2803 DEFAULT_PRIORITY, SocketTag(),
2804 /*cert_verify_flags=*/0, url_, net_log_,
2805 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012806 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242807 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9c541572016-03-29 17:51:482808 EXPECT_TRUE(stream.get());
2809
2810 // Cause QUIC stream to be created.
2811 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392812 request_info.traffic_annotation =
2813 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272814 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392815 net_log_, CompletionOnceCallback()));
jri9c541572016-03-29 17:51:482816
2817 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502818 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri9c541572016-03-29 17:51:482819 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2820 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2821
2822 // Set session config to have connection migration disabled.
Ryan Hamilton8d9ee76e2018-05-29 23:52:522823 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
2824 session->config());
jri9c541572016-03-29 17:51:482825 EXPECT_TRUE(session->config()->DisableConnectionMigration());
2826
2827 // Trigger connection migration. Since there is a non-migratable stream,
2828 // this should cause a RST_STREAM frame to be emitted with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522829 // quic::QUIC_RST_ACKNOWLEDGEMENT error code, and the session will be closed.
jri9c541572016-03-29 17:51:482830 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2831 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
2832
2833 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2834 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2835
2836 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2837 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2838}
2839
jri9f303712016-09-13 01:10:222840TEST_P(QuicStreamFactoryTest, OnNetworkMadeDefaultNoOpenStreams) {
Zhongyi Shi5f587cc2017-11-21 23:24:172841 InitializeConnectionMigrationV2Test(
2842 {kDefaultNetworkForTests, kNewNetworkForTests});
2843 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2844 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2845
2846 MockQuicData socket_data;
2847 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432848 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:172849 socket_data.AddSocketDataToFactory(socket_factory_.get());
2850
2851 // Create request and QuicHttpStream.
2852 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332853 EXPECT_EQ(ERR_IO_PENDING,
2854 request.Request(host_port_pair_, version_, privacy_mode_,
2855 DEFAULT_PRIORITY, SocketTag(),
2856 /*cert_verify_flags=*/0, url_, net_log_,
2857 &net_error_details_, callback_.callback()));
Zhongyi Shi5f587cc2017-11-21 23:24:172858 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2859 std::unique_ptr<HttpStream> stream = CreateStream(&request);
2860 EXPECT_TRUE(stream.get());
2861
2862 // Ensure that session is alive and active.
2863 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
2864 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2865 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2866
2867 // Trigger connection migration.
2868 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2869 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2870
2871 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2872 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2873
2874 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2875 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2876}
2877
jri9f303712016-09-13 01:10:222878TEST_P(QuicStreamFactoryTest, OnNetworkDisconnectedNoOpenStreams) {
Zhongyi Shi5f587cc2017-11-21 23:24:172879 InitializeConnectionMigrationV2Test(
2880 {kDefaultNetworkForTests, kNewNetworkForTests});
2881 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2882 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2883
2884 MockQuicData socket_data;
2885 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432886 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:172887 socket_data.AddSocketDataToFactory(socket_factory_.get());
2888
2889 // Create request and QuicHttpStream.
2890 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332891 EXPECT_EQ(ERR_IO_PENDING,
2892 request.Request(host_port_pair_, version_, privacy_mode_,
2893 DEFAULT_PRIORITY, SocketTag(),
2894 /*cert_verify_flags=*/0, url_, net_log_,
2895 &net_error_details_, callback_.callback()));
Zhongyi Shi5f587cc2017-11-21 23:24:172896 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2897 std::unique_ptr<HttpStream> stream = CreateStream(&request);
2898 EXPECT_TRUE(stream.get());
2899
2900 // Ensure that session is alive and active.
2901 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
2902 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2903 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2904
2905 // Trigger connection migration. Since there are no active streams,
2906 // the session will be closed.
2907 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2908 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
2909
2910 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2911 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2912
2913 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2914 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2915}
2916
Zhongyi Shi9f316b262018-06-18 22:01:162917// This test verifies session migrates to the alternate network immediately when
2918// default network disconnects with a synchronous write before migration.
2919TEST_P(QuicStreamFactoryTest, MigrateOnDefaultNetworkDisconnectedSync) {
2920 TestMigrationOnNetworkDisconnected(/*async_write_before*/ false);
2921}
2922
2923// This test verifies session migrates to the alternate network immediately when
2924// default network disconnects with an asynchronously write before migration.
2925TEST_P(QuicStreamFactoryTest, MigrateOnDefaultNetworkDisconnectedAsync) {
2926 TestMigrationOnNetworkDisconnected(/*async_write_before*/ true);
2927}
2928
2929void QuicStreamFactoryTestBase::TestMigrationOnNetworkDisconnected(
2930 bool async_write_before) {
2931 InitializeConnectionMigrationV2Test(
2932 {kDefaultNetworkForTests, kNewNetworkForTests});
2933 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2934 ->NotifyNetworkMadeDefault(kDefaultNetworkForTests);
2935 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2936 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2937 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2938
2939 // Use the test task runner.
2940 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
2941
2942 int packet_number = 1;
2943 MockQuicData socket_data;
2944 quic::QuicStreamOffset header_stream_offset = 0;
2945 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2946 socket_data.AddWrite(
2947 SYNCHRONOUS,
2948 ConstructInitialSettingsPacket(packet_number++, &header_stream_offset));
2949 socket_data.AddWrite(
2950 SYNCHRONOUS, ConstructGetRequestPacket(
2951 packet_number++, GetNthClientInitiatedStreamId(0), true,
2952 true, &header_stream_offset));
2953 if (async_write_before) {
2954 socket_data.AddWrite(ASYNC, OK);
2955 packet_number++;
2956 }
2957 socket_data.AddSocketDataToFactory(socket_factory_.get());
2958
2959 // Create request and QuicHttpStream.
2960 QuicStreamRequest request(factory_.get());
2961 EXPECT_EQ(ERR_IO_PENDING,
2962 request.Request(host_port_pair_, version_, privacy_mode_,
2963 DEFAULT_PRIORITY, SocketTag(),
2964 /*cert_verify_flags=*/0, url_, net_log_,
2965 &net_error_details_, callback_.callback()));
2966 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2967 std::unique_ptr<HttpStream> stream = CreateStream(&request);
2968 EXPECT_TRUE(stream.get());
2969
2970 // Cause QUIC stream to be created.
2971 HttpRequestInfo request_info;
2972 request_info.method = "GET";
2973 request_info.url = url_;
2974 request_info.traffic_annotation =
2975 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2976 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
2977 net_log_, CompletionOnceCallback()));
2978
2979 // Ensure that session is alive and active.
2980 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
2981 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2982 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2983
2984 // Send GET request on stream.
2985 HttpResponseInfo response;
2986 HttpRequestHeaders request_headers;
2987 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
2988 callback_.callback()));
2989
Zhongyi Shi22fd5f52018-06-20 17:39:092990 if (async_write_before)
Zhongyi Shi9f316b262018-06-18 22:01:162991 session->SendPing();
Zhongyi Shi9f316b262018-06-18 22:01:162992
2993 // Set up second socket data provider that is used after migration.
2994 // The response to the earlier request is read on this new socket.
2995 MockQuicData socket_data1;
2996 socket_data1.AddWrite(
2997 SYNCHRONOUS,
2998 client_maker_.MakePingPacket(packet_number++, /*include_version=*/true));
2999 socket_data1.AddRead(
3000 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
3001 false, false));
3002 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3003 socket_data1.AddWrite(
3004 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
3005 packet_number++, false, GetNthClientInitiatedStreamId(0),
3006 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
3007 socket_data1.AddSocketDataToFactory(socket_factory_.get());
3008
3009 // Trigger connection migration.
3010 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3011 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
3012
3013 // The connection should still be alive, not marked as going away.
3014 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3015 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3016 EXPECT_EQ(1u, session->GetNumActiveStreams());
3017 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3018
3019 // Ensure that the session is still alive.
3020 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3021 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3022 EXPECT_EQ(1u, session->GetNumActiveStreams());
3023
3024 // Run the message loop so that data queued in the new socket is read by the
3025 // packet reader.
3026 runner_->RunNextTask();
3027
3028 // Response headers are received over the new network.
3029 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3030 EXPECT_EQ(200, response.headers->response_code());
3031
3032 // Check that the session is still alive.
3033 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3034 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3035
3036 // There should be posted tasks not executed, which is to migrate back to
3037 // default network.
3038 EXPECT_FALSE(runner_->GetPostedTasks().empty());
3039
3040 // Receive signal to mark new network as default.
3041 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3042 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3043
3044 stream.reset();
3045 EXPECT_TRUE(socket_data.AllReadDataConsumed());
3046 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
3047 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
3048 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
3049}
3050
Zhongyi Shi5f587cc2017-11-21 23:24:173051// This test receives NCN signals in the following order:
3052// - default network disconnected
3053// - after a pause, new network is connected.
3054// - new network is made default.
3055TEST_P(QuicStreamFactoryTest, NewNetworkConnectedAfterNoNetwork) {
3056 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
3057 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3058 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3059 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3060
3061 // Use the test task runner.
3062 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
3063
3064 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523065 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shi5f587cc2017-11-21 23:24:173066 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3067 socket_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433068 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
3069 socket_data.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
3070 2, GetNthClientInitiatedStreamId(0),
3071 true, true, &header_stream_offset));
Zhongyi Shi5f587cc2017-11-21 23:24:173072 socket_data.AddSocketDataToFactory(socket_factory_.get());
3073
3074 // Create request and QuicHttpStream.
3075 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:333076 EXPECT_EQ(ERR_IO_PENDING,
3077 request.Request(host_port_pair_, version_, privacy_mode_,
3078 DEFAULT_PRIORITY, SocketTag(),
3079 /*cert_verify_flags=*/0, url_, net_log_,
3080 &net_error_details_, callback_.callback()));
Zhongyi Shi5f587cc2017-11-21 23:24:173081 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3082 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3083 EXPECT_TRUE(stream.get());
3084
3085 // Cause QUIC stream to be created.
3086 HttpRequestInfo request_info;
3087 request_info.method = "GET";
3088 request_info.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:393089 request_info.traffic_annotation =
3090 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:273091 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:393092 net_log_, CompletionOnceCallback()));
Zhongyi Shi5f587cc2017-11-21 23:24:173093
3094 // Ensure that session is alive and active.
3095 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3096 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3097 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3098
3099 // Send GET request on stream.
3100 HttpResponseInfo response;
3101 HttpRequestHeaders request_headers;
3102 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3103 callback_.callback()));
3104
3105 // Trigger connection migration. Since there are no networks
3106 // to migrate to, this should cause the session to wait for a new network.
3107 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3108 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
3109
3110 // The connection should still be alive, not marked as going away.
3111 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3112 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3113 EXPECT_EQ(1u, session->GetNumActiveStreams());
3114 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3115
3116 // Set up second socket data provider that is used after migration.
3117 // The response to the earlier request is read on this new socket.
3118 MockQuicData socket_data1;
3119 socket_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433120 SYNCHRONOUS, client_maker_.MakePingPacket(3, /*include_version=*/true));
3121 socket_data1.AddRead(
3122 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
3123 false, false));
Zhongyi Shi5f587cc2017-11-21 23:24:173124 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:433125 socket_data1.AddWrite(SYNCHRONOUS,
3126 client_maker_.MakeAckAndRstPacket(
3127 4, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:523128 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:173129 socket_data1.AddSocketDataToFactory(socket_factory_.get());
3130
3131 // Add a new network and notify the stream factory of a new connected network.
3132 // This causes a PING packet to be sent over the new network.
3133 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3134 ->SetConnectedNetworksList({kNewNetworkForTests});
3135 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3136 ->NotifyNetworkConnected(kNewNetworkForTests);
3137
3138 // Ensure that the session is still alive.
3139 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3140 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3141 EXPECT_EQ(1u, session->GetNumActiveStreams());
3142
3143 // Run the message loop so that data queued in the new socket is read by the
3144 // packet reader.
3145 runner_->RunNextTask();
3146
3147 // Response headers are received over the new network.
3148 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3149 EXPECT_EQ(200, response.headers->response_code());
3150
3151 // Check that the session is still alive.
3152 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3153 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3154
3155 // There should posted tasks not executed, which is to migrate back to default
3156 // network.
3157 EXPECT_FALSE(runner_->GetPostedTasks().empty());
3158
3159 // Receive signal to mark new network as default.
3160 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3161 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3162
3163 stream.reset();
3164 EXPECT_TRUE(socket_data.AllReadDataConsumed());
3165 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
3166 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
3167 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
3168}
3169
Zhongyi Shid3d5f502018-08-10 00:22:223170// Regression test for http://crbug.com/872011.
3171// This test verifies that migrate to the probing socket will not trigger
3172// new packets being read synchronously and generate ACK frame while
3173// processing the initial connectivity probe response, which may cause a
3174// connection being closed with INTERNAL_ERROR as pending ACK frame is not
3175// allowed when processing a new packet.
3176TEST_P(QuicStreamFactoryTest, MigrateToProbingSocket) {
3177 InitializeConnectionMigrationV2Test(
3178 {kDefaultNetworkForTests, kNewNetworkForTests});
3179 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3180 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3181 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3182
3183 // Using a testing task runner so that we can control time.
3184 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3185 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
3186
3187 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3188 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3189
3190 int packet_number = 1;
3191 MockQuicData quic_data1;
3192 quic::QuicStreamOffset header_stream_offset = 0;
3193 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
3194 quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
3195 packet_number++, &header_stream_offset));
3196 quic_data1.AddWrite(
3197 SYNCHRONOUS, ConstructGetRequestPacket(
3198 packet_number++, GetNthClientInitiatedStreamId(0), true,
3199 true, &header_stream_offset));
3200 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3201
3202 // Set up the second socket data provider that is used for probing on the
3203 // alternate network.
3204 MockQuicData quic_data2;
3205 // Connectivity probe to be sent on the new path.
3206 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(
3207 packet_number++, true));
3208 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3209 // First connectivity probe to receive from the server, which will complete
3210 // connection migraiton on path degrading.
3211 quic_data2.AddRead(ASYNC,
3212 server_maker_.MakeConnectivityProbingPacket(1, false));
3213 // Read multiple connectivity probes synchronously.
3214 quic_data2.AddRead(SYNCHRONOUS,
3215 server_maker_.MakeConnectivityProbingPacket(2, false));
3216 quic_data2.AddRead(SYNCHRONOUS,
3217 server_maker_.MakeConnectivityProbingPacket(3, false));
3218 quic_data2.AddRead(SYNCHRONOUS,
3219 server_maker_.MakeConnectivityProbingPacket(4, false));
3220 quic_data2.AddWrite(
3221 ASYNC, client_maker_.MakeAckPacket(packet_number++, 1, 4, 1, 1, true));
3222 quic_data2.AddRead(
3223 ASYNC, ConstructOkResponsePacket(5, GetNthClientInitiatedStreamId(0),
3224 false, false));
3225 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3226 quic_data2.AddWrite(
3227 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
3228 packet_number++, false, GetNthClientInitiatedStreamId(0),
3229 quic::QUIC_STREAM_CANCELLED, 5, 1, 1, true));
3230 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3231
3232 // Create request and QuicHttpStream.
3233 QuicStreamRequest request(factory_.get());
3234 EXPECT_EQ(ERR_IO_PENDING,
3235 request.Request(host_port_pair_, version_, privacy_mode_,
3236 DEFAULT_PRIORITY, SocketTag(),
3237 /*cert_verify_flags=*/0, url_, net_log_,
3238 &net_error_details_, callback_.callback()));
3239 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3240 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3241 EXPECT_TRUE(stream.get());
3242
3243 // Cause QUIC stream to be created.
3244 HttpRequestInfo request_info;
3245 request_info.method = "GET";
3246 request_info.url = url_;
3247 request_info.traffic_annotation =
3248 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3249 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3250 net_log_, CompletionOnceCallback()));
3251
3252 // Ensure that session is alive and active.
3253 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3254 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3255 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3256
3257 // Send GET request on stream.
3258 HttpResponseInfo response;
3259 HttpRequestHeaders request_headers;
3260 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3261 callback_.callback()));
3262
3263 // Cause the connection to report path degrading to the session.
3264 // Session will start to probe the alternate network.
3265 session->connection()->OnPathDegradingTimeout();
3266
3267 // Next connectivity probe is scheduled to be sent in 2 *
3268 // kDefaultRTTMilliSecs.
3269 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3270 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
3271 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3272 next_task_delay);
3273
3274 // The connection should still be alive, and not marked as going away.
3275 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3276 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3277 EXPECT_EQ(1u, session->GetNumActiveStreams());
3278 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3279
3280 // Resume quic data and a connectivity probe response will be read on the new
3281 // socket.
3282 quic_data2.Resume();
3283
3284 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3285 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3286 EXPECT_EQ(1u, session->GetNumActiveStreams());
3287
3288 // There should be three pending tasks, the nearest one will complete
3289 // migration to the new network.
3290 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
3291 next_task_delay = task_runner->NextPendingTaskDelay();
3292 EXPECT_EQ(base::TimeDelta(), next_task_delay);
3293 task_runner->FastForwardBy(next_task_delay);
3294
3295 // Response headers are received over the new network.
3296 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3297 EXPECT_EQ(200, response.headers->response_code());
3298
3299 // Now there are two pending tasks, the nearest one was to send connectivity
3300 // probe and has been cancelled due to successful migration.
3301 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
3302 next_task_delay = task_runner->NextPendingTaskDelay();
3303 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3304 next_task_delay);
3305 task_runner->FastForwardBy(next_task_delay);
3306
3307 // There's one more task to mgirate back to the default network in 0.4s.
3308 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3309 next_task_delay = task_runner->NextPendingTaskDelay();
3310 base::TimeDelta expected_delay =
3311 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
3312 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
3313 EXPECT_EQ(expected_delay, next_task_delay);
3314
3315 // Deliver a signal that the alternate network now becomes default to session,
3316 // this will cancel mgirate back to default network timer.
3317 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3318 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3319
3320 task_runner->FastForwardBy(next_task_delay);
3321 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
3322
3323 // Verify that the session is still alive.
3324 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3325 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3326
3327 stream.reset();
3328 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
3329 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
3330 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
3331 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
3332}
3333
Zhongyi Shic4823bd2018-04-27 00:49:193334// This test verifies that the connection migrates to the alternate network
Zhongyi Shi22fd5f52018-06-20 17:39:093335// early when path degrading is detected with an ASYNCHRONOUS write before
3336// migration.
3337TEST_P(QuicStreamFactoryTest, MigrateEarlyOnPathDegradingAysnc) {
3338 TestMigrationOnPathDegrading(/*async_write_before_migration*/ true);
3339}
3340
3341// This test verifies that the connection migrates to the alternate network
3342// early when path degrading is detected with a SYNCHRONOUS write before
3343// migration.
3344TEST_P(QuicStreamFactoryTest, MigrateEarlyOnPathDegradingSync) {
3345 TestMigrationOnPathDegrading(/*async_write_before_migration*/ false);
3346}
3347
3348void QuicStreamFactoryTestBase::TestMigrationOnPathDegrading(
3349 bool async_write_before) {
Zhongyi Shic4823bd2018-04-27 00:49:193350 InitializeConnectionMigrationV2Test(
3351 {kDefaultNetworkForTests, kNewNetworkForTests});
3352 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3353 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3354 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3355
3356 // Using a testing task runner so that we can control time.
3357 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3358 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
3359
3360 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3361 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3362
Zhongyi Shi22fd5f52018-06-20 17:39:093363 int packet_number = 1;
Zhongyi Shic4823bd2018-04-27 00:49:193364 MockQuicData quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523365 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shic4823bd2018-04-27 00:49:193366 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
Zhongyi Shi22fd5f52018-06-20 17:39:093367 quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
3368 packet_number++, &header_stream_offset));
3369 quic_data1.AddWrite(
3370 SYNCHRONOUS, ConstructGetRequestPacket(
3371 packet_number++, GetNthClientInitiatedStreamId(0), true,
3372 true, &header_stream_offset));
3373 if (async_write_before) {
3374 quic_data1.AddWrite(ASYNC, OK);
3375 packet_number++;
3376 }
Zhongyi Shic4823bd2018-04-27 00:49:193377 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3378
3379 // Set up the second socket data provider that is used after migration.
3380 // The response to the earlier request is read on the new socket.
3381 MockQuicData quic_data2;
3382 // Connectivity probe to be sent on the new path.
Zhongyi Shi22fd5f52018-06-20 17:39:093383 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(
Zhongyi Shi879659422018-08-02 17:58:253384 packet_number++, true));
Zhongyi Shic4823bd2018-04-27 00:49:193385 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3386 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:253387 quic_data2.AddRead(ASYNC,
3388 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shic4823bd2018-04-27 00:49:193389 // Ping packet to send after migration is completed.
Zhongyi Shi22fd5f52018-06-20 17:39:093390 quic_data2.AddWrite(ASYNC, client_maker_.MakeAckAndPingPacket(
3391 packet_number++, false, 1, 1, 1));
Ryan Hamiltona3ee93a72018-08-01 22:03:083392 quic_data2.AddRead(
3393 ASYNC, ConstructOkResponsePacket(2, GetNthClientInitiatedStreamId(0),
3394 false, false));
Zhongyi Shic4823bd2018-04-27 00:49:193395 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi22fd5f52018-06-20 17:39:093396 quic_data2.AddWrite(
3397 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
3398 packet_number++, false, GetNthClientInitiatedStreamId(0),
3399 quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true));
Zhongyi Shic4823bd2018-04-27 00:49:193400 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3401
3402 // Create request and QuicHttpStream.
3403 QuicStreamRequest request(factory_.get());
3404 EXPECT_EQ(ERR_IO_PENDING,
3405 request.Request(host_port_pair_, version_, privacy_mode_,
3406 DEFAULT_PRIORITY, SocketTag(),
3407 /*cert_verify_flags=*/0, url_, net_log_,
3408 &net_error_details_, callback_.callback()));
3409 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3410 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3411 EXPECT_TRUE(stream.get());
3412
3413 // Cause QUIC stream to be created.
3414 HttpRequestInfo request_info;
3415 request_info.method = "GET";
3416 request_info.url = url_;
3417 request_info.traffic_annotation =
3418 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3419 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3420 net_log_, CompletionOnceCallback()));
3421
3422 // Ensure that session is alive and active.
3423 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3424 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3425 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3426
3427 // Send GET request on stream.
3428 HttpResponseInfo response;
3429 HttpRequestHeaders request_headers;
3430 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3431 callback_.callback()));
3432
Zhongyi Shi22fd5f52018-06-20 17:39:093433 if (async_write_before)
3434 session->SendPing();
3435
Zhongyi Shiaba4a832018-04-30 20:29:083436 // Cause the connection to report path degrading to the session.
3437 // Session will start to probe the alternate network.
3438 session->connection()->OnPathDegradingTimeout();
3439
3440 // Next connectivity probe is scheduled to be sent in 2 *
3441 // kDefaultRTTMilliSecs.
3442 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3443 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
3444 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3445 next_task_delay);
3446
3447 // The connection should still be alive, and not marked as going away.
3448 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3449 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3450 EXPECT_EQ(1u, session->GetNumActiveStreams());
3451 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3452
3453 // Resume quic data and a connectivity probe response will be read on the new
3454 // socket.
3455 quic_data2.Resume();
3456
3457 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3458 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3459 EXPECT_EQ(1u, session->GetNumActiveStreams());
3460
3461 // There should be three pending tasks, the nearest one will complete
3462 // migration to the new network.
3463 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
3464 next_task_delay = task_runner->NextPendingTaskDelay();
3465 EXPECT_EQ(base::TimeDelta(), next_task_delay);
3466 task_runner->FastForwardBy(next_task_delay);
3467
3468 // Response headers are received over the new network.
3469 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3470 EXPECT_EQ(200, response.headers->response_code());
3471
3472 // Now there are two pending tasks, the nearest one was to send connectivity
3473 // probe and has been cancelled due to successful migration.
3474 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
3475 next_task_delay = task_runner->NextPendingTaskDelay();
3476 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3477 next_task_delay);
3478 task_runner->FastForwardBy(next_task_delay);
3479
3480 // There's one more task to mgirate back to the default network in 0.4s.
3481 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3482 next_task_delay = task_runner->NextPendingTaskDelay();
3483 base::TimeDelta expected_delay =
3484 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
3485 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
3486 EXPECT_EQ(expected_delay, next_task_delay);
3487
3488 // Deliver a signal that the alternate network now becomes default to session,
3489 // this will cancel mgirate back to default network timer.
3490 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3491 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3492
3493 task_runner->FastForwardBy(next_task_delay);
3494 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
3495
3496 // Verify that the session is still alive.
3497 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3498 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3499
3500 stream.reset();
3501 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
3502 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
3503 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
3504 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
3505}
3506
Renjiea5722ccf2018-08-10 00:18:493507// This test verifies that the session marks itself GOAWAY on path degrading
3508// and it does not receive any new request
3509TEST_P(QuicStreamFactoryTest, GoawayOnPathDegrading) {
3510 go_away_on_path_degrading_ = true;
3511 Initialize();
3512 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3513 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3514 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3515
3516 MockQuicData quic_data1;
3517 quic::QuicStreamOffset header_stream_offset = 0;
3518 quic_data1.AddWrite(SYNCHRONOUS,
3519 ConstructInitialSettingsPacket(1, &header_stream_offset));
3520 quic_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
3521 2, GetNthClientInitiatedStreamId(0),
3522 true, true, &header_stream_offset));
3523 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3524 quic_data1.AddRead(
3525 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
3526 false, true));
3527 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
3528 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3529
3530 MockQuicData quic_data2;
3531 quic::QuicStreamOffset header_stream_offset2 = 0;
3532 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
3533 quic_data2.AddWrite(
3534 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset2));
3535 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3536
3537 // Creat request and QuicHttpStream.
3538 QuicStreamRequest request(factory_.get());
3539 EXPECT_EQ(ERR_IO_PENDING,
3540 request.Request(host_port_pair_, version_, privacy_mode_,
3541 DEFAULT_PRIORITY, SocketTag(),
3542 /*cerf_verify_flags=*/0, url_, net_log_,
3543 &net_error_details_, callback_.callback()));
3544 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3545 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3546 EXPECT_TRUE(stream.get());
3547
3548 // Cause QUIC stream to be created.
3549 HttpRequestInfo request_info;
3550 request_info.method = "GET";
3551 request_info.url = url_;
3552 request_info.traffic_annotation =
3553 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3554 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3555 net_log_, CompletionOnceCallback()));
3556
3557 // Ensure that session is alive and active.
3558 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3559 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3560 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3561
3562 // Send GET request on stream.
3563 HttpResponseInfo response;
3564 HttpRequestHeaders request_headers;
3565 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3566 callback_.callback()));
3567
3568 // Trigger the connection to report path degrading to the session.
3569 // Session will mark itself GOAWAY.
3570 session->connection()->OnPathDegradingTimeout();
3571
3572 // The connection should still be alive, but marked as going away.
3573 EXPECT_FALSE(HasActiveSession(host_port_pair_));
3574 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3575 EXPECT_EQ(1u, session->GetNumActiveStreams());
3576
3577 // Second request should be sent on a new connection.
3578 QuicStreamRequest request2(factory_.get());
3579 EXPECT_EQ(ERR_IO_PENDING,
3580 request2.Request(host_port_pair_, version_, privacy_mode_,
3581 DEFAULT_PRIORITY, SocketTag(),
3582 /*cert_verify_flags=*/0, url_, net_log_,
3583 &net_error_details_, callback_.callback()));
3584 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3585 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
3586 EXPECT_TRUE(stream2.get());
3587
3588 // Resume the data, verify old request can read response on the old session
3589 // successfully.
3590 quic_data1.Resume();
3591 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
3592 EXPECT_EQ(200, response.headers->response_code());
3593 EXPECT_EQ(0U, session->GetNumActiveStreams());
3594
3595 // Check an active session exists for the destination.
3596 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3597 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3598 QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
3599 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
3600 EXPECT_NE(session, session2);
3601
3602 stream.reset();
3603 stream2.reset();
3604 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
3605 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
3606 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
3607 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
3608}
3609
Zhongyi Shibb770d92018-06-16 02:07:003610// This test verifies that the connection will not migrate to a bad socket
3611// when path degrading is detected.
3612TEST_P(QuicStreamFactoryTest, DoNotMigrateToBadSocketOnPathDegrading) {
3613 InitializeConnectionMigrationV2Test(
3614 {kDefaultNetworkForTests, kNewNetworkForTests});
3615 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3616 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3617 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3618
3619 // Using a testing task runner so that we can control time.
3620 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3621 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
3622
3623 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3624 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3625
3626 MockQuicData quic_data;
3627 quic::QuicStreamOffset header_stream_offset = 0;
3628 quic_data.AddWrite(SYNCHRONOUS,
3629 ConstructInitialSettingsPacket(1, &header_stream_offset));
3630 quic_data.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
3631 2, GetNthClientInitiatedStreamId(0), true,
3632 true, &header_stream_offset));
3633 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3634 quic_data.AddRead(
3635 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
3636 false, false));
3637 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3638 quic_data.AddWrite(SYNCHRONOUS,
3639 client_maker_.MakeAckAndRstPacket(
3640 3, false, GetNthClientInitiatedStreamId(0),
3641 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
3642 quic_data.AddSocketDataToFactory(socket_factory_.get());
3643
3644 // Set up second socket that will immediately return disconnected.
3645 // The stream factory will abort probe the alternate network.
3646 MockConnect bad_connect = MockConnect(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
3647 SequencedSocketData socket_data(bad_connect, base::span<MockRead>(),
3648 base::span<MockWrite>());
3649 socket_factory_->AddSocketDataProvider(&socket_data);
3650
3651 // Create request and QuicHttpStream.
3652 QuicStreamRequest request(factory_.get());
3653 EXPECT_EQ(ERR_IO_PENDING,
3654 request.Request(host_port_pair_, version_, privacy_mode_,
3655 DEFAULT_PRIORITY, SocketTag(),
3656 /*cert_verify_flags=*/0, url_, net_log_,
3657 &net_error_details_, callback_.callback()));
3658 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3659 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3660 EXPECT_TRUE(stream.get());
3661
3662 // Cause QUIC stream to be created.
3663 HttpRequestInfo request_info;
3664 request_info.method = "GET";
3665 request_info.url = url_;
3666 request_info.traffic_annotation =
3667 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3668 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3669 net_log_, CompletionOnceCallback()));
3670
3671 // Ensure that session is alive and active.
3672 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3673 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3674 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3675
3676 // Send GET request on stream.
3677 HttpResponseInfo response;
3678 HttpRequestHeaders request_headers;
3679 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3680 callback_.callback()));
3681
3682 // Cause the connection to report path degrading to the session.
3683 // Session will start to probe the alternate network.
3684 session->connection()->OnPathDegradingTimeout();
3685
3686 // The connection should still be alive, and not marked as going away.
3687 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3688 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3689 EXPECT_EQ(1u, session->GetNumActiveStreams());
3690 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3691
3692 // Resume the data, and response header is received over the original network.
3693 quic_data.Resume();
3694 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3695 EXPECT_EQ(200, response.headers->response_code());
3696
3697 // Verify there is no pending task as probing alternate network is halted.
3698 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
3699
3700 // Verify that the session is still alive.
3701 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3702 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3703
3704 stream.reset();
3705 EXPECT_TRUE(quic_data.AllReadDataConsumed());
3706 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
3707}
3708
Zhongyi Shif5cc30392018-05-30 18:25:153709// Regression test for http://crbug.com/847569.
3710// This test verifies that the connection migrates to the alternate network
3711// early when there is no active stream but a draining stream.
Zhongyi Shib3bc982c2018-07-10 19:59:243712// The first packet being written after migration is a synchrnous write, which
3713// will cause a PING packet being sent.
3714TEST_P(QuicStreamFactoryTest, MigrateSessionWithDrainingStreamSync) {
3715 TestMigrateSessionWithDrainingStream(SYNCHRONOUS);
3716}
3717
3718// Regression test for http://crbug.com/847569.
3719// This test verifies that the connection migrates to the alternate network
3720// early when there is no active stream but a draining stream.
3721// The first packet being written after migration is an asynchronous write, no
3722// PING packet will be sent.
3723TEST_P(QuicStreamFactoryTest, MigrateSessionWithDrainingStreamAsync) {
3724 TestMigrateSessionWithDrainingStream(ASYNC);
3725}
3726
3727void QuicStreamFactoryTestBase::TestMigrateSessionWithDrainingStream(
3728 IoMode write_mode_for_queued_packet) {
Zhongyi Shif5cc30392018-05-30 18:25:153729 InitializeConnectionMigrationV2Test(
3730 {kDefaultNetworkForTests, kNewNetworkForTests});
3731 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3732 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3733 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3734
3735 // Using a testing task runner so that we can control time.
3736 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3737 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
3738
3739 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3740 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3741
Zhongyi Shib3bc982c2018-07-10 19:59:243742 int packet_number = 1;
Zhongyi Shif5cc30392018-05-30 18:25:153743 MockQuicData quic_data1;
3744 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shib3bc982c2018-07-10 19:59:243745 quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
3746 packet_number++, &header_stream_offset));
3747 quic_data1.AddWrite(
3748 SYNCHRONOUS, ConstructGetRequestPacket(
3749 packet_number++, GetNthClientInitiatedStreamId(0), true,
3750 true, &header_stream_offset));
Zhongyi Shif5cc30392018-05-30 18:25:153751 // Read an out of order packet with FIN to drain the stream.
3752 quic_data1.AddRead(
3753 ASYNC, ConstructOkResponsePacket(2, GetNthClientInitiatedStreamId(0),
3754 false, true)); // keep sending version.
Zhongyi Shib3bc982c2018-07-10 19:59:243755 quic_data1.AddWrite(SYNCHRONOUS, client_maker_.MakeAckPacket(
3756 packet_number++, 2, 2, 2, 1, true));
Zhongyi Shif5cc30392018-05-30 18:25:153757 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3758 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3759
3760 // Set up the second socket data provider that is used after migration.
3761 MockQuicData quic_data2;
3762 // Connectivity probe to be sent on the new path.
Zhongyi Shib3bc982c2018-07-10 19:59:243763 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(
Zhongyi Shi879659422018-08-02 17:58:253764 packet_number++, false));
Zhongyi Shif5cc30392018-05-30 18:25:153765 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3766 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:253767 quic_data2.AddRead(ASYNC,
3768 server_maker_.MakeConnectivityProbingPacket(3, false));
Zhongyi Shif5cc30392018-05-30 18:25:153769 // Ping packet to send after migration is completed.
Zhongyi Shib3bc982c2018-07-10 19:59:243770 quic_data2.AddWrite(
3771 write_mode_for_queued_packet,
3772 client_maker_.MakeAckPacket(packet_number++, 2, 3, 3, 1, true));
3773 if (write_mode_for_queued_packet == SYNCHRONOUS) {
3774 quic_data2.AddWrite(ASYNC,
3775 client_maker_.MakePingPacket(packet_number++, false));
3776 }
Zhongyi Shif5cc30392018-05-30 18:25:153777 quic_data2.AddRead(
3778 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
3779 false, false));
Zhongyi Shib3bc982c2018-07-10 19:59:243780 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeAckPacket(
3781 packet_number++, 1, 3, 1, 1, true));
Zhongyi Shif5cc30392018-05-30 18:25:153782 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3783 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3784
3785 // Create request and QuicHttpStream.
3786 QuicStreamRequest request(factory_.get());
3787 EXPECT_EQ(ERR_IO_PENDING,
3788 request.Request(host_port_pair_, version_, privacy_mode_,
3789 DEFAULT_PRIORITY, SocketTag(),
3790 /*cert_verify_flags=*/0, url_, net_log_,
3791 &net_error_details_, callback_.callback()));
3792 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3793 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3794 EXPECT_TRUE(stream.get());
3795
3796 // Cause QUIC stream to be created.
3797 HttpRequestInfo request_info;
3798 request_info.method = "GET";
3799 request_info.url = url_;
3800 request_info.traffic_annotation =
3801 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3802 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3803 net_log_, CompletionOnceCallback()));
3804
3805 // Ensure that session is alive and active.
3806 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3807 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3808 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3809
3810 // Send GET request on stream.
3811 HttpResponseInfo response;
3812 HttpRequestHeaders request_headers;
3813 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3814 callback_.callback()));
3815
3816 // Run the message loop to receive the out of order packet which contains a
3817 // FIN and drains the stream.
3818 base::RunLoop().RunUntilIdle();
3819 EXPECT_EQ(0u, session->GetNumActiveStreams());
3820
3821 // Cause the connection to report path degrading to the session.
3822 // Session should still start to probe the alternate network.
3823 session->connection()->OnPathDegradingTimeout();
3824 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3825
3826 // Next connectivity probe is scheduled to be sent in 2 *
3827 // kDefaultRTTMilliSecs.
3828 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3829 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
3830 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3831 next_task_delay);
3832
3833 // The connection should still be alive, and not marked as going away.
3834 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shif5cc30392018-05-30 18:25:153835
3836 // Resume quic data and a connectivity probe response will be read on the new
3837 // socket.
3838 quic_data2.Resume();
3839
3840 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3841 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:263842 EXPECT_EQ(0u, session->GetNumActiveStreams());
3843 EXPECT_EQ(1u, session->GetNumDrainingStreams());
Zhongyi Shif5cc30392018-05-30 18:25:153844
3845 // There should be three pending tasks, the nearest one will complete
3846 // migration to the new network.
3847 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
3848 next_task_delay = task_runner->NextPendingTaskDelay();
3849 EXPECT_EQ(base::TimeDelta(), next_task_delay);
3850 task_runner->FastForwardBy(next_task_delay);
3851
3852 // Now there are two pending tasks, the nearest one was to send connectivity
3853 // probe and has been cancelled due to successful migration.
3854 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
3855 next_task_delay = task_runner->NextPendingTaskDelay();
3856 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3857 next_task_delay);
3858 task_runner->FastForwardBy(next_task_delay);
3859
3860 // There's one more task to mgirate back to the default network in 0.4s.
3861 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3862 next_task_delay = task_runner->NextPendingTaskDelay();
3863 base::TimeDelta expected_delay =
3864 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
3865 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
3866 EXPECT_EQ(expected_delay, next_task_delay);
3867
Zhongyi Shib3bc982c2018-07-10 19:59:243868 base::RunLoop().RunUntilIdle();
3869
Zhongyi Shif5cc30392018-05-30 18:25:153870 // Deliver a signal that the alternate network now becomes default to session,
3871 // this will cancel mgirate back to default network timer.
3872 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3873 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3874
3875 task_runner->FastForwardBy(next_task_delay);
3876 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
3877
3878 // Verify that the session is still alive.
3879 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3880 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:263881 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
Zhongyi Shif5cc30392018-05-30 18:25:153882
3883 stream.reset();
3884 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
3885 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
3886 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
3887 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
3888}
3889
Zhongyi Shiaba4a832018-04-30 20:29:083890// Regression test for http://crbug.com/835444.
3891// This test verifies that the connection migrates to the alternate network
3892// when the alternate network is connected after path has been degrading.
3893TEST_P(QuicStreamFactoryTest, MigrateOnNewNetworkConnectAfterPathDegrading) {
3894 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
3895 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3896 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3897 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3898
3899 // Using a testing task runner so that we can control time.
3900 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3901 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
3902
3903 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3904 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3905
3906 MockQuicData quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523907 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shiaba4a832018-04-30 20:29:083908 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
3909 quic_data1.AddWrite(SYNCHRONOUS,
3910 ConstructInitialSettingsPacket(1, &header_stream_offset));
3911 quic_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
3912 2, GetNthClientInitiatedStreamId(0),
3913 true, true, &header_stream_offset));
3914 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3915
3916 // Set up the second socket data provider that is used after migration.
3917 // The response to the earlier request is read on the new socket.
3918 MockQuicData quic_data2;
3919 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:253920 quic_data2.AddWrite(SYNCHRONOUS,
3921 client_maker_.MakeConnectivityProbingPacket(3, true));
Zhongyi Shiaba4a832018-04-30 20:29:083922 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3923 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:253924 quic_data2.AddRead(ASYNC,
3925 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shiaba4a832018-04-30 20:29:083926 // Ping packet to send after migration is completed.
3927 quic_data2.AddWrite(ASYNC,
3928 client_maker_.MakeAckAndPingPacket(4, false, 1, 1, 1));
3929 quic_data2.AddRead(
3930 ASYNC, ConstructOkResponsePacket(2, GetNthClientInitiatedStreamId(0),
3931 false, false));
3932 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3933 quic_data2.AddWrite(SYNCHRONOUS,
3934 client_maker_.MakeAckAndRstPacket(
3935 5, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:523936 quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true));
Zhongyi Shiaba4a832018-04-30 20:29:083937 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3938
3939 // Create request and QuicHttpStream.
3940 QuicStreamRequest request(factory_.get());
3941 EXPECT_EQ(ERR_IO_PENDING,
3942 request.Request(host_port_pair_, version_, privacy_mode_,
3943 DEFAULT_PRIORITY, SocketTag(),
3944 /*cert_verify_flags=*/0, url_, net_log_,
3945 &net_error_details_, callback_.callback()));
3946 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3947 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3948 EXPECT_TRUE(stream.get());
3949
3950 // Cause QUIC stream to be created.
3951 HttpRequestInfo request_info;
3952 request_info.method = "GET";
3953 request_info.url = url_;
3954 request_info.traffic_annotation =
3955 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3956 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3957 net_log_, CompletionOnceCallback()));
3958
3959 // Ensure that session is alive and active.
3960 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3961 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3962 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3963
3964 // Send GET request on stream.
3965 HttpResponseInfo response;
3966 HttpRequestHeaders request_headers;
3967 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3968 callback_.callback()));
3969
3970 // Cause the connection to report path degrading to the session.
3971 // Due to lack of alternate network, session will not mgirate connection.
3972 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
3973 session->connection()->OnPathDegradingTimeout();
3974 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
3975
3976 // Deliver a signal that a alternate network is connected now, this should
3977 // cause the connection to start early migration on path degrading.
3978 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3979 ->SetConnectedNetworksList(
3980 {kDefaultNetworkForTests, kNewNetworkForTests});
3981 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3982 ->NotifyNetworkConnected(kNewNetworkForTests);
Zhongyi Shic4823bd2018-04-27 00:49:193983
3984 // Next connectivity probe is scheduled to be sent in 2 *
3985 // kDefaultRTTMilliSecs.
3986 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3987 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
3988 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3989 next_task_delay);
3990
3991 // The connection should still be alive, and not marked as going away.
3992 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3993 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3994 EXPECT_EQ(1u, session->GetNumActiveStreams());
3995 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3996
3997 // Resume quic data and a connectivity probe response will be read on the new
3998 // socket.
3999 quic_data2.Resume();
4000
4001 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4002 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4003 EXPECT_EQ(1u, session->GetNumActiveStreams());
4004
4005 // There should be three pending tasks, the nearest one will complete
4006 // migration to the new network.
4007 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
4008 next_task_delay = task_runner->NextPendingTaskDelay();
4009 EXPECT_EQ(base::TimeDelta(), next_task_delay);
4010 task_runner->FastForwardBy(next_task_delay);
4011
4012 // Response headers are received over the new network.
4013 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4014 EXPECT_EQ(200, response.headers->response_code());
4015
4016 // Now there are two pending tasks, the nearest one was to send connectivity
4017 // probe and has been cancelled due to successful migration.
4018 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
4019 next_task_delay = task_runner->NextPendingTaskDelay();
4020 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
4021 next_task_delay);
4022 task_runner->FastForwardBy(next_task_delay);
4023
4024 // There's one more task to mgirate back to the default network in 0.4s.
4025 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4026 next_task_delay = task_runner->NextPendingTaskDelay();
4027 base::TimeDelta expected_delay =
4028 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
4029 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
4030 EXPECT_EQ(expected_delay, next_task_delay);
4031
4032 // Deliver a signal that the alternate network now becomes default to session,
4033 // this will cancel mgirate back to default network timer.
4034 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4035 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
4036
4037 task_runner->FastForwardBy(next_task_delay);
4038 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4039
4040 // Verify that the session is still alive.
4041 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4042 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4043
4044 stream.reset();
4045 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
4046 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
4047 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
4048 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
4049}
4050
Zhongyi Shi28f6e352018-06-20 21:15:434051// This test verifies that multiple sessions are migrated on connection
4052// migration signal.
jrie3d187c2016-09-16 14:29:174053TEST_P(QuicStreamFactoryTest,
Zhongyi Shi28f6e352018-06-20 21:15:434054 MigrateMultipleSessionsToBadSocketsAfterDisconnected) {
4055 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jrie3d187c2016-09-16 14:29:174056
4057 MockQuicData socket_data1;
4058 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434059 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jrie3d187c2016-09-16 14:29:174060 socket_data1.AddWrite(ASYNC, OK);
Zhongyi Shi5f587cc2017-11-21 23:24:174061 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jrie3d187c2016-09-16 14:29:174062 MockQuicData socket_data2;
4063 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434064 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jrie3d187c2016-09-16 14:29:174065 socket_data2.AddWrite(ASYNC, OK);
Zhongyi Shi5f587cc2017-11-21 23:24:174066 socket_data2.AddSocketDataToFactory(socket_factory_.get());
jrie3d187c2016-09-16 14:29:174067
4068 HostPortPair server1(kDefaultServerHostName, 443);
4069 HostPortPair server2(kServer2HostName, 443);
4070
4071 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4072 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4073 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4074
4075 host_resolver_.set_synchronous_mode(true);
4076 host_resolver_.rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
4077 host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.2", "");
4078
4079 // Create request and QuicHttpStream to create session1.
zhongyi98d6a9262017-05-19 02:47:454080 QuicStreamRequest request1(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:334081 EXPECT_EQ(OK, request1.Request(server1, version_, privacy_mode_,
4082 DEFAULT_PRIORITY, SocketTag(),
4083 /*cert_verify_flags=*/0, url_, net_log_,
4084 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:244085 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
jrie3d187c2016-09-16 14:29:174086 EXPECT_TRUE(stream1.get());
4087
4088 // Create request and QuicHttpStream to create session2.
zhongyi98d6a9262017-05-19 02:47:454089 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:334090 EXPECT_EQ(OK, request2.Request(server2, version_, privacy_mode_,
4091 DEFAULT_PRIORITY, SocketTag(),
4092 /*cert_verify_flags=*/0, url2_, net_log_,
4093 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:244094 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
jrie3d187c2016-09-16 14:29:174095 EXPECT_TRUE(stream2.get());
4096
4097 QuicChromiumClientSession* session1 = GetActiveSession(server1);
4098 QuicChromiumClientSession* session2 = GetActiveSession(server2);
4099 EXPECT_NE(session1, session2);
4100
4101 // Cause QUIC stream to be created and send GET so session1 has an open
4102 // stream.
4103 HttpRequestInfo request_info1;
4104 request_info1.method = "GET";
4105 request_info1.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:394106 request_info1.traffic_annotation =
4107 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274108 EXPECT_EQ(OK,
4109 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394110 net_log_, CompletionOnceCallback()));
jrie3d187c2016-09-16 14:29:174111 HttpResponseInfo response1;
4112 HttpRequestHeaders request_headers1;
4113 EXPECT_EQ(OK, stream1->SendRequest(request_headers1, &response1,
4114 callback_.callback()));
4115
4116 // Cause QUIC stream to be created and send GET so session2 has an open
4117 // stream.
4118 HttpRequestInfo request_info2;
4119 request_info2.method = "GET";
4120 request_info2.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:394121 request_info2.traffic_annotation =
4122 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274123 EXPECT_EQ(OK,
4124 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394125 net_log_, CompletionOnceCallback()));
jrie3d187c2016-09-16 14:29:174126 HttpResponseInfo response2;
4127 HttpRequestHeaders request_headers2;
4128 EXPECT_EQ(OK, stream2->SendRequest(request_headers2, &response2,
4129 callback_.callback()));
4130
4131 // Cause both sessions to be paused due to DISCONNECTED.
4132 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4133 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
4134
4135 // Ensure that both sessions are paused but alive.
4136 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session1));
4137 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
4138
Zhongyi Shi28f6e352018-06-20 21:15:434139 // Add new sockets to use post migration. Those are bad sockets and will cause
4140 // migration to fail.
jrie3d187c2016-09-16 14:29:174141 MockConnect connect_result =
4142 MockConnect(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
Ryan Sleevib8d7ea02018-05-07 20:01:014143 SequencedSocketData socket_data3(connect_result, base::span<MockRead>(),
4144 base::span<MockWrite>());
Zhongyi Shi5f587cc2017-11-21 23:24:174145 socket_factory_->AddSocketDataProvider(&socket_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:014146 SequencedSocketData socket_data4(connect_result, base::span<MockRead>(),
4147 base::span<MockWrite>());
Zhongyi Shi5f587cc2017-11-21 23:24:174148 socket_factory_->AddSocketDataProvider(&socket_data4);
jrie3d187c2016-09-16 14:29:174149
Zhongyi Shi28f6e352018-06-20 21:15:434150 // Connect the new network and cause migration to bad sockets, causing
4151 // sessions to close.
jrie3d187c2016-09-16 14:29:174152 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4153 ->SetConnectedNetworksList({kNewNetworkForTests});
4154 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4155 ->NotifyNetworkConnected(kNewNetworkForTests);
4156
4157 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session1));
4158 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
4159
4160 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
4161 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
4162 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
4163 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
4164}
4165
Zhongyi Shi6ec9b36e2018-06-20 20:32:544166// This test verifies that session attempts connection migration with signals
4167// delivered in the following order (no alternate network is available):
4168// - path degrading is detected: session attempts connection migration but no
4169// alternate network is available, session caches path degrading signal in
4170// connection and stays on the original network.
4171// - original network backs up, request is served in the orignal network,
4172// session is not marked as going away.
4173TEST_P(QuicStreamFactoryTest, MigrateOnPathDegradingWithNoNewNetwork) {
4174 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jrid36ada62016-02-06 02:42:084175 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4176 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4177
Zhongyi Shi6ec9b36e2018-06-20 20:32:544178 MockQuicData quic_data;
4179 quic::QuicStreamOffset header_stream_offset = 0;
4180 quic_data.AddWrite(SYNCHRONOUS,
4181 ConstructInitialSettingsPacket(1, &header_stream_offset));
4182 quic_data.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
4183 2, GetNthClientInitiatedStreamId(0), true,
4184 true, &header_stream_offset));
4185 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause for path degrading signal.
4186
4187 // The rest of the data will still flow in the original socket as there is no
4188 // new network after path degrading.
4189 quic_data.AddRead(
4190 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
4191 false, false));
4192 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4193 quic_data.AddWrite(SYNCHRONOUS,
4194 client_maker_.MakeAckAndRstPacket(
4195 3, false, GetNthClientInitiatedStreamId(0),
4196 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
4197 quic_data.AddSocketDataToFactory(socket_factory_.get());
jrid36ada62016-02-06 02:42:084198
4199 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:454200 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:334201 EXPECT_EQ(ERR_IO_PENDING,
4202 request.Request(host_port_pair_, version_, privacy_mode_,
4203 DEFAULT_PRIORITY, SocketTag(),
4204 /*cert_verify_flags=*/0, url_, net_log_,
4205 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:014206 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:244207 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jrid36ada62016-02-06 02:42:084208 EXPECT_TRUE(stream.get());
4209
4210 // Cause QUIC stream to be created.
4211 HttpRequestInfo request_info;
Zhongyi Shi6ec9b36e2018-06-20 20:32:544212 request_info.method = "GET";
4213 request_info.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:394214 request_info.traffic_annotation =
4215 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Zhongyi Shi6ec9b36e2018-06-20 20:32:544216 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394217 net_log_, CompletionOnceCallback()));
jrid36ada62016-02-06 02:42:084218
4219 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:504220 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jrid36ada62016-02-06 02:42:084221 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4222 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4223
Zhongyi Shi6ec9b36e2018-06-20 20:32:544224 // Send GET request on stream.
4225 HttpResponseInfo response;
4226 HttpRequestHeaders request_headers;
4227 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
4228 callback_.callback()));
jrid36ada62016-02-06 02:42:084229
Zhongyi Shi6ec9b36e2018-06-20 20:32:544230 // Trigger connection migration on path degrading. Since there are no networks
4231 // to migrate to, the session will remain on the original network, not marked
4232 // as going away.
4233 session->connection()->OnPathDegradingTimeout();
4234 EXPECT_TRUE(session->connection()->IsPathDegrading());
4235
4236 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4237 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4238 EXPECT_EQ(1u, session->GetNumActiveStreams());
4239 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
4240
4241 // Resume so that rest of the data will flow in the original socket.
4242 quic_data.Resume();
jrid36ada62016-02-06 02:42:084243
4244 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4245 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4246 EXPECT_EQ(1u, session->GetNumActiveStreams());
4247
4248 stream.reset();
Zhongyi Shi6ec9b36e2018-06-20 20:32:544249 EXPECT_TRUE(quic_data.AllReadDataConsumed());
4250 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
jrid36ada62016-02-06 02:42:084251}
4252
Zhongyi Shi21e99532018-07-17 22:23:074253// This test verifies that session with non-migratable stream will probe the
4254// alternate network on path degrading, and close the non-migratable streams
4255// when probe is successful.
jri231c2972016-03-08 19:50:114256TEST_P(QuicStreamFactoryTest, MigrateSessionEarlyNonMigratableStream) {
Zhongyi Shi1a054612018-06-14 04:59:084257 InitializeConnectionMigrationV2Test(
jri231c2972016-03-08 19:50:114258 {kDefaultNetworkForTests, kNewNetworkForTests});
4259 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4260 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4261
rcha00569732016-08-27 11:09:364262 MockQuicData socket_data;
4263 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434264 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:174265 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri231c2972016-03-08 19:50:114266
Zhongyi Shi21e99532018-07-17 22:23:074267 // Set up the second socket data provider that is used for probing.
4268 MockQuicData quic_data1;
4269 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:254270 quic_data1.AddWrite(SYNCHRONOUS,
4271 client_maker_.MakeConnectivityProbingPacket(2, true));
Zhongyi Shi21e99532018-07-17 22:23:074272 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
4273 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:254274 quic_data1.AddRead(ASYNC,
4275 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shi21e99532018-07-17 22:23:074276 quic_data1.AddSocketDataToFactory(socket_factory_.get());
4277
jri231c2972016-03-08 19:50:114278 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:454279 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:334280 EXPECT_EQ(ERR_IO_PENDING,
4281 request.Request(host_port_pair_, version_, privacy_mode_,
4282 DEFAULT_PRIORITY, SocketTag(),
4283 /*cert_verify_flags=*/0, url_, net_log_,
4284 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:014285 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:244286 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri231c2972016-03-08 19:50:114287 EXPECT_TRUE(stream.get());
4288
4289 // Cause QUIC stream to be created, but marked as non-migratable.
4290 HttpRequestInfo request_info;
Zhongyi Shibb28b1f2018-07-18 02:41:264291 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Ramin Halavati683bcaa92018-02-14 08:42:394292 request_info.traffic_annotation =
4293 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274294 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394295 net_log_, CompletionOnceCallback()));
jri231c2972016-03-08 19:50:114296
4297 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:504298 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri231c2972016-03-08 19:50:114299 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4300 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4301
4302 // Trigger connection migration. Since there is a non-migratable stream,
4303 // this should cause session to be continue without migrating.
4304 session->OnPathDegrading();
4305
4306 // Run the message loop so that data queued in the new socket is read by the
4307 // packet reader.
4308 base::RunLoop().RunUntilIdle();
4309
4310 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4311 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4312 EXPECT_EQ(1u, session->GetNumActiveStreams());
4313
Zhongyi Shi21e99532018-07-17 22:23:074314 // Resume the data to read the connectivity probing response to declare probe
4315 // as successful. Non-migratable streams will be closed.
4316 quic_data1.Resume();
4317 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4318 EXPECT_FALSE(HasActiveSession(host_port_pair_));
4319 EXPECT_EQ(0u, session->GetNumActiveStreams());
jri231c2972016-03-08 19:50:114320
Zhongyi Shi21e99532018-07-17 22:23:074321 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
4322 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
jri231c2972016-03-08 19:50:114323 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4324 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4325}
4326
jri9c541572016-03-29 17:51:484327TEST_P(QuicStreamFactoryTest, MigrateSessionEarlyConnectionMigrationDisabled) {
Zhongyi Shi1a054612018-06-14 04:59:084328 InitializeConnectionMigrationV2Test(
jri9c541572016-03-29 17:51:484329 {kDefaultNetworkForTests, kNewNetworkForTests});
4330 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4331 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4332
rcha00569732016-08-27 11:09:364333 MockQuicData socket_data;
4334 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434335 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
4336 socket_data.AddWrite(
4337 SYNCHRONOUS,
4338 client_maker_.MakeRstPacket(2, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:524339 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:174340 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9c541572016-03-29 17:51:484341
4342 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:454343 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:334344 EXPECT_EQ(ERR_IO_PENDING,
4345 request.Request(host_port_pair_, version_, privacy_mode_,
4346 DEFAULT_PRIORITY, SocketTag(),
4347 /*cert_verify_flags=*/0, url_, net_log_,
4348 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:014349 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:244350 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9c541572016-03-29 17:51:484351 EXPECT_TRUE(stream.get());
4352
4353 // Cause QUIC stream to be created.
4354 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:394355 request_info.traffic_annotation =
4356 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274357 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394358 net_log_, CompletionOnceCallback()));
jri9c541572016-03-29 17:51:484359
4360 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:504361 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri9c541572016-03-29 17:51:484362 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4363 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4364
4365 // Set session config to have connection migration disabled.
Ryan Hamilton8d9ee76e2018-05-29 23:52:524366 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
4367 session->config());
jri9c541572016-03-29 17:51:484368 EXPECT_TRUE(session->config()->DisableConnectionMigration());
4369
4370 // Trigger connection migration. Since there is a non-migratable stream,
4371 // this should cause session to be continue without migrating.
4372 session->OnPathDegrading();
4373
4374 // Run the message loop so that data queued in the new socket is read by the
4375 // packet reader.
4376 base::RunLoop().RunUntilIdle();
4377
4378 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4379 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4380 EXPECT_EQ(1u, session->GetNumActiveStreams());
4381
4382 stream.reset();
4383
4384 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4385 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4386}
4387
Zhongyi Shi3c4c9e92018-07-02 23:16:234388// Regression test for http://crbug.com/791886.
4389// This test verifies that the old packet writer which encountered an
4390// asynchronous write error will be blocked during migration on write error. New
4391// packets would not be written until the one with write error is rewritten on
4392// the new network.
4393TEST_P(QuicStreamFactoryTest, MigrateSessionOnAysncWriteError) {
4394 InitializeConnectionMigrationV2Test(
4395 {kDefaultNetworkForTests, kNewNetworkForTests});
4396 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4397 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4398 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4399
4400 // Using a testing task runner so that we can control time.
4401 // base::RunLoop() controls mocked socket writes and reads.
4402 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4403 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4404
4405 MockQuicData socket_data;
4406 quic::QuicStreamOffset header_stream_offset = 0;
4407 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4408 socket_data.AddWrite(
4409 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4410 socket_data.AddWrite(ASYNC, ERR_ADDRESS_UNREACHABLE);
4411 socket_data.AddSocketDataToFactory(socket_factory_.get());
4412
4413 // Set up second socket data provider that is used after
4414 // migration. The request is rewritten to this new socket, and the
4415 // response to the request is read on this new socket.
4416 MockQuicData socket_data1;
4417 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
4418 2, GetNthClientInitiatedStreamId(0),
4419 true, true, &header_stream_offset));
4420 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
4421 3, GetNthClientInitiatedStreamId(1),
4422 GetNthClientInitiatedStreamId(0), true,
4423 true, &header_stream_offset));
4424 socket_data1.AddRead(
4425 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
4426 false, false));
4427 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4428 socket_data1.AddWrite(SYNCHRONOUS,
4429 client_maker_.MakeAckAndRstPacket(
4430 4, false, GetNthClientInitiatedStreamId(0),
4431 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
4432 socket_data1.AddWrite(
4433 SYNCHRONOUS,
4434 client_maker_.MakeRstPacket(5, false, GetNthClientInitiatedStreamId(1),
4435 quic::QUIC_STREAM_CANCELLED, 0));
4436
4437 socket_data1.AddSocketDataToFactory(socket_factory_.get());
4438
4439 // Create request #1 and QuicHttpStream.
4440 QuicStreamRequest request1(factory_.get());
4441 EXPECT_EQ(ERR_IO_PENDING,
4442 request1.Request(host_port_pair_, version_, privacy_mode_,
4443 DEFAULT_PRIORITY, SocketTag(),
4444 /*cert_verify_flags=*/0, url_, net_log_,
4445 &net_error_details_, callback_.callback()));
4446 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4447 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
4448 EXPECT_TRUE(stream1.get());
4449
4450 HttpRequestInfo request_info1;
4451 request_info1.method = "GET";
4452 request_info1.url = GURL("https://www.example.org/");
4453 request_info1.traffic_annotation =
4454 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4455 EXPECT_EQ(OK,
4456 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
4457 net_log_, CompletionOnceCallback()));
4458
4459 // Request #2 returns synchronously because it pools to existing session.
4460 TestCompletionCallback callback2;
4461 QuicStreamRequest request2(factory_.get());
4462 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_, privacy_mode_,
4463 DEFAULT_PRIORITY, SocketTag(),
4464 /*cert_verify_flags=*/0, url_, net_log_,
4465 &net_error_details_, callback2.callback()));
4466 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
4467 EXPECT_TRUE(stream2.get());
4468
4469 HttpRequestInfo request_info2;
4470 request_info2.method = "GET";
4471 request_info2.url = GURL("https://www.example.org/");
4472 request_info2.traffic_annotation =
4473 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4474 EXPECT_EQ(OK,
4475 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
4476 net_log_, CompletionOnceCallback()));
4477
4478 // Ensure that session is alive and active.
4479 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
4480 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4481 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4482 EXPECT_EQ(2u, session->GetNumActiveStreams());
4483
4484 // Send GET request on stream1. This should cause an async write error.
4485 HttpResponseInfo response;
4486 HttpRequestHeaders request_headers;
4487 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
4488 callback_.callback()));
4489 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4490
4491 // Run the message loop so that asynchronous write completes and a connection
4492 // migration on write error attempt is posted in QuicStreamFactory's task
4493 // runner.
4494 base::RunLoop().RunUntilIdle();
4495 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4496
4497 // Send GET request on stream. This will cause another write attempt before
4498 // migration on write error is exectued.
4499 HttpResponseInfo response2;
4500 HttpRequestHeaders request_headers2;
4501 EXPECT_EQ(OK, stream2->SendRequest(request_headers2, &response2,
4502 callback2.callback()));
4503
4504 // Run the task runner so that migration on write error is finally executed.
4505 task_runner->RunUntilIdle();
4506
Zhongyi Shia7dd46b2018-07-12 22:59:294507 // Verify the session is still alive and not marked as going away.
Zhongyi Shi3c4c9e92018-07-02 23:16:234508 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:294509 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi3c4c9e92018-07-02 23:16:234510 EXPECT_EQ(2u, session->GetNumActiveStreams());
Zhongyi Shia7dd46b2018-07-12 22:59:294511 // There should be one task posted to migrate back to the default network in
4512 // kMinRetryTimeForDefaultNetworkSecs.
4513 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4514 EXPECT_EQ(base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs),
4515 task_runner->NextPendingTaskDelay());
Zhongyi Shi3c4c9e92018-07-02 23:16:234516
4517 // Verify that response headers on the migrated socket were delivered to the
4518 // stream.
4519 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
4520 EXPECT_EQ(200, response.headers->response_code());
4521
4522 stream1.reset();
4523 stream2.reset();
4524
4525 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4526 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4527 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
4528 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
4529}
4530
Zhongyi Shia7dd46b2018-07-12 22:59:294531// Verify session is not marked as going away after connection migration on
4532// write error and migrate back to default network logic is applied to bring the
4533// migrated session back to the default network. Migration singals delivered
4534// in the following order (alternate network is always availabe):
4535// - session on the default network encountered a write error;
4536// - session successfully migrated to the non-default network;
4537// - session attempts to migrate back to default network post migration;
4538// - migration back to the default network is successful.
4539TEST_P(QuicStreamFactoryTest, MigrateBackToDefaultPostMigrationOnWriteError) {
4540 InitializeConnectionMigrationV2Test(
4541 {kDefaultNetworkForTests, kNewNetworkForTests});
4542 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4543 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4544 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4545
4546 // Using a testing task runner so that we can control time.
4547 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4548 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4549
4550 MockQuicData socket_data;
4551 quic::QuicStreamOffset header_stream_offset = 0;
4552 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4553 socket_data.AddWrite(
4554 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4555 socket_data.AddWrite(ASYNC, ERR_ADDRESS_UNREACHABLE);
4556 socket_data.AddSocketDataToFactory(socket_factory_.get());
4557
4558 // Set up second socket data provider that is used after
4559 // migration. The request is rewritten to this new socket, and the
4560 // response to the request is read on this new socket.
4561 MockQuicData quic_data2;
4562 quic_data2.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
4563 2, GetNthClientInitiatedStreamId(0),
4564 true, true, &header_stream_offset));
4565 quic_data2.AddRead(
4566 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
4567 false, false));
4568 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4569 quic_data2.AddSocketDataToFactory(socket_factory_.get());
4570
4571 // Create request QuicHttpStream.
4572 QuicStreamRequest request1(factory_.get());
4573 EXPECT_EQ(ERR_IO_PENDING,
4574 request1.Request(host_port_pair_, version_, privacy_mode_,
4575 DEFAULT_PRIORITY, SocketTag(),
4576 /*cert_verify_flags=*/0, url_, net_log_,
4577 &net_error_details_, callback_.callback()));
4578 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4579 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
4580 EXPECT_TRUE(stream1.get());
4581
4582 HttpRequestInfo request_info1;
4583 request_info1.method = "GET";
4584 request_info1.url = GURL("https://www.example.org/");
4585 request_info1.traffic_annotation =
4586 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4587 EXPECT_EQ(OK,
4588 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
4589 net_log_, CompletionOnceCallback()));
4590
4591 // Ensure that session is alive and active.
4592 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
4593 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4594 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4595 EXPECT_EQ(1u, session->GetNumActiveStreams());
4596
4597 // Send GET request. This should cause an async write error.
4598 HttpResponseInfo response;
4599 HttpRequestHeaders request_headers;
4600 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
4601 callback_.callback()));
4602 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4603
4604 // Run the message loop so that asynchronous write completes and a connection
4605 // migration on write error attempt is posted in QuicStreamFactory's task
4606 // runner.
4607 base::RunLoop().RunUntilIdle();
4608 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4609
4610 // Run the task runner so that migration on write error is finally executed.
4611 task_runner->RunUntilIdle();
4612
4613 // Verify the session is still alive and not marked as going away.
4614 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4615 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4616 EXPECT_EQ(1u, session->GetNumActiveStreams());
4617 // There should be one task posted to migrate back to the default network in
4618 // kMinRetryTimeForDefaultNetworkSecs.
4619 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4620 base::TimeDelta expected_delay =
4621 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs);
4622 EXPECT_EQ(expected_delay, task_runner->NextPendingTaskDelay());
4623
4624 // Verify that response headers on the migrated socket were delivered to the
4625 // stream.
4626 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
4627 EXPECT_EQ(200, response.headers->response_code());
4628
4629 // Set up the third socket data provider for migrate back to default network.
4630 MockQuicData quic_data3;
4631 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:254632 quic_data3.AddWrite(SYNCHRONOUS,
4633 client_maker_.MakeConnectivityProbingPacket(3, false));
Zhongyi Shia7dd46b2018-07-12 22:59:294634 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:254635 quic_data3.AddRead(ASYNC,
4636 server_maker_.MakeConnectivityProbingPacket(2, false));
Zhongyi Shia7dd46b2018-07-12 22:59:294637 quic_data3.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4638 quic_data3.AddWrite(ASYNC, client_maker_.MakeAckPacket(4, 1, 2, 1, 1, true));
4639 quic_data3.AddWrite(
4640 SYNCHRONOUS,
4641 client_maker_.MakeRstPacket(5, false, GetNthClientInitiatedStreamId(0),
4642 quic::QUIC_STREAM_CANCELLED, 0));
4643 quic_data3.AddSocketDataToFactory(socket_factory_.get());
4644
4645 // Fast forward to fire the migrate back timer and verify the session
4646 // successfully migrates back to the default network.
4647 task_runner->FastForwardBy(expected_delay);
4648
4649 // Verify the session is still alive and not marked as going away.
4650 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4651 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4652 EXPECT_EQ(1u, session->GetNumActiveStreams());
4653
4654 // There should be one task posted to one will resend a connectivity probe and
4655 // the other will retry migrate back, both are cancelled.
4656 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
4657 task_runner->FastForwardBy(
4658 base::TimeDelta::FromSeconds(2 * kMinRetryTimeForDefaultNetworkSecs));
4659 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4660
4661 stream1.reset();
4662 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4663 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4664 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
4665 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
4666 EXPECT_TRUE(quic_data3.AllReadDataConsumed());
4667 EXPECT_TRUE(quic_data3.AllWriteDataConsumed());
4668}
4669
Zhongyi Shic1449372018-08-09 09:58:584670// This test verifies that the connection will not attempt connection migration
4671// (send connectivity probes on alternate path) when path degrading is detected
4672// and handshake is not confirmed.
4673TEST_P(QuicStreamFactoryTest,
4674 NoMigrationOnPathDegradingBeforeHandshakeConfirmed) {
4675 InitializeConnectionMigrationV2Test(
4676 {kDefaultNetworkForTests, kNewNetworkForTests});
4677
4678 // Using a testing task runner.
4679 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4680 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4681
4682 // Use cold start mode to send crypto message for handshake.
4683 crypto_client_stream_factory_.set_handshake_mode(
4684 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
4685
4686 MockQuicData socket_data;
4687 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4688 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
4689 socket_data.AddSocketDataToFactory(socket_factory_.get());
4690
4691 // Create request and QuicHttpStream.
4692 QuicStreamRequest request(factory_.get());
4693 EXPECT_EQ(ERR_IO_PENDING,
4694 request.Request(host_port_pair_, version_, privacy_mode_,
4695 DEFAULT_PRIORITY, SocketTag(),
4696 /*cert_verify_flags=*/0, url_, net_log_,
4697 &net_error_details_, callback_.callback()));
4698
4699 base::RunLoop().RunUntilIdle();
4700
4701 // Ensure that session is alive but not active.
4702 EXPECT_FALSE(HasActiveSession(host_port_pair_));
4703 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
4704 QuicChromiumClientSession* session = GetPendingSession(host_port_pair_);
4705 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4706 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4707
4708 // Cause the connection to report path degrading to the session.
4709 // Session will ignore the signal as handshake is not completed.
4710 session->connection()->OnPathDegradingTimeout();
4711 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4712
4713 EXPECT_FALSE(HasActiveSession(host_port_pair_));
Zhongyi Shi8de43832018-08-15 23:40:004714 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
Zhongyi Shic1449372018-08-09 09:58:584715 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4716 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4717}
4718
Zhongyi Shi8de43832018-08-15 23:40:004719TEST_P(QuicStreamFactoryTest, NewConnectionBeforeHandshakeAfterIdleTimeout) {
4720 TestNewConnectionOnAlternateNetworkBeforeHandshake(
4721 quic::QUIC_NETWORK_IDLE_TIMEOUT);
4722}
4723
4724TEST_P(QuicStreamFactoryTest, NewConnectionAfterHandshakeTimeout) {
4725 TestNewConnectionOnAlternateNetworkBeforeHandshake(
4726 quic::QUIC_HANDSHAKE_TIMEOUT);
4727}
4728
4729void QuicStreamFactoryTestBase::
4730 TestNewConnectionOnAlternateNetworkBeforeHandshake(
4731 quic::QuicErrorCode quic_error) {
4732 DCHECK(quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT ||
4733 quic_error == quic::QUIC_HANDSHAKE_TIMEOUT);
4734 InitializeConnectionMigrationV2Test(
4735 {kDefaultNetworkForTests, kNewNetworkForTests});
4736
4737 // Using a testing task runner.
4738 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4739 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4740
4741 // Use cold start mode to send crypto message for handshake.
4742 crypto_client_stream_factory_.set_handshake_mode(
4743 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
4744
4745 // Socket data for connection on the default network.
4746 MockQuicData socket_data;
4747 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4748 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
4749 socket_data.AddSocketDataToFactory(socket_factory_.get());
4750
4751 // Socket data for connection on the alternate network.
4752 MockQuicData socket_data2;
4753 quic::QuicStreamOffset header_stream_offset = 0;
4754 socket_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
4755 socket_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
4756 // Change the encryption level after handshake is confirmed.
4757 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
4758 socket_data2.AddWrite(
4759 ASYNC, ConstructInitialSettingsPacket(2, &header_stream_offset));
4760 socket_data2.AddWrite(
4761 ASYNC, ConstructGetRequestPacket(3, GetNthClientInitiatedStreamId(0),
4762 true, true, &header_stream_offset));
4763 socket_data2.AddRead(
4764 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
4765 false, false));
4766 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4767 socket_data2.AddWrite(SYNCHRONOUS,
4768 client_maker_.MakeAckAndRstPacket(
4769 4, false, GetNthClientInitiatedStreamId(0),
4770 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
4771 socket_data2.AddSocketDataToFactory(socket_factory_.get());
4772
4773 // Create request and QuicHttpStream.
4774 QuicStreamRequest request(factory_.get());
4775 EXPECT_EQ(ERR_IO_PENDING,
4776 request.Request(host_port_pair_, version_, privacy_mode_,
4777 DEFAULT_PRIORITY, SocketTag(),
4778 /*cert_verify_flags=*/0, url_, net_log_,
4779 &net_error_details_, callback_.callback()));
4780
4781 base::RunLoop().RunUntilIdle();
4782
4783 // Ensure that session is alive but not active.
4784 EXPECT_FALSE(HasActiveSession(host_port_pair_));
4785 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
4786 QuicChromiumClientSession* session = GetPendingSession(host_port_pair_);
4787 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4788 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4789
4790 quic::QuicString error_details;
4791 if (quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT) {
4792 error_details = "No recent network activity.";
4793 } else {
4794 error_details = "Handshake timeout expired.";
4795 }
4796 session->connection()->CloseConnection(
4797 quic_error, error_details, quic::ConnectionCloseBehavior::SILENT_CLOSE);
4798
4799 // A task will be posted to clean up the session in the factory.
4800 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4801 task_runner->FastForwardUntilNoTasksRemain();
4802
4803 // Verify a new session is created on the alternate network.
4804 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
4805 EXPECT_FALSE(HasActiveSession(host_port_pair_));
4806 QuicChromiumClientSession* session2 = GetPendingSession(host_port_pair_);
4807 EXPECT_NE(session, session2);
4808
4809 // Confirm the handshake on the alternate network.
4810 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
4811 quic::QuicSession::HANDSHAKE_CONFIRMED);
4812 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4813 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4814 // Resume the data now so that data can be sent and read.
4815 socket_data2.Resume();
4816
4817 // Create the stream.
4818 std::unique_ptr<HttpStream> stream = CreateStream(&request);
4819 EXPECT_TRUE(stream.get());
4820 HttpRequestInfo request_info;
4821 request_info.method = "GET";
4822 request_info.url = GURL("https://www.example.org/");
4823 request_info.traffic_annotation =
4824 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4825 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
4826 net_log_, CompletionOnceCallback()));
4827 // Send the request.
4828 HttpResponseInfo response;
4829 HttpRequestHeaders request_headers;
4830 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
4831 callback_.callback()));
4832 // Run the message loop to finish asynchronous mock write.
4833 base::RunLoop().RunUntilIdle();
4834 // Read the response.
4835 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
4836 EXPECT_EQ(200, response.headers->response_code());
4837
4838 stream.reset();
4839 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4840 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4841 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
4842 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
4843}
4844
Zhongyi Shi247d6322018-07-24 07:03:354845// Test that connection will be closed with PACKET_WRITE_ERROR if a write error
4846// is triggered before handshake is confirmed and connection migration is turned
4847// on.
4848TEST_P(QuicStreamFactoryTest, MigrationOnWriteErrorBeforeHandshakeConfirmed) {
4849 InitializeConnectionMigrationV2Test(
4850 {kDefaultNetworkForTests, kNewNetworkForTests});
4851
4852 // Use unmocked crypto stream to do crypto connect.
4853 crypto_client_stream_factory_.set_handshake_mode(
Zhongyi Shi879659422018-08-02 17:58:254854 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
Zhongyi Shi247d6322018-07-24 07:03:354855
4856 MockQuicData socket_data;
4857 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4858 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
4859 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
4860 socket_data.AddSocketDataToFactory(socket_factory_.get());
4861
4862 // Create request, should fail after the write of the CHLO fails.
4863 QuicStreamRequest request(factory_.get());
4864 EXPECT_EQ(ERR_IO_PENDING,
4865 request.Request(host_port_pair_, version_, privacy_mode_,
4866 DEFAULT_PRIORITY, SocketTag(),
4867 /*cert_verify_flags=*/0, url_, net_log_,
4868 &net_error_details_, callback_.callback()));
4869 EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED, callback_.WaitForResult());
4870 EXPECT_FALSE(HasActiveSession(host_port_pair_));
4871 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
4872
4873 // Verify new requests can be sent normally.
4874 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:274875 MockCryptoClientStream::COLD_START);
Zhongyi Shi247d6322018-07-24 07:03:354876 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4877 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4878 MockQuicData socket_data2;
4879 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4880 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
4881 socket_data2.AddSocketDataToFactory(socket_factory_.get());
4882
4883 QuicStreamRequest request2(factory_.get());
4884 EXPECT_EQ(ERR_IO_PENDING,
4885 request2.Request(host_port_pair_, version_, privacy_mode_,
4886 DEFAULT_PRIORITY, SocketTag(),
4887 /*cert_verify_flags=*/0, url_, net_log_,
4888 &net_error_details_, callback_.callback()));
4889 EXPECT_FALSE(HasActiveSession(host_port_pair_));
4890 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
4891 // Run the message loop to complete host resolution.
4892 base::RunLoop().RunUntilIdle();
4893
4894 // Complete handshake. QuicStreamFactory::Job should complete and succeed.
4895 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
4896 quic::QuicSession::HANDSHAKE_CONFIRMED);
4897 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4898 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4899 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
4900
4901 // Create QuicHttpStream.
4902 std::unique_ptr<HttpStream> stream = CreateStream(&request2);
4903 EXPECT_TRUE(stream.get());
4904 stream.reset();
4905 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4906 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4907 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
4908 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
4909}
4910
jri9f303712016-09-13 01:10:224911void QuicStreamFactoryTestBase::TestMigrationOnWriteError(
4912 IoMode write_error_mode) {
Zhongyi Shi1a054612018-06-14 04:59:084913 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:224914 {kDefaultNetworkForTests, kNewNetworkForTests});
4915 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4916 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4917 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4918
Zhongyi Shi3c4c9e92018-07-02 23:16:234919 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4920
jri9f303712016-09-13 01:10:224921 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524922 quic::QuicStreamOffset header_stream_offset = 0;
jri9f303712016-09-13 01:10:224923 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
rch5cb522462017-04-25 20:18:364924 socket_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434925 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
jri9f303712016-09-13 01:10:224926 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:174927 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:224928
4929 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:454930 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:334931 EXPECT_EQ(ERR_IO_PENDING,
4932 request.Request(host_port_pair_, version_, privacy_mode_,
4933 DEFAULT_PRIORITY, SocketTag(),
4934 /*cert_verify_flags=*/0, url_, net_log_,
4935 &net_error_details_, callback_.callback()));
jri9f303712016-09-13 01:10:224936 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:244937 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:224938 EXPECT_TRUE(stream.get());
4939
4940 // Cause QUIC stream to be created.
4941 HttpRequestInfo request_info;
4942 request_info.method = "GET";
4943 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:394944 request_info.traffic_annotation =
4945 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274946 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394947 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:224948
4949 // Ensure that session is alive and active.
4950 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
4951 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4952 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4953
4954 // Set up second socket data provider that is used after
4955 // migration. The request is rewritten to this new socket, and the
4956 // response to the request is read on this new socket.
4957 MockQuicData socket_data1;
Zhongyi Shi32f2fd02018-04-16 18:23:434958 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
4959 2, GetNthClientInitiatedStreamId(0),
4960 true, true, &header_stream_offset));
4961 socket_data1.AddRead(
4962 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
4963 false, false));
jri9f303712016-09-13 01:10:224964 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434965 socket_data1.AddWrite(SYNCHRONOUS,
4966 client_maker_.MakeAckAndRstPacket(
4967 3, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:524968 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:174969 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:224970
4971 // Send GET request on stream. This should cause a write error, which triggers
4972 // a connection migration attempt.
4973 HttpResponseInfo response;
4974 HttpRequestHeaders request_headers;
4975 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
4976 callback_.callback()));
4977
4978 // Run the message loop so that the migration attempt is executed and
4979 // data queued in the new socket is read by the packet reader.
4980 base::RunLoop().RunUntilIdle();
4981
Zhongyi Shia7dd46b2018-07-12 22:59:294982 // Verify that session is alive and not marked as going awya.
jri9f303712016-09-13 01:10:224983 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:294984 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri9f303712016-09-13 01:10:224985 EXPECT_EQ(1u, session->GetNumActiveStreams());
4986
4987 // Verify that response headers on the migrated socket were delivered to the
4988 // stream.
4989 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
4990 EXPECT_EQ(200, response.headers->response_code());
4991
4992 stream.reset();
4993
4994 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4995 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4996 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
4997 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
4998}
4999
5000TEST_P(QuicStreamFactoryTest, MigrateSessionOnWriteErrorSynchronous) {
5001 TestMigrationOnWriteError(SYNCHRONOUS);
5002}
5003
5004TEST_P(QuicStreamFactoryTest, MigrateSessionOnWriteErrorAsync) {
5005 TestMigrationOnWriteError(ASYNC);
5006}
5007
5008void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorNoNewNetwork(
5009 IoMode write_error_mode) {
Zhongyi Shi1a054612018-06-14 04:59:085010 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri9f303712016-09-13 01:10:225011 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5012 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5013
jri5b785512016-09-13 04:29:115014 // Use the test task runner, to force the migration alarm timeout later.
5015 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
5016
jri9f303712016-09-13 01:10:225017 MockQuicData socket_data;
5018 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:435019 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jri9f303712016-09-13 01:10:225020 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:175021 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:225022
5023 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:455024 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:335025 EXPECT_EQ(ERR_IO_PENDING,
5026 request.Request(host_port_pair_, version_, privacy_mode_,
5027 DEFAULT_PRIORITY, SocketTag(),
5028 /*cert_verify_flags=*/0, url_, net_log_,
5029 &net_error_details_, callback_.callback()));
jri9f303712016-09-13 01:10:225030 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:245031 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:225032 EXPECT_TRUE(stream.get());
5033
5034 // Cause QUIC stream to be created.
5035 HttpRequestInfo request_info;
5036 request_info.method = "GET";
5037 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:395038 request_info.traffic_annotation =
5039 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:275040 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:395041 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:225042
5043 // Ensure that session is alive and active.
5044 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5045 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5046 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5047
jri5b785512016-09-13 04:29:115048 // Send GET request on stream. This causes a write error, which triggers
5049 // a connection migration attempt. Since there are no networks
5050 // to migrate to, this causes the session to wait for a new network.
jri9f303712016-09-13 01:10:225051 HttpResponseInfo response;
5052 HttpRequestHeaders request_headers;
5053 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5054 callback_.callback()));
jri5b785512016-09-13 04:29:115055
5056 // Complete any pending writes. Pending async MockQuicData writes
5057 // are run on the message loop, not on the test runner.
jri9f303712016-09-13 01:10:225058 base::RunLoop().RunUntilIdle();
jri5b785512016-09-13 04:29:115059
5060 // Write error causes migration task to be posted. Spin the loop.
5061 if (write_error_mode == ASYNC)
5062 runner_->RunNextTask();
5063
5064 // Migration has not yet failed. The session should be alive and active.
5065 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5066 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5067 EXPECT_EQ(1u, session->GetNumActiveStreams());
5068 EXPECT_TRUE(session->connection()->writer()->IsWriteBlocked());
5069
5070 // The migration will not fail until the migration alarm timeout.
5071 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5072 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5073 EXPECT_EQ(1u, session->GetNumActiveStreams());
5074 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
5075
5076 // Force migration alarm timeout to run.
5077 RunTestLoopUntilIdle();
5078
5079 // The connection should be closed. A request for response headers
5080 // should fail.
jri9f303712016-09-13 01:10:225081 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5082 EXPECT_FALSE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:115083 EXPECT_EQ(ERR_NETWORK_CHANGED, callback_.WaitForResult());
5084 EXPECT_EQ(ERR_NETWORK_CHANGED,
5085 stream->ReadResponseHeaders(callback_.callback()));
jri9f303712016-09-13 01:10:225086
5087 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5088 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5089}
5090
5091TEST_P(QuicStreamFactoryTest,
5092 MigrateSessionOnWriteErrorNoNewNetworkSynchronous) {
5093 TestMigrationOnWriteErrorNoNewNetwork(SYNCHRONOUS);
5094}
5095
5096TEST_P(QuicStreamFactoryTest, MigrateSessionOnWriteErrorNoNewNetworkAsync) {
5097 TestMigrationOnWriteErrorNoNewNetwork(ASYNC);
5098}
5099
Zhongyi Shi0439ecc72018-07-11 04:41:265100TEST_P(QuicStreamFactoryTest,
5101 MigrateSessionOnWriteErrorWithMultipleRequestsSync) {
5102 TestMigrationOnWriteErrorWithMultipleRequests(SYNCHRONOUS);
5103}
5104
5105TEST_P(QuicStreamFactoryTest,
5106 MigrateSessionOnWriteErrorWithMultipleRequestsAsync) {
5107 TestMigrationOnWriteErrorWithMultipleRequests(ASYNC);
5108}
5109
5110// Sets up a test which verifies that connection migration on write error can
5111// eventually succeed and rewrite the packet on the new network with *multiple*
5112// migratable streams.
5113void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorWithMultipleRequests(
5114 IoMode write_error_mode) {
5115 InitializeConnectionMigrationV2Test(
5116 {kDefaultNetworkForTests, kNewNetworkForTests});
5117 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5118 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5119 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5120
5121 MockQuicData socket_data;
5122 quic::QuicStreamOffset header_stream_offset = 0;
5123 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5124 socket_data.AddWrite(
5125 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5126 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
5127 socket_data.AddSocketDataToFactory(socket_factory_.get());
5128
5129 // Set up second socket data provider that is used after
5130 // migration. The request is rewritten to this new socket, and the
5131 // response to the request is read on this new socket.
5132 MockQuicData socket_data1;
5133 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
5134 2, GetNthClientInitiatedStreamId(0),
5135 true, true, &header_stream_offset));
5136 socket_data1.AddRead(
5137 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
5138 false, false));
5139 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5140 socket_data1.AddWrite(SYNCHRONOUS,
5141 client_maker_.MakeAckAndRstPacket(
5142 3, false, GetNthClientInitiatedStreamId(0),
5143 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
5144 socket_data1.AddWrite(
5145 SYNCHRONOUS,
5146 client_maker_.MakeRstPacket(4, false, GetNthClientInitiatedStreamId(1),
5147 quic::QUIC_STREAM_CANCELLED, 0));
5148
5149 socket_data1.AddSocketDataToFactory(socket_factory_.get());
5150
5151 // Create request #1 and QuicHttpStream.
5152 QuicStreamRequest request1(factory_.get());
5153 EXPECT_EQ(ERR_IO_PENDING,
5154 request1.Request(host_port_pair_, version_, privacy_mode_,
5155 DEFAULT_PRIORITY, SocketTag(),
5156 /*cert_verify_flags=*/0, url_, net_log_,
5157 &net_error_details_, callback_.callback()));
5158 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5159 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
5160 EXPECT_TRUE(stream1.get());
5161
5162 HttpRequestInfo request_info1;
5163 request_info1.method = "GET";
5164 request_info1.url = GURL("https://www.example.org/");
5165 request_info1.traffic_annotation =
5166 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5167 EXPECT_EQ(OK,
5168 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
5169 net_log_, CompletionOnceCallback()));
5170
5171 // Second request returns synchronously because it pools to existing session.
5172 TestCompletionCallback callback2;
5173 QuicStreamRequest request2(factory_.get());
5174 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_, privacy_mode_,
5175 DEFAULT_PRIORITY, SocketTag(),
5176 /*cert_verify_flags=*/0, url_, net_log_,
5177 &net_error_details_, callback2.callback()));
5178 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
5179 EXPECT_TRUE(stream2.get());
5180 HttpRequestInfo request_info2;
5181 request_info2.method = "GET";
5182 request_info2.url = GURL("https://www.example.org/");
5183 request_info2.traffic_annotation =
5184 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5185 EXPECT_EQ(OK,
5186 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
5187 net_log_, CompletionOnceCallback()));
5188
5189 // Ensure that session is alive and active.
5190 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5191 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5192 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5193 EXPECT_EQ(2u, session->GetNumActiveStreams());
5194
5195 // Send GET request on stream. This should cause a write error, which triggers
5196 // a connection migration attempt.
5197 HttpResponseInfo response;
5198 HttpRequestHeaders request_headers;
5199 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
5200 callback_.callback()));
5201
5202 // Run the message loop so that the migration attempt is executed and
5203 // data queued in the new socket is read by the packet reader.
5204 base::RunLoop().RunUntilIdle();
5205
Zhongyi Shia7dd46b2018-07-12 22:59:295206 // Verify session is still alive and not marked as going away.
Zhongyi Shi0439ecc72018-07-11 04:41:265207 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:295208 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:265209 EXPECT_EQ(2u, session->GetNumActiveStreams());
5210
5211 // Verify that response headers on the migrated socket were delivered to the
5212 // stream.
5213 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
5214 EXPECT_EQ(200, response.headers->response_code());
5215
5216 stream1.reset();
5217 stream2.reset();
5218
5219 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5220 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5221 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
5222 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
5223}
5224
5225TEST_P(QuicStreamFactoryTest, MigrateOnWriteErrorWithMixedRequestsSync) {
5226 TestMigrationOnWriteErrorMixedStreams(SYNCHRONOUS);
5227}
5228
5229TEST_P(QuicStreamFactoryTest, MigrateOnWriteErrorWithMixedRequestsAsync) {
5230 TestMigrationOnWriteErrorMixedStreams(ASYNC);
5231}
5232
5233// Sets up a test that verifies connection migration manages to migrate to
5234// alternate network after encountering a SYNC/ASYNC write error based on
5235// |write_error_mode| on the original network.
5236// Note there are mixed types of unfinished requests before migration: one
5237// migratable and one non-migratable. The *migratable* one triggers write
5238// error.
5239void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorMixedStreams(
5240 IoMode write_error_mode) {
5241 InitializeConnectionMigrationV2Test(
5242 {kDefaultNetworkForTests, kNewNetworkForTests});
5243 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5244 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5245 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5246
5247 int packet_number = 1;
5248 MockQuicData socket_data;
5249 quic::QuicStreamOffset header_stream_offset = 0;
5250 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5251 socket_data.AddWrite(
5252 SYNCHRONOUS,
5253 ConstructInitialSettingsPacket(packet_number++, &header_stream_offset));
5254 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
5255 socket_data.AddSocketDataToFactory(socket_factory_.get());
5256
5257 // Set up second socket data provider that is used after
5258 // migration. The request is rewritten to this new socket, and the
5259 // response to the request is read on this new socket.
5260 MockQuicData socket_data1;
5261 socket_data1.AddWrite(
5262 SYNCHRONOUS, ConstructGetRequestPacket(
5263 packet_number++, GetNthClientInitiatedStreamId(0), true,
5264 true, &header_stream_offset));
5265 socket_data1.AddWrite(
5266 SYNCHRONOUS, client_maker_.MakeRstPacket(packet_number++, true,
5267 GetNthClientInitiatedStreamId(1),
5268 quic::QUIC_STREAM_CANCELLED, 0));
5269 socket_data1.AddRead(
5270 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
5271 false, false));
5272 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5273 socket_data1.AddWrite(
5274 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
5275 packet_number++, false, GetNthClientInitiatedStreamId(0),
5276 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
5277 socket_data1.AddSocketDataToFactory(socket_factory_.get());
5278
5279 // Create request #1 and QuicHttpStream.
5280 QuicStreamRequest request1(factory_.get());
5281 EXPECT_EQ(ERR_IO_PENDING,
5282 request1.Request(host_port_pair_, version_, privacy_mode_,
5283 DEFAULT_PRIORITY, SocketTag(),
5284 /*cert_verify_flags=*/0, url_, net_log_,
5285 &net_error_details_, callback_.callback()));
5286 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5287 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
5288 EXPECT_TRUE(stream1.get());
5289
5290 HttpRequestInfo request_info1;
5291 request_info1.method = "GET";
5292 request_info1.url = GURL("https://www.example.org/");
5293 request_info1.traffic_annotation =
5294 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5295 EXPECT_EQ(OK,
5296 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
5297 net_log_, CompletionOnceCallback()));
5298
5299 // Second request returns synchronously because it pools to existing session.
5300 TestCompletionCallback callback2;
5301 QuicStreamRequest request2(factory_.get());
5302 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_, privacy_mode_,
5303 DEFAULT_PRIORITY, SocketTag(),
5304 /*cert_verify_flags=*/0, url_, net_log_,
5305 &net_error_details_, callback2.callback()));
5306 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
5307 EXPECT_TRUE(stream2.get());
5308
5309 HttpRequestInfo request_info2;
5310 request_info2.method = "GET";
Zhongyi Shibb28b1f2018-07-18 02:41:265311 request_info2.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Zhongyi Shi0439ecc72018-07-11 04:41:265312 request_info2.url = GURL("https://www.example.org/");
5313 request_info2.traffic_annotation =
5314 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5315 EXPECT_EQ(OK,
5316 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
5317 net_log_, CompletionOnceCallback()));
5318
5319 // Ensure that session is alive and active.
5320 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5321 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5322 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5323 EXPECT_EQ(2u, session->GetNumActiveStreams());
5324
5325 // Send GET request on stream 1. This should cause a write error, which
5326 // triggers a connection migration attempt.
5327 HttpResponseInfo response;
5328 HttpRequestHeaders request_headers;
5329 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
5330 callback_.callback()));
5331
5332 // Run the message loop so that the migration attempt is executed and
5333 // data queued in the new socket is read by the packet reader.
5334 base::RunLoop().RunUntilIdle();
5335
Zhongyi Shia7dd46b2018-07-12 22:59:295336 // Verify that the session is still alive and not marked as going away.
5337 // Non-migratable stream should be closed due to migration.
Zhongyi Shi0439ecc72018-07-11 04:41:265338 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:295339 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:265340 EXPECT_EQ(1u, session->GetNumActiveStreams());
5341
5342 // Verify that response headers on the migrated socket were delivered to the
5343 // stream.
5344 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
5345 EXPECT_EQ(200, response.headers->response_code());
5346
5347 stream1.reset();
5348
5349 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5350 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5351 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
5352 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
5353}
5354
5355TEST_P(QuicStreamFactoryTest, MigrateOnWriteErrorWithMixedRequests2Sync) {
5356 TestMigrationOnWriteErrorMixedStreams2(SYNCHRONOUS);
5357}
5358
5359TEST_P(QuicStreamFactoryTest, MigrateOnWriteErrorWithMixedRequests2Async) {
5360 TestMigrationOnWriteErrorMixedStreams2(ASYNC);
5361}
5362
5363// The one triggers write error is a non-migratable stream.
5364// Sets up a test that verifies connection migration manages to migrate to
5365// alternate network after encountering a SYNC/ASYNC write error based on
5366// |write_error_mode| on the original network.
5367// Note there are mixed types of unfinished requests before migration: one
5368// migratable and one non-migratable. The *non-migratable* one triggers write
5369// error.
5370void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorMixedStreams2(
5371 IoMode write_error_mode) {
5372 InitializeConnectionMigrationV2Test(
5373 {kDefaultNetworkForTests, kNewNetworkForTests});
5374 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5375 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5376 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5377
5378 int packet_number = 1;
5379 MockQuicData socket_data;
5380 quic::QuicStreamOffset header_stream_offset = 0;
5381 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5382 socket_data.AddWrite(
5383 SYNCHRONOUS,
5384 ConstructInitialSettingsPacket(packet_number++, &header_stream_offset));
5385 socket_data.AddWrite(write_error_mode,
5386 ERR_ADDRESS_UNREACHABLE); // Write error.
5387 socket_data.AddSocketDataToFactory(socket_factory_.get());
5388
5389 // Set up second socket data provider that is used after
5390 // migration. The request is rewritten to this new socket, and the
5391 // response to the request is read on this new socket.
5392 MockQuicData socket_data1;
5393 // The packet triggered writer error will be sent anyway even if the stream
5394 // will be cancelled later.
5395 socket_data1.AddWrite(
5396 SYNCHRONOUS, ConstructGetRequestPacket(
5397 packet_number++, GetNthClientInitiatedStreamId(1), true,
5398 true, &header_stream_offset));
5399 socket_data1.AddWrite(
5400 SYNCHRONOUS, client_maker_.MakeRstPacket(packet_number++, true,
5401 GetNthClientInitiatedStreamId(1),
5402 quic::QUIC_STREAM_CANCELLED, 0));
5403 socket_data1.AddWrite(
5404 SYNCHRONOUS, ConstructGetRequestPacket(
5405 packet_number++, GetNthClientInitiatedStreamId(0), true,
5406 true, &header_stream_offset));
5407 socket_data1.AddRead(
5408 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
5409 false, false));
5410 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5411 socket_data1.AddWrite(
5412 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
5413 packet_number++, false, GetNthClientInitiatedStreamId(0),
5414 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
5415 socket_data1.AddSocketDataToFactory(socket_factory_.get());
5416
5417 // Create request #1 and QuicHttpStream.
5418 QuicStreamRequest request1(factory_.get());
5419 EXPECT_EQ(ERR_IO_PENDING,
5420 request1.Request(host_port_pair_, version_, privacy_mode_,
5421 DEFAULT_PRIORITY, SocketTag(),
5422 /*cert_verify_flags=*/0, url_, net_log_,
5423 &net_error_details_, callback_.callback()));
5424 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5425 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
5426 EXPECT_TRUE(stream1.get());
5427
5428 HttpRequestInfo request_info1;
5429 request_info1.method = "GET";
5430 request_info1.url = GURL("https://www.example.org/");
5431 request_info1.traffic_annotation =
5432 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5433 EXPECT_EQ(OK,
5434 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
5435 net_log_, CompletionOnceCallback()));
5436
5437 // Second request returns synchronously because it pools to existing session.
5438 TestCompletionCallback callback2;
5439 QuicStreamRequest request2(factory_.get());
5440 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_, privacy_mode_,
5441 DEFAULT_PRIORITY, SocketTag(),
5442 /*cert_verify_flags=*/0, url_, net_log_,
5443 &net_error_details_, callback2.callback()));
5444 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
5445 EXPECT_TRUE(stream2.get());
5446
5447 HttpRequestInfo request_info2;
5448 request_info2.method = "GET";
Zhongyi Shibb28b1f2018-07-18 02:41:265449 request_info2.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Zhongyi Shi0439ecc72018-07-11 04:41:265450 request_info2.url = GURL("https://www.example.org/");
5451 request_info2.traffic_annotation =
5452 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5453 EXPECT_EQ(OK,
5454 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
5455 net_log_, CompletionOnceCallback()));
5456
5457 // Ensure that session is alive and active.
5458 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5459 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5460 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5461 EXPECT_EQ(2u, session->GetNumActiveStreams());
5462
5463 // Send GET request on stream 2 which is non-migratable. This should cause a
5464 // write error, which triggers a connection migration attempt.
5465 HttpResponseInfo response2;
5466 HttpRequestHeaders request_headers2;
5467 EXPECT_EQ(OK, stream2->SendRequest(request_headers2, &response2,
5468 callback2.callback()));
5469
5470 // Run the message loop so that the migration attempt is executed and
Zhongyi Shia7dd46b2018-07-12 22:59:295471 // data queued in the new socket is read by the packet reader. Session is
5472 // still alive and not marked as going away, non-migratable stream will be
5473 // closed.
Zhongyi Shi0439ecc72018-07-11 04:41:265474 base::RunLoop().RunUntilIdle();
5475 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:295476 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:265477 EXPECT_EQ(1u, session->GetNumActiveStreams());
5478
5479 // Send GET request on stream 1.
5480 HttpResponseInfo response;
5481 HttpRequestHeaders request_headers;
5482 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
5483 callback_.callback()));
5484
5485 base::RunLoop().RunUntilIdle();
5486
5487 // Verify that response headers on the migrated socket were delivered to the
5488 // stream.
5489 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
5490 EXPECT_EQ(200, response.headers->response_code());
5491
5492 stream1.reset();
5493
5494 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5495 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5496 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
5497 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
5498}
5499
jri9f303712016-09-13 01:10:225500void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorNonMigratableStream(
5501 IoMode write_error_mode) {
5502 DVLOG(1) << "Mode: "
5503 << ((write_error_mode == SYNCHRONOUS) ? "SYNCHRONOUS" : "ASYNC");
Zhongyi Shi1a054612018-06-14 04:59:085504 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:225505 {kDefaultNetworkForTests, kNewNetworkForTests});
5506 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5507 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5508
5509 MockQuicData socket_data;
5510 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:435511 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jri9f303712016-09-13 01:10:225512 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:175513 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:225514
5515 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:455516 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:335517 EXPECT_EQ(ERR_IO_PENDING,
5518 request.Request(host_port_pair_, version_, privacy_mode_,
5519 DEFAULT_PRIORITY, SocketTag(),
5520 /*cert_verify_flags=*/0, url_, net_log_,
5521 &net_error_details_, callback_.callback()));
jri9f303712016-09-13 01:10:225522 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:245523 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:225524 EXPECT_TRUE(stream.get());
5525
5526 // Cause QUIC stream to be created, but marked as non-migratable.
5527 HttpRequestInfo request_info;
Zhongyi Shibb28b1f2018-07-18 02:41:265528 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
jri9f303712016-09-13 01:10:225529 request_info.method = "GET";
5530 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:395531 request_info.traffic_annotation =
5532 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:275533 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:395534 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:225535
5536 // Ensure that session is alive and active.
5537 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5538 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5539 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5540
5541 // Send GET request on stream. This should cause a write error, which triggers
5542 // a connection migration attempt.
5543 HttpResponseInfo response;
5544 HttpRequestHeaders request_headers;
5545 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5546 callback_.callback()));
5547
5548 // Run message loop to execute migration attempt.
5549 base::RunLoop().RunUntilIdle();
5550
5551 // Migration fails, and session is closed and deleted.
5552 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5553 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5554
5555 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5556 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5557}
5558
5559TEST_P(QuicStreamFactoryTest,
5560 MigrateSessionOnWriteErrorNonMigratableStreamSynchronous) {
5561 TestMigrationOnWriteErrorNonMigratableStream(SYNCHRONOUS);
5562}
5563
5564TEST_P(QuicStreamFactoryTest,
5565 MigrateSessionOnWriteErrorNonMigratableStreamAsync) {
5566 TestMigrationOnWriteErrorNonMigratableStream(ASYNC);
5567}
5568
5569void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorMigrationDisabled(
5570 IoMode write_error_mode) {
Zhongyi Shi1a054612018-06-14 04:59:085571 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:225572 {kDefaultNetworkForTests, kNewNetworkForTests});
5573 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5574 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5575
5576 MockQuicData socket_data;
5577 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:435578 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jri9f303712016-09-13 01:10:225579 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:175580 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:225581
5582 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:455583 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:335584 EXPECT_EQ(ERR_IO_PENDING,
5585 request.Request(host_port_pair_, version_, privacy_mode_,
5586 DEFAULT_PRIORITY, SocketTag(),
5587 /*cert_verify_flags=*/0, url_, net_log_,
5588 &net_error_details_, callback_.callback()));
jri9f303712016-09-13 01:10:225589 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:245590 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:225591 EXPECT_TRUE(stream.get());
5592
5593 // Cause QUIC stream to be created.
5594 HttpRequestInfo request_info;
5595 request_info.method = "GET";
5596 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:395597 request_info.traffic_annotation =
5598 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:275599 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:395600 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:225601
5602 // Ensure that session is alive and active.
5603 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5604 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5605 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5606
5607 // Set session config to have connection migration disabled.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525608 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
5609 session->config());
jri9f303712016-09-13 01:10:225610 EXPECT_TRUE(session->config()->DisableConnectionMigration());
5611
5612 // Send GET request on stream. This should cause a write error, which triggers
5613 // a connection migration attempt.
5614 HttpResponseInfo response;
5615 HttpRequestHeaders request_headers;
5616 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5617 callback_.callback()));
5618 // Run message loop to execute migration attempt.
5619 base::RunLoop().RunUntilIdle();
5620 // Migration fails, and session is closed and deleted.
5621 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5622 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5623 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5624 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5625}
5626
5627TEST_P(QuicStreamFactoryTest,
5628 MigrateSessionOnWriteErrorMigrationDisabledSynchronous) {
5629 TestMigrationOnWriteErrorMigrationDisabled(SYNCHRONOUS);
5630}
5631
5632TEST_P(QuicStreamFactoryTest,
5633 MigrateSessionOnWriteErrorMigrationDisabledAsync) {
5634 TestMigrationOnWriteErrorMigrationDisabled(ASYNC);
5635}
5636
Zhongyi Shi7f1d9212018-06-22 23:24:365637// Sets up a test which verifies that connection migration on write error can
5638// eventually succeed and rewrite the packet on the new network with singals
5639// delivered in the following order (alternate network is always availabe):
5640// - original network encounters a SYNC/ASYNC write error based on
5641// |write_error_mode_on_old_network|, the packet failed to be written is
5642// cached, session migrates immediately to the alternate network.
5643// - an immediate SYNC/ASYNC write error based on
5644// |write_error_mode_on_new_network| is encountered after migration to the
5645// alternate network, session migrates immediately to the original network.
5646// - an immediate SYNC/ASYNC write error based on
5647// |write_error_mode_on_old_network| is encountered after migration to the
5648// original network, session migrates immediately to the alternate network.
5649// - finally, session successfully sends the packet and reads the response on
5650// the alternate network.
5651// TODO(zhongyi): once https://crbug.com/855666 is fixed, this test should be
5652// modified to test that session is closed early if hopping between networks
5653// with consecutive write errors is detected.
jri9f303712016-09-13 01:10:225654void QuicStreamFactoryTestBase::TestMigrationOnMultipleWriteErrors(
Zhongyi Shi7f1d9212018-06-22 23:24:365655 IoMode write_error_mode_on_old_network,
5656 IoMode write_error_mode_on_new_network) {
5657 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:225658 {kDefaultNetworkForTests, kNewNetworkForTests});
5659 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5660 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5661 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5662
Zhongyi Shi7f1d9212018-06-22 23:24:365663 // Set up the socket data used by the original network, which encounters a
5664 // write erorr.
5665 MockQuicData socket_data1;
5666 quic::QuicStreamOffset header_stream_offset = 0;
5667 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5668 socket_data1.AddWrite(
5669 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5670 socket_data1.AddWrite(write_error_mode_on_old_network,
5671 ERR_ADDRESS_UNREACHABLE); // Write Error
5672 socket_data1.AddSocketDataToFactory(socket_factory_.get());
5673
5674 // Set up the socket data used by the alternate network, which also
5675 // encounters a write error.
5676 MockQuicData failed_quic_data2;
5677 failed_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5678 failed_quic_data2.AddWrite(write_error_mode_on_new_network, ERR_FAILED);
5679 failed_quic_data2.AddSocketDataToFactory(socket_factory_.get());
5680
5681 // Set up the third socket data used by original network, which encounters a
5682 // write error again.
5683 MockQuicData failed_quic_data1;
5684 failed_quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5685 failed_quic_data1.AddWrite(write_error_mode_on_old_network, ERR_FAILED);
5686 failed_quic_data1.AddSocketDataToFactory(socket_factory_.get());
5687
5688 // Set up the last socket data used by the alternate network, which will
5689 // finish migration successfully. The request is rewritten to this new socket,
5690 // and the response to the request is read on this socket.
5691 MockQuicData socket_data2;
5692 socket_data2.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
5693 2, GetNthClientInitiatedStreamId(0),
5694 true, true, &header_stream_offset));
5695 socket_data2.AddRead(
5696 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
5697 false, false));
5698 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5699 socket_data2.AddWrite(SYNCHRONOUS,
5700 client_maker_.MakeAckAndRstPacket(
5701 3, false, GetNthClientInitiatedStreamId(0),
5702 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
5703 socket_data2.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:225704
5705 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:455706 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:335707 EXPECT_EQ(ERR_IO_PENDING,
5708 request.Request(host_port_pair_, version_, privacy_mode_,
5709 DEFAULT_PRIORITY, SocketTag(),
5710 /*cert_verify_flags=*/0, url_, net_log_,
5711 &net_error_details_, callback_.callback()));
jri9f303712016-09-13 01:10:225712 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:245713 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:225714 EXPECT_TRUE(stream.get());
5715
5716 // Cause QUIC stream to be created.
5717 HttpRequestInfo request_info;
5718 request_info.method = "GET";
5719 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:395720 request_info.traffic_annotation =
5721 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:275722 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:395723 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:225724
5725 // Ensure that session is alive and active.
5726 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5727 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5728 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5729
Zhongyi Shi7f1d9212018-06-22 23:24:365730 // Send GET request on stream.
5731 // This should encounter a write error on network 1,
5732 // then migrate to network 2, which encounters another write error,
5733 // and migrate again to network 1, which encoutners one more write error.
5734 // Finally the session migrates to network 2 successfully.
jri9f303712016-09-13 01:10:225735 HttpResponseInfo response;
5736 HttpRequestHeaders request_headers;
5737 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5738 callback_.callback()));
jri9f303712016-09-13 01:10:225739
jri9f303712016-09-13 01:10:225740 base::RunLoop().RunUntilIdle();
Zhongyi Shi7f1d9212018-06-22 23:24:365741 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5742 EXPECT_EQ(1u, session->GetNumActiveStreams());
jri9f303712016-09-13 01:10:225743
Zhongyi Shi7f1d9212018-06-22 23:24:365744 // Verify that response headers on the migrated socket were delivered to the
5745 // stream.
5746 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
5747 EXPECT_EQ(200, response.headers->response_code());
jri9f303712016-09-13 01:10:225748
5749 stream.reset();
Zhongyi Shi7f1d9212018-06-22 23:24:365750 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
5751 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
5752 EXPECT_TRUE(failed_quic_data2.AllReadDataConsumed());
5753 EXPECT_TRUE(failed_quic_data2.AllWriteDataConsumed());
5754 EXPECT_TRUE(failed_quic_data1.AllReadDataConsumed());
5755 EXPECT_TRUE(failed_quic_data1.AllWriteDataConsumed());
5756 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
5757 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
jri9f303712016-09-13 01:10:225758}
5759
5760TEST_P(QuicStreamFactoryTest, MigrateSessionOnMultipleWriteErrorsSyncSync) {
Zhongyi Shi7f1d9212018-06-22 23:24:365761 TestMigrationOnMultipleWriteErrors(
5762 /*write_error_mode_on_old_network*/ SYNCHRONOUS,
5763 /*write_error_mode_on_new_network*/ SYNCHRONOUS);
jri9f303712016-09-13 01:10:225764}
5765
5766TEST_P(QuicStreamFactoryTest, MigrateSessionOnMultipleWriteErrorsSyncAsync) {
Zhongyi Shi7f1d9212018-06-22 23:24:365767 TestMigrationOnMultipleWriteErrors(
5768 /*write_error_mode_on_old_network*/ SYNCHRONOUS,
5769 /*write_error_mode_on_new_network*/ ASYNC);
jri9f303712016-09-13 01:10:225770}
5771
5772TEST_P(QuicStreamFactoryTest, MigrateSessionOnMultipleWriteErrorsAsyncSync) {
Zhongyi Shi7f1d9212018-06-22 23:24:365773 TestMigrationOnMultipleWriteErrors(
5774 /*write_error_mode_on_old_network*/ ASYNC,
5775 /*write_error_mode_on_new_network*/ SYNCHRONOUS);
jri9f303712016-09-13 01:10:225776}
5777
5778TEST_P(QuicStreamFactoryTest, MigrateSessionOnMultipleWriteErrorsAsyncAsync) {
Zhongyi Shi7f1d9212018-06-22 23:24:365779 TestMigrationOnMultipleWriteErrors(
5780 /*write_error_mode_on_old_network*/ ASYNC,
5781 /*write_error_mode_on_new_network*/ ASYNC);
jri9f303712016-09-13 01:10:225782}
5783
Zhongyi Shi6abe33812018-07-24 19:43:115784// Verifies that a connection is closed when connection migration is triggered
5785// on network being disconnected and the handshake is not confirmed.
5786TEST_P(QuicStreamFactoryTest, NoMigrationBeforeHandshakeOnNetworkDisconnected) {
5787 InitializeConnectionMigrationV2Test(
5788 {kDefaultNetworkForTests, kNewNetworkForTests});
5789
Zhongyi Shi879659422018-08-02 17:58:255790 // Use cold start mode to do crypto connect, and send CHLO packet on wire.
Zhongyi Shi6abe33812018-07-24 19:43:115791 crypto_client_stream_factory_.set_handshake_mode(
Zhongyi Shi879659422018-08-02 17:58:255792 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
Zhongyi Shi6abe33812018-07-24 19:43:115793
Zhongyi Shi6abe33812018-07-24 19:43:115794 MockQuicData socket_data;
Zhongyi Shi879659422018-08-02 17:58:255795 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5068bb02018-08-03 02:44:095796 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
Zhongyi Shi6abe33812018-07-24 19:43:115797 socket_data.AddSocketDataToFactory(socket_factory_.get());
5798
5799 // Create request and QuicHttpStream.
5800 QuicStreamRequest request(factory_.get());
5801 EXPECT_EQ(ERR_IO_PENDING,
5802 request.Request(host_port_pair_, version_, privacy_mode_,
5803 DEFAULT_PRIORITY, SocketTag(),
5804 /*cert_verify_flags=*/0, url_, net_log_,
5805 &net_error_details_, callback_.callback()));
5806 // Deliver the network notification, which should cause the connection to be
5807 // closed.
5808 scoped_mock_network_change_notifier_->mock_network_change_notifier()
5809 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
5810 EXPECT_EQ(ERR_NETWORK_CHANGED, callback_.WaitForResult());
Zhongyi Shi4293b142018-07-25 00:33:575811
Zhongyi Shi6abe33812018-07-24 19:43:115812 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5813 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
Zhongyi Shi4293b142018-07-25 00:33:575814 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5815 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
Zhongyi Shi6abe33812018-07-24 19:43:115816}
5817
Zhongyi Shib24001c02018-06-18 20:01:525818// Sets up the connection migration test where network change notification is
5819// queued BEFORE connection migration attempt on write error is posted.
5820void QuicStreamFactoryTestBase::
5821 TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
5822 bool disconnected) {
5823 InitializeConnectionMigrationV2Test(
jried79618b2016-07-02 03:18:525824 {kDefaultNetworkForTests, kNewNetworkForTests});
5825 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5826 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5827 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5828
rcha00569732016-08-27 11:09:365829 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525830 quic::QuicStreamOffset header_stream_offset = 0;
rcha00569732016-08-27 11:09:365831 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
rch5cb522462017-04-25 20:18:365832 socket_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435833 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
rcha00569732016-08-27 11:09:365834 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:175835 socket_data.AddSocketDataToFactory(socket_factory_.get());
jried79618b2016-07-02 03:18:525836
5837 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:455838 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:335839 EXPECT_EQ(ERR_IO_PENDING,
5840 request.Request(host_port_pair_, version_, privacy_mode_,
5841 DEFAULT_PRIORITY, SocketTag(),
5842 /*cert_verify_flags=*/0, url_, net_log_,
5843 &net_error_details_, callback_.callback()));
jried79618b2016-07-02 03:18:525844 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:245845 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jried79618b2016-07-02 03:18:525846 EXPECT_TRUE(stream.get());
5847
5848 // Cause QUIC stream to be created.
5849 HttpRequestInfo request_info;
5850 request_info.method = "GET";
5851 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:395852 request_info.traffic_annotation =
5853 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:275854 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:395855 net_log_, CompletionOnceCallback()));
jried79618b2016-07-02 03:18:525856
5857 // Ensure that session is alive and active.
5858 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5859 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5860 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5861
5862 // Set up second socket data provider that is used after
5863 // migration. The request is rewritten to this new socket, and the
5864 // response to the request is read on this new socket.
rcha00569732016-08-27 11:09:365865 MockQuicData socket_data1;
Zhongyi Shi32f2fd02018-04-16 18:23:435866 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
5867 2, GetNthClientInitiatedStreamId(0),
5868 true, true, &header_stream_offset));
5869 socket_data1.AddRead(
5870 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
5871 false, false));
rcha00569732016-08-27 11:09:365872 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:435873 socket_data1.AddWrite(SYNCHRONOUS,
5874 client_maker_.MakeAckAndRstPacket(
5875 3, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:525876 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:175877 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jried79618b2016-07-02 03:18:525878
jri9f303712016-09-13 01:10:225879 // First queue a network change notification in the message loop.
5880 if (disconnected) {
5881 scoped_mock_network_change_notifier_->mock_network_change_notifier()
5882 ->QueueNetworkDisconnected(kDefaultNetworkForTests);
5883 } else {
5884 scoped_mock_network_change_notifier_->mock_network_change_notifier()
5885 ->QueueNetworkMadeDefault(kNewNetworkForTests);
5886 }
5887 // Send GET request on stream. This should cause a write error,
5888 // which triggers a connection migration attempt. This will queue a
5889 // migration attempt behind the notification in the message loop.
jried79618b2016-07-02 03:18:525890 HttpResponseInfo response;
5891 HttpRequestHeaders request_headers;
5892 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5893 callback_.callback()));
5894
jried79618b2016-07-02 03:18:525895 base::RunLoop().RunUntilIdle();
Zhongyi Shia7dd46b2018-07-12 22:59:295896 // Verify the session is still alive and not marked as going away post
5897 // migration.
jried79618b2016-07-02 03:18:525898 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:295899 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jried79618b2016-07-02 03:18:525900 EXPECT_EQ(1u, session->GetNumActiveStreams());
5901
5902 // Verify that response headers on the migrated socket were delivered to the
5903 // stream.
5904 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
5905 EXPECT_EQ(200, response.headers->response_code());
5906
5907 stream.reset();
5908
5909 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5910 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5911 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
5912 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
5913}
5914
Zhongyi Shib24001c02018-06-18 20:01:525915// This test verifies that session attempts connection migration successfully
5916// with signals delivered in the following order (alternate network is always
5917// available):
5918// - a notification that default network is disconnected is queued.
5919// - write error is triggered: session posts a task to attempt connection
5920// migration, |migration_pending_| set to true.
5921// - default network disconnected is delivered: session immediately migrates to
5922// the alternate network, |migration_pending_| set to false.
Zhongyi Shif3d6cddb2018-07-11 03:30:025923// - connection migration on write error attempt aborts: writer encountered
5924// error is no longer in active use.
jri9f303712016-09-13 01:10:225925TEST_P(QuicStreamFactoryTest,
Zhongyi Shib24001c02018-06-18 20:01:525926 MigrateOnNetworkDisconnectedWithWriteErrorQueuedLater) {
5927 TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
5928 /*disconnected=*/true);
jri9f303712016-09-13 01:10:225929}
5930
Zhongyi Shib24001c02018-06-18 20:01:525931// This test verifies that session attempts connection migration successfully
5932// with signals delivered in the following order (alternate network is always
5933// available):
5934// - a notification that alternate network is made default is queued.
5935// - write error is triggered: session posts a task to attempt connection
5936// migration, block future migrations.
5937// - new default notification is delivered: migrate back timer spins and task is
5938// posted to migrate to the new default network.
5939// - connection migration on write error attempt proceeds successfully: session
5940// is
5941// marked as going away, future migrations unblocked.
5942// - migrate back to default network task executed: session is already on the
5943// default network, no-op.
jri9f303712016-09-13 01:10:225944TEST_P(QuicStreamFactoryTest,
Zhongyi Shib24001c02018-06-18 20:01:525945 MigrateOnWriteErrorWithNetworkMadeDefaultQueuedEarlier) {
5946 TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
5947 /*disconnected=*/false);
jri9f303712016-09-13 01:10:225948}
5949
Zhongyi Shi1e2bc742018-06-16 02:06:075950// Sets up the connection migration test where network change notification is
5951// queued AFTER connection migration attempt on write error is posted.
5952void QuicStreamFactoryTestBase::
5953 TestMigrationOnWriteErrorWithNotificationQueuedLater(bool disconnected) {
Zhongyi Shi1a054612018-06-14 04:59:085954 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:225955 {kDefaultNetworkForTests, kNewNetworkForTests});
jried79618b2016-07-02 03:18:525956 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5957 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri9f303712016-09-13 01:10:225958 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jried79618b2016-07-02 03:18:525959
rcha00569732016-08-27 11:09:365960 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525961 quic::QuicStreamOffset header_stream_offset = 0;
rcha00569732016-08-27 11:09:365962 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
rch5cb522462017-04-25 20:18:365963 socket_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435964 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
rcha00569732016-08-27 11:09:365965 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:175966 socket_data.AddSocketDataToFactory(socket_factory_.get());
jried79618b2016-07-02 03:18:525967
5968 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:455969 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:335970 EXPECT_EQ(ERR_IO_PENDING,
5971 request.Request(host_port_pair_, version_, privacy_mode_,
5972 DEFAULT_PRIORITY, SocketTag(),
5973 /*cert_verify_flags=*/0, url_, net_log_,
5974 &net_error_details_, callback_.callback()));
jried79618b2016-07-02 03:18:525975 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:245976 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jried79618b2016-07-02 03:18:525977 EXPECT_TRUE(stream.get());
5978
5979 // Cause QUIC stream to be created.
5980 HttpRequestInfo request_info;
5981 request_info.method = "GET";
5982 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:395983 request_info.traffic_annotation =
5984 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:275985 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:395986 net_log_, CompletionOnceCallback()));
jried79618b2016-07-02 03:18:525987
5988 // Ensure that session is alive and active.
5989 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5990 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5991 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5992
jri9f303712016-09-13 01:10:225993 // Set up second socket data provider that is used after
5994 // migration. The request is rewritten to this new socket, and the
5995 // response to the request is read on this new socket.
5996 MockQuicData socket_data1;
Zhongyi Shi32f2fd02018-04-16 18:23:435997 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
5998 2, GetNthClientInitiatedStreamId(0),
5999 true, true, &header_stream_offset));
6000 socket_data1.AddRead(
6001 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
6002 false, false));
jri9f303712016-09-13 01:10:226003 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436004 socket_data1.AddWrite(SYNCHRONOUS,
6005 client_maker_.MakeAckAndRstPacket(
6006 3, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:526007 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:176008 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:226009
6010 // Send GET request on stream. This should cause a write error,
6011 // which triggers a connection migration attempt. This will queue a
6012 // migration attempt in the message loop.
jried79618b2016-07-02 03:18:526013 HttpResponseInfo response;
6014 HttpRequestHeaders request_headers;
jri9f303712016-09-13 01:10:226015 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6016 callback_.callback()));
jried79618b2016-07-02 03:18:526017
jri9f303712016-09-13 01:10:226018 // Now queue a network change notification in the message loop behind
6019 // the migration attempt.
6020 if (disconnected) {
6021 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6022 ->QueueNetworkDisconnected(kDefaultNetworkForTests);
6023 } else {
6024 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6025 ->QueueNetworkMadeDefault(kNewNetworkForTests);
6026 }
6027
6028 base::RunLoop().RunUntilIdle();
Zhongyi Shia7dd46b2018-07-12 22:59:296029 // Verify session is still alive and not marked as going away.
jri9f303712016-09-13 01:10:226030 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:296031 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri9f303712016-09-13 01:10:226032 EXPECT_EQ(1u, session->GetNumActiveStreams());
6033
6034 // Verify that response headers on the migrated socket were delivered to the
6035 // stream.
6036 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6037 EXPECT_EQ(200, response.headers->response_code());
6038
6039 stream.reset();
jried79618b2016-07-02 03:18:526040
6041 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6042 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
jri9f303712016-09-13 01:10:226043 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6044 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
jried79618b2016-07-02 03:18:526045}
6046
Zhongyi Shi1e2bc742018-06-16 02:06:076047// This test verifies that session attempts connection migration successfully
6048// with signals delivered in the following order (alternate network is always
6049// available):
6050// - write error is triggered: session posts a task to complete connection
6051// migration.
6052// - a notification that alternate network is made default is queued.
6053// - connection migration attempt proceeds successfully, session is marked as
6054// going away.
6055// - new default notification is delivered after connection migration has been
6056// completed.
jri9f303712016-09-13 01:10:226057TEST_P(QuicStreamFactoryTest,
Zhongyi Shi1e2bc742018-06-16 02:06:076058 MigrateOnWriteErrorWithNetworkMadeDefaultQueuedLater) {
6059 TestMigrationOnWriteErrorWithNotificationQueuedLater(/*disconnected=*/false);
jried79618b2016-07-02 03:18:526060}
6061
Zhongyi Shi1e2bc742018-06-16 02:06:076062// This test verifies that session attempts connection migration successfully
6063// with signals delivered in the following order (alternate network is always
6064// available):
6065// - write error is triggered: session posts a task to complete connection
6066// migration.
6067// - a notification that default network is diconnected is queued.
6068// - connection migration attempt proceeds successfully, session is marked as
6069// going away.
6070// - disconnect notification is delivered after connection migration has been
6071// completed.
jri9f303712016-09-13 01:10:226072TEST_P(QuicStreamFactoryTest,
Zhongyi Shi1e2bc742018-06-16 02:06:076073 MigrateOnWriteErrorWithNetworkDisconnectedQueuedLater) {
6074 TestMigrationOnWriteErrorWithNotificationQueuedLater(/*disconnected=*/true);
jried79618b2016-07-02 03:18:526075}
6076
Zhongyi Shia3810c52018-06-15 23:07:196077// This tests connection migration on write error with signals delivered in the
6078// following order:
6079// - a synchronous/asynchronous write error is triggered base on
Zhongyi Shif3d6cddb2018-07-11 03:30:026080// |write_error_mode|: connection migration attempt is posted.
6081// - old default network disconnects, migration waits for a new network.
Zhongyi Shia3810c52018-06-15 23:07:196082// - after a pause, new network is connected: session will migrate to new
6083// network immediately.
Zhongyi Shif3d6cddb2018-07-11 03:30:026084// - migration on writer error is exectued and aborts as writer passed in is no
6085// longer active in use.
Zhongyi Shia3810c52018-06-15 23:07:196086// - new network is made default.
jri5b785512016-09-13 04:29:116087void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorPauseBeforeConnected(
6088 IoMode write_error_mode) {
Zhongyi Shia3810c52018-06-15 23:07:196089 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri5b785512016-09-13 04:29:116090 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6091 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6092 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6093
Zhongyi Shia3810c52018-06-15 23:07:196094 // Use the test task runner.
6095 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
6096
jri5b785512016-09-13 04:29:116097 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526098 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shia3810c52018-06-15 23:07:196099 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
rch5cb522462017-04-25 20:18:366100 socket_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436101 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Zhongyi Shia3810c52018-06-15 23:07:196102 socket_data.AddWrite(write_error_mode, ERR_FAILED);
Zhongyi Shi5f587cc2017-11-21 23:24:176103 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri5b785512016-09-13 04:29:116104
6105 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456106 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336107 EXPECT_EQ(ERR_IO_PENDING,
6108 request.Request(host_port_pair_, version_, privacy_mode_,
6109 DEFAULT_PRIORITY, SocketTag(),
6110 /*cert_verify_flags=*/0, url_, net_log_,
6111 &net_error_details_, callback_.callback()));
Zhongyi Shia3810c52018-06-15 23:07:196112 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:246113 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri5b785512016-09-13 04:29:116114 EXPECT_TRUE(stream.get());
6115
6116 // Cause QUIC stream to be created.
6117 HttpRequestInfo request_info;
6118 request_info.method = "GET";
Zhongyi Shia3810c52018-06-15 23:07:196119 request_info.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:396120 request_info.traffic_annotation =
6121 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276122 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396123 net_log_, CompletionOnceCallback()));
jri5b785512016-09-13 04:29:116124
6125 // Ensure that session is alive and active.
6126 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6127 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6128 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6129
Zhongyi Shia3810c52018-06-15 23:07:196130 // Send GET request on stream.
jri5b785512016-09-13 04:29:116131 HttpResponseInfo response;
6132 HttpRequestHeaders request_headers;
6133 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6134 callback_.callback()));
6135
Zhongyi Shia3810c52018-06-15 23:07:196136 // The connection should still be alive, not marked as going away.
jri5b785512016-09-13 04:29:116137 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6138 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6139 EXPECT_EQ(1u, session->GetNumActiveStreams());
6140 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
6141
Zhongyi Shia3810c52018-06-15 23:07:196142 // Set up second socket data provider that is used after migration.
6143 // The response to the earlier request is read on this new socket.
jri5b785512016-09-13 04:29:116144 MockQuicData socket_data1;
Zhongyi Shi32f2fd02018-04-16 18:23:436145 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
6146 2, GetNthClientInitiatedStreamId(0),
6147 true, true, &header_stream_offset));
6148 socket_data1.AddRead(
6149 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
6150 false, false));
jri5b785512016-09-13 04:29:116151 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436152 socket_data1.AddWrite(SYNCHRONOUS,
6153 client_maker_.MakeAckAndRstPacket(
6154 3, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:526155 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:176156 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri5b785512016-09-13 04:29:116157
Zhongyi Shia3810c52018-06-15 23:07:196158 // On a DISCONNECTED notification, nothing happens.
6159 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6160 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
6161 // Add a new network and notify the stream factory of a new connected network.
6162 // This causes a PING packet to be sent over the new network.
jri5b785512016-09-13 04:29:116163 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6164 ->SetConnectedNetworksList({kNewNetworkForTests});
6165 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6166 ->NotifyNetworkConnected(kNewNetworkForTests);
6167
Zhongyi Shia3810c52018-06-15 23:07:196168 // Ensure that the session is still alive.
jri5b785512016-09-13 04:29:116169 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia3810c52018-06-15 23:07:196170 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:116171 EXPECT_EQ(1u, session->GetNumActiveStreams());
6172
Zhongyi Shia3810c52018-06-15 23:07:196173 // Run the message loop migration for write error can finish.
6174 runner_->RunUntilIdle();
6175
6176 // Response headers are received over the new network.
jri5b785512016-09-13 04:29:116177 EXPECT_THAT(callback_.WaitForResult(), IsOk());
6178 EXPECT_EQ(200, response.headers->response_code());
6179
Zhongyi Shia3810c52018-06-15 23:07:196180 // Check that the session is still alive.
6181 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
jri5b785512016-09-13 04:29:116182 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shia3810c52018-06-15 23:07:196183
6184 // There should be no posted tasks not executed, no way to migrate back to
6185 // default network.
6186 EXPECT_TRUE(runner_->GetPostedTasks().empty());
6187
6188 // Receive signal to mark new network as default.
6189 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6190 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri5b785512016-09-13 04:29:116191
6192 stream.reset();
jri5b785512016-09-13 04:29:116193 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6194 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6195 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6196 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
jri5b785512016-09-13 04:29:116197}
6198
6199TEST_P(QuicStreamFactoryTest,
Zhongyi Shia3810c52018-06-15 23:07:196200 MigrateSessionOnSyncWriteErrorPauseBeforeConnected) {
jri5b785512016-09-13 04:29:116201 TestMigrationOnWriteErrorPauseBeforeConnected(SYNCHRONOUS);
6202}
6203
6204TEST_P(QuicStreamFactoryTest,
Zhongyi Shia3810c52018-06-15 23:07:196205 MigrateSessionOnAsyncWriteErrorPauseBeforeConnected) {
jri5b785512016-09-13 04:29:116206 TestMigrationOnWriteErrorPauseBeforeConnected(ASYNC);
6207}
6208
Zhongyi Shif3d6cddb2018-07-11 03:30:026209// This test verifies that when session successfully migrate to the alternate
6210// network, packet write error on the old writer will be ignored and will not
6211// trigger connection migration on write error.
6212TEST_P(QuicStreamFactoryTest, IgnoreWriteErrorFromOldWriterAfterMigration) {
6213 InitializeConnectionMigrationV2Test(
6214 {kDefaultNetworkForTests, kNewNetworkForTests});
6215 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6216 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6217 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6218
6219 // Using a testing task runner so that we can verify whether the migrate on
6220 // write error task is posted.
6221 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
6222 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
6223
6224 MockQuicData socket_data;
6225 quic::QuicStreamOffset header_stream_offset = 0;
6226 socket_data.AddWrite(
6227 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6228 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
6229 socket_data.AddWrite(ASYNC, ERR_ADDRESS_UNREACHABLE);
6230 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6231 socket_data.AddSocketDataToFactory(socket_factory_.get());
6232
6233 // Create request and QuicHttpStream.
6234 QuicStreamRequest request(factory_.get());
6235 EXPECT_EQ(ERR_IO_PENDING,
6236 request.Request(host_port_pair_, version_, privacy_mode_,
6237 DEFAULT_PRIORITY, SocketTag(),
6238 /*cert_verify_flags=*/0, url_, net_log_,
6239 &net_error_details_, callback_.callback()));
6240 EXPECT_EQ(OK, callback_.WaitForResult());
6241 std::unique_ptr<HttpStream> stream = CreateStream(&request);
6242 EXPECT_TRUE(stream.get());
6243
6244 // Cause QUIC stream to be created.
6245 HttpRequestInfo request_info;
6246 request_info.method = "GET";
6247 request_info.url = GURL("https://www.example.org/");
6248 request_info.traffic_annotation =
6249 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6250 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
6251 net_log_, CompletionOnceCallback()));
6252
6253 // Ensure that session is alive and active.
6254 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6255 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6256 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6257
6258 // Set up second socket data provider that is used after
6259 // migration. The response to the request is read on this new socket.
6260 MockQuicData socket_data1;
6261 socket_data1.AddWrite(
6262 SYNCHRONOUS, client_maker_.MakePingPacket(3, /*include_version=*/true));
6263 socket_data1.AddRead(
6264 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
6265 false, false));
6266 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6267 socket_data1.AddWrite(SYNCHRONOUS,
6268 client_maker_.MakeAckAndRstPacket(
6269 4, false, GetNthClientInitiatedStreamId(0),
6270 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
6271 socket_data1.AddSocketDataToFactory(socket_factory_.get());
6272
6273 // Send GET request on stream.
6274 HttpResponseInfo response;
6275 HttpRequestHeaders request_headers;
6276 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6277 callback_.callback()));
6278
6279 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
6280 // Now notify network is disconnected, cause the migration to complete
6281 // immediately.
6282 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6283 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
6284 // There will be two pending task, one will complete migration with no delay
6285 // and the other will attempt to migrate back to the default network with
6286 // delay.
6287 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
6288
6289 // Complete migration.
6290 task_runner->RunUntilIdle();
6291 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
6292
6293 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6294 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6295 EXPECT_EQ(1u, session->GetNumActiveStreams());
6296
6297 // Verify that response headers on the migrated socket were delivered to the
6298 // stream.
6299 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6300 EXPECT_EQ(200, response.headers->response_code());
6301
6302 // Resume the old socket data, a write error will be delivered to the old
6303 // packet writer. Verify no additional task is posted.
6304 socket_data.Resume();
6305 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
6306
6307 stream.reset();
6308 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6309 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6310 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6311}
6312
6313// This test verifies that when session successfully migrate to the alternate
6314// network, packet read error on the old reader will be ignored and will not
6315// close the connection.
6316TEST_P(QuicStreamFactoryTest, IgnoreReadErrorFromOldReaderAfterMigration) {
6317 InitializeConnectionMigrationV2Test(
6318 {kDefaultNetworkForTests, kNewNetworkForTests});
6319 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6320 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6321 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6322
6323 // Using a testing task runner.
6324 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
6325 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
6326
6327 MockQuicData socket_data;
6328 quic::QuicStreamOffset header_stream_offset = 0;
6329 socket_data.AddWrite(
6330 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6331 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
6332 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE);
6333 socket_data.AddSocketDataToFactory(socket_factory_.get());
6334
6335 // Create request and QuicHttpStream.
6336 QuicStreamRequest request(factory_.get());
6337 EXPECT_EQ(ERR_IO_PENDING,
6338 request.Request(host_port_pair_, version_, privacy_mode_,
6339 DEFAULT_PRIORITY, SocketTag(),
6340 /*cert_verify_flags=*/0, url_, net_log_,
6341 &net_error_details_, callback_.callback()));
6342 EXPECT_EQ(OK, callback_.WaitForResult());
6343 std::unique_ptr<HttpStream> stream = CreateStream(&request);
6344 EXPECT_TRUE(stream.get());
6345
6346 // Cause QUIC stream to be created.
6347 HttpRequestInfo request_info;
6348 request_info.method = "GET";
6349 request_info.url = GURL("https://www.example.org/");
6350 request_info.traffic_annotation =
6351 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6352 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
6353 net_log_, CompletionOnceCallback()));
6354
6355 // Ensure that session is alive and active.
6356 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6357 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6358 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6359
6360 // Set up second socket data provider that is used after
6361 // migration. The request is written to this new socket, and the
6362 // response to the request is read on this new socket.
6363 MockQuicData socket_data1;
6364 socket_data1.AddWrite(
6365 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
6366 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
6367 3, GetNthClientInitiatedStreamId(0),
6368 true, true, &header_stream_offset));
6369 socket_data1.AddRead(
6370 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
6371 false, false));
6372 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6373 socket_data1.AddWrite(SYNCHRONOUS,
6374 client_maker_.MakeAckAndRstPacket(
6375 4, false, GetNthClientInitiatedStreamId(0),
6376 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
6377 socket_data1.AddSocketDataToFactory(socket_factory_.get());
6378
6379 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
6380 // Now notify network is disconnected, cause the migration to complete
6381 // immediately.
6382 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6383 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
6384 // There will be two pending task, one will complete migration with no delay
6385 // and the other will attempt to migrate back to the default network with
6386 // delay.
6387 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
6388
6389 // Complete migration.
6390 task_runner->RunUntilIdle();
6391 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
6392
6393 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6394 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6395 EXPECT_EQ(1u, session->GetNumActiveStreams());
6396
6397 // Send GET request on stream.
6398 HttpResponseInfo response;
6399 HttpRequestHeaders request_headers;
6400 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6401 callback_.callback()));
6402
6403 // Verify that response headers on the migrated socket were delivered to the
6404 // stream.
6405 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
6406 EXPECT_EQ(OK, callback_.WaitForResult());
6407 EXPECT_EQ(200, response.headers->response_code());
6408
6409 // Resume the old socket data, a read error will be delivered to the old
6410 // packet reader. Verify that the session is not affected.
6411 socket_data.Resume();
6412 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
6413 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6414 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6415 EXPECT_EQ(1u, session->GetNumActiveStreams());
6416
6417 stream.reset();
6418 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6419 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6420 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6421 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6422}
6423
6424// This test verifies that after migration on network is executed, packet
6425// read error on the old reader will be ignored and will not close the
6426// connection.
6427TEST_P(QuicStreamFactoryTest, IgnoreReadErrorOnOldReaderDuringMigration) {
6428 InitializeConnectionMigrationV2Test(
6429 {kDefaultNetworkForTests, kNewNetworkForTests});
6430 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6431 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6432 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6433
6434 // Using a testing task runner.
6435 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
6436 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
6437
6438 MockQuicData socket_data;
6439 quic::QuicStreamOffset header_stream_offset = 0;
6440 socket_data.AddWrite(
6441 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6442 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
6443 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE);
6444 socket_data.AddSocketDataToFactory(socket_factory_.get());
6445
6446 // Create request and QuicHttpStream.
6447 QuicStreamRequest request(factory_.get());
6448 EXPECT_EQ(ERR_IO_PENDING,
6449 request.Request(host_port_pair_, version_, privacy_mode_,
6450 DEFAULT_PRIORITY, SocketTag(),
6451 /*cert_verify_flags=*/0, url_, net_log_,
6452 &net_error_details_, callback_.callback()));
6453 EXPECT_EQ(OK, callback_.WaitForResult());
6454 std::unique_ptr<HttpStream> stream = CreateStream(&request);
6455 EXPECT_TRUE(stream.get());
6456
6457 // Cause QUIC stream to be created.
6458 HttpRequestInfo request_info;
6459 request_info.method = "GET";
6460 request_info.url = GURL("https://www.example.org/");
6461 request_info.traffic_annotation =
6462 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6463 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
6464 net_log_, CompletionOnceCallback()));
6465
6466 // Ensure that session is alive and active.
6467 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6468 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6469 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6470
6471 // Set up second socket data provider that is used after
6472 // migration. The request is written to this new socket, and the
6473 // response to the request is read on this new socket.
6474 MockQuicData socket_data1;
6475 socket_data1.AddWrite(
6476 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
6477 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
6478 3, GetNthClientInitiatedStreamId(0),
6479 true, true, &header_stream_offset));
6480 socket_data1.AddRead(
6481 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
6482 false, false));
6483 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6484 socket_data1.AddWrite(SYNCHRONOUS,
6485 client_maker_.MakeAckAndRstPacket(
6486 4, false, GetNthClientInitiatedStreamId(0),
6487 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
6488 socket_data1.AddSocketDataToFactory(socket_factory_.get());
6489
6490 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
6491 // Now notify network is disconnected, cause the migration to complete
6492 // immediately.
6493 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6494 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
6495 // There will be two pending task, one will complete migration with no delay
6496 // and the other will attempt to migrate back to the default network with
6497 // delay.
6498 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
6499
6500 // Resume the old socket data, a read error will be delivered to the old
6501 // packet reader. Verify that the session is not affected.
6502 socket_data.Resume();
6503 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
6504 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6505 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6506 EXPECT_EQ(1u, session->GetNumActiveStreams());
6507
6508 // Complete migration.
6509 task_runner->RunUntilIdle();
6510 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
6511
6512 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6513 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6514 EXPECT_EQ(1u, session->GetNumActiveStreams());
6515
6516 // Send GET request on stream.
6517 HttpResponseInfo response;
6518 HttpRequestHeaders request_headers;
6519 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6520 callback_.callback()));
6521
6522 // Verify that response headers on the migrated socket were delivered to the
6523 // stream.
6524 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
6525 EXPECT_EQ(OK, callback_.WaitForResult());
6526 EXPECT_EQ(200, response.headers->response_code());
6527
6528 stream.reset();
6529 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6530 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6531 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6532 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6533}
6534
6535// This test verifies that after migration on write error is posted, packet
6536// read error on the old reader will be ignored and will not close the
6537// connection.
6538TEST_P(QuicStreamFactoryTest,
6539 IgnoreReadErrorOnOldReaderDuringPendingMigrationOnWriteError) {
6540 InitializeConnectionMigrationV2Test(
6541 {kDefaultNetworkForTests, kNewNetworkForTests});
6542 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6543 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6544 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6545
6546 // Using a testing task runner.
6547 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
6548 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
6549
6550 MockQuicData socket_data;
6551 quic::QuicStreamOffset header_stream_offset = 0;
6552 socket_data.AddWrite(
6553 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6554 socket_data.AddWrite(ASYNC, ERR_FAILED); // Write error.
6555 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE); // Read error.
6556 socket_data.AddSocketDataToFactory(socket_factory_.get());
6557
6558 // Create request and QuicHttpStream.
6559 QuicStreamRequest request(factory_.get());
6560 EXPECT_EQ(ERR_IO_PENDING,
6561 request.Request(host_port_pair_, version_, privacy_mode_,
6562 DEFAULT_PRIORITY, SocketTag(),
6563 /*cert_verify_flags=*/0, url_, net_log_,
6564 &net_error_details_, callback_.callback()));
6565 EXPECT_EQ(OK, callback_.WaitForResult());
6566 std::unique_ptr<HttpStream> stream = CreateStream(&request);
6567 EXPECT_TRUE(stream.get());
6568
6569 // Cause QUIC stream to be created.
6570 HttpRequestInfo request_info;
6571 request_info.method = "GET";
6572 request_info.url = GURL("https://www.example.org/");
6573 request_info.traffic_annotation =
6574 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6575 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
6576 net_log_, CompletionOnceCallback()));
6577
6578 // Ensure that session is alive and active.
6579 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6580 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6581 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6582
6583 // Set up second socket data provider that is used after
6584 // migration. The request is written to this new socket, and the
6585 // response to the request is read on this new socket.
6586 MockQuicData socket_data1;
6587 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
6588 2, GetNthClientInitiatedStreamId(0),
6589 true, true, &header_stream_offset));
6590 socket_data1.AddRead(
6591 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
6592 false, false));
6593
6594 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
6595 socket_data1.AddRead(ASYNC, ERR_FAILED); // Read error to close connection.
6596 socket_data1.AddSocketDataToFactory(socket_factory_.get());
6597
6598 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
6599 // Send GET request on stream.
6600 HttpResponseInfo response;
6601 HttpRequestHeaders request_headers;
6602 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6603 callback_.callback()));
6604 // Run the message loop to complete asynchronous write and read with errors.
6605 base::RunLoop().RunUntilIdle();
6606 // There will be one pending task to complete migration on write error.
6607 // Verify session is not closed with read error.
6608 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
6609 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6610 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6611 EXPECT_EQ(1u, session->GetNumActiveStreams());
6612
6613 // Complete migration.
6614 task_runner->RunUntilIdle();
Zhongyi Shia7dd46b2018-07-12 22:59:296615 // There will be one more task posted attempting to migrate back to the
6616 // default network.
6617 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
Zhongyi Shif3d6cddb2018-07-11 03:30:026618 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:296619 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shif3d6cddb2018-07-11 03:30:026620 EXPECT_EQ(1u, session->GetNumActiveStreams());
6621
6622 // Verify that response headers on the migrated socket were delivered to the
6623 // stream.
6624 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6625 EXPECT_EQ(200, response.headers->response_code());
6626
6627 // Resume to consume the read error on new socket, which will close
6628 // the connection.
6629 socket_data1.Resume();
6630
6631 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6632 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6633 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6634 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6635}
6636
Zhongyi Shi4ac9e1f2018-06-21 05:21:476637// Migrate on asynchronous write error, old network disconnects after alternate
6638// network connects.
6639TEST_P(QuicStreamFactoryTest,
6640 MigrateSessionOnWriteErrorWithDisconnectAfterConnectAysnc) {
6641 TestMigrationOnWriteErrorWithMultipleNotifications(
6642 ASYNC, /*disconnect_before_connect*/ false);
6643}
6644
6645// Migrate on synchronous write error, old network disconnects after alternate
6646// network connects.
6647TEST_P(QuicStreamFactoryTest,
6648 MigrateSessionOnWriteErrorWithDisconnectAfterConnectSync) {
6649 TestMigrationOnWriteErrorWithMultipleNotifications(
6650 SYNCHRONOUS, /*disconnect_before_connect*/ false);
6651}
6652
6653// Migrate on asynchronous write error, old network disconnects before alternate
6654// network connects.
6655TEST_P(QuicStreamFactoryTest,
6656 MigrateSessionOnWriteErrorWithDisconnectBeforeConnectAysnc) {
6657 TestMigrationOnWriteErrorWithMultipleNotifications(
6658 ASYNC, /*disconnect_before_connect*/ true);
6659}
6660
6661// Migrate on synchronous write error, old network disconnects before alternate
6662// network connects.
6663TEST_P(QuicStreamFactoryTest,
6664 MigrateSessionOnWriteErrorWithDisconnectBeforeConnectSync) {
6665 TestMigrationOnWriteErrorWithMultipleNotifications(
6666 SYNCHRONOUS, /*disconnect_before_connect*/ true);
6667}
6668
6669// Setps up test which verifies that session successfully migrate to alternate
6670// network with signals delivered in the following order:
6671// *NOTE* Signal (A) and (B) can reverse order based on
6672// |disconnect_before_connect|.
6673// - (No alternate network is connected) session connects to
6674// kDefaultNetworkForTests.
6675// - An async/sync write error is encountered based on |write_error_mode|:
6676// session posted task to migrate session on write error.
6677// - Posted task is executed, miration moves to pending state due to lack of
6678// alternate network.
6679// - (A) An alternate network is connected, pending migration completes.
6680// - (B) Old default network disconnects, no migration will be attempted as
Zhongyi Shi329f5cbd2018-06-22 23:51:186681// session has already migrate to the alternate network.
Zhongyi Shi4ac9e1f2018-06-21 05:21:476682// - The alternate network is made default.
jri5b785512016-09-13 04:29:116683void QuicStreamFactoryTestBase::
Zhongyi Shi4ac9e1f2018-06-21 05:21:476684 TestMigrationOnWriteErrorWithMultipleNotifications(
jri5b785512016-09-13 04:29:116685 IoMode write_error_mode,
Zhongyi Shi4ac9e1f2018-06-21 05:21:476686 bool disconnect_before_connect) {
Zhongyi Shi329f5cbd2018-06-22 23:51:186687 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri5b785512016-09-13 04:29:116688 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6689 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6690 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6691
6692 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526693 quic::QuicStreamOffset header_stream_offset = 0;
jri5b785512016-09-13 04:29:116694 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
rch5cb522462017-04-25 20:18:366695 socket_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436696 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Zhongyi Shi4ac9e1f2018-06-21 05:21:476697 socket_data.AddWrite(write_error_mode, ERR_FAILED); // Write error.
Zhongyi Shi5f587cc2017-11-21 23:24:176698 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri5b785512016-09-13 04:29:116699
6700 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456701 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336702 EXPECT_EQ(ERR_IO_PENDING,
6703 request.Request(host_port_pair_, version_, privacy_mode_,
6704 DEFAULT_PRIORITY, SocketTag(),
6705 /*cert_verify_flags=*/0, url_, net_log_,
6706 &net_error_details_, callback_.callback()));
jri5b785512016-09-13 04:29:116707 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246708 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri5b785512016-09-13 04:29:116709 EXPECT_TRUE(stream.get());
6710
6711 // Cause QUIC stream to be created.
6712 HttpRequestInfo request_info;
6713 request_info.method = "GET";
6714 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396715 request_info.traffic_annotation =
6716 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276717 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396718 net_log_, CompletionOnceCallback()));
jri5b785512016-09-13 04:29:116719
6720 // Ensure that session is alive and active.
6721 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6722 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6723 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6724
6725 // Send GET request on stream. This should cause a write error, which triggers
6726 // a connection migration attempt.
6727 HttpResponseInfo response;
6728 HttpRequestHeaders request_headers;
6729 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6730 callback_.callback()));
Zhongyi Shi4ac9e1f2018-06-21 05:21:476731 // Run the message loop so that posted task to migrate to socket will be
6732 // executed. A new task will be posted to wait for a new network.
jri5b785512016-09-13 04:29:116733 base::RunLoop().RunUntilIdle();
6734
6735 // In this particular code path, the network will not yet be marked
6736 // as going away and the session will still be alive.
6737 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6738 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6739 EXPECT_EQ(1u, session->GetNumActiveStreams());
6740 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
6741
6742 // Set up second socket data provider that is used after
6743 // migration. The request is rewritten to this new socket, and the
6744 // response to the request is read on this new socket.
6745 MockQuicData socket_data1;
Zhongyi Shi32f2fd02018-04-16 18:23:436746 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
6747 2, GetNthClientInitiatedStreamId(0),
6748 true, true, &header_stream_offset));
6749 socket_data1.AddRead(
6750 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
6751 false, false));
jri5b785512016-09-13 04:29:116752 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436753 socket_data1.AddWrite(SYNCHRONOUS,
6754 client_maker_.MakeAckAndRstPacket(
6755 3, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:526756 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:176757 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri5b785512016-09-13 04:29:116758
6759 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6760 ->SetConnectedNetworksList(
6761 {kDefaultNetworkForTests, kNewNetworkForTests});
Zhongyi Shi4ac9e1f2018-06-21 05:21:476762 if (disconnect_before_connect) {
6763 // Now deliver a DISCONNECT notification.
jri5b785512016-09-13 04:29:116764 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6765 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
Zhongyi Shi4ac9e1f2018-06-21 05:21:476766
6767 // Now deliver a CONNECTED notification and completes migration.
jri5b785512016-09-13 04:29:116768 scoped_mock_network_change_notifier_->mock_network_change_notifier()
Zhongyi Shi4ac9e1f2018-06-21 05:21:476769 ->NotifyNetworkConnected(kNewNetworkForTests);
6770 } else {
6771 // Now deliver a CONNECTED notification and completes migration.
6772 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6773 ->NotifyNetworkConnected(kNewNetworkForTests);
6774
6775 // Now deliver a DISCONNECT notification.
6776 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6777 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
jri5b785512016-09-13 04:29:116778 }
jri5b785512016-09-13 04:29:116779 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shi329f5cbd2018-06-22 23:51:186780 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:116781 EXPECT_EQ(1u, session->GetNumActiveStreams());
6782
6783 // This is the callback for the response headers that returned
6784 // pending previously, because no result was available. Check that
6785 // the result is now available due to the successful migration.
6786 EXPECT_THAT(callback_.WaitForResult(), IsOk());
6787 EXPECT_EQ(200, response.headers->response_code());
6788
Zhongyi Shi4ac9e1f2018-06-21 05:21:476789 // Deliver a MADEDEFAULT notification.
jri5b785512016-09-13 04:29:116790 scoped_mock_network_change_notifier_->mock_network_change_notifier()
Zhongyi Shi4ac9e1f2018-06-21 05:21:476791 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri5b785512016-09-13 04:29:116792
zhongyi98d6a9262017-05-19 02:47:456793 QuicStreamRequest request2(factory_.get());
Zhongyi Shi329f5cbd2018-06-22 23:51:186794 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_, privacy_mode_,
6795 DEFAULT_PRIORITY, SocketTag(),
6796 /*cert_verify_flags=*/0, url_, net_log_,
6797 &net_error_details_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:246798 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
jri5b785512016-09-13 04:29:116799 EXPECT_TRUE(stream2.get());
6800
6801 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi329f5cbd2018-06-22 23:51:186802 EXPECT_EQ(session, GetActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:116803
6804 stream.reset();
6805 stream2.reset();
6806
6807 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6808 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6809 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6810 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
jri5b785512016-09-13 04:29:116811}
6812
jri217455a12016-07-13 20:15:096813TEST_P(QuicStreamFactoryTest, ServerMigration) {
6814 allow_server_migration_ = true;
6815 Initialize();
6816
6817 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6818 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6819 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6820
rcha00569732016-08-27 11:09:366821 MockQuicData socket_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526822 quic::QuicStreamOffset header_stream_offset = 0;
rcha00569732016-08-27 11:09:366823 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
rch5cb522462017-04-25 20:18:366824 socket_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436825 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6826 socket_data1.AddWrite(SYNCHRONOUS, ConstructGetRequestPacket(
6827 2, GetNthClientInitiatedStreamId(0),
6828 true, true, &header_stream_offset));
Zhongyi Shi5f587cc2017-11-21 23:24:176829 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri217455a12016-07-13 20:15:096830
6831 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456832 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336833 EXPECT_EQ(ERR_IO_PENDING,
6834 request.Request(host_port_pair_, version_, privacy_mode_,
6835 DEFAULT_PRIORITY, SocketTag(),
6836 /*cert_verify_flags=*/0, url_, net_log_,
6837 &net_error_details_, callback_.callback()));
jri217455a12016-07-13 20:15:096838 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246839 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri217455a12016-07-13 20:15:096840 EXPECT_TRUE(stream.get());
6841
6842 // Cause QUIC stream to be created.
6843 HttpRequestInfo request_info;
6844 request_info.method = "GET";
6845 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396846 request_info.traffic_annotation =
6847 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276848 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396849 net_log_, CompletionOnceCallback()));
jri217455a12016-07-13 20:15:096850
6851 // Ensure that session is alive and active.
6852 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6853 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6854 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6855
6856 // Send GET request on stream.
6857 HttpResponseInfo response;
6858 HttpRequestHeaders request_headers;
6859 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6860 callback_.callback()));
6861
6862 IPEndPoint ip;
6863 session->GetDefaultSocket()->GetPeerAddress(&ip);
6864 DVLOG(1) << "Socket connected to: " << ip.address().ToString() << " "
6865 << ip.port();
6866
6867 // Set up second socket data provider that is used after
6868 // migration. The request is rewritten to this new socket, and the
6869 // response to the request is read on this new socket.
rcha00569732016-08-27 11:09:366870 MockQuicData socket_data2;
6871 socket_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436872 SYNCHRONOUS, client_maker_.MakePingPacket(3, /*include_version=*/true));
6873 socket_data2.AddRead(
6874 ASYNC, ConstructOkResponsePacket(1, GetNthClientInitiatedStreamId(0),
6875 false, false));
rcha00569732016-08-27 11:09:366876 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436877 socket_data2.AddWrite(SYNCHRONOUS,
6878 client_maker_.MakeAckAndRstPacket(
6879 4, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:526880 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:176881 socket_data2.AddSocketDataToFactory(socket_factory_.get());
jri217455a12016-07-13 20:15:096882
6883 const uint8_t kTestIpAddress[] = {1, 2, 3, 4};
6884 const uint16_t kTestPort = 123;
Zhongyi Shif124a582017-11-02 00:15:046885 session->Migrate(NetworkChangeNotifier::kInvalidNetworkHandle,
6886 IPEndPoint(IPAddress(kTestIpAddress), kTestPort), true,
6887 net_log_);
jri217455a12016-07-13 20:15:096888
6889 session->GetDefaultSocket()->GetPeerAddress(&ip);
6890 DVLOG(1) << "Socket migrated to: " << ip.address().ToString() << " "
6891 << ip.port();
6892
6893 // The session should be alive and active.
6894 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6895 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6896 EXPECT_EQ(1u, session->GetNumActiveStreams());
6897
6898 // Run the message loop so that data queued in the new socket is read by the
6899 // packet reader.
6900 base::RunLoop().RunUntilIdle();
6901
6902 // Verify that response headers on the migrated socket were delivered to the
6903 // stream.
6904 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6905 EXPECT_EQ(200, response.headers->response_code());
6906
6907 stream.reset();
6908
6909 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6910 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6911 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
6912 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
6913}
6914
jri053fdbd2016-08-19 02:33:056915TEST_P(QuicStreamFactoryTest, ServerMigrationIPv4ToIPv4) {
6916 // Add alternate IPv4 server address to config.
6917 IPEndPoint alt_address = IPEndPoint(IPAddress(1, 2, 3, 4), 123);
Ryan Hamilton8d9ee76e2018-05-29 23:52:526918 quic::QuicConfig config;
fayang91ca2012016-11-22 07:42:466919 config.SetAlternateServerAddressToSend(
Ryan Hamilton8d9ee76e2018-05-29 23:52:526920 quic::QuicSocketAddress(quic::QuicSocketAddressImpl(alt_address)));
jri053fdbd2016-08-19 02:33:056921 VerifyServerMigration(config, alt_address);
6922}
6923
6924TEST_P(QuicStreamFactoryTest, ServerMigrationIPv6ToIPv6) {
6925 // Add a resolver rule to make initial connection to an IPv6 address.
6926 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
6927 "fe80::aebc:32ff:febb:1e33", "");
6928 // Add alternate IPv6 server address to config.
6929 IPEndPoint alt_address = IPEndPoint(
6930 IPAddress(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), 123);
Ryan Hamilton8d9ee76e2018-05-29 23:52:526931 quic::QuicConfig config;
fayang91ca2012016-11-22 07:42:466932 config.SetAlternateServerAddressToSend(
Ryan Hamilton8d9ee76e2018-05-29 23:52:526933 quic::QuicSocketAddress(quic::QuicSocketAddressImpl(alt_address)));
jri053fdbd2016-08-19 02:33:056934 VerifyServerMigration(config, alt_address);
6935}
6936
6937TEST_P(QuicStreamFactoryTest, ServerMigrationIPv6ToIPv4) {
6938 // Add a resolver rule to make initial connection to an IPv6 address.
6939 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
6940 "fe80::aebc:32ff:febb:1e33", "");
6941 // Add alternate IPv4 server address to config.
6942 IPEndPoint alt_address = IPEndPoint(IPAddress(1, 2, 3, 4), 123);
Ryan Hamilton8d9ee76e2018-05-29 23:52:526943 quic::QuicConfig config;
fayang91ca2012016-11-22 07:42:466944 config.SetAlternateServerAddressToSend(
Ryan Hamilton8d9ee76e2018-05-29 23:52:526945 quic::QuicSocketAddress(quic::QuicSocketAddressImpl(alt_address)));
jri053fdbd2016-08-19 02:33:056946 IPEndPoint expected_address(
6947 ConvertIPv4ToIPv4MappedIPv6(alt_address.address()), alt_address.port());
6948 VerifyServerMigration(config, expected_address);
6949}
6950
6951TEST_P(QuicStreamFactoryTest, ServerMigrationIPv4ToIPv6Fails) {
6952 allow_server_migration_ = true;
6953 Initialize();
6954
6955 // Add a resolver rule to make initial connection to an IPv4 address.
6956 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(), "1.2.3.4",
6957 "");
6958 // Add alternate IPv6 server address to config.
6959 IPEndPoint alt_address = IPEndPoint(
6960 IPAddress(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), 123);
Ryan Hamilton8d9ee76e2018-05-29 23:52:526961 quic::QuicConfig config;
fayang91ca2012016-11-22 07:42:466962 config.SetAlternateServerAddressToSend(
Ryan Hamilton8d9ee76e2018-05-29 23:52:526963 quic::QuicSocketAddress(quic::QuicSocketAddressImpl(alt_address)));
jri053fdbd2016-08-19 02:33:056964
6965 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6966 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6967 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6968
6969 crypto_client_stream_factory_.SetConfig(config);
6970
6971 // Set up only socket data provider.
rcha00569732016-08-27 11:09:366972 MockQuicData socket_data1;
6973 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436974 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
6975 socket_data1.AddWrite(
6976 SYNCHRONOUS,
6977 client_maker_.MakeRstPacket(2, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:526978 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:176979 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri053fdbd2016-08-19 02:33:056980
6981 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456982 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336983 EXPECT_EQ(ERR_IO_PENDING,
6984 request.Request(host_port_pair_, version_, privacy_mode_,
6985 DEFAULT_PRIORITY, SocketTag(),
6986 /*cert_verify_flags=*/0, url_, net_log_,
6987 &net_error_details_, callback_.callback()));
jri053fdbd2016-08-19 02:33:056988 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246989 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri053fdbd2016-08-19 02:33:056990 EXPECT_TRUE(stream.get());
6991
6992 // Cause QUIC stream to be created.
6993 HttpRequestInfo request_info;
6994 request_info.method = "GET";
6995 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396996 request_info.traffic_annotation =
6997 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276998 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396999 net_log_, CompletionOnceCallback()));
jri053fdbd2016-08-19 02:33:057000
7001 // Ensure that session is alive and active.
7002 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7003 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7004 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7005
7006 IPEndPoint actual_address;
7007 session->GetDefaultSocket()->GetPeerAddress(&actual_address);
7008 // No migration should have happened.
7009 IPEndPoint expected_address =
7010 IPEndPoint(IPAddress(1, 2, 3, 4), kDefaultServerPort);
7011 EXPECT_EQ(actual_address, expected_address);
7012 DVLOG(1) << "Socket connected to: " << actual_address.address().ToString()
7013 << " " << actual_address.port();
7014 DVLOG(1) << "Expected address: " << expected_address.address().ToString()
7015 << " " << expected_address.port();
7016
7017 stream.reset();
7018 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7019 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7020}
7021
rch02d87792015-09-09 09:05:537022TEST_P(QuicStreamFactoryTest, OnSSLConfigChanged) {
jri7046038f2015-10-22 00:29:267023 Initialize();
rch6faa4d42016-01-05 20:48:437024 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7025 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7026 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7027
rcha00569732016-08-27 11:09:367028 MockQuicData socket_data;
7029 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437030 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Ryan Hamilton8d9ee76e2018-05-29 23:52:527031 socket_data.AddWrite(
7032 SYNCHRONOUS, ConstructClientRstPacket(2, quic::QUIC_RST_ACKNOWLEDGEMENT));
Zhongyi Shi5f587cc2017-11-21 23:24:177033 socket_data.AddSocketDataToFactory(socket_factory_.get());
rch02d87792015-09-09 09:05:537034
rcha00569732016-08-27 11:09:367035 MockQuicData socket_data2;
7036 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437037 socket_data2.AddWrite(SYNCHRONOUS,
7038 ConstructInitialSettingsPacket(1, nullptr));
Zhongyi Shi5f587cc2017-11-21 23:24:177039 socket_data2.AddSocketDataToFactory(socket_factory_.get());
rch02d87792015-09-09 09:05:537040
zhongyi98d6a9262017-05-19 02:47:457041 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337042 EXPECT_EQ(ERR_IO_PENDING,
7043 request.Request(host_port_pair_, version_, privacy_mode_,
7044 DEFAULT_PRIORITY, SocketTag(),
7045 /*cert_verify_flags=*/0, url_, net_log_,
7046 &net_error_details_, callback_.callback()));
rch02d87792015-09-09 09:05:537047
robpercival214763f2016-07-01 23:27:017048 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:247049 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Cherie Shie615a0842018-02-28 02:01:137050 HttpRequestInfo request_info;
7051 request_info.traffic_annotation =
7052 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7053 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békyd8a21fc32018-06-27 18:29:587054 net_log_, CompletionOnceCallback()));
rch02d87792015-09-09 09:05:537055
nharper642ae4b2016-06-30 00:40:367056 ssl_config_service_->NotifySSLConfigChange();
Cherie Shie615a0842018-02-28 02:01:137057 EXPECT_EQ(ERR_CERT_DATABASE_CHANGED,
7058 stream->ReadResponseHeaders(callback_.callback()));
jri7046038f2015-10-22 00:29:267059 EXPECT_FALSE(factory_->require_confirmation());
rch02d87792015-09-09 09:05:537060
7061 // Now attempting to request a stream to the same origin should create
7062 // a new session.
Cherie Shie615a0842018-02-28 02:01:137063
zhongyi98d6a9262017-05-19 02:47:457064 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337065 EXPECT_EQ(ERR_IO_PENDING,
7066 request2.Request(host_port_pair_, version_, privacy_mode_,
7067 DEFAULT_PRIORITY, SocketTag(),
7068 /*cert_verify_flags=*/0, url_, net_log_,
7069 &net_error_details_, callback_.callback()));
rch02d87792015-09-09 09:05:537070
robpercival214763f2016-07-01 23:27:017071 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Cherie Shie615a0842018-02-28 02:01:137072 stream = CreateStream(&request2);
7073 stream.reset(); // Will reset stream 3.
rch02d87792015-09-09 09:05:537074
7075 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7076 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7077 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
7078 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
7079}
7080
rsleevi17784692016-10-12 01:36:207081TEST_P(QuicStreamFactoryTest, OnCertDBChanged) {
jri7046038f2015-10-22 00:29:267082 Initialize();
rch6faa4d42016-01-05 20:48:437083 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7084 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7085 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7086
rcha00569732016-08-27 11:09:367087 MockQuicData socket_data;
7088 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437089 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:177090 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]d7d1e50b2013-11-25 22:08:097091
rcha00569732016-08-27 11:09:367092 MockQuicData socket_data2;
7093 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437094 socket_data2.AddWrite(SYNCHRONOUS,
7095 ConstructInitialSettingsPacket(1, nullptr));
Zhongyi Shi5f587cc2017-11-21 23:24:177096 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]d7d1e50b2013-11-25 22:08:097097
zhongyi98d6a9262017-05-19 02:47:457098 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337099 EXPECT_EQ(ERR_IO_PENDING,
7100 request.Request(host_port_pair_, version_, privacy_mode_,
7101 DEFAULT_PRIORITY, SocketTag(),
7102 /*cert_verify_flags=*/0, url_, net_log_,
7103 &net_error_details_, callback_.callback()));
[email protected]d7d1e50b2013-11-25 22:08:097104
robpercival214763f2016-07-01 23:27:017105 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:247106 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Charles 'Buck' Krasic71763c9f2018-02-16 02:37:287107 EXPECT_TRUE(stream);
7108 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
[email protected]d7d1e50b2013-11-25 22:08:097109
7110 // Change the CA cert and verify that stream saw the event.
mattmfd05a1f2017-02-18 06:18:447111 factory_->OnCertDBChanged();
Charles 'Buck' Krasic71763c9f2018-02-16 02:37:287112
jri7046038f2015-10-22 00:29:267113 EXPECT_FALSE(factory_->require_confirmation());
Charles 'Buck' Krasic71763c9f2018-02-16 02:37:287114 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7115 EXPECT_FALSE(HasActiveSession(host_port_pair_));
[email protected]d7d1e50b2013-11-25 22:08:097116
7117 // Now attempting to request a stream to the same origin should create
7118 // a new session.
7119
zhongyi98d6a9262017-05-19 02:47:457120 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337121 EXPECT_EQ(ERR_IO_PENDING,
7122 request2.Request(host_port_pair_, version_, privacy_mode_,
7123 DEFAULT_PRIORITY, SocketTag(),
7124 /*cert_verify_flags=*/0, url_, net_log_,
7125 &net_error_details_, callback_.callback()));
[email protected]d7d1e50b2013-11-25 22:08:097126
robpercival214763f2016-07-01 23:27:017127 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Charles 'Buck' Krasic71763c9f2018-02-16 02:37:287128 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
7129 EXPECT_TRUE(stream2);
7130 QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
7131 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7132 EXPECT_NE(session, session2);
7133 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7134 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
7135
7136 stream2.reset();
7137 stream.reset();
[email protected]d7d1e50b2013-11-25 22:08:097138
rch37de576c2015-05-17 20:28:177139 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7140 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7141 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
7142 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]d7d1e50b2013-11-25 22:08:097143}
7144
[email protected]1e960032013-12-20 19:00:207145TEST_P(QuicStreamFactoryTest, SharedCryptoConfig) {
jri7046038f2015-10-22 00:29:267146 Initialize();
rch6faa4d42016-01-05 20:48:437147
rch872e00e2016-12-02 02:48:187148 std::vector<string> cannoncial_suffixes;
[email protected]6e12d702013-11-13 00:17:177149 cannoncial_suffixes.push_back(string(".c.youtube.com"));
7150 cannoncial_suffixes.push_back(string(".googlevideo.com"));
[email protected]c49ff182013-09-28 08:33:267151
[email protected]6e12d702013-11-13 00:17:177152 for (unsigned i = 0; i < cannoncial_suffixes.size(); ++i) {
7153 string r1_host_name("r1");
7154 string r2_host_name("r2");
7155 r1_host_name.append(cannoncial_suffixes[i]);
7156 r2_host_name.append(cannoncial_suffixes[i]);
[email protected]b70fdb792013-10-25 19:04:147157
[email protected]bf4ea2f2014-03-10 22:57:537158 HostPortPair host_port_pair1(r1_host_name, 80);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527159 quic::QuicCryptoClientConfig* crypto_config =
jri7046038f2015-10-22 00:29:267160 QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
Ryan Hamilton4f0b26e2018-06-27 23:52:327161 quic::QuicServerId server_id1(host_port_pair1.host(),
7162 host_port_pair1.port(), privacy_mode_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527163 quic::QuicCryptoClientConfig::CachedState* cached1 =
[email protected]257f24f2014-04-01 09:15:377164 crypto_config->LookupOrCreate(server_id1);
[email protected]6e12d702013-11-13 00:17:177165 EXPECT_FALSE(cached1->proof_valid());
7166 EXPECT_TRUE(cached1->source_address_token().empty());
7167
7168 // Mutate the cached1 to have different data.
7169 // TODO(rtenneti): mutate other members of CachedState.
7170 cached1->set_source_address_token(r1_host_name);
7171 cached1->SetProofValid();
7172
[email protected]bf4ea2f2014-03-10 22:57:537173 HostPortPair host_port_pair2(r2_host_name, 80);
Ryan Hamilton4f0b26e2018-06-27 23:52:327174 quic::QuicServerId server_id2(host_port_pair2.host(),
7175 host_port_pair2.port(), privacy_mode_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527176 quic::QuicCryptoClientConfig::CachedState* cached2 =
[email protected]257f24f2014-04-01 09:15:377177 crypto_config->LookupOrCreate(server_id2);
[email protected]6e12d702013-11-13 00:17:177178 EXPECT_EQ(cached1->source_address_token(), cached2->source_address_token());
7179 EXPECT_TRUE(cached2->proof_valid());
7180 }
[email protected]b70fdb792013-10-25 19:04:147181}
7182
[email protected]1e960032013-12-20 19:00:207183TEST_P(QuicStreamFactoryTest, CryptoConfigWhenProofIsInvalid) {
jri7046038f2015-10-22 00:29:267184 Initialize();
rch872e00e2016-12-02 02:48:187185 std::vector<string> cannoncial_suffixes;
[email protected]6e12d702013-11-13 00:17:177186 cannoncial_suffixes.push_back(string(".c.youtube.com"));
7187 cannoncial_suffixes.push_back(string(".googlevideo.com"));
[email protected]b70fdb792013-10-25 19:04:147188
[email protected]6e12d702013-11-13 00:17:177189 for (unsigned i = 0; i < cannoncial_suffixes.size(); ++i) {
7190 string r3_host_name("r3");
7191 string r4_host_name("r4");
7192 r3_host_name.append(cannoncial_suffixes[i]);
7193 r4_host_name.append(cannoncial_suffixes[i]);
[email protected]b70fdb792013-10-25 19:04:147194
[email protected]bf4ea2f2014-03-10 22:57:537195 HostPortPair host_port_pair1(r3_host_name, 80);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527196 quic::QuicCryptoClientConfig* crypto_config =
jri7046038f2015-10-22 00:29:267197 QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
Ryan Hamilton4f0b26e2018-06-27 23:52:327198 quic::QuicServerId server_id1(host_port_pair1.host(),
7199 host_port_pair1.port(), privacy_mode_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527200 quic::QuicCryptoClientConfig::CachedState* cached1 =
[email protected]257f24f2014-04-01 09:15:377201 crypto_config->LookupOrCreate(server_id1);
[email protected]6e12d702013-11-13 00:17:177202 EXPECT_FALSE(cached1->proof_valid());
7203 EXPECT_TRUE(cached1->source_address_token().empty());
7204
7205 // Mutate the cached1 to have different data.
7206 // TODO(rtenneti): mutate other members of CachedState.
7207 cached1->set_source_address_token(r3_host_name);
7208 cached1->SetProofInvalid();
7209
[email protected]bf4ea2f2014-03-10 22:57:537210 HostPortPair host_port_pair2(r4_host_name, 80);
Ryan Hamilton4f0b26e2018-06-27 23:52:327211 quic::QuicServerId server_id2(host_port_pair2.host(),
7212 host_port_pair2.port(), privacy_mode_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527213 quic::QuicCryptoClientConfig::CachedState* cached2 =
[email protected]257f24f2014-04-01 09:15:377214 crypto_config->LookupOrCreate(server_id2);
[email protected]6e12d702013-11-13 00:17:177215 EXPECT_NE(cached1->source_address_token(), cached2->source_address_token());
7216 EXPECT_TRUE(cached2->source_address_token().empty());
7217 EXPECT_FALSE(cached2->proof_valid());
7218 }
[email protected]c49ff182013-09-28 08:33:267219}
7220
rtenneti34dffe752015-02-24 23:27:327221TEST_P(QuicStreamFactoryTest, EnableNotLoadFromDiskCache) {
jri7046038f2015-10-22 00:29:267222 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:207223 factory_->set_require_confirmation(false);
rch6faa4d42016-01-05 20:48:437224 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7225 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7226
jri7046038f2015-10-22 00:29:267227 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
rtenneti34dffe752015-02-24 23:27:327228
rcha00569732016-08-27 11:09:367229 MockQuicData socket_data;
7230 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:177231 socket_data.AddSocketDataToFactory(socket_factory_.get());
rtenneti34dffe752015-02-24 23:27:327232
7233 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:277234 MockCryptoClientStream::ZERO_RTT);
rtenneti34dffe752015-02-24 23:27:327235 host_resolver_.set_synchronous_mode(true);
7236 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
7237 "192.168.0.1", "");
7238
zhongyi98d6a9262017-05-19 02:47:457239 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337240 EXPECT_EQ(OK, request.Request(host_port_pair_, version_, privacy_mode_,
7241 DEFAULT_PRIORITY, SocketTag(),
7242 /*cert_verify_flags=*/0, url_, net_log_,
7243 &net_error_details_, callback_.callback()));
rtenneti34dffe752015-02-24 23:27:327244
7245 // If we are waiting for disk cache, we would have posted a task. Verify that
7246 // the CancelWaitForDataReady task hasn't been posted.
7247 ASSERT_EQ(0u, runner_->GetPostedTasks().size());
7248
Yixin Wang7891a39d2017-11-08 20:59:247249 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rtenneti34dffe752015-02-24 23:27:327250 EXPECT_TRUE(stream.get());
rch37de576c2015-05-17 20:28:177251 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7252 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
rtenneti34dffe752015-02-24 23:27:327253}
7254
dmurph44ca4f42016-09-09 20:39:097255TEST_P(QuicStreamFactoryTest, ReducePingTimeoutOnConnectionTimeOutOpenStreams) {
7256 reduced_ping_timeout_seconds_ = 10;
dmurph44ca4f42016-09-09 20:39:097257 Initialize();
7258 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7259 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7260 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7261
7262 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
zhongyidd1439f62016-09-02 02:02:267263
7264 MockQuicData socket_data;
7265 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437266 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:177267 socket_data.AddSocketDataToFactory(socket_factory_.get());
zhongyidd1439f62016-09-02 02:02:267268
7269 MockQuicData socket_data2;
7270 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437271 socket_data2.AddWrite(SYNCHRONOUS,
7272 ConstructInitialSettingsPacket(1, nullptr));
Zhongyi Shi5f587cc2017-11-21 23:24:177273 socket_data2.AddSocketDataToFactory(socket_factory_.get());
zhongyidd1439f62016-09-02 02:02:267274
7275 HostPortPair server2(kServer2HostName, kDefaultServerPort);
7276
7277 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:277278 MockCryptoClientStream::CONFIRM_HANDSHAKE);
zhongyidd1439f62016-09-02 02:02:267279 host_resolver_.set_synchronous_mode(true);
7280 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
7281 "192.168.0.1", "");
7282 host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
7283
7284 // Quic should use default PING timeout when no previous connection times out
7285 // with open stream.
Ryan Hamilton8d9ee76e2018-05-29 23:52:527286 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(quic::kPingTimeoutSecs),
zhongyidd1439f62016-09-02 02:02:267287 QuicStreamFactoryPeer::GetPingTimeout(factory_.get()));
zhongyi98d6a9262017-05-19 02:47:457288 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337289 EXPECT_EQ(OK, request.Request(host_port_pair_, version_, privacy_mode_,
7290 DEFAULT_PRIORITY, SocketTag(),
7291 /*cert_verify_flags=*/0, url_, net_log_,
7292 &net_error_details_, callback_.callback()));
zhongyidd1439f62016-09-02 02:02:267293
7294 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527295 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(quic::kPingTimeoutSecs),
zhongyidd1439f62016-09-02 02:02:267296 session->connection()->ping_timeout());
7297
Yixin Wang7891a39d2017-11-08 20:59:247298 std::unique_ptr<HttpStream> stream = CreateStream(&request);
zhongyidd1439f62016-09-02 02:02:267299 EXPECT_TRUE(stream.get());
7300 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:397301 request_info.traffic_annotation =
7302 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:277303 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:397304 net_log_, CompletionOnceCallback()));
zhongyidd1439f62016-09-02 02:02:267305
7306 DVLOG(1)
7307 << "Created 1st session and initialized a stream. Now trigger timeout";
Ryan Hamilton8d9ee76e2018-05-29 23:52:527308 session->connection()->CloseConnection(
7309 quic::QUIC_NETWORK_IDLE_TIMEOUT, "test",
7310 quic::ConnectionCloseBehavior::SILENT_CLOSE);
zhongyidd1439f62016-09-02 02:02:267311 // Need to spin the loop now to ensure that
7312 // QuicStreamFactory::OnSessionClosed() runs.
7313 base::RunLoop run_loop;
7314 run_loop.RunUntilIdle();
7315
zhongyidd1439f62016-09-02 02:02:267316 // The first connection times out with open stream, QUIC should reduce initial
7317 // PING time for subsequent connections.
Ryan Hamilton8d9ee76e2018-05-29 23:52:527318 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(10),
zhongyidd1439f62016-09-02 02:02:267319 QuicStreamFactoryPeer::GetPingTimeout(factory_.get()));
7320
7321 // Test two-in-a-row timeouts with open streams.
7322 DVLOG(1) << "Create 2nd session and timeout with open stream";
7323 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:457324 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337325 EXPECT_EQ(OK, request2.Request(server2, version_, privacy_mode_,
7326 DEFAULT_PRIORITY, SocketTag(),
7327 /*cert_verify_flags=*/0, url2_, net_log_,
7328 &net_error_details_, callback2.callback()));
zhongyidd1439f62016-09-02 02:02:267329 QuicChromiumClientSession* session2 = GetActiveSession(server2);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527330 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(10),
zhongyidd1439f62016-09-02 02:02:267331 session2->connection()->ping_timeout());
7332
Yixin Wang7891a39d2017-11-08 20:59:247333 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
zhongyidd1439f62016-09-02 02:02:267334 EXPECT_TRUE(stream2.get());
Steven Valdezb4ff0412018-01-18 22:39:277335 EXPECT_EQ(OK,
7336 stream2->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:397337 net_log_, CompletionOnceCallback()));
zhongyidd1439f62016-09-02 02:02:267338 session2->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527339 quic::QUIC_NETWORK_IDLE_TIMEOUT, "test",
7340 quic::ConnectionCloseBehavior::SILENT_CLOSE);
zhongyidd1439f62016-09-02 02:02:267341 // Need to spin the loop now to ensure that
7342 // QuicStreamFactory::OnSessionClosed() runs.
7343 base::RunLoop run_loop2;
7344 run_loop2.RunUntilIdle();
zhongyidd1439f62016-09-02 02:02:267345
7346 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7347 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7348 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
7349 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
7350}
7351
tbansal3b966952016-10-25 23:25:147352// Verifies that the QUIC stream factory is initialized correctly.
rtenneticd2aaa15b2015-10-10 20:29:337353TEST_P(QuicStreamFactoryTest, MaybeInitialize) {
tbansal9b1cdf32017-05-10 17:28:397354 VerifyInitialization();
rtenneti8a80a6dc2015-09-21 19:51:137355}
7356
rtennetid073dd22016-08-04 01:58:337357TEST_P(QuicStreamFactoryTest, StartCertVerifyJob) {
7358 Initialize();
7359
rcha00569732016-08-27 11:09:367360 MockQuicData socket_data;
7361 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437362 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:177363 socket_data.AddSocketDataToFactory(socket_factory_.get());
rtennetid073dd22016-08-04 01:58:337364
7365 // Save current state of |race_cert_verification|.
7366 bool race_cert_verification =
7367 QuicStreamFactoryPeer::GetRaceCertVerification(factory_.get());
7368
7369 // Load server config.
7370 HostPortPair host_port_pair(kDefaultServerHostName, kDefaultServerPort);
Ryan Hamilton4f0b26e2018-06-27 23:52:327371 quic::QuicServerId quic_server_id(host_port_pair_.host(),
7372 host_port_pair_.port(),
7373 privacy_mode_ == PRIVACY_MODE_ENABLED);
rtennetid073dd22016-08-04 01:58:337374 QuicStreamFactoryPeer::CacheDummyServerConfig(factory_.get(), quic_server_id);
7375
7376 QuicStreamFactoryPeer::SetRaceCertVerification(factory_.get(), true);
7377 EXPECT_FALSE(HasActiveCertVerifierJob(quic_server_id));
7378
7379 // Start CertVerifyJob.
Ryan Hamilton8d9ee76e2018-05-29 23:52:527380 quic::QuicAsyncStatus status = QuicStreamFactoryPeer::StartCertVerifyJob(
rtennetid073dd22016-08-04 01:58:337381 factory_.get(), quic_server_id, /*cert_verify_flags=*/0, net_log_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527382 if (status == quic::QUIC_PENDING) {
rtennetid073dd22016-08-04 01:58:337383 // Verify CertVerifierJob has started.
7384 EXPECT_TRUE(HasActiveCertVerifierJob(quic_server_id));
7385
7386 while (HasActiveCertVerifierJob(quic_server_id)) {
7387 base::RunLoop().RunUntilIdle();
7388 }
7389 }
7390 // Verify CertVerifierJob has finished.
7391 EXPECT_FALSE(HasActiveCertVerifierJob(quic_server_id));
7392
7393 // Start a QUIC request.
zhongyi98d6a9262017-05-19 02:47:457394 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337395 EXPECT_EQ(ERR_IO_PENDING,
7396 request.Request(host_port_pair_, version_, privacy_mode_,
7397 DEFAULT_PRIORITY, SocketTag(),
7398 /*cert_verify_flags=*/0, url_, net_log_,
7399 &net_error_details_, callback_.callback()));
rtennetid073dd22016-08-04 01:58:337400
7401 EXPECT_EQ(OK, callback_.WaitForResult());
7402
Yixin Wang7891a39d2017-11-08 20:59:247403 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rtennetid073dd22016-08-04 01:58:337404 EXPECT_TRUE(stream.get());
7405
7406 // Restore |race_cert_verification|.
7407 QuicStreamFactoryPeer::SetRaceCertVerification(factory_.get(),
7408 race_cert_verification);
7409
7410 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7411 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7412
7413 // Verify there are no outstanding CertVerifierJobs after request has
7414 // finished.
7415 EXPECT_FALSE(HasActiveCertVerifierJob(quic_server_id));
7416}
7417
rtenneti1cd3b162015-09-29 02:58:287418TEST_P(QuicStreamFactoryTest, YieldAfterPackets) {
jri7046038f2015-10-22 00:29:267419 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:207420 factory_->set_require_confirmation(false);
rch6faa4d42016-01-05 20:48:437421 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7422 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:267423 QuicStreamFactoryPeer::SetYieldAfterPackets(factory_.get(), 0);
rtenneti1cd3b162015-09-29 02:58:287424
rcha00569732016-08-27 11:09:367425 MockQuicData socket_data;
Zhongyi Shi32f2fd02018-04-16 18:23:437426 socket_data.AddRead(SYNCHRONOUS, ConstructClientConnectionClosePacket(0));
rcha00569732016-08-27 11:09:367427 socket_data.AddRead(ASYNC, OK);
Zhongyi Shi5f587cc2017-11-21 23:24:177428 socket_data.AddSocketDataToFactory(socket_factory_.get());
rtenneti1cd3b162015-09-29 02:58:287429
7430 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:277431 MockCryptoClientStream::ZERO_RTT);
rtenneti1cd3b162015-09-29 02:58:287432 host_resolver_.set_synchronous_mode(true);
7433 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
7434 "192.168.0.1", "");
7435
rcha02807b42016-01-29 21:56:157436 // Set up the TaskObserver to verify QuicChromiumPacketReader::StartReading
7437 // posts a task.
rtenneti1cd3b162015-09-29 02:58:287438 // TODO(rtenneti): Change SpdySessionTestTaskObserver to NetTestTaskObserver??
rcha02807b42016-01-29 21:56:157439 SpdySessionTestTaskObserver observer("quic_chromium_packet_reader.cc",
7440 "StartReading");
rtenneti1cd3b162015-09-29 02:58:287441
zhongyi98d6a9262017-05-19 02:47:457442 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337443 EXPECT_EQ(OK, request.Request(host_port_pair_, version_, privacy_mode_,
7444 DEFAULT_PRIORITY, SocketTag(),
7445 /*cert_verify_flags=*/0, url_, net_log_,
7446 &net_error_details_, callback_.callback()));
rtenneti1cd3b162015-09-29 02:58:287447
rcha02807b42016-01-29 21:56:157448 // Call run_loop so that QuicChromiumPacketReader::OnReadComplete() gets
7449 // called.
rtenneti1cd3b162015-09-29 02:58:287450 base::RunLoop run_loop;
7451 run_loop.RunUntilIdle();
7452
7453 // Verify task that the observer's executed_count is 1, which indicates
rcha02807b42016-01-29 21:56:157454 // QuicChromiumPacketReader::StartReading() has posted only one task and
7455 // yielded the read.
rtenneti1cd3b162015-09-29 02:58:287456 EXPECT_EQ(1u, observer.executed_count());
7457
Yixin Wang7891a39d2017-11-08 20:59:247458 std::unique_ptr<HttpStream> stream = CreateStream(&request);
xunjieli2608f9b2016-03-14 13:39:237459 EXPECT_FALSE(stream.get()); // Session is already closed.
rtenneti1cd3b162015-09-29 02:58:287460 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7461 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7462}
7463
7464TEST_P(QuicStreamFactoryTest, YieldAfterDuration) {
jri7046038f2015-10-22 00:29:267465 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:207466 factory_->set_require_confirmation(false);
rch6faa4d42016-01-05 20:48:437467 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7468 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rtenneti1cd3b162015-09-29 02:58:287469 QuicStreamFactoryPeer::SetYieldAfterDuration(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527470 factory_.get(), quic::QuicTime::Delta::FromMilliseconds(-1));
rtenneti1cd3b162015-09-29 02:58:287471
rcha00569732016-08-27 11:09:367472 MockQuicData socket_data;
Zhongyi Shi32f2fd02018-04-16 18:23:437473 socket_data.AddRead(SYNCHRONOUS, ConstructClientConnectionClosePacket(0));
rcha00569732016-08-27 11:09:367474 socket_data.AddRead(ASYNC, OK);
Zhongyi Shi5f587cc2017-11-21 23:24:177475 socket_data.AddSocketDataToFactory(socket_factory_.get());
rtenneti1cd3b162015-09-29 02:58:287476
7477 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:277478 MockCryptoClientStream::ZERO_RTT);
rtenneti1cd3b162015-09-29 02:58:287479 host_resolver_.set_synchronous_mode(true);
7480 host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
7481 "192.168.0.1", "");
7482
rcha02807b42016-01-29 21:56:157483 // Set up the TaskObserver to verify QuicChromiumPacketReader::StartReading
7484 // posts a task.
rtenneti1cd3b162015-09-29 02:58:287485 // TODO(rtenneti): Change SpdySessionTestTaskObserver to NetTestTaskObserver??
rcha02807b42016-01-29 21:56:157486 SpdySessionTestTaskObserver observer("quic_chromium_packet_reader.cc",
7487 "StartReading");
rtenneti1cd3b162015-09-29 02:58:287488
zhongyi98d6a9262017-05-19 02:47:457489 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337490 EXPECT_EQ(OK, request.Request(host_port_pair_, version_, privacy_mode_,
7491 DEFAULT_PRIORITY, SocketTag(),
7492 /*cert_verify_flags=*/0, url_, net_log_,
7493 &net_error_details_, callback_.callback()));
rtenneti1cd3b162015-09-29 02:58:287494
rcha02807b42016-01-29 21:56:157495 // Call run_loop so that QuicChromiumPacketReader::OnReadComplete() gets
7496 // called.
rtenneti1cd3b162015-09-29 02:58:287497 base::RunLoop run_loop;
7498 run_loop.RunUntilIdle();
7499
7500 // Verify task that the observer's executed_count is 1, which indicates
rcha02807b42016-01-29 21:56:157501 // QuicChromiumPacketReader::StartReading() has posted only one task and
7502 // yielded the read.
rtenneti1cd3b162015-09-29 02:58:287503 EXPECT_EQ(1u, observer.executed_count());
7504
Yixin Wang7891a39d2017-11-08 20:59:247505 std::unique_ptr<HttpStream> stream = CreateStream(&request);
xunjieli2608f9b2016-03-14 13:39:237506 EXPECT_FALSE(stream.get()); // Session is already closed.
rtenneti1cd3b162015-09-29 02:58:287507 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7508 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7509}
7510
ckrasic3865ee0f2016-02-29 22:04:567511TEST_P(QuicStreamFactoryTest, ServerPushSessionAffinity) {
7512 Initialize();
7513 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7514 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7515
rcha00569732016-08-27 11:09:367516 MockQuicData socket_data;
7517 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437518 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:177519 socket_data.AddSocketDataToFactory(socket_factory_.get());
ckrasic3865ee0f2016-02-29 22:04:567520
zhongyi98d6a9262017-05-19 02:47:457521 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337522 EXPECT_EQ(ERR_IO_PENDING,
7523 request.Request(host_port_pair_, version_, privacy_mode_,
7524 DEFAULT_PRIORITY, SocketTag(),
7525 /*cert_verify_flags=*/0, url_, net_log_,
7526 &net_error_details_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:567527
robpercival214763f2016-07-01 23:27:017528 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:247529 std::unique_ptr<HttpStream> stream = CreateStream(&request);
ckrasic3865ee0f2016-02-29 22:04:567530 EXPECT_TRUE(stream.get());
7531
7532 EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumPushStreamsCreated(factory_.get()));
7533
bnc5fdc07162016-05-23 17:36:037534 string url = "https://www.example.org/";
ckrasic3865ee0f2016-02-29 22:04:567535
bnc912a04b2016-04-20 14:19:507536 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
ckrasic3865ee0f2016-02-29 22:04:567537
Ryan Hamilton8d9ee76e2018-05-29 23:52:527538 quic::QuicClientPromisedInfo promised(
7539 session, GetNthServerInitiatedStreamId(0), kDefaultUrl);
ckrasic3865ee0f2016-02-29 22:04:567540 (*QuicStreamFactoryPeer::GetPushPromiseIndex(factory_.get())
bnc3d9035b32016-06-30 18:18:487541 ->promised_by_url())[kDefaultUrl] = &promised;
ckrasic3865ee0f2016-02-29 22:04:567542
zhongyi98d6a9262017-05-19 02:47:457543 QuicStreamRequest request2(factory_.get());
zhongyia00ca012017-07-06 23:36:397544 EXPECT_EQ(OK, request2.Request(host_port_pair_, version_, privacy_mode_,
Paul Jensen8e3c5d32018-02-19 17:06:337545 DEFAULT_PRIORITY, SocketTag(),
7546 /*cert_verify_flags=*/0, url_, net_log_,
7547 &net_error_details_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:567548
7549 EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumPushStreamsCreated(factory_.get()));
7550}
7551
7552TEST_P(QuicStreamFactoryTest, ServerPushPrivacyModeMismatch) {
7553 Initialize();
7554 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7555 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7556 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7557
rcha00569732016-08-27 11:09:367558 MockQuicData socket_data1;
7559 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437560 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
7561 socket_data1.AddWrite(
7562 SYNCHRONOUS,
7563 client_maker_.MakeRstPacket(2, true, GetNthServerInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:527564 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:177565 socket_data1.AddSocketDataToFactory(socket_factory_.get());
ckrasic3865ee0f2016-02-29 22:04:567566
rcha00569732016-08-27 11:09:367567 MockQuicData socket_data2;
7568 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437569 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:177570 socket_data2.AddSocketDataToFactory(socket_factory_.get());
ckrasic3865ee0f2016-02-29 22:04:567571
zhongyi98d6a9262017-05-19 02:47:457572 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337573 EXPECT_EQ(ERR_IO_PENDING,
7574 request.Request(host_port_pair_, version_, privacy_mode_,
7575 DEFAULT_PRIORITY, SocketTag(),
7576 /*cert_verify_flags=*/0, url_, net_log_,
7577 &net_error_details_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:567578
robpercival214763f2016-07-01 23:27:017579 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:247580 std::unique_ptr<HttpStream> stream = CreateStream(&request);
ckrasic3865ee0f2016-02-29 22:04:567581 EXPECT_TRUE(stream.get());
7582
7583 EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumPushStreamsCreated(factory_.get()));
7584
bnc5fdc07162016-05-23 17:36:037585 string url = "https://www.example.org/";
bnc912a04b2016-04-20 14:19:507586 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
ckrasic3865ee0f2016-02-29 22:04:567587
Ryan Hamilton8d9ee76e2018-05-29 23:52:527588 quic::QuicClientPromisedInfo promised(
7589 session, GetNthServerInitiatedStreamId(0), kDefaultUrl);
ckrasic3865ee0f2016-02-29 22:04:567590
Ryan Hamilton8d9ee76e2018-05-29 23:52:527591 quic::QuicClientPushPromiseIndex* index =
ckrasic3865ee0f2016-02-29 22:04:567592 QuicStreamFactoryPeer::GetPushPromiseIndex(factory_.get());
7593
bnc3d9035b32016-06-30 18:18:487594 (*index->promised_by_url())[kDefaultUrl] = &promised;
7595 EXPECT_EQ(index->GetPromised(kDefaultUrl), &promised);
ckrasic3865ee0f2016-02-29 22:04:567596
7597 // Doing the request should not use the push stream, but rather
7598 // cancel it because the privacy modes do not match.
zhongyi98d6a9262017-05-19 02:47:457599 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337600 EXPECT_EQ(ERR_IO_PENDING,
7601 request2.Request(host_port_pair_, version_, PRIVACY_MODE_ENABLED,
7602 DEFAULT_PRIORITY, SocketTag(),
7603 /*cert_verify_flags=*/0, url_, net_log_,
7604 &net_error_details_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:567605
7606 EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumPushStreamsCreated(factory_.get()));
bnc3d9035b32016-06-30 18:18:487607 EXPECT_EQ(index->GetPromised(kDefaultUrl), nullptr);
ckrasic3865ee0f2016-02-29 22:04:567608
robpercival214763f2016-07-01 23:27:017609 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:247610 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
ckrasic3865ee0f2016-02-29 22:04:567611 EXPECT_TRUE(stream2.get());
7612
7613 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7614 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7615 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
7616 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
7617}
7618
Ryan Hamilton8d9ee76e2018-05-29 23:52:527619// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:457620// even if destination is different.
7621TEST_P(QuicStreamFactoryTest, PoolByOrigin) {
7622 Initialize();
7623
7624 HostPortPair destination1("first.example.com", 443);
7625 HostPortPair destination2("second.example.com", 443);
7626
7627 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7628 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7629
rcha00569732016-08-27 11:09:367630 MockQuicData socket_data;
7631 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:437632 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:177633 socket_data.AddSocketDataToFactory(socket_factory_.get());
bnc359ed2a2016-04-29 20:43:457634
zhongyi98d6a9262017-05-19 02:47:457635 QuicStreamRequest request1(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337636 EXPECT_EQ(ERR_IO_PENDING,
7637 request1.Request(destination1, version_, privacy_mode_,
7638 DEFAULT_PRIORITY, SocketTag(),
7639 /*cert_verify_flags=*/0, url_, net_log_,
7640 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:017641 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:247642 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
bnc359ed2a2016-04-29 20:43:457643 EXPECT_TRUE(stream1.get());
7644 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7645
7646 // Second request returns synchronously because it pools to existing session.
7647 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:457648 QuicStreamRequest request2(factory_.get());
zhongyia00ca012017-07-06 23:36:397649 EXPECT_EQ(OK, request2.Request(destination2, version_, privacy_mode_,
Paul Jensen8e3c5d32018-02-19 17:06:337650 DEFAULT_PRIORITY, SocketTag(),
7651 /*cert_verify_flags=*/0, url_, net_log_,
7652 &net_error_details_, callback2.callback()));
Yixin Wang7891a39d2017-11-08 20:59:247653 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
bnc359ed2a2016-04-29 20:43:457654 EXPECT_TRUE(stream2.get());
7655
rchf0b18c8a2017-05-05 19:31:577656 QuicChromiumClientSession::Handle* session1 =
7657 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
7658 QuicChromiumClientSession::Handle* session2 =
7659 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
7660 EXPECT_TRUE(session1->SharesSameSession(*session2));
Ryan Hamilton4f0b26e2018-06-27 23:52:327661 EXPECT_EQ(quic::QuicServerId(host_port_pair_.host(), host_port_pair_.port(),
7662 privacy_mode_ == PRIVACY_MODE_ENABLED),
bnc359ed2a2016-04-29 20:43:457663 session1->server_id());
7664
7665 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7666 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7667}
7668
7669class QuicStreamFactoryWithDestinationTest
7670 : public QuicStreamFactoryTestBase,
7671 public ::testing::TestWithParam<PoolingTestParams> {
7672 protected:
7673 QuicStreamFactoryWithDestinationTest()
Yixin Wang079ad542018-01-11 04:06:057674 : QuicStreamFactoryTestBase(
7675 GetParam().version,
7676 GetParam().client_headers_include_h2_stream_dependency),
bnc359ed2a2016-04-29 20:43:457677 destination_type_(GetParam().destination_type),
7678 hanging_read_(SYNCHRONOUS, ERR_IO_PENDING, 0) {}
7679
7680 HostPortPair GetDestination() {
7681 switch (destination_type_) {
7682 case SAME_AS_FIRST:
7683 return origin1_;
7684 case SAME_AS_SECOND:
7685 return origin2_;
7686 case DIFFERENT:
7687 return HostPortPair(kDifferentHostname, 443);
7688 default:
7689 NOTREACHED();
7690 return HostPortPair();
7691 }
7692 }
7693
7694 void AddHangingSocketData() {
7695 std::unique_ptr<SequencedSocketData> sequenced_socket_data(
Ryan Sleevib8d7ea02018-05-07 20:01:017696 new SequencedSocketData(base::make_span(&hanging_read_, 1),
7697 base::span<MockWrite>()));
Zhongyi Shi5f587cc2017-11-21 23:24:177698 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
bnc359ed2a2016-04-29 20:43:457699 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
7700 }
7701
7702 bool AllDataConsumed() {
7703 for (const auto& socket_data_ptr : sequenced_socket_data_vector_) {
7704 if (!socket_data_ptr->AllReadDataConsumed() ||
7705 !socket_data_ptr->AllWriteDataConsumed()) {
7706 return false;
7707 }
7708 }
7709 return true;
7710 }
7711
7712 DestinationType destination_type_;
7713 HostPortPair origin1_;
7714 HostPortPair origin2_;
7715 MockRead hanging_read_;
rch872e00e2016-12-02 02:48:187716 std::vector<std::unique_ptr<SequencedSocketData>>
7717 sequenced_socket_data_vector_;
bnc359ed2a2016-04-29 20:43:457718};
7719
Bence Békyce380cb2018-04-26 23:39:557720INSTANTIATE_TEST_CASE_P(VersionIncludeStreamDependencySequence,
bnc359ed2a2016-04-29 20:43:457721 QuicStreamFactoryWithDestinationTest,
7722 ::testing::ValuesIn(GetPoolingTestParams()));
7723
7724// A single QUIC request fails because the certificate does not match the origin
7725// hostname, regardless of whether it matches the alternative service hostname.
7726TEST_P(QuicStreamFactoryWithDestinationTest, InvalidCertificate) {
7727 if (destination_type_ == DIFFERENT)
7728 return;
7729
7730 Initialize();
7731
7732 GURL url("https://mail.example.com/");
7733 origin1_ = HostPortPair::FromURL(url);
7734
7735 // Not used for requests, but this provides a test case where the certificate
7736 // is valid for the hostname of the alternative service.
7737 origin2_ = HostPortPair("mail.example.org", 433);
7738
7739 HostPortPair destination = GetDestination();
7740
7741 scoped_refptr<X509Certificate> cert(
7742 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247743 ASSERT_FALSE(cert->VerifyNameMatch(origin1_.host()));
7744 ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host()));
bnc359ed2a2016-04-29 20:43:457745
7746 ProofVerifyDetailsChromium verify_details;
7747 verify_details.cert_verify_result.verified_cert = cert;
7748 verify_details.cert_verify_result.is_issued_by_known_root = true;
7749 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7750
7751 AddHangingSocketData();
7752
zhongyi98d6a9262017-05-19 02:47:457753 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337754 EXPECT_EQ(ERR_IO_PENDING,
7755 request.Request(destination, version_, privacy_mode_,
7756 DEFAULT_PRIORITY, SocketTag(),
7757 /*cert_verify_flags=*/0, url, net_log_,
7758 &net_error_details_, callback_.callback()));
bnc359ed2a2016-04-29 20:43:457759
robpercival214763f2016-07-01 23:27:017760 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_QUIC_HANDSHAKE_FAILED));
bnc359ed2a2016-04-29 20:43:457761
7762 EXPECT_TRUE(AllDataConsumed());
7763}
7764
7765// QuicStreamRequest is pooled based on |destination| if certificate matches.
7766TEST_P(QuicStreamFactoryWithDestinationTest, SharedCertificate) {
7767 Initialize();
7768
7769 GURL url1("https://www.example.org/");
7770 GURL url2("https://mail.example.org/");
7771 origin1_ = HostPortPair::FromURL(url1);
7772 origin2_ = HostPortPair::FromURL(url2);
7773
7774 HostPortPair destination = GetDestination();
7775
7776 scoped_refptr<X509Certificate> cert(
7777 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247778 ASSERT_TRUE(cert->VerifyNameMatch(origin1_.host()));
7779 ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host()));
7780 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457781
7782 ProofVerifyDetailsChromium verify_details;
7783 verify_details.cert_verify_result.verified_cert = cert;
7784 verify_details.cert_verify_result.is_issued_by_known_root = true;
7785 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7786
fayang3bcb8b502016-12-07 21:44:377787 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:527788 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:367789 client_maker_.MakeInitialSettingsPacket(1, nullptr));
bnceb9aa7112017-01-05 01:03:467790 MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(),
7791 settings_packet->length(), 1)};
fayang3bcb8b502016-12-07 21:44:377792 std::unique_ptr<SequencedSocketData> sequenced_socket_data(
Ryan Sleevib8d7ea02018-05-07 20:01:017793 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:177794 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
fayang3bcb8b502016-12-07 21:44:377795 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
bnc359ed2a2016-04-29 20:43:457796
zhongyi98d6a9262017-05-19 02:47:457797 QuicStreamRequest request1(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337798 EXPECT_EQ(ERR_IO_PENDING,
7799 request1.Request(destination, version_, privacy_mode_,
7800 DEFAULT_PRIORITY, SocketTag(),
7801 /*cert_verify_flags=*/0, url1, net_log_,
7802 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:017803 EXPECT_THAT(callback_.WaitForResult(), IsOk());
fayang3bcb8b502016-12-07 21:44:377804
Yixin Wang7891a39d2017-11-08 20:59:247805 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
bnc359ed2a2016-04-29 20:43:457806 EXPECT_TRUE(stream1.get());
7807 EXPECT_TRUE(HasActiveSession(origin1_));
7808
7809 // Second request returns synchronously because it pools to existing session.
7810 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:457811 QuicStreamRequest request2(factory_.get());
zhongyia00ca012017-07-06 23:36:397812 EXPECT_EQ(OK, request2.Request(destination, version_, privacy_mode_,
Paul Jensen8e3c5d32018-02-19 17:06:337813 DEFAULT_PRIORITY, SocketTag(),
7814 /*cert_verify_flags=*/0, url2, net_log_,
7815 &net_error_details_, callback2.callback()));
Yixin Wang7891a39d2017-11-08 20:59:247816 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
bnc359ed2a2016-04-29 20:43:457817 EXPECT_TRUE(stream2.get());
7818
rchf0b18c8a2017-05-05 19:31:577819 QuicChromiumClientSession::Handle* session1 =
7820 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
7821 QuicChromiumClientSession::Handle* session2 =
7822 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
7823 EXPECT_TRUE(session1->SharesSameSession(*session2));
bnc359ed2a2016-04-29 20:43:457824
Ryan Hamilton4f0b26e2018-06-27 23:52:327825 EXPECT_EQ(quic::QuicServerId(origin1_.host(), origin1_.port(),
7826 privacy_mode_ == PRIVACY_MODE_ENABLED),
7827 session1->server_id());
bnc359ed2a2016-04-29 20:43:457828
7829 EXPECT_TRUE(AllDataConsumed());
7830}
7831
bnc47eba7d2016-07-01 00:43:387832// QuicStreamRequest is not pooled if PrivacyMode differs.
7833TEST_P(QuicStreamFactoryWithDestinationTest, DifferentPrivacyMode) {
7834 Initialize();
7835
7836 GURL url1("https://www.example.org/");
7837 GURL url2("https://mail.example.org/");
7838 origin1_ = HostPortPair::FromURL(url1);
7839 origin2_ = HostPortPair::FromURL(url2);
7840
7841 HostPortPair destination = GetDestination();
7842
7843 scoped_refptr<X509Certificate> cert(
7844 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247845 ASSERT_TRUE(cert->VerifyNameMatch(origin1_.host()));
7846 ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host()));
7847 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc47eba7d2016-07-01 00:43:387848
7849 ProofVerifyDetailsChromium verify_details1;
7850 verify_details1.cert_verify_result.verified_cert = cert;
7851 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7852 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7853
7854 ProofVerifyDetailsChromium verify_details2;
7855 verify_details2.cert_verify_result.verified_cert = cert;
7856 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7857 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7858
fayang3bcb8b502016-12-07 21:44:377859 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:527860 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:367861 client_maker_.MakeInitialSettingsPacket(1, nullptr));
bnceb9aa7112017-01-05 01:03:467862 MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(),
7863 settings_packet->length(), 1)};
fayang3bcb8b502016-12-07 21:44:377864 std::unique_ptr<SequencedSocketData> sequenced_socket_data(
Ryan Sleevib8d7ea02018-05-07 20:01:017865 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:177866 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
fayang3bcb8b502016-12-07 21:44:377867 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
7868 std::unique_ptr<SequencedSocketData> sequenced_socket_data1(
Ryan Sleevib8d7ea02018-05-07 20:01:017869 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:177870 socket_factory_->AddSocketDataProvider(sequenced_socket_data1.get());
fayang3bcb8b502016-12-07 21:44:377871 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data1));
bnc47eba7d2016-07-01 00:43:387872
zhongyi98d6a9262017-05-19 02:47:457873 QuicStreamRequest request1(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337874 EXPECT_EQ(ERR_IO_PENDING,
7875 request1.Request(destination, version_, PRIVACY_MODE_DISABLED,
7876 DEFAULT_PRIORITY, SocketTag(),
7877 /*cert_verify_flags=*/0, url1, net_log_,
7878 &net_error_details_, callback_.callback()));
bnc47eba7d2016-07-01 00:43:387879 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:247880 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
bnc47eba7d2016-07-01 00:43:387881 EXPECT_TRUE(stream1.get());
7882 EXPECT_TRUE(HasActiveSession(origin1_));
7883
7884 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:457885 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337886 EXPECT_EQ(ERR_IO_PENDING,
7887 request2.Request(destination, version_, PRIVACY_MODE_ENABLED,
7888 DEFAULT_PRIORITY, SocketTag(),
7889 /*cert_verify_flags=*/0, url2, net_log_,
7890 &net_error_details_, callback2.callback()));
bnc47eba7d2016-07-01 00:43:387891 EXPECT_EQ(OK, callback2.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:247892 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
bnc47eba7d2016-07-01 00:43:387893 EXPECT_TRUE(stream2.get());
7894
7895 // |request2| does not pool to the first session, because PrivacyMode does not
7896 // match. Instead, another session is opened to the same destination, but
Ryan Hamilton8d9ee76e2018-05-29 23:52:527897 // with a different quic::QuicServerId.
rchf0b18c8a2017-05-05 19:31:577898 QuicChromiumClientSession::Handle* session1 =
7899 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
7900 QuicChromiumClientSession::Handle* session2 =
7901 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
7902 EXPECT_FALSE(session1->SharesSameSession(*session2));
bnc47eba7d2016-07-01 00:43:387903
Ryan Hamilton4f0b26e2018-06-27 23:52:327904 EXPECT_EQ(quic::QuicServerId(origin1_.host(), origin1_.port(), false),
bnc47eba7d2016-07-01 00:43:387905 session1->server_id());
Ryan Hamilton4f0b26e2018-06-27 23:52:327906 EXPECT_EQ(quic::QuicServerId(origin2_.host(), origin2_.port(), true),
bnc47eba7d2016-07-01 00:43:387907 session2->server_id());
7908
7909 EXPECT_TRUE(AllDataConsumed());
7910}
7911
bnc359ed2a2016-04-29 20:43:457912// QuicStreamRequest is not pooled if certificate does not match its origin.
7913TEST_P(QuicStreamFactoryWithDestinationTest, DisjointCertificate) {
7914 Initialize();
7915
7916 GURL url1("https://news.example.org/");
7917 GURL url2("https://mail.example.com/");
7918 origin1_ = HostPortPair::FromURL(url1);
7919 origin2_ = HostPortPair::FromURL(url2);
7920
7921 HostPortPair destination = GetDestination();
7922
7923 scoped_refptr<X509Certificate> cert1(
7924 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247925 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_.host()));
7926 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_.host()));
7927 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457928
7929 ProofVerifyDetailsChromium verify_details1;
7930 verify_details1.cert_verify_result.verified_cert = cert1;
7931 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7932 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7933
7934 scoped_refptr<X509Certificate> cert2(
7935 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247936 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_.host()));
7937 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457938
7939 ProofVerifyDetailsChromium verify_details2;
7940 verify_details2.cert_verify_result.verified_cert = cert2;
7941 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7942 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7943
fayang3bcb8b502016-12-07 21:44:377944 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:527945 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:367946 client_maker_.MakeInitialSettingsPacket(1, nullptr));
bnceb9aa7112017-01-05 01:03:467947 MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(),
7948 settings_packet->length(), 1)};
fayang3bcb8b502016-12-07 21:44:377949 std::unique_ptr<SequencedSocketData> sequenced_socket_data(
Ryan Sleevib8d7ea02018-05-07 20:01:017950 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:177951 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
fayang3bcb8b502016-12-07 21:44:377952 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
7953 std::unique_ptr<SequencedSocketData> sequenced_socket_data1(
Ryan Sleevib8d7ea02018-05-07 20:01:017954 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:177955 socket_factory_->AddSocketDataProvider(sequenced_socket_data1.get());
fayang3bcb8b502016-12-07 21:44:377956 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data1));
bnc359ed2a2016-04-29 20:43:457957
zhongyi98d6a9262017-05-19 02:47:457958 QuicStreamRequest request1(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337959 EXPECT_EQ(ERR_IO_PENDING,
7960 request1.Request(destination, version_, privacy_mode_,
7961 DEFAULT_PRIORITY, SocketTag(),
7962 /*cert_verify_flags=*/0, url1, net_log_,
7963 &net_error_details_, callback_.callback()));
robpercival214763f2016-07-01 23:27:017964 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:247965 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
bnc359ed2a2016-04-29 20:43:457966 EXPECT_TRUE(stream1.get());
7967 EXPECT_TRUE(HasActiveSession(origin1_));
7968
7969 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:457970 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:337971 EXPECT_EQ(ERR_IO_PENDING,
7972 request2.Request(destination, version_, privacy_mode_,
7973 DEFAULT_PRIORITY, SocketTag(),
7974 /*cert_verify_flags=*/0, url2, net_log_,
7975 &net_error_details_, callback2.callback()));
robpercival214763f2016-07-01 23:27:017976 EXPECT_THAT(callback2.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:247977 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
bnc359ed2a2016-04-29 20:43:457978 EXPECT_TRUE(stream2.get());
7979
7980 // |request2| does not pool to the first session, because the certificate does
7981 // not match. Instead, another session is opened to the same destination, but
Ryan Hamilton8d9ee76e2018-05-29 23:52:527982 // with a different quic::QuicServerId.
rchf0b18c8a2017-05-05 19:31:577983 QuicChromiumClientSession::Handle* session1 =
7984 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
7985 QuicChromiumClientSession::Handle* session2 =
7986 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
7987 EXPECT_FALSE(session1->SharesSameSession(*session2));
bnc359ed2a2016-04-29 20:43:457988
Ryan Hamilton4f0b26e2018-06-27 23:52:327989 EXPECT_EQ(quic::QuicServerId(origin1_.host(), origin1_.port(),
7990 privacy_mode_ == PRIVACY_MODE_ENABLED),
7991 session1->server_id());
7992 EXPECT_EQ(quic::QuicServerId(origin2_.host(), origin2_.port(),
7993 privacy_mode_ == PRIVACY_MODE_ENABLED),
7994 session2->server_id());
bnc359ed2a2016-04-29 20:43:457995
7996 EXPECT_TRUE(AllDataConsumed());
7997}
7998
msramek992625ec2016-08-04 18:33:587999// This test verifies that QuicStreamFactory::ClearCachedStatesInCryptoConfig
8000// correctly transform an origin filter to a ServerIdFilter. Whether the
8001// deletion itself works correctly is tested in QuicCryptoClientConfigTest.
8002TEST_P(QuicStreamFactoryTest, ClearCachedStatesInCryptoConfig) {
8003 Initialize();
Ryan Hamilton8d9ee76e2018-05-29 23:52:528004 quic::QuicCryptoClientConfig* crypto_config =
msramek992625ec2016-08-04 18:33:588005 QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
8006
8007 struct TestCase {
8008 TestCase(const std::string& host,
8009 int port,
8010 PrivacyMode privacy_mode,
Ryan Hamilton8d9ee76e2018-05-29 23:52:528011 quic::QuicCryptoClientConfig* crypto_config)
msramek992625ec2016-08-04 18:33:588012 : server_id(host, port, privacy_mode),
8013 state(crypto_config->LookupOrCreate(server_id)) {
rch872e00e2016-12-02 02:48:188014 std::vector<string> certs(1);
msramek992625ec2016-08-04 18:33:588015 certs[0] = "cert";
8016 state->SetProof(certs, "cert_sct", "chlo_hash", "signature");
8017 state->set_source_address_token("TOKEN");
8018 state->SetProofValid();
8019
8020 EXPECT_FALSE(state->certs().empty());
8021 }
8022
Ryan Hamilton8d9ee76e2018-05-29 23:52:528023 quic::QuicServerId server_id;
8024 quic::QuicCryptoClientConfig::CachedState* state;
msramek992625ec2016-08-04 18:33:588025 } test_cases[] = {
8026 TestCase("www.google.com", 443, privacy_mode_, crypto_config),
8027 TestCase("www.example.com", 443, privacy_mode_, crypto_config),
8028 TestCase("www.example.com", 4433, privacy_mode_, crypto_config)};
8029
8030 // Clear cached states for the origin https://www.example.com:4433.
8031 GURL origin("https://www.example.com:4433");
csharrisonebeca8e2016-10-18 02:35:368032 factory_->ClearCachedStatesInCryptoConfig(base::Bind(
8033 static_cast<bool (*)(const GURL&, const GURL&)>(::operator==), origin));
msramek992625ec2016-08-04 18:33:588034 EXPECT_FALSE(test_cases[0].state->certs().empty());
8035 EXPECT_FALSE(test_cases[1].state->certs().empty());
8036 EXPECT_TRUE(test_cases[2].state->certs().empty());
8037
8038 // Clear all cached states.
8039 factory_->ClearCachedStatesInCryptoConfig(
8040 base::Callback<bool(const GURL&)>());
8041 EXPECT_TRUE(test_cases[0].state->certs().empty());
8042 EXPECT_TRUE(test_cases[1].state->certs().empty());
8043 EXPECT_TRUE(test_cases[2].state->certs().empty());
8044}
8045
Yixin Wang46a425f2017-08-10 23:02:208046// Passes connection options and client connection options to QuicStreamFactory,
Ryan Hamilton8d9ee76e2018-05-29 23:52:528047// then checks that its internal quic::QuicConfig is correct.
Yixin Wang46a425f2017-08-10 23:02:208048TEST_P(QuicStreamFactoryTest, ConfigConnectionOptions) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:528049 connection_options_.push_back(quic::kTIME);
8050 connection_options_.push_back(quic::kTBBR);
8051 connection_options_.push_back(quic::kREJ);
Yixin Wang46a425f2017-08-10 23:02:208052
Ryan Hamilton8d9ee76e2018-05-29 23:52:528053 client_connection_options_.push_back(quic::kTBBR);
8054 client_connection_options_.push_back(quic::k1RTT);
Yixin Wang46a425f2017-08-10 23:02:208055
8056 Initialize();
8057
Ryan Hamilton8d9ee76e2018-05-29 23:52:528058 const quic::QuicConfig* config =
8059 QuicStreamFactoryPeer::GetConfig(factory_.get());
Yixin Wang46a425f2017-08-10 23:02:208060 EXPECT_EQ(connection_options_, config->SendConnectionOptions());
8061 EXPECT_TRUE(config->HasClientRequestedIndependentOption(
Ryan Hamilton8d9ee76e2018-05-29 23:52:528062 quic::kTBBR, quic::Perspective::IS_CLIENT));
Yixin Wang46a425f2017-08-10 23:02:208063 EXPECT_TRUE(config->HasClientRequestedIndependentOption(
Ryan Hamilton8d9ee76e2018-05-29 23:52:528064 quic::k1RTT, quic::Perspective::IS_CLIENT));
Yixin Wang46a425f2017-08-10 23:02:208065}
8066
Yixin Wang247ea642017-11-15 01:15:508067// Verifies that the host resolver uses the request priority passed to
8068// QuicStreamRequest::Request().
8069TEST_P(QuicStreamFactoryTest, HostResolverUsesRequestPriority) {
8070 Initialize();
8071 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8072 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8073
8074 MockQuicData socket_data;
8075 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:438076 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:178077 socket_data.AddSocketDataToFactory(socket_factory_.get());
Yixin Wang247ea642017-11-15 01:15:508078
8079 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338080 EXPECT_EQ(ERR_IO_PENDING,
8081 request.Request(host_port_pair_, version_, privacy_mode_,
8082 MAXIMUM_PRIORITY, SocketTag(),
8083 /*cert_verify_flags=*/0, url_, net_log_,
8084 &net_error_details_, callback_.callback()));
Yixin Wang247ea642017-11-15 01:15:508085
8086 EXPECT_THAT(callback_.WaitForResult(), IsOk());
8087 std::unique_ptr<HttpStream> stream = CreateStream(&request);
8088 EXPECT_TRUE(stream.get());
8089
8090 EXPECT_EQ(MAXIMUM_PRIORITY, host_resolver_.last_request_priority());
8091
8092 EXPECT_TRUE(socket_data.AllReadDataConsumed());
8093 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
8094}
8095
Yixin Wang469da562017-11-15 21:34:588096// Passes |max_time_before_crypto_handshake_seconds| and
8097// |max_idle_time_before_crypto_handshake_seconds| to QuicStreamFactory, then
Ryan Hamilton8d9ee76e2018-05-29 23:52:528098// checks that its internal quic::QuicConfig is correct.
Yixin Wang469da562017-11-15 21:34:588099TEST_P(QuicStreamFactoryTest, ConfigMaxTimeBeforeCryptoHandshake) {
8100 max_time_before_crypto_handshake_seconds_ = 11;
8101 max_idle_time_before_crypto_handshake_seconds_ = 13;
8102
8103 Initialize();
8104
Ryan Hamilton8d9ee76e2018-05-29 23:52:528105 const quic::QuicConfig* config =
8106 QuicStreamFactoryPeer::GetConfig(factory_.get());
8107 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(11),
Yixin Wang469da562017-11-15 21:34:588108 config->max_time_before_crypto_handshake());
Ryan Hamilton8d9ee76e2018-05-29 23:52:528109 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(13),
Yixin Wang469da562017-11-15 21:34:588110 config->max_idle_time_before_crypto_handshake());
8111}
8112
Yixin Wang7c5d11a82017-12-21 02:40:008113// Verify ResultAfterHostResolutionCallback behavior when host resolution
8114// succeeds asynchronously, then crypto handshake fails synchronously.
8115TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackAsyncSync) {
8116 Initialize();
8117 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8118 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8119
8120 host_resolver_.set_ondemand_mode(true);
8121
8122 MockQuicData socket_data;
8123 socket_data.AddRead(SYNCHRONOUS, ERR_FAILED);
8124 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
8125 socket_data.AddSocketDataToFactory(socket_factory_.get());
8126
8127 QuicStreamRequest request(factory_.get());
8128 EXPECT_EQ(ERR_IO_PENDING,
8129 request.Request(host_port_pair_, version_, privacy_mode_,
Paul Jensen8e3c5d32018-02-19 17:06:338130 DEFAULT_PRIORITY, SocketTag(),
Yixin Wang7c5d11a82017-12-21 02:40:008131 /*cert_verify_flags=*/0, url_, net_log_,
8132 &net_error_details_, callback_.callback()));
8133
8134 TestCompletionCallback host_resolution_callback;
8135 EXPECT_TRUE(
8136 request.WaitForHostResolution(host_resolution_callback.callback()));
8137
8138 // |host_resolver_| has not finished host resolution at this point, so
8139 // |host_resolution_callback| should not have a result.
8140 base::RunLoop().RunUntilIdle();
8141 EXPECT_FALSE(host_resolution_callback.have_result());
8142
8143 // Allow |host_resolver_| to finish host resolution.
8144 // Since the request fails immediately after host resolution (getting
8145 // ERR_FAILED from socket reads/writes), |host_resolution_callback| should be
8146 // called with ERR_QUIC_PROTOCOL_ERROR since that's the next result in
8147 // forming the connection.
8148 host_resolver_.ResolveAllPending();
8149 base::RunLoop().RunUntilIdle();
8150 EXPECT_TRUE(host_resolution_callback.have_result());
8151 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, host_resolution_callback.WaitForResult());
8152
8153 // Calling WaitForHostResolution() a second time should return
8154 // false since host resolution has finished already.
8155 EXPECT_FALSE(
8156 request.WaitForHostResolution(host_resolution_callback.callback()));
8157
8158 EXPECT_TRUE(callback_.have_result());
8159 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
8160}
8161
8162// Verify ResultAfterHostResolutionCallback behavior when host resolution
8163// succeeds asynchronously, then crypto handshake fails asynchronously.
8164TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackAsyncAsync) {
8165 Initialize();
8166 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8167 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8168
8169 host_resolver_.set_ondemand_mode(true);
8170 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:278171 MockCryptoClientStream::ZERO_RTT);
Yixin Wang7c5d11a82017-12-21 02:40:008172 factory_->set_require_confirmation(true);
8173
8174 MockQuicData socket_data;
8175 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
8176 socket_data.AddRead(ASYNC, ERR_FAILED);
8177 socket_data.AddWrite(ASYNC, ERR_FAILED);
8178 socket_data.AddSocketDataToFactory(socket_factory_.get());
8179
8180 QuicStreamRequest request(factory_.get());
8181 EXPECT_EQ(ERR_IO_PENDING,
8182 request.Request(host_port_pair_, version_, privacy_mode_,
Paul Jensen8e3c5d32018-02-19 17:06:338183 DEFAULT_PRIORITY, SocketTag(),
Yixin Wang7c5d11a82017-12-21 02:40:008184 /*cert_verify_flags=*/0, url_, net_log_,
8185 &net_error_details_, callback_.callback()));
8186
8187 TestCompletionCallback host_resolution_callback;
8188 EXPECT_TRUE(
8189 request.WaitForHostResolution(host_resolution_callback.callback()));
8190
8191 // |host_resolver_| has not finished host resolution at this point, so
8192 // |host_resolution_callback| should not have a result.
8193 base::RunLoop().RunUntilIdle();
8194 EXPECT_FALSE(host_resolution_callback.have_result());
8195
8196 // Allow |host_resolver_| to finish host resolution. Since crypto handshake
8197 // will hang after host resolution, |host_resolution_callback| should run with
8198 // ERR_IO_PENDING since that's the next result in forming the connection.
8199 host_resolver_.ResolveAllPending();
8200 base::RunLoop().RunUntilIdle();
8201 EXPECT_TRUE(host_resolution_callback.have_result());
8202 EXPECT_EQ(ERR_IO_PENDING, host_resolution_callback.WaitForResult());
8203
8204 // Calling WaitForHostResolution() a second time should return
8205 // false since host resolution has finished already.
8206 EXPECT_FALSE(
8207 request.WaitForHostResolution(host_resolution_callback.callback()));
8208
8209 EXPECT_FALSE(callback_.have_result());
8210 socket_data.GetSequencedSocketData()->Resume();
8211 base::RunLoop().RunUntilIdle();
8212 EXPECT_TRUE(callback_.have_result());
8213 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
8214}
8215
8216// Verify ResultAfterHostResolutionCallback behavior when host resolution
8217// succeeds synchronously, then crypto handshake fails synchronously.
8218TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackSyncSync) {
8219 Initialize();
8220 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8221 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8222
8223 host_resolver_.set_synchronous_mode(true);
8224
8225 MockQuicData socket_data;
8226 socket_data.AddRead(SYNCHRONOUS, ERR_FAILED);
8227 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
8228 socket_data.AddSocketDataToFactory(socket_factory_.get());
8229
8230 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338231 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR,
8232 request.Request(host_port_pair_, version_, privacy_mode_,
8233 DEFAULT_PRIORITY, SocketTag(),
8234 /*cert_verify_flags=*/0, url_, net_log_,
8235 &net_error_details_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:008236
8237 // WaitForHostResolution() should return false since host
8238 // resolution has finished already.
8239 TestCompletionCallback host_resolution_callback;
8240 EXPECT_FALSE(
8241 request.WaitForHostResolution(host_resolution_callback.callback()));
8242 base::RunLoop().RunUntilIdle();
8243 EXPECT_FALSE(host_resolution_callback.have_result());
8244 EXPECT_FALSE(callback_.have_result());
8245}
8246
8247// Verify ResultAfterHostResolutionCallback behavior when host resolution
8248// succeeds synchronously, then crypto handshake fails asynchronously.
8249TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackSyncAsync) {
8250 Initialize();
8251 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8252 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8253
8254 // Host resolution will succeed synchronously, but Request() as a whole
8255 // will fail asynchronously.
8256 host_resolver_.set_synchronous_mode(true);
8257 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:278258 MockCryptoClientStream::ZERO_RTT);
Yixin Wang7c5d11a82017-12-21 02:40:008259 factory_->set_require_confirmation(true);
8260
8261 MockQuicData socket_data;
8262 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
8263 socket_data.AddRead(ASYNC, ERR_FAILED);
8264 socket_data.AddWrite(ASYNC, ERR_FAILED);
8265 socket_data.AddSocketDataToFactory(socket_factory_.get());
8266
8267 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338268 EXPECT_EQ(ERR_IO_PENDING,
8269 request.Request(host_port_pair_, version_, privacy_mode_,
8270 DEFAULT_PRIORITY, SocketTag(),
8271 /*cert_verify_flags=*/0, url_, net_log_,
8272 &net_error_details_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:008273
8274 // WaitForHostResolution() should return false since host
8275 // resolution has finished already.
8276 TestCompletionCallback host_resolution_callback;
8277 EXPECT_FALSE(
8278 request.WaitForHostResolution(host_resolution_callback.callback()));
8279 base::RunLoop().RunUntilIdle();
8280 EXPECT_FALSE(host_resolution_callback.have_result());
8281
8282 EXPECT_FALSE(callback_.have_result());
8283 socket_data.GetSequencedSocketData()->Resume();
8284 base::RunLoop().RunUntilIdle();
8285 EXPECT_TRUE(callback_.have_result());
8286 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
8287}
8288
8289// Verify ResultAfterHostResolutionCallback behavior when host resolution fails
8290// synchronously.
8291TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackFailSync) {
8292 Initialize();
8293 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8294 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8295
8296 // Host resolution will fail synchronously.
8297 host_resolver_.rules()->AddSimulatedFailure(host_port_pair_.host());
8298 host_resolver_.set_synchronous_mode(true);
8299
8300 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338301 EXPECT_EQ(ERR_NAME_NOT_RESOLVED,
8302 request.Request(host_port_pair_, version_, privacy_mode_,
8303 DEFAULT_PRIORITY, SocketTag(),
8304 /*cert_verify_flags=*/0, url_, net_log_,
8305 &net_error_details_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:008306
8307 // WaitForHostResolution() should return false since host
8308 // resolution has failed already.
8309 TestCompletionCallback host_resolution_callback;
8310 EXPECT_FALSE(
8311 request.WaitForHostResolution(host_resolution_callback.callback()));
8312 base::RunLoop().RunUntilIdle();
8313 EXPECT_FALSE(host_resolution_callback.have_result());
8314}
8315
8316// Verify ResultAfterHostResolutionCallback behavior when host resolution fails
8317// asynchronously.
8318TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackFailAsync) {
8319 Initialize();
8320 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8321 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8322
8323 host_resolver_.rules()->AddSimulatedFailure(host_port_pair_.host());
8324
8325 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338326 EXPECT_EQ(ERR_IO_PENDING,
8327 request.Request(host_port_pair_, version_, privacy_mode_,
8328 DEFAULT_PRIORITY, SocketTag(),
8329 /*cert_verify_flags=*/0, url_, net_log_,
8330 &net_error_details_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:008331
8332 TestCompletionCallback host_resolution_callback;
8333 EXPECT_TRUE(
8334 request.WaitForHostResolution(host_resolution_callback.callback()));
8335
8336 // Allow |host_resolver_| to fail host resolution. |host_resolution_callback|
8337 // Should run with ERR_NAME_NOT_RESOLVED since that's the error host
8338 // resolution failed with.
8339 base::RunLoop().RunUntilIdle();
8340 EXPECT_TRUE(host_resolution_callback.have_result());
8341 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, host_resolution_callback.WaitForResult());
8342
8343 EXPECT_TRUE(callback_.have_result());
8344 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, callback_.WaitForResult());
8345}
8346
Paul Jensen8e3c5d32018-02-19 17:06:338347// Test that QuicStreamRequests with similar and different tags results in
8348// reused and unique QUIC streams using appropriately tagged sockets.
8349TEST_P(QuicStreamFactoryTest, Tag) {
8350 MockTaggingClientSocketFactory* socket_factory =
8351 new MockTaggingClientSocketFactory();
8352 socket_factory_.reset(socket_factory);
8353 Initialize();
8354 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8355 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8356
8357 // Prepare to establish two QUIC sessions.
8358 MockQuicData socket_data;
8359 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:438360 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Paul Jensen8e3c5d32018-02-19 17:06:338361 socket_data.AddSocketDataToFactory(socket_factory_.get());
8362 MockQuicData socket_data2;
8363 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:438364 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Paul Jensen8e3c5d32018-02-19 17:06:338365 socket_data2.AddSocketDataToFactory(socket_factory_.get());
8366
8367#if defined(OS_ANDROID)
8368 SocketTag tag1(SocketTag::UNSET_UID, 0x12345678);
8369 SocketTag tag2(getuid(), 0x87654321);
8370#else
8371 // On non-Android platforms we can only use the default constructor.
8372 SocketTag tag1, tag2;
8373#endif
8374
8375 // Request a stream with |tag1|.
8376 QuicStreamRequest request1(factory_.get());
8377 int rv =
8378 request1.Request(host_port_pair_, version_, privacy_mode_,
8379 DEFAULT_PRIORITY, tag1, /*cert_verify_flags=*/0, url_,
8380 net_log_, &net_error_details_, callback_.callback());
8381 EXPECT_THAT(callback_.GetResult(rv), IsOk());
8382 EXPECT_EQ(socket_factory->GetLastProducedUDPSocket()->tag(), tag1);
8383 EXPECT_TRUE(socket_factory->GetLastProducedUDPSocket()
8384 ->tagged_before_data_transferred());
8385 std::unique_ptr<QuicChromiumClientSession::Handle> stream1 =
8386 request1.ReleaseSessionHandle();
8387 EXPECT_TRUE(stream1);
8388 EXPECT_TRUE(stream1->IsConnected());
8389
8390 // Request a stream with |tag1| and verify underlying session is reused.
8391 QuicStreamRequest request2(factory_.get());
8392 rv = request2.Request(host_port_pair_, version_, privacy_mode_,
8393 DEFAULT_PRIORITY, tag1,
8394 /*cert_verify_flags=*/0, url_, net_log_,
8395 &net_error_details_, callback_.callback());
8396 EXPECT_THAT(callback_.GetResult(rv), IsOk());
8397 std::unique_ptr<QuicChromiumClientSession::Handle> stream2 =
8398 request2.ReleaseSessionHandle();
8399 EXPECT_TRUE(stream2);
8400 EXPECT_TRUE(stream2->IsConnected());
8401 EXPECT_TRUE(stream2->SharesSameSession(*stream1));
8402
8403 // Request a stream with |tag2| and verify a new session is created.
8404 QuicStreamRequest request3(factory_.get());
8405 rv = request3.Request(host_port_pair_, version_, privacy_mode_,
8406 DEFAULT_PRIORITY, tag2,
8407 /*cert_verify_flags=*/0, url_, net_log_,
8408 &net_error_details_, callback_.callback());
8409 EXPECT_THAT(callback_.GetResult(rv), IsOk());
8410 EXPECT_EQ(socket_factory->GetLastProducedUDPSocket()->tag(), tag2);
8411 EXPECT_TRUE(socket_factory->GetLastProducedUDPSocket()
8412 ->tagged_before_data_transferred());
8413 std::unique_ptr<QuicChromiumClientSession::Handle> stream3 =
8414 request3.ReleaseSessionHandle();
8415 EXPECT_TRUE(stream3);
8416 EXPECT_TRUE(stream3->IsConnected());
8417#if defined(OS_ANDROID)
8418 EXPECT_FALSE(stream3->SharesSameSession(*stream1));
8419#else
8420 // Same tag should reuse session.
8421 EXPECT_TRUE(stream3->SharesSameSession(*stream1));
8422#endif
8423}
8424
[email protected]e13201d82012-12-12 05:00:328425} // namespace test
[email protected]e13201d82012-12-12 05:00:328426} // namespace net