1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/quic/quic_session_pool.h"
6
7 #include <sys/types.h>
8
9 #include <memory>
10 #include <ostream>
11 #include <set>
12 #include <string>
13 #include <utility>
14
15 #include "base/functional/bind.h"
16 #include "base/functional/callback.h"
17 #include "base/logging.h"
18 #include "base/memory/raw_ptr.h"
19 #include "base/run_loop.h"
20 #include "base/strings/strcat.h"
21 #include "base/strings/string_number_conversions.h"
22 #include "base/strings/string_util.h"
23 #include "base/strings/stringprintf.h"
24 #include "base/test/bind.h"
25 #include "base/test/scoped_feature_list.h"
26 #include "base/test/simple_test_tick_clock.h"
27 #include "base/test/test_mock_time_task_runner.h"
28 #include "base/time/time.h"
29 #include "build/build_config.h"
30 #include "net/base/features.h"
31 #include "net/base/host_port_pair.h"
32 #include "net/base/http_user_agent_settings.h"
33 #include "net/base/load_flags.h"
34 #include "net/base/mock_network_change_notifier.h"
35 #include "net/base/net_error_details.h"
36 #include "net/base/net_errors.h"
37 #include "net/base/network_anonymization_key.h"
38 #include "net/base/proxy_chain.h"
39 #include "net/base/proxy_server.h"
40 #include "net/base/schemeful_site.h"
41 #include "net/base/session_usage.h"
42 #include "net/base/test_proxy_delegate.h"
43 #include "net/cert/mock_cert_verifier.h"
44 #include "net/dns/mock_host_resolver.h"
45 #include "net/dns/public/dns_query_type.h"
46 #include "net/dns/public/host_resolver_source.h"
47 #include "net/dns/public/secure_dns_policy.h"
48 #include "net/http/http_response_headers.h"
49 #include "net/http/http_response_info.h"
50 #include "net/http/http_server_properties.h"
51 #include "net/http/http_util.h"
52 #include "net/http/transport_security_state.h"
53 #include "net/http/transport_security_state_test_util.h"
54 #include "net/quic/address_utils.h"
55 #include "net/quic/crypto/proof_verifier_chromium.h"
56 #include "net/quic/mock_crypto_client_stream_factory.h"
57 #include "net/quic/mock_quic_context.h"
58 #include "net/quic/mock_quic_data.h"
59 #include "net/quic/properties_based_quic_server_info.h"
60 #include "net/quic/quic_chromium_alarm_factory.h"
61 #include "net/quic/quic_chromium_client_session.h"
62 #include "net/quic/quic_chromium_client_session_peer.h"
63 #include "net/quic/quic_context.h"
64 #include "net/quic/quic_http_stream.h"
65 #include "net/quic/quic_http_utils.h"
66 #include "net/quic/quic_server_info.h"
67 #include "net/quic/quic_session_key.h"
68 #include "net/quic/quic_session_pool_peer.h"
69 #include "net/quic/quic_session_pool_test_base.h"
70 #include "net/quic/quic_test_packet_maker.h"
71 #include "net/quic/quic_test_packet_printer.h"
72 #include "net/quic/test_task_runner.h"
73 #include "net/socket/next_proto.h"
74 #include "net/socket/socket_tag.h"
75 #include "net/socket/socket_test_util.h"
76 #include "net/spdy/spdy_session_test_util.h"
77 #include "net/spdy/spdy_test_util_common.h"
78 #include "net/ssl/test_ssl_config_service.h"
79 #include "net/test/cert_test_util.h"
80 #include "net/test/gtest_util.h"
81 #include "net/test/test_data_directory.h"
82 #include "net/test/test_with_task_environment.h"
83 #include "net/third_party/quiche/src/quiche/common/quiche_data_writer.h"
84 #include "net/third_party/quiche/src/quiche/quic/core/crypto/crypto_handshake.h"
85 #include "net/third_party/quiche/src/quiche/quic/core/crypto/quic_crypto_client_config.h"
86 #include "net/third_party/quiche/src/quiche/quic/core/crypto/quic_decrypter.h"
87 #include "net/third_party/quiche/src/quiche/quic/core/crypto/quic_encrypter.h"
88 #include "net/third_party/quiche/src/quiche/quic/core/quic_constants.h"
89 #include "net/third_party/quiche/src/quiche/quic/core/quic_utils.h"
90 #include "net/third_party/quiche/src/quiche/quic/platform/api/quic_test.h"
91 #include "net/third_party/quiche/src/quiche/quic/test_tools/mock_clock.h"
92 #include "net/third_party/quiche/src/quiche/quic/test_tools/mock_random.h"
93 #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_config_peer.h"
94 #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_connection_peer.h"
95 #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_path_validator_peer.h"
96 #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_session_peer.h"
97 #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_spdy_session_peer.h"
98 #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_test_utils.h"
99 #include "net/third_party/quiche/src/quiche/spdy/test_tools/spdy_test_utils.h"
100 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
101 #include "net/url_request/static_http_user_agent_settings.h"
102 #include "testing/gmock/include/gmock/gmock.h"
103 #include "testing/gtest/include/gtest/gtest.h"
104 #include "url/gurl.h"
105 #include "url/scheme_host_port.h"
106 #include "url/url_constants.h"
107
108 using std::string;
109
110 namespace net::test {
111
112 class QuicHttpStreamPeer {
113 public:
GetSessionHandle(HttpStream * stream)114 static QuicChromiumClientSession::Handle* GetSessionHandle(
115 HttpStream* stream) {
116 return static_cast<QuicHttpStream*>(stream)->quic_session();
117 }
118 };
119
120 namespace {
121
122 // Run QuicSessionPoolTest instances with all value combinations of version
123 // and the `PriorityHeader` feature.
124 struct TestParams {
125 quic::ParsedQuicVersion version;
126 bool priority_header_enabled;
127 };
128
129 // Used by ::testing::PrintToStringParamName().
PrintToString(const TestParams & p)130 std::string PrintToString(const TestParams& p) {
131 return base::StrCat({ParsedQuicVersionToString(p.version), "_",
132 p.priority_header_enabled ? "PriorityHeaderEnabled"
133 : "PriorityHeaderDisabled"});
134 }
135
GetTestParams()136 std::vector<TestParams> GetTestParams() {
137 std::vector<TestParams> params;
138 quic::ParsedQuicVersionVector all_supported_versions =
139 AllSupportedQuicVersions();
140 for (const auto& version : all_supported_versions) {
141 params.push_back(TestParams{version, true});
142 params.push_back(TestParams{version, false});
143 }
144 return params;
145 }
146
147 } // namespace
148
149 // TestConnectionMigrationSocketFactory will vend sockets with incremental fake
150 // IPV4 address.
151 class TestConnectionMigrationSocketFactory : public MockClientSocketFactory {
152 public:
153 TestConnectionMigrationSocketFactory() = default;
154
155 TestConnectionMigrationSocketFactory(
156 const TestConnectionMigrationSocketFactory&) = delete;
157 TestConnectionMigrationSocketFactory& operator=(
158 const TestConnectionMigrationSocketFactory&) = delete;
159
160 ~TestConnectionMigrationSocketFactory() override = default;
161
CreateDatagramClientSocket(DatagramSocket::BindType bind_type,NetLog * net_log,const NetLogSource & source)162 std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
163 DatagramSocket::BindType bind_type,
164 NetLog* net_log,
165 const NetLogSource& source) override {
166 SocketDataProvider* data_provider = mock_data().GetNext();
167 auto socket = std::make_unique<MockUDPClientSocket>(data_provider, net_log);
168 socket->set_source_host(IPAddress(192, 0, 2, next_source_host_num_++));
169 return std::move(socket);
170 }
171
172 private:
173 uint8_t next_source_host_num_ = 1u;
174 };
175
176 // TestPortMigrationSocketFactory will vend sockets with incremental port
177 // number.
178 class TestPortMigrationSocketFactory : public MockClientSocketFactory {
179 public:
180 TestPortMigrationSocketFactory() = default;
181
182 TestPortMigrationSocketFactory(const TestPortMigrationSocketFactory&) =
183 delete;
184 TestPortMigrationSocketFactory& operator=(
185 const TestPortMigrationSocketFactory&) = delete;
186
187 ~TestPortMigrationSocketFactory() override = default;
188
CreateDatagramClientSocket(DatagramSocket::BindType bind_type,NetLog * net_log,const NetLogSource & source)189 std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
190 DatagramSocket::BindType bind_type,
191 NetLog* net_log,
192 const NetLogSource& source) override {
193 SocketDataProvider* data_provider = mock_data().GetNext();
194 auto socket = std::make_unique<MockUDPClientSocket>(data_provider, net_log);
195 socket->set_source_port(next_source_port_num_++);
196 return std::move(socket);
197 }
198
199 private:
200 uint16_t next_source_port_num_ = 1u;
201 };
202
203 class MockQuicSessionPool : public QuicSessionPool {
204 public:
MockQuicSessionPool(NetLog * net_log,HostResolver * host_resolver,SSLConfigService * ssl_config_service,ClientSocketFactory * client_socket_factory,HttpServerProperties * http_server_properties,CertVerifier * cert_verifier,TransportSecurityState * transport_security_state,ProxyDelegate * proxy_delegate,SCTAuditingDelegate * sct_auditing_delegate,SocketPerformanceWatcherFactory * socket_performance_watcher_factory,QuicCryptoClientStreamFactory * quic_crypto_client_stream_factory,QuicContext * context)205 MockQuicSessionPool(
206 NetLog* net_log,
207 HostResolver* host_resolver,
208 SSLConfigService* ssl_config_service,
209 ClientSocketFactory* client_socket_factory,
210 HttpServerProperties* http_server_properties,
211 CertVerifier* cert_verifier,
212 TransportSecurityState* transport_security_state,
213 ProxyDelegate* proxy_delegate,
214 SCTAuditingDelegate* sct_auditing_delegate,
215 SocketPerformanceWatcherFactory* socket_performance_watcher_factory,
216 QuicCryptoClientStreamFactory* quic_crypto_client_stream_factory,
217 QuicContext* context)
218 : QuicSessionPool(net_log,
219 host_resolver,
220 ssl_config_service,
221 client_socket_factory,
222 http_server_properties,
223 cert_verifier,
224 transport_security_state,
225 proxy_delegate,
226 sct_auditing_delegate,
227 socket_performance_watcher_factory,
228 quic_crypto_client_stream_factory,
229 context) {}
230
231 MockQuicSessionPool(const MockQuicSessionPool&) = delete;
232 MockQuicSessionPool& operator=(const MockQuicSessionPool&) = delete;
233
234 ~MockQuicSessionPool() override = default;
235
236 MOCK_METHOD0(MockFinishConnectAndConfigureSocket, void());
237
FinishConnectAndConfigureSocket(CompletionOnceCallback callback,DatagramClientSocket * socket,const SocketTag & socket_tag,int rv)238 void FinishConnectAndConfigureSocket(CompletionOnceCallback callback,
239 DatagramClientSocket* socket,
240 const SocketTag& socket_tag,
241 int rv) override {
242 QuicSessionPool::FinishConnectAndConfigureSocket(std::move(callback),
243 socket, socket_tag, rv);
244 MockFinishConnectAndConfigureSocket();
245 }
246 };
247
248 class QuicSessionPoolTest : public QuicSessionPoolTestBase,
249 public ::testing::TestWithParam<TestParams> {
250 protected:
QuicSessionPoolTest()251 QuicSessionPoolTest()
252 : QuicSessionPoolTestBase(GetParam().version),
253 runner_(base::MakeRefCounted<TestTaskRunner>(context_.mock_clock())) {
254 if (GetParam().priority_header_enabled) {
255 feature_list_.InitAndEnableFeature(net::features::kPriorityHeader);
256 } else {
257 feature_list_.InitAndDisableFeature(net::features::kPriorityHeader);
258 }
259 }
260
261 void RunTestLoopUntilIdle();
262
263 void InitializeConnectionMigrationV2Test(
264 NetworkChangeNotifier::NetworkList connected_networks);
265
266 // Helper method for server migration tests.
267 void VerifyServerMigration(const quic::QuicConfig& config,
268 IPEndPoint expected_address);
269
270 // Verifies that the QUIC stream factory is initialized correctly.
271 // If |vary_network_anonymization_key| is true, stores data for two different
272 // NetworkAnonymizationKeys, but the same server. If false, stores data for
273 // two different servers, using the same NetworkAnonymizationKey.
274 void VerifyInitialization(bool vary_network_anonymization_key);
275
276 // Helper methods for tests of connection migration on write error.
277 void TestMigrationOnWriteErrorNonMigratableStream(IoMode write_error_mode,
278 bool migrate_idle_sessions);
279 // Migratable stream triggers write error.
280 void TestMigrationOnWriteErrorMixedStreams(IoMode write_error_mode);
281 // Non-migratable stream triggers write error.
282 void TestMigrationOnWriteErrorMixedStreams2(IoMode write_error_mode);
283 void TestMigrationOnWriteErrorMigrationDisabled(IoMode write_error_mode);
284 void TestMigrationOnWriteError(IoMode write_error_mode);
285 void TestMigrationOnWriteErrorWithMultipleRequests(IoMode write_error_mode);
286 void TestMigrationOnWriteErrorNoNewNetwork(IoMode write_error_mode);
287 void TestMigrationOnMultipleWriteErrors(
288 IoMode write_error_mode_on_old_network,
289 IoMode write_error_mode_on_new_network);
290 void TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
291 bool disconnected);
292 void TestMigrationOnWriteErrorWithNotificationQueuedLater(bool disconnected);
293 void TestMigrationOnNetworkDisconnected(bool async_write_before);
294 void TestMigrationOnNetworkMadeDefault(IoMode write_mode);
295 void TestMigrationOnPathDegrading(bool async_write_before);
296 void TestMigrateSessionWithDrainingStream(
297 IoMode write_mode_for_queued_packet);
298 void TestMigrationOnWriteErrorPauseBeforeConnected(IoMode write_error_mode);
299 void TestMigrationOnWriteErrorWithMultipleNotifications(
300 IoMode write_error_mode,
301 bool disconnect_before_connect);
302 void TestNoAlternateNetworkBeforeHandshake(quic::QuicErrorCode error);
303 void
304 TestThatBlackHoleIsDisabledOnNoNewNetworkThenResumedAfterConnectingToANetwork(
305 bool is_blackhole_disabled_after_disconnecting);
306 void TestNewConnectionOnAlternateNetworkBeforeHandshake(
307 quic::QuicErrorCode error);
308 void TestOnNetworkMadeDefaultNonMigratableStream(bool migrate_idle_sessions);
309 void TestMigrateSessionEarlyNonMigratableStream(bool migrate_idle_sessions);
310 void TestOnNetworkDisconnectedNoOpenStreams(bool migrate_idle_sessions);
311 void TestOnNetworkMadeDefaultNoOpenStreams(bool migrate_idle_sessions);
312 void TestOnNetworkDisconnectedNonMigratableStream(bool migrate_idle_sessions);
313
314 // Port migrations.
315 void TestSimplePortMigrationOnPathDegrading();
316
317 // Tests for DNS HTTPS record with alpn.
318 void TestRequireDnsHttpsAlpn(
319 std::vector<HostResolverEndpointResult> endpoints,
320 bool expect_success);
321
322 scoped_refptr<TestTaskRunner> runner_;
323
324 private:
325 base::test::ScopedFeatureList feature_list_;
326 };
327
RunTestLoopUntilIdle()328 void QuicSessionPoolTest::RunTestLoopUntilIdle() {
329 while (!runner_->GetPostedTasks().empty()) {
330 runner_->RunNextTask();
331 }
332 }
333
InitializeConnectionMigrationV2Test(NetworkChangeNotifier::NetworkList connected_networks)334 void QuicSessionPoolTest::InitializeConnectionMigrationV2Test(
335 NetworkChangeNotifier::NetworkList connected_networks) {
336 scoped_mock_network_change_notifier_ =
337 std::make_unique<ScopedMockNetworkChangeNotifier>();
338 MockNetworkChangeNotifier* mock_ncn =
339 scoped_mock_network_change_notifier_->mock_network_change_notifier();
340 mock_ncn->ForceNetworkHandlesSupported();
341 mock_ncn->SetConnectedNetworksList(connected_networks);
342 quic_params_->migrate_sessions_on_network_change_v2 = true;
343 quic_params_->migrate_sessions_early_v2 = true;
344 socket_factory_ = std::make_unique<TestConnectionMigrationSocketFactory>();
345 Initialize();
346 }
347
VerifyServerMigration(const quic::QuicConfig & config,IPEndPoint expected_address)348 void QuicSessionPoolTest::VerifyServerMigration(const quic::QuicConfig& config,
349 IPEndPoint expected_address) {
350 quic_params_->allow_server_migration = true;
351 Initialize();
352
353 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
354 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
355 crypto_client_stream_factory_.SetConfig(config);
356
357 // Set up first socket data provider.
358 MockQuicData socket_data1(version_);
359 socket_data1.AddReadPauseForever();
360 socket_data1.AddSocketDataToFactory(socket_factory_.get());
361
362 // Set up second socket data provider that is used after
363 // migration.
364 MockQuicData socket_data2(version_);
365 client_maker_.set_connection_id(kNewCID);
366 socket_data2.AddReadPauseForever();
367 int packet_num = 1;
368 socket_data2.AddWrite(SYNCHRONOUS,
369 ConstructInitialSettingsPacket(packet_num++));
370 socket_data2.AddWrite(SYNCHRONOUS,
371 client_maker_.MakePingPacket(packet_num++));
372 socket_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeRetireConnectionIdPacket(
373 packet_num++,
374 /*sequence_number=*/0u));
375 socket_data2.AddWrite(SYNCHRONOUS,
376 client_maker_.MakeDataPacket(
377 packet_num++, GetQpackDecoderStreamId(), false,
378 StreamCancellationQpackDecoderInstruction(0)));
379 socket_data2.AddWrite(
380 SYNCHRONOUS,
381 client_maker_.MakeRstPacket(packet_num++,
382 GetNthClientInitiatedBidirectionalStreamId(0),
383 quic::QUIC_STREAM_CANCELLED));
384 socket_data2.AddSocketDataToFactory(socket_factory_.get());
385
386 // Create request and QuicHttpStream.
387 RequestBuilder builder(this);
388 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
389 EXPECT_EQ(OK, callback_.WaitForResult());
390
391 // Run QuicChromiumClientSession::WriteToNewSocket()
392 // posted by QuicChromiumClientSession::MigrateToSocket().
393 base::RunLoop().RunUntilIdle();
394
395 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
396 EXPECT_TRUE(stream.get());
397
398 // Cause QUIC stream to be created.
399 HttpRequestInfo request_info;
400 request_info.method = "GET";
401 request_info.url = GURL("https://www.example.org/");
402 request_info.traffic_annotation =
403 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
404 stream->RegisterRequest(&request_info);
405 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
406 CompletionOnceCallback()));
407 // Ensure that session is alive and active.
408 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
409 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
410 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
411
412 IPEndPoint actual_address;
413 session->GetDefaultSocket()->GetPeerAddress(&actual_address);
414 EXPECT_EQ(actual_address, expected_address);
415 DVLOG(1) << "Socket connected to: " << actual_address.address().ToString()
416 << " " << actual_address.port();
417 DVLOG(1) << "Expected address: " << expected_address.address().ToString()
418 << " " << expected_address.port();
419
420 stream.reset();
421 socket_data1.ExpectAllReadDataConsumed();
422 socket_data2.ExpectAllReadDataConsumed();
423 socket_data2.ExpectAllWriteDataConsumed();
424 }
425
426 // Verifies that the QUIC stream factory is initialized correctly.
427 // If |vary_network_anonymization_key| is true, stores data for two different
428 // NetworkAnonymizationKeys, but the same server. If false, stores data for
429 // two different servers, using the same NetworkAnonymizationKey.
VerifyInitialization(bool vary_network_anonymization_key)430 void QuicSessionPoolTest::VerifyInitialization(
431 bool vary_network_anonymization_key) {
432 const SchemefulSite kSite1(GURL("https://foo.test/"));
433 const SchemefulSite kSite2(GURL("https://bar.test/"));
434
435 const auto network_anonymization_key1 =
436 NetworkAnonymizationKey::CreateSameSite(kSite1);
437 quic::QuicServerId quic_server_id1(kDefaultServerHostName, kDefaultServerPort,
438 PRIVACY_MODE_DISABLED);
439
440 NetworkAnonymizationKey network_anonymization_key2;
441 quic::QuicServerId quic_server_id2;
442
443 if (vary_network_anonymization_key) {
444 network_anonymization_key2 =
445 NetworkAnonymizationKey::CreateSameSite(kSite2);
446 quic_server_id2 = quic_server_id1;
447 } else {
448 network_anonymization_key2 = network_anonymization_key1;
449 quic_server_id2 = quic::QuicServerId(kServer2HostName, kDefaultServerPort,
450 PRIVACY_MODE_DISABLED);
451 }
452
453 quic_params_->max_server_configs_stored_in_properties = 1;
454 quic_params_->idle_connection_timeout = base::Seconds(500);
455 Initialize();
456 factory_->set_is_quic_known_to_work_on_current_network(true);
457 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
458 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
459 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
460 crypto_client_stream_factory_.set_handshake_mode(
461 MockCryptoClientStream::ZERO_RTT);
462 const quic::QuicConfig* config =
463 QuicSessionPoolPeer::GetConfig(factory_.get());
464 EXPECT_EQ(500, config->IdleNetworkTimeout().ToSeconds());
465
466 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), runner_.get());
467
468 const AlternativeService alternative_service1(
469 kProtoQUIC, kDefaultServerHostName, kDefaultServerPort);
470 AlternativeServiceInfoVector alternative_service_info_vector;
471 base::Time expiration = base::Time::Now() + base::Days(1);
472 alternative_service_info_vector.push_back(
473 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
474 alternative_service1, expiration, {version_}));
475 http_server_properties_->SetAlternativeServices(
476 url::SchemeHostPort("https", quic_server_id1.host(),
477 quic_server_id1.port()),
478 network_anonymization_key1, alternative_service_info_vector);
479
480 const AlternativeService alternative_service2(
481 kProtoQUIC, quic_server_id2.host(), quic_server_id2.port());
482 AlternativeServiceInfoVector alternative_service_info_vector2;
483 alternative_service_info_vector2.push_back(
484 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
485 alternative_service2, expiration, {version_}));
486
487 http_server_properties_->SetAlternativeServices(
488 url::SchemeHostPort("https", quic_server_id2.host(),
489 quic_server_id2.port()),
490 network_anonymization_key2, alternative_service_info_vector2);
491 // Verify that the properties of both QUIC servers are stored in the
492 // HTTP properties map.
493 EXPECT_EQ(2U, http_server_properties_->server_info_map_for_testing().size());
494
495 http_server_properties_->SetMaxServerConfigsStoredInProperties(
496 kDefaultMaxQuicServerEntries);
497
498 std::unique_ptr<QuicServerInfo> quic_server_info =
499 std::make_unique<PropertiesBasedQuicServerInfo>(
500 quic_server_id1, network_anonymization_key1,
501 http_server_properties_.get());
502
503 // Update quic_server_info's server_config and persist it.
504 QuicServerInfo::State* state = quic_server_info->mutable_state();
505 // Minimum SCFG that passes config validation checks.
506 const char scfg[] = {// SCFG
507 0x53, 0x43, 0x46, 0x47,
508 // num entries
509 0x01, 0x00,
510 // padding
511 0x00, 0x00,
512 // EXPY
513 0x45, 0x58, 0x50, 0x59,
514 // EXPY end offset
515 0x08, 0x00, 0x00, 0x00,
516 // Value
517 '1', '2', '3', '4', '5', '6', '7', '8'};
518
519 // Create temporary strings because Persist() clears string data in |state|.
520 string server_config(reinterpret_cast<const char*>(&scfg), sizeof(scfg));
521 string source_address_token("test_source_address_token");
522 string cert_sct("test_cert_sct");
523 string chlo_hash("test_chlo_hash");
524 string signature("test_signature");
525 string test_cert("test_cert");
526 std::vector<string> certs;
527 certs.push_back(test_cert);
528 state->server_config = server_config;
529 state->source_address_token = source_address_token;
530 state->cert_sct = cert_sct;
531 state->chlo_hash = chlo_hash;
532 state->server_config_sig = signature;
533 state->certs = certs;
534
535 quic_server_info->Persist();
536
537 std::unique_ptr<QuicServerInfo> quic_server_info2 =
538 std::make_unique<PropertiesBasedQuicServerInfo>(
539 quic_server_id2, network_anonymization_key2,
540 http_server_properties_.get());
541 // Update quic_server_info2's server_config and persist it.
542 QuicServerInfo::State* state2 = quic_server_info2->mutable_state();
543
544 // Minimum SCFG that passes config validation checks.
545 const char scfg2[] = {// SCFG
546 0x53, 0x43, 0x46, 0x47,
547 // num entries
548 0x01, 0x00,
549 // padding
550 0x00, 0x00,
551 // EXPY
552 0x45, 0x58, 0x50, 0x59,
553 // EXPY end offset
554 0x08, 0x00, 0x00, 0x00,
555 // Value
556 '8', '7', '3', '4', '5', '6', '2', '1'};
557
558 // Create temporary strings because Persist() clears string data in
559 // |state2|.
560 string server_config2(reinterpret_cast<const char*>(&scfg2), sizeof(scfg2));
561 string source_address_token2("test_source_address_token2");
562 string cert_sct2("test_cert_sct2");
563 string chlo_hash2("test_chlo_hash2");
564 string signature2("test_signature2");
565 string test_cert2("test_cert2");
566 std::vector<string> certs2;
567 certs2.push_back(test_cert2);
568 state2->server_config = server_config2;
569 state2->source_address_token = source_address_token2;
570 state2->cert_sct = cert_sct2;
571 state2->chlo_hash = chlo_hash2;
572 state2->server_config_sig = signature2;
573 state2->certs = certs2;
574
575 quic_server_info2->Persist();
576
577 // Verify the MRU order is maintained.
578 const HttpServerProperties::QuicServerInfoMap& quic_server_info_map =
579 http_server_properties_->quic_server_info_map();
580 EXPECT_EQ(2u, quic_server_info_map.size());
581 auto quic_server_info_map_it = quic_server_info_map.begin();
582 EXPECT_EQ(quic_server_info_map_it->first.server_id, quic_server_id2);
583 ++quic_server_info_map_it;
584 EXPECT_EQ(quic_server_info_map_it->first.server_id, quic_server_id1);
585
586 host_resolver_->rules()->AddIPLiteralRule(kDefaultServerHostName,
587 "192.168.0.1", "");
588
589 // Create a session and verify that the cached state is loaded.
590 MockQuicData socket_data(version_);
591 socket_data.AddReadPauseForever();
592 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
593 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
594 socket_data.AddSocketDataToFactory(socket_factory_.get());
595
596 RequestBuilder builder(this);
597 builder.destination = url::SchemeHostPort(
598 url::kHttpsScheme, quic_server_id1.host(), quic_server_id1.port());
599 builder.network_anonymization_key = network_anonymization_key1;
600 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
601 EXPECT_THAT(callback_.WaitForResult(), IsOk());
602
603 EXPECT_FALSE(QuicSessionPoolPeer::CryptoConfigCacheIsEmpty(
604 factory_.get(), quic_server_id1, network_anonymization_key1));
605
606 std::unique_ptr<QuicCryptoClientConfigHandle> crypto_config_handle1 =
607 QuicSessionPoolPeer::GetCryptoConfig(factory_.get(),
608 network_anonymization_key1);
609 quic::QuicCryptoClientConfig::CachedState* cached =
610 crypto_config_handle1->GetConfig()->LookupOrCreate(quic_server_id1);
611 EXPECT_FALSE(cached->server_config().empty());
612 EXPECT_TRUE(cached->GetServerConfig());
613 EXPECT_EQ(server_config, cached->server_config());
614 EXPECT_EQ(source_address_token, cached->source_address_token());
615 EXPECT_EQ(cert_sct, cached->cert_sct());
616 EXPECT_EQ(chlo_hash, cached->chlo_hash());
617 EXPECT_EQ(signature, cached->signature());
618 ASSERT_EQ(1U, cached->certs().size());
619 EXPECT_EQ(test_cert, cached->certs()[0]);
620
621 socket_data.ExpectAllWriteDataConsumed();
622
623 // Create a session and verify that the cached state is loaded.
624 MockQuicData socket_data2(version_);
625 socket_data2.AddReadPauseForever();
626 client_maker_.Reset();
627 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
628 socket_data2.AddSocketDataToFactory(socket_factory_.get());
629
630 host_resolver_->rules()->ClearRules();
631 host_resolver_->rules()->AddIPLiteralRule(kDefaultServerHostName,
632 "192.168.0.2", "");
633
634 RequestBuilder builder2(this);
635 builder2.destination = url::SchemeHostPort(
636 url::kHttpsScheme, quic_server_id2.host(), quic_server_id2.port());
637 builder2.network_anonymization_key = network_anonymization_key2;
638 builder2.url = vary_network_anonymization_key
639 ? GURL(kDefaultUrl)
640 : GURL("https://mail.example.org/");
641 EXPECT_EQ(ERR_IO_PENDING, builder2.CallRequest());
642 EXPECT_THAT(callback_.WaitForResult(), IsOk());
643
644 EXPECT_FALSE(QuicSessionPoolPeer::CryptoConfigCacheIsEmpty(
645 factory_.get(), quic_server_id2, network_anonymization_key2));
646 std::unique_ptr<QuicCryptoClientConfigHandle> crypto_config_handle2 =
647 QuicSessionPoolPeer::GetCryptoConfig(factory_.get(),
648 network_anonymization_key2);
649 quic::QuicCryptoClientConfig::CachedState* cached2 =
650 crypto_config_handle2->GetConfig()->LookupOrCreate(quic_server_id2);
651 EXPECT_FALSE(cached2->server_config().empty());
652 EXPECT_TRUE(cached2->GetServerConfig());
653 EXPECT_EQ(server_config2, cached2->server_config());
654 EXPECT_EQ(source_address_token2, cached2->source_address_token());
655 EXPECT_EQ(cert_sct2, cached2->cert_sct());
656 EXPECT_EQ(chlo_hash2, cached2->chlo_hash());
657 EXPECT_EQ(signature2, cached2->signature());
658 ASSERT_EQ(1U, cached->certs().size());
659 EXPECT_EQ(test_cert2, cached2->certs()[0]);
660 }
661
662 INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
663 QuicSessionPoolTest,
664 ::testing::ValuesIn(GetTestParams()),
665 ::testing::PrintToStringParamName());
666
TEST_P(QuicSessionPoolTest,CreateSyncQuicSession)667 TEST_P(QuicSessionPoolTest, CreateSyncQuicSession) {
668 base::test::ScopedFeatureList scoped_feature_list;
669 scoped_feature_list.InitAndDisableFeature(net::features::kAsyncQuicSession);
670 Initialize();
671 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
672 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
673
674 MockQuicData socket_data(version_);
675 socket_data.AddReadPauseForever();
676 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
677 socket_data.AddSocketDataToFactory(socket_factory_.get());
678
679 RequestBuilder builder(this);
680 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
681
682 EXPECT_THAT(callback_.WaitForResult(), IsOk());
683 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
684 EXPECT_TRUE(stream.get());
685
686 EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_->last_request_priority());
687
688 RequestBuilder builder2(this);
689 EXPECT_EQ(OK, builder2.CallRequest());
690 // Will reset stream 3.
691 stream = CreateStream(&builder2.request);
692
693 EXPECT_TRUE(stream.get());
694
695 // TODO(rtenneti): We should probably have a tests that HTTP and HTTPS result
696 // in streams on different sessions.
697 RequestBuilder builder3(this);
698 EXPECT_EQ(OK, builder3.CallRequest());
699 stream = CreateStream(&builder3.request); // Will reset stream 5.
700 stream.reset(); // Will reset stream 7.
701
702 socket_data.ExpectAllReadDataConsumed();
703 socket_data.ExpectAllWriteDataConsumed();
704 }
705
TEST_P(QuicSessionPoolTest,CreateAsyncQuicSession)706 TEST_P(QuicSessionPoolTest, CreateAsyncQuicSession) {
707 Initialize();
708 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
709 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
710
711 MockQuicData socket_data(version_);
712 socket_data.AddReadPauseForever();
713 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
714 socket_data.AddSocketDataToFactory(socket_factory_.get());
715
716 RequestBuilder builder(this);
717 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
718 EXPECT_THAT(callback_.WaitForResult(), IsOk());
719 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
720 EXPECT_TRUE(stream.get());
721
722 EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_->last_request_priority());
723
724 RequestBuilder builder2(this);
725 EXPECT_EQ(OK, builder2.CallRequest());
726 // Will reset stream 3.
727 stream = CreateStream(&builder2.request);
728 EXPECT_TRUE(stream.get());
729
730 // TODO(rtenneti): We should probably have a tests that HTTP and HTTPS result
731 // in streams on different sessions.
732 RequestBuilder builder3(this);
733 EXPECT_EQ(OK, builder3.CallRequest());
734 stream = CreateStream(&builder3.request); // Will reset stream 5.
735 stream.reset(); // Will reset stream 7.
736
737 socket_data.ExpectAllReadDataConsumed();
738 socket_data.ExpectAllWriteDataConsumed();
739 }
740
741 // This test uses synchronous QUIC session creation
TEST_P(QuicSessionPoolTest,SyncCreateZeroRtt)742 TEST_P(QuicSessionPoolTest, SyncCreateZeroRtt) {
743 base::test::ScopedFeatureList scoped_feature_list;
744 scoped_feature_list.InitAndDisableFeature(net::features::kAsyncQuicSession);
745 Initialize();
746 factory_->set_is_quic_known_to_work_on_current_network(true);
747 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
748 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
749
750 MockQuicData socket_data(version_);
751 socket_data.AddReadPauseForever();
752 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
753 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
754 socket_data.AddSocketDataToFactory(socket_factory_.get());
755
756 crypto_client_stream_factory_.set_handshake_mode(
757 MockCryptoClientStream::ZERO_RTT);
758 host_resolver_->set_synchronous_mode(true);
759 host_resolver_->rules()->AddIPLiteralRule(kDefaultServerHostName,
760 "192.168.0.1", "");
761
762 RequestBuilder builder(this);
763 EXPECT_EQ(OK, builder.CallRequest());
764 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
765 EXPECT_TRUE(stream.get());
766 socket_data.ExpectAllReadDataConsumed();
767 socket_data.ExpectAllWriteDataConsumed();
768 }
769
TEST_P(QuicSessionPoolTest,AsyncCreateZeroRtt)770 TEST_P(QuicSessionPoolTest, AsyncCreateZeroRtt) {
771 Initialize();
772 factory_->set_is_quic_known_to_work_on_current_network(true);
773 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
774 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
775
776 MockQuicData socket_data(version_);
777 socket_data.AddReadPauseForever();
778 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
779 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
780 socket_data.AddSocketDataToFactory(socket_factory_.get());
781
782 crypto_client_stream_factory_.set_handshake_mode(
783 MockCryptoClientStream::ZERO_RTT);
784 host_resolver_->set_synchronous_mode(true);
785 host_resolver_->rules()->AddIPLiteralRule(kDefaultServerHostName,
786 "192.168.0.1", "");
787
788 RequestBuilder builder(this);
789 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
790 int rv = callback_.WaitForResult();
791 EXPECT_EQ(OK, rv);
792
793 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
794 EXPECT_TRUE(stream.get());
795 socket_data.ExpectAllReadDataConsumed();
796 socket_data.ExpectAllWriteDataConsumed();
797 }
798
799 // Regression test for crbug.com/1117331.
TEST_P(QuicSessionPoolTest,AsyncZeroRtt)800 TEST_P(QuicSessionPoolTest, AsyncZeroRtt) {
801 Initialize();
802
803 factory_->set_is_quic_known_to_work_on_current_network(true);
804 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
805 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
806
807 MockQuicData socket_data(version_);
808 socket_data.AddReadPauseForever();
809 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
810 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
811 socket_data.AddSocketDataToFactory(socket_factory_.get());
812
813 crypto_client_stream_factory_.set_handshake_mode(
814 MockCryptoClientStream::ASYNC_ZERO_RTT);
815 host_resolver_->set_synchronous_mode(true);
816 host_resolver_->rules()->AddIPLiteralRule(kDefaultServerHostName,
817 "192.168.0.1", "");
818
819 RequestBuilder builder(this);
820 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
821 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
822 EXPECT_EQ(nullptr, CreateStream(&builder.request));
823
824 base::RunLoop().RunUntilIdle();
825 crypto_client_stream_factory_.last_stream()->NotifySessionZeroRttComplete();
826 EXPECT_THAT(callback_.WaitForResult(), IsOk());
827 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
828
829 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
830 EXPECT_TRUE(stream.get());
831 socket_data.ExpectAllReadDataConsumed();
832 socket_data.ExpectAllWriteDataConsumed();
833 }
834
TEST_P(QuicSessionPoolTest,DefaultInitialRtt)835 TEST_P(QuicSessionPoolTest, DefaultInitialRtt) {
836 Initialize();
837 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
838 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
839
840 MockQuicData socket_data(version_);
841 socket_data.AddReadPauseForever();
842 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
843 socket_data.AddSocketDataToFactory(socket_factory_.get());
844
845 RequestBuilder builder(this);
846 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
847 EXPECT_THAT(callback_.WaitForResult(), IsOk());
848 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
849 EXPECT_TRUE(stream.get());
850
851 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
852 EXPECT_TRUE(session->require_confirmation());
853 EXPECT_EQ(100000u, session->connection()->GetStats().srtt_us);
854 ASSERT_FALSE(session->config()->HasInitialRoundTripTimeUsToSend());
855 }
856
TEST_P(QuicSessionPoolTest,FactoryDestroyedWhenJobPending)857 TEST_P(QuicSessionPoolTest, FactoryDestroyedWhenJobPending) {
858 Initialize();
859 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
860 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
861
862 MockQuicData socket_data(version_);
863 socket_data.AddReadPauseForever();
864 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
865 socket_data.AddSocketDataToFactory(socket_factory_.get());
866
867 auto builder = std::make_unique<RequestBuilder>(this);
868 EXPECT_EQ(ERR_IO_PENDING, builder->CallRequest());
869 builder.reset();
870 EXPECT_TRUE(HasActiveJob(kDefaultDestination, PRIVACY_MODE_DISABLED));
871 // Tearing down a QuicSessionPool with a pending Job should not cause any
872 // crash. crbug.com/768343.
873 factory_.reset();
874 }
875
TEST_P(QuicSessionPoolTest,RequireConfirmation)876 TEST_P(QuicSessionPoolTest, RequireConfirmation) {
877 base::test::ScopedFeatureList scoped_feature_list;
878 scoped_feature_list.InitAndDisableFeature(net::features::kAsyncQuicSession);
879 crypto_client_stream_factory_.set_handshake_mode(
880 MockCryptoClientStream::ZERO_RTT);
881 host_resolver_->set_synchronous_mode(true);
882 host_resolver_->rules()->AddIPLiteralRule(kDefaultServerHostName,
883 "192.168.0.1", "");
884 Initialize();
885 factory_->set_is_quic_known_to_work_on_current_network(false);
886 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
887 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
888
889 MockQuicData socket_data(version_);
890 socket_data.AddReadPauseForever();
891 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
892 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
893 socket_data.AddSocketDataToFactory(socket_factory_.get());
894
895 RequestBuilder builder(this);
896 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
897 EXPECT_FALSE(http_server_properties_->HasLastLocalAddressWhenQuicWorked());
898
899 crypto_client_stream_factory_.last_stream()
900 ->NotifySessionOneRttKeyAvailable();
901
902 EXPECT_TRUE(http_server_properties_->HasLastLocalAddressWhenQuicWorked());
903
904 EXPECT_THAT(callback_.WaitForResult(), IsOk());
905 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
906 EXPECT_TRUE(stream.get());
907
908 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
909 EXPECT_TRUE(session->require_confirmation());
910 }
911
TEST_P(QuicSessionPoolTest,RequireConfirmationAsyncQuicSession)912 TEST_P(QuicSessionPoolTest, RequireConfirmationAsyncQuicSession) {
913 crypto_client_stream_factory_.set_handshake_mode(
914 MockCryptoClientStream::ZERO_RTT);
915 host_resolver_->set_synchronous_mode(true);
916 host_resolver_->rules()->AddIPLiteralRule(kDefaultServerHostName,
917 "192.168.0.1", "");
918 Initialize();
919 factory_->set_is_quic_known_to_work_on_current_network(false);
920 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
921 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
922
923 MockQuicData socket_data(version_);
924 socket_data.AddReadPauseForever();
925 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
926 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
927 socket_data.AddSocketDataToFactory(socket_factory_.get());
928
929 RequestBuilder builder(this);
930 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
931 EXPECT_FALSE(http_server_properties_->HasLastLocalAddressWhenQuicWorked());
932
933 base::RunLoop().RunUntilIdle();
934 crypto_client_stream_factory_.last_stream()
935 ->NotifySessionOneRttKeyAvailable();
936
937 EXPECT_TRUE(http_server_properties_->HasLastLocalAddressWhenQuicWorked());
938
939 EXPECT_THAT(callback_.WaitForResult(), IsOk());
940 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
941 EXPECT_TRUE(stream.get());
942
943 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
944 EXPECT_TRUE(session->require_confirmation());
945 }
946
TEST_P(QuicSessionPoolTest,DontRequireConfirmationFromSameIP)947 TEST_P(QuicSessionPoolTest, DontRequireConfirmationFromSameIP) {
948 crypto_client_stream_factory_.set_handshake_mode(
949 MockCryptoClientStream::ZERO_RTT);
950 host_resolver_->set_synchronous_mode(true);
951 host_resolver_->rules()->AddIPLiteralRule(kDefaultServerHostName,
952 "192.168.0.1", "");
953 Initialize();
954 factory_->set_is_quic_known_to_work_on_current_network(false);
955 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
956 IPAddress(192, 0, 2, 33));
957
958 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
959 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
960
961 MockQuicData socket_data(version_);
962 socket_data.AddReadPauseForever();
963 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
964 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
965 socket_data.AddSocketDataToFactory(socket_factory_.get());
966
967 RequestBuilder builder(this);
968 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
969 EXPECT_THAT(callback_.WaitForResult(), IsOk());
970 EXPECT_FALSE(http_server_properties_->HasLastLocalAddressWhenQuicWorked());
971
972 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
973 EXPECT_TRUE(stream.get());
974
975 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
976 EXPECT_FALSE(session->require_confirmation());
977
978 crypto_client_stream_factory_.last_stream()
979 ->NotifySessionOneRttKeyAvailable();
980 EXPECT_TRUE(http_server_properties_->HasLastLocalAddressWhenQuicWorked());
981 }
982
TEST_P(QuicSessionPoolTest,CachedInitialRtt)983 TEST_P(QuicSessionPoolTest, CachedInitialRtt) {
984 ServerNetworkStats stats;
985 stats.srtt = base::Milliseconds(10);
986 http_server_properties_->SetServerNetworkStats(
987 url::SchemeHostPort(GURL(kDefaultUrl)), NetworkAnonymizationKey(), stats);
988 quic_params_->estimate_initial_rtt = true;
989
990 Initialize();
991 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
992 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
993
994 MockQuicData socket_data(version_);
995 socket_data.AddReadPauseForever();
996 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
997 socket_data.AddSocketDataToFactory(socket_factory_.get());
998
999 RequestBuilder builder(this);
1000 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
1001 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1002 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
1003 EXPECT_TRUE(stream.get());
1004
1005 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
1006 EXPECT_EQ(10000u, session->connection()->GetStats().srtt_us);
1007 ASSERT_TRUE(session->config()->HasInitialRoundTripTimeUsToSend());
1008 EXPECT_EQ(10000u, session->config()->GetInitialRoundTripTimeUsToSend());
1009 }
1010
1011 // Test that QUIC sessions use the cached RTT from HttpServerProperties for the
1012 // correct NetworkAnonymizationKey.
TEST_P(QuicSessionPoolTest,CachedInitialRttWithNetworkAnonymizationKey)1013 TEST_P(QuicSessionPoolTest, CachedInitialRttWithNetworkAnonymizationKey) {
1014 const SchemefulSite kSite1(GURL("https://foo.test/"));
1015 const SchemefulSite kSite2(GURL("https://bar.test/"));
1016 const auto kNetworkAnonymizationKey1 =
1017 NetworkAnonymizationKey::CreateSameSite(kSite1);
1018 const auto kNetworkAnonymizationKey2 =
1019 NetworkAnonymizationKey::CreateSameSite(kSite2);
1020
1021 base::test::ScopedFeatureList feature_list;
1022 feature_list.InitWithFeatures(
1023 // enabled_features
1024 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
1025 // Need to partition connections by NetworkAnonymizationKey for
1026 // QuicSessionAliasKey to include NetworkAnonymizationKeys.
1027 features::kPartitionConnectionsByNetworkIsolationKey},
1028 // disabled_features
1029 {});
1030 // Since HttpServerProperties caches the feature value, have to create a new
1031 // one.
1032 http_server_properties_ = std::make_unique<HttpServerProperties>();
1033
1034 ServerNetworkStats stats;
1035 stats.srtt = base::Milliseconds(10);
1036 http_server_properties_->SetServerNetworkStats(
1037 url::SchemeHostPort(GURL(kDefaultUrl)), kNetworkAnonymizationKey1, stats);
1038 quic_params_->estimate_initial_rtt = true;
1039 Initialize();
1040
1041 for (const auto& network_anonymization_key :
1042 {kNetworkAnonymizationKey1, kNetworkAnonymizationKey2,
1043 NetworkAnonymizationKey()}) {
1044 SCOPED_TRACE(network_anonymization_key.ToDebugString());
1045
1046 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1047 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1048
1049 QuicTestPacketMaker packet_maker(
1050 version_,
1051 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
1052 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
1053 true);
1054
1055 MockQuicData socket_data(version_);
1056 socket_data.AddReadPauseForever();
1057 socket_data.AddWrite(SYNCHRONOUS,
1058 packet_maker.MakeInitialSettingsPacket(1));
1059 socket_data.AddSocketDataToFactory(socket_factory_.get());
1060
1061 RequestBuilder builder(this);
1062 builder.network_anonymization_key = network_anonymization_key;
1063 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
1064 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1065 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
1066 EXPECT_TRUE(stream.get());
1067
1068 QuicChromiumClientSession* session =
1069 GetActiveSession(kDefaultDestination, network_anonymization_key);
1070 if (network_anonymization_key == kNetworkAnonymizationKey1) {
1071 EXPECT_EQ(10000, session->connection()->GetStats().srtt_us);
1072 ASSERT_TRUE(session->config()->HasInitialRoundTripTimeUsToSend());
1073 EXPECT_EQ(10000u, session->config()->GetInitialRoundTripTimeUsToSend());
1074 } else {
1075 EXPECT_EQ(quic::kInitialRttMs * 1000,
1076 session->connection()->GetStats().srtt_us);
1077 EXPECT_FALSE(session->config()->HasInitialRoundTripTimeUsToSend());
1078 }
1079 }
1080 }
1081
1082 TEST_P(QuicSessionPoolTest, 2gInitialRtt) {
1083 ScopedMockNetworkChangeNotifier notifier;
1084 notifier.mock_network_change_notifier()->SetConnectionType(
1085 NetworkChangeNotifier::CONNECTION_2G);
1086 quic_params_->estimate_initial_rtt = true;
1087
1088 Initialize();
1089 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1090 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1091
1092 MockQuicData socket_data(version_);
1093 socket_data.AddReadPauseForever();
1094 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
1095 socket_data.AddSocketDataToFactory(socket_factory_.get());
1096
1097 RequestBuilder builder(this);
1098 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
1099 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1100 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
1101 EXPECT_TRUE(stream.get());
1102
1103 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
1104 EXPECT_EQ(1000000u, session->connection()->GetStats().srtt_us);
1105 ASSERT_TRUE(session->config()->HasInitialRoundTripTimeUsToSend());
1106 EXPECT_EQ(1200000u, session->config()->GetInitialRoundTripTimeUsToSend());
1107 }
1108
1109 TEST_P(QuicSessionPoolTest, 3gInitialRtt) {
1110 ScopedMockNetworkChangeNotifier notifier;
1111 notifier.mock_network_change_notifier()->SetConnectionType(
1112 NetworkChangeNotifier::CONNECTION_3G);
1113 quic_params_->estimate_initial_rtt = true;
1114
1115 Initialize();
1116 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1117 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1118
1119 MockQuicData socket_data(version_);
1120 socket_data.AddReadPauseForever();
1121 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
1122 socket_data.AddSocketDataToFactory(socket_factory_.get());
1123
1124 RequestBuilder builder(this);
1125 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
1126 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1127 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
1128 EXPECT_TRUE(stream.get());
1129
1130 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
1131 EXPECT_EQ(400000u, session->connection()->GetStats().srtt_us);
1132 ASSERT_TRUE(session->config()->HasInitialRoundTripTimeUsToSend());
1133 EXPECT_EQ(400000u, session->config()->GetInitialRoundTripTimeUsToSend());
1134 }
1135
TEST_P(QuicSessionPoolTest,GoAway)1136 TEST_P(QuicSessionPoolTest, GoAway) {
1137 Initialize();
1138 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1139 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1140
1141 MockQuicData socket_data(version_);
1142 socket_data.AddReadPauseForever();
1143 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
1144 socket_data.AddSocketDataToFactory(socket_factory_.get());
1145
1146 RequestBuilder builder(this);
1147 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
1148 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1149 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
1150 EXPECT_TRUE(stream.get());
1151
1152 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
1153
1154 session->OnHttp3GoAway(0);
1155
1156 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
1157
1158 socket_data.ExpectAllReadDataConsumed();
1159 socket_data.ExpectAllWriteDataConsumed();
1160 }
1161
1162 // Makes sure that setting and clearing ServerNetworkStats respects the
1163 // NetworkAnonymizationKey.
TEST_P(QuicSessionPoolTest,ServerNetworkStatsWithNetworkAnonymizationKey)1164 TEST_P(QuicSessionPoolTest, ServerNetworkStatsWithNetworkAnonymizationKey) {
1165 const SchemefulSite kSite1(GURL("https://foo.test/"));
1166 const SchemefulSite kSite2(GURL("https://bar.test/"));
1167 const auto kNetworkAnonymizationKey1 =
1168 NetworkAnonymizationKey::CreateSameSite(kSite1);
1169 const auto kNetworkAnonymizationKey2 =
1170 NetworkAnonymizationKey::CreateSameSite(kSite2);
1171
1172 const NetworkAnonymizationKey kNetworkAnonymizationKeys[] = {
1173 kNetworkAnonymizationKey1, kNetworkAnonymizationKey2,
1174 NetworkAnonymizationKey()};
1175
1176 base::test::ScopedFeatureList feature_list;
1177 feature_list.InitWithFeatures(
1178 // enabled_features
1179 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
1180 // Need to partition connections by NetworkAnonymizationKey for
1181 // QuicSessionAliasKey to include NetworkAnonymizationKeys.
1182 features::kPartitionConnectionsByNetworkIsolationKey},
1183 // disabled_features
1184 {});
1185 // Since HttpServerProperties caches the feature value, have to create a new
1186 // one.
1187 http_server_properties_ = std::make_unique<HttpServerProperties>();
1188 Initialize();
1189
1190 // For each server, set up and tear down a QUIC session cleanly, and check
1191 // that stats have been added to HttpServerProperties using the correct
1192 // NetworkAnonymizationKey.
1193 for (size_t i = 0; i < std::size(kNetworkAnonymizationKeys); ++i) {
1194 SCOPED_TRACE(i);
1195
1196 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1197 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1198
1199 QuicTestPacketMaker packet_maker(
1200 version_,
1201 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
1202 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
1203 true);
1204
1205 MockQuicData socket_data(version_);
1206 socket_data.AddReadPauseForever();
1207 socket_data.AddWrite(SYNCHRONOUS,
1208 packet_maker.MakeInitialSettingsPacket(1));
1209 socket_data.AddSocketDataToFactory(socket_factory_.get());
1210
1211 RequestBuilder builder(this);
1212 builder.network_anonymization_key = kNetworkAnonymizationKeys[i];
1213 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
1214 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1215 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
1216 EXPECT_TRUE(stream.get());
1217
1218 QuicChromiumClientSession* session =
1219 GetActiveSession(kDefaultDestination, kNetworkAnonymizationKeys[i]);
1220
1221 session->OnHttp3GoAway(0);
1222
1223 EXPECT_FALSE(
1224 HasActiveSession(kDefaultDestination, kNetworkAnonymizationKeys[i]));
1225
1226 socket_data.ExpectAllReadDataConsumed();
1227 socket_data.ExpectAllWriteDataConsumed();
1228
1229 for (size_t j = 0; j < std::size(kNetworkAnonymizationKeys); ++j) {
1230 // Stats up to kNetworkAnonymizationKeys[j] should have been populated,
1231 // all others should remain empty.
1232 if (j <= i) {
1233 EXPECT_TRUE(http_server_properties_->GetServerNetworkStats(
1234 url::SchemeHostPort(GURL(kDefaultUrl)),
1235 kNetworkAnonymizationKeys[j]));
1236 } else {
1237 EXPECT_FALSE(http_server_properties_->GetServerNetworkStats(
1238 url::SchemeHostPort(GURL(kDefaultUrl)),
1239 kNetworkAnonymizationKeys[j]));
1240 }
1241 }
1242 }
1243
1244 // Use unmocked crypto stream to do crypto connect, since crypto errors result
1245 // in deleting network stats..
1246 crypto_client_stream_factory_.set_handshake_mode(
1247 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
1248
1249 // For each server, simulate an error during session creation, and check that
1250 // stats have been deleted from HttpServerProperties using the correct
1251 // NetworkAnonymizationKey.
1252 for (size_t i = 0; i < std::size(kNetworkAnonymizationKeys); ++i) {
1253 SCOPED_TRACE(i);
1254
1255 MockQuicData socket_data(version_);
1256 socket_data.AddReadPauseForever();
1257 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
1258 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
1259 socket_data.AddSocketDataToFactory(socket_factory_.get());
1260
1261 RequestBuilder builder(this);
1262 builder.network_anonymization_key = kNetworkAnonymizationKeys[i];
1263 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
1264 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_QUIC_HANDSHAKE_FAILED));
1265
1266 EXPECT_FALSE(
1267 HasActiveSession(kDefaultDestination, kNetworkAnonymizationKeys[i]));
1268
1269 for (size_t j = 0; j < std::size(kNetworkAnonymizationKeys); ++j) {
1270 // Stats up to kNetworkAnonymizationKeys[j] should have been deleted, all
1271 // others should still be populated.
1272 if (j <= i) {
1273 EXPECT_FALSE(http_server_properties_->GetServerNetworkStats(
1274 url::SchemeHostPort(GURL(kDefaultUrl)),
1275 kNetworkAnonymizationKeys[j]));
1276 } else {
1277 EXPECT_TRUE(http_server_properties_->GetServerNetworkStats(
1278 url::SchemeHostPort(GURL(kDefaultUrl)),
1279 kNetworkAnonymizationKeys[j]));
1280 }
1281 }
1282 }
1283 }
1284
TEST_P(QuicSessionPoolTest,Pooling)1285 TEST_P(QuicSessionPoolTest, Pooling) {
1286 quic_params_->supported_versions = {version_};
1287 Initialize();
1288 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1289 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1290
1291 MockQuicData socket_data(version_);
1292 socket_data.AddReadPauseForever();
1293 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
1294 socket_data.AddSocketDataToFactory(socket_factory_.get());
1295
1296 client_maker_.Reset();
1297 MockQuicData socket_data2(version_);
1298 socket_data2.AddReadPauseForever();
1299 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
1300 socket_data2.AddSocketDataToFactory(socket_factory_.get());
1301
1302 const IPEndPoint kRightIP(*IPAddress::FromIPLiteral("192.168.0.1"),
1303 kDefaultServerPort);
1304 const IPEndPoint kWrongIP(*IPAddress::FromIPLiteral("192.168.0.2"),
1305 kDefaultServerPort);
1306 const std::string kRightALPN = quic::AlpnForVersion(version_);
1307 const std::string kWrongALPN = "h2";
1308
1309 url::SchemeHostPort server2(url::kHttpsScheme, kServer2HostName,
1310 kDefaultServerPort);
1311 url::SchemeHostPort server3(url::kHttpsScheme, kServer3HostName,
1312 kDefaultServerPort);
1313 url::SchemeHostPort server4(url::kHttpsScheme, kServer4HostName,
1314 kDefaultServerPort);
1315 url::SchemeHostPort server5(url::kHttpsScheme, kServer5HostName,
1316 kDefaultServerPort);
1317 host_resolver_->set_synchronous_mode(true);
1318 host_resolver_->rules()->AddIPLiteralRule(kDefaultServerHostName,
1319 "192.168.0.1", "");
1320
1321 // `server2` resolves to the same IP address via A/AAAA records, i.e. without
1322 // ALPN information.
1323 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
1324
1325 // `server3` resolves to the same IP address, but only via an alternative
1326 // endpoint with matching ALPN.
1327 std::vector<HostResolverEndpointResult> endpoints(1);
1328 endpoints[0].ip_endpoints = {kRightIP};
1329 endpoints[0].metadata.supported_protocol_alpns = {kRightALPN};
1330 host_resolver_->rules()->AddRule(
1331 server3.host(),
1332 MockHostResolverBase::RuleResolver::RuleResult({std::move(endpoints)}));
1333
1334 // `server4` resolves to the same IP address, but only via an alternative
1335 // endpoint with a mismatching ALPN.
1336 endpoints = std::vector<HostResolverEndpointResult>(2);
1337 endpoints[0].ip_endpoints = {kRightIP};
1338 endpoints[0].metadata.supported_protocol_alpns = {kWrongALPN};
1339 endpoints[1].ip_endpoints = {kWrongIP};
1340 endpoints[1].metadata.supported_protocol_alpns = {kRightALPN};
1341 host_resolver_->rules()->AddRule(
1342 server4.host(),
1343 MockHostResolverBase::RuleResolver::RuleResult({std::move(endpoints)}));
1344
1345 // `server5` resolves to the same IP address via A/AAAA records, i.e. without
1346 // ALPN information.
1347 host_resolver_->rules()->AddIPLiteralRule(server5.host(), "192.168.0.1", "");
1348
1349 // Establish a QUIC session to pool against.
1350 RequestBuilder builder(this);
1351 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
1352 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1353 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
1354 EXPECT_TRUE(stream.get());
1355
1356 // `server2` can pool with the existing session. Although the endpoint does
1357 // not specify ALPN, we connect here with preexisting knowledge of the version
1358 // (from Alt-Svc), so an A/AAAA match is sufficient.
1359 TestCompletionCallback callback;
1360 RequestBuilder builder2(this);
1361 builder2.destination = server2;
1362 builder2.url = GURL(kServer2Url);
1363 EXPECT_EQ(OK, builder2.CallRequest());
1364 std::unique_ptr<HttpStream> stream2 = CreateStream(&builder2.request);
1365 EXPECT_TRUE(stream2.get());
1366 EXPECT_EQ(GetActiveSession(kDefaultDestination), GetActiveSession(server2));
1367
1368 // `server3` can pool with the existing session. The endpoint's ALPN protocol
1369 // matches.
1370 RequestBuilder builder3(this);
1371 builder3.destination = server3;
1372 builder3.url = GURL(kServer3Url);
1373 EXPECT_EQ(OK, builder3.CallRequest());
1374 std::unique_ptr<HttpStream> stream3 = CreateStream(&builder3.request);
1375 EXPECT_TRUE(stream3.get());
1376 EXPECT_EQ(GetActiveSession(kDefaultDestination), GetActiveSession(server3));
1377
1378 // `server4` cannot pool with the existing session. No endpoint matches both
1379 // IP and ALPN protocol.
1380 RequestBuilder builder4(this);
1381 builder4.destination = server4;
1382 builder4.url = GURL(kServer4Url);
1383 EXPECT_EQ(ERR_IO_PENDING, builder4.CallRequest());
1384 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1385 std::unique_ptr<HttpStream> stream4 = CreateStream(&builder4.request);
1386 EXPECT_TRUE(stream4.get());
1387 EXPECT_NE(GetActiveSession(kDefaultDestination), GetActiveSession(server4));
1388
1389 // `server5` cannot pool with the existing session. Although the IP address
1390 // matches, if we connect without prior knowledge of QUIC support, endpoints
1391 // are only eligible for cross-name pooling when associated with a QUIC ALPN.
1392 //
1393 // Without pooling, the DNS response is insufficient to start a QUIC
1394 // connection, so the connection will fail.
1395 RequestBuilder builder5(this);
1396 builder5.destination = server5;
1397 builder5.quic_version = quic::ParsedQuicVersion::Unsupported();
1398 builder5.require_dns_https_alpn = true;
1399 builder5.url = GURL(kServer5Url);
1400 EXPECT_EQ(ERR_DNS_NO_MATCHING_SUPPORTED_ALPN, builder5.CallRequest());
1401
1402 socket_data.ExpectAllReadDataConsumed();
1403 socket_data.ExpectAllWriteDataConsumed();
1404 socket_data2.ExpectAllReadDataConsumed();
1405 socket_data2.ExpectAllWriteDataConsumed();
1406 }
1407
1408 // Regression test for https://crbug.com/639916.
TEST_P(QuicSessionPoolTest,PoolingWithServerMigration)1409 TEST_P(QuicSessionPoolTest, PoolingWithServerMigration) {
1410 // Set up session to migrate.
1411 host_resolver_->rules()->AddIPLiteralRule(kDefaultServerHostName,
1412 "192.168.0.1", "");
1413 IPEndPoint alt_address = IPEndPoint(IPAddress(1, 2, 3, 4), 443);
1414 quic::QuicConfig config;
1415 config.SetIPv4AlternateServerAddressToSend(ToQuicSocketAddress(alt_address));
1416 config.SetPreferredAddressConnectionIdAndTokenToSend(
1417 kNewCID, quic::QuicUtils::GenerateStatelessResetToken(kNewCID));
1418 quic::QuicConnectionId cid_on_old_path =
1419 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator());
1420 VerifyServerMigration(config, alt_address);
1421
1422 // Close server-migrated session.
1423 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
1424 session->CloseSessionOnError(0u, quic::QUIC_NO_ERROR,
1425 quic::ConnectionCloseBehavior::SILENT_CLOSE);
1426 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
1427
1428 client_maker_.Reset();
1429 // Set up server IP, socket, proof, and config for new session.
1430 url::SchemeHostPort server2(url::kHttpsScheme, kServer2HostName,
1431 kDefaultServerPort);
1432 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
1433
1434 MockQuicData socket_data1(version_);
1435 socket_data1.AddReadPauseForever();
1436 client_maker_.set_connection_id(cid_on_old_path);
1437 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
1438 socket_data1.AddSocketDataToFactory(socket_factory_.get());
1439
1440 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1441 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1442 quic::QuicConfig config2;
1443 crypto_client_stream_factory_.SetConfig(config2);
1444
1445 // Create new request to cause new session creation.
1446 TestCompletionCallback callback;
1447 RequestBuilder builder2(this);
1448 builder2.destination = server2;
1449 builder2.url = GURL(kServer2Url);
1450 builder2.callback = callback.callback();
1451 EXPECT_EQ(ERR_IO_PENDING, builder2.CallRequest());
1452 EXPECT_EQ(OK, callback.WaitForResult());
1453 std::unique_ptr<HttpStream> stream2 = CreateStream(&builder2.request);
1454 EXPECT_TRUE(stream2.get());
1455
1456 socket_data1.ExpectAllReadDataConsumed();
1457 socket_data1.ExpectAllWriteDataConsumed();
1458
1459 EXPECT_TRUE(HasActiveSession(server2));
1460
1461 // No zombie entry in session map.
1462 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
1463 }
1464
TEST_P(QuicSessionPoolTest,NoPoolingAfterGoAway)1465 TEST_P(QuicSessionPoolTest, NoPoolingAfterGoAway) {
1466 Initialize();
1467 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1468 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1469 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1470
1471 MockQuicData socket_data1(version_);
1472 socket_data1.AddReadPauseForever();
1473 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
1474 socket_data1.AddSocketDataToFactory(socket_factory_.get());
1475 client_maker_.Reset();
1476 MockQuicData socket_data2(version_);
1477 socket_data2.AddReadPauseForever();
1478 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
1479 socket_data2.AddSocketDataToFactory(socket_factory_.get());
1480
1481 url::SchemeHostPort server2(url::kHttpsScheme, kServer2HostName,
1482 kDefaultServerPort);
1483 host_resolver_->set_synchronous_mode(true);
1484 host_resolver_->rules()->AddIPLiteralRule(kDefaultServerHostName,
1485 "192.168.0.1", "");
1486 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
1487
1488 RequestBuilder builder(this);
1489 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
1490 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1491 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
1492 EXPECT_TRUE(stream.get());
1493
1494 TestCompletionCallback callback;
1495 RequestBuilder builder2(this);
1496 builder2.destination = server2;
1497 builder2.url = GURL(kServer2Url);
1498 builder2.callback = callback.callback();
1499 EXPECT_EQ(OK, builder2.CallRequest());
1500 std::unique_ptr<HttpStream> stream2 = CreateStream(&builder2.request);
1501 EXPECT_TRUE(stream2.get());
1502
1503 factory_->OnSessionGoingAway(GetActiveSession(kDefaultDestination));
1504 base::RunLoop().RunUntilIdle();
1505 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
1506 EXPECT_FALSE(HasActiveSession(server2));
1507
1508 TestCompletionCallback callback3;
1509 RequestBuilder builder3(this);
1510 builder3.destination = server2;
1511 builder3.url = GURL(kServer2Url);
1512 builder3.callback = callback3.callback();
1513 EXPECT_EQ(ERR_IO_PENDING, builder3.CallRequest());
1514 EXPECT_THAT(callback3.WaitForResult(), IsOk());
1515 std::unique_ptr<HttpStream> stream3 = CreateStream(&builder3.request);
1516 EXPECT_TRUE(stream3.get());
1517
1518 EXPECT_TRUE(HasActiveSession(server2));
1519
1520 socket_data1.ExpectAllReadDataConsumed();
1521 socket_data1.ExpectAllWriteDataConsumed();
1522 socket_data2.ExpectAllReadDataConsumed();
1523 socket_data2.ExpectAllWriteDataConsumed();
1524 }
1525
TEST_P(QuicSessionPoolTest,HttpsPooling)1526 TEST_P(QuicSessionPoolTest, HttpsPooling) {
1527 Initialize();
1528
1529 MockQuicData socket_data(version_);
1530 socket_data.AddReadPauseForever();
1531 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
1532 socket_data.AddSocketDataToFactory(socket_factory_.get());
1533
1534 url::SchemeHostPort server1(url::kHttpsScheme, kDefaultServerHostName, 443);
1535 url::SchemeHostPort server2(url::kHttpsScheme, kServer2HostName, 443);
1536
1537 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1538 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1539
1540 host_resolver_->set_synchronous_mode(true);
1541 host_resolver_->rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
1542 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
1543
1544 RequestBuilder builder(this);
1545 builder.destination = server1;
1546 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
1547 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1548 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
1549 EXPECT_TRUE(stream.get());
1550
1551 RequestBuilder builder2(this);
1552 builder2.destination = server2;
1553 builder2.url = GURL(kServer2Url);
1554 EXPECT_EQ(OK, builder2.CallRequest());
1555 std::unique_ptr<HttpStream> stream2 = CreateStream(&builder2.request);
1556 EXPECT_TRUE(stream2.get());
1557
1558 EXPECT_EQ(GetActiveSession(server1), GetActiveSession(server2));
1559
1560 socket_data.ExpectAllReadDataConsumed();
1561 socket_data.ExpectAllWriteDataConsumed();
1562 }
1563
TEST_P(QuicSessionPoolTest,HttpsPoolingWithMatchingPins)1564 TEST_P(QuicSessionPoolTest, HttpsPoolingWithMatchingPins) {
1565 Initialize();
1566 MockQuicData socket_data(version_);
1567 socket_data.AddReadPauseForever();
1568 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
1569 socket_data.AddSocketDataToFactory(socket_factory_.get());
1570
1571 url::SchemeHostPort server1(url::kHttpsScheme, kDefaultServerHostName, 443);
1572 url::SchemeHostPort server2(url::kHttpsScheme, kServer2HostName, 443);
1573 transport_security_state_.EnableStaticPinsForTesting();
1574 ScopedTransportSecurityStateSource scoped_security_state_source;
1575
1576 HashValue primary_pin(HASH_VALUE_SHA256);
1577 EXPECT_TRUE(primary_pin.FromString(
1578 "sha256/Nn8jk5By4Vkq6BeOVZ7R7AC6XUUBZsWmUbJR1f1Y5FY="));
1579 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1580 verify_details.cert_verify_result.public_key_hashes.push_back(primary_pin);
1581 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1582
1583 host_resolver_->set_synchronous_mode(true);
1584 host_resolver_->rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
1585 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
1586
1587 RequestBuilder builder(this);
1588 builder.destination = server1;
1589 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
1590 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1591 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
1592 EXPECT_TRUE(stream.get());
1593
1594 RequestBuilder builder2(this);
1595 builder2.destination = server2;
1596 builder2.url = GURL(kServer2Url);
1597 EXPECT_EQ(OK, builder2.CallRequest());
1598 std::unique_ptr<HttpStream> stream2 = CreateStream(&builder2.request);
1599 EXPECT_TRUE(stream2.get());
1600
1601 EXPECT_EQ(GetActiveSession(server1), GetActiveSession(server2));
1602
1603 socket_data.ExpectAllReadDataConsumed();
1604 socket_data.ExpectAllWriteDataConsumed();
1605 }
1606
TEST_P(QuicSessionPoolTest,NoHttpsPoolingWithDifferentPins)1607 TEST_P(QuicSessionPoolTest, NoHttpsPoolingWithDifferentPins) {
1608 base::test::ScopedFeatureList scoped_feature_list;
1609 scoped_feature_list.InitAndEnableFeature(
1610 net::features::kStaticKeyPinningEnforcement);
1611 Initialize();
1612
1613 MockQuicData socket_data1(version_);
1614 socket_data1.AddReadPauseForever();
1615 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
1616 socket_data1.AddSocketDataToFactory(socket_factory_.get());
1617 client_maker_.Reset();
1618 MockQuicData socket_data2(version_);
1619 socket_data2.AddReadPauseForever();
1620 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
1621 socket_data2.AddSocketDataToFactory(socket_factory_.get());
1622
1623 url::SchemeHostPort server1(url::kHttpsScheme, kDefaultServerHostName, 443);
1624 url::SchemeHostPort server2(url::kHttpsScheme, kServer2HostName, 443);
1625 transport_security_state_.EnableStaticPinsForTesting();
1626 transport_security_state_.SetPinningListAlwaysTimelyForTesting(true);
1627 ScopedTransportSecurityStateSource scoped_security_state_source;
1628
1629 ProofVerifyDetailsChromium verify_details1 = DefaultProofVerifyDetails();
1630 uint8_t bad_pin = 3;
1631 verify_details1.cert_verify_result.public_key_hashes.push_back(
1632 test::GetTestHashValue(bad_pin));
1633 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
1634
1635 HashValue primary_pin(HASH_VALUE_SHA256);
1636 EXPECT_TRUE(primary_pin.FromString(
1637 "sha256/Nn8jk5By4Vkq6BeOVZ7R7AC6XUUBZsWmUbJR1f1Y5FY="));
1638 ProofVerifyDetailsChromium verify_details2 = DefaultProofVerifyDetails();
1639 verify_details2.cert_verify_result.public_key_hashes.push_back(primary_pin);
1640 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
1641
1642 host_resolver_->set_synchronous_mode(true);
1643 host_resolver_->rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
1644 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
1645
1646 RequestBuilder builder(this);
1647 builder.destination = server1;
1648 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
1649 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1650 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
1651 EXPECT_TRUE(stream.get());
1652
1653 RequestBuilder builder2(this);
1654 builder2.destination = server2;
1655 builder2.url = GURL(kServer2Url);
1656 EXPECT_EQ(ERR_IO_PENDING, builder2.CallRequest());
1657 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1658 std::unique_ptr<HttpStream> stream2 = CreateStream(&builder2.request);
1659 EXPECT_TRUE(stream2.get());
1660
1661 EXPECT_NE(GetActiveSession(server1), GetActiveSession(server2));
1662
1663 socket_data1.ExpectAllReadDataConsumed();
1664 socket_data1.ExpectAllWriteDataConsumed();
1665 socket_data2.ExpectAllReadDataConsumed();
1666 socket_data2.ExpectAllWriteDataConsumed();
1667 }
1668
TEST_P(QuicSessionPoolTest,Goaway)1669 TEST_P(QuicSessionPoolTest, Goaway) {
1670 Initialize();
1671 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1672 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1673 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1674
1675 MockQuicData socket_data(version_);
1676 socket_data.AddReadPauseForever();
1677 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
1678 socket_data.AddSocketDataToFactory(socket_factory_.get());
1679 client_maker_.Reset();
1680 MockQuicData socket_data2(version_);
1681 socket_data2.AddReadPauseForever();
1682 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
1683 socket_data2.AddSocketDataToFactory(socket_factory_.get());
1684
1685 RequestBuilder builder(this);
1686 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
1687 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1688 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
1689 EXPECT_TRUE(stream.get());
1690
1691 // Mark the session as going away. Ensure that while it is still alive
1692 // that it is no longer active.
1693 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
1694 factory_->OnSessionGoingAway(session);
1695 EXPECT_EQ(true, QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
1696 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
1697
1698 // Create a new request for the same destination and verify that a
1699 // new session is created.
1700 RequestBuilder builder2(this);
1701 EXPECT_EQ(ERR_IO_PENDING, builder2.CallRequest());
1702 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1703 std::unique_ptr<HttpStream> stream2 = CreateStream(&builder2.request);
1704 EXPECT_TRUE(stream2.get());
1705
1706 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
1707 EXPECT_NE(session, GetActiveSession(kDefaultDestination));
1708 EXPECT_EQ(true, QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
1709
1710 stream2.reset();
1711 stream.reset();
1712
1713 socket_data.ExpectAllReadDataConsumed();
1714 socket_data.ExpectAllWriteDataConsumed();
1715 socket_data2.ExpectAllReadDataConsumed();
1716 socket_data2.ExpectAllWriteDataConsumed();
1717 }
1718
TEST_P(QuicSessionPoolTest,MaxOpenStream)1719 TEST_P(QuicSessionPoolTest, MaxOpenStream) {
1720 Initialize();
1721 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1722 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1723
1724 quic::QuicStreamId stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
1725 MockQuicData socket_data(version_);
1726 int packet_num = 1;
1727 socket_data.AddWrite(SYNCHRONOUS,
1728 ConstructInitialSettingsPacket(packet_num++));
1729 socket_data.AddWrite(SYNCHRONOUS, client_maker_.MakeStreamsBlockedPacket(
1730 packet_num++, 50,
1731 /*unidirectional=*/false));
1732 socket_data.AddWrite(SYNCHRONOUS,
1733 client_maker_.MakeDataPacket(
1734 packet_num++, GetQpackDecoderStreamId(), false,
1735 StreamCancellationQpackDecoderInstruction(0)));
1736 socket_data.AddWrite(
1737 SYNCHRONOUS, client_maker_.MakeRstPacket(packet_num++, stream_id,
1738 quic::QUIC_STREAM_CANCELLED));
1739 socket_data.AddRead(ASYNC, server_maker_.MakeRstPacket(
1740 1, stream_id, quic::QUIC_STREAM_CANCELLED));
1741 socket_data.AddRead(
1742 ASYNC, server_maker_.MakeMaxStreamsPacket(2, 52,
1743 /*unidirectional=*/false));
1744 socket_data.AddWrite(SYNCHRONOUS,
1745 client_maker_.MakeAckPacket(packet_num++, 2, 1));
1746 socket_data.AddReadPauseForever();
1747 socket_data.AddSocketDataToFactory(socket_factory_.get());
1748
1749 HttpRequestInfo request_info;
1750 request_info.traffic_annotation =
1751 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1752
1753 std::vector<std::unique_ptr<HttpStream>> streams;
1754 // The MockCryptoClientStream sets max_open_streams to be
1755 // quic::kDefaultMaxStreamsPerConnection / 2.
1756 for (size_t i = 0; i < quic::kDefaultMaxStreamsPerConnection / 2; i++) {
1757 RequestBuilder builder(this);
1758 int rv = builder.CallRequest();
1759 if (i == 0) {
1760 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1761 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1762 } else {
1763 EXPECT_THAT(rv, IsOk());
1764 }
1765 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
1766 EXPECT_TRUE(stream);
1767 stream->RegisterRequest(&request_info);
1768 EXPECT_EQ(OK, stream->InitializeStream(false, DEFAULT_PRIORITY, net_log_,
1769 CompletionOnceCallback()));
1770 streams.push_back(std::move(stream));
1771 }
1772
1773 RequestBuilder builder(this);
1774 builder.callback = CompletionOnceCallback();
1775 EXPECT_EQ(OK, builder.CallRequest());
1776 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
1777 EXPECT_TRUE(stream);
1778 stream->RegisterRequest(&request_info);
1779 EXPECT_EQ(ERR_IO_PENDING,
1780 stream->InitializeStream(false, DEFAULT_PRIORITY, net_log_,
1781 callback_.callback()));
1782
1783 // Close the first stream.
1784 streams.front()->Close(false);
1785 // Trigger exchange of RSTs that in turn allow progress for the last
1786 // stream.
1787 base::RunLoop().RunUntilIdle();
1788 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1789
1790 socket_data.ExpectAllReadDataConsumed();
1791 socket_data.ExpectAllWriteDataConsumed();
1792
1793 // Force close of the connection to suppress the generation of RST
1794 // packets when streams are torn down, which wouldn't be relevant to
1795 // this test anyway.
1796 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
1797 session->connection()->CloseConnection(
1798 quic::QUIC_PUBLIC_RESET, "test",
1799 quic::ConnectionCloseBehavior::SILENT_CLOSE);
1800 }
1801
TEST_P(QuicSessionPoolTest,ResolutionErrorInCreate)1802 TEST_P(QuicSessionPoolTest, ResolutionErrorInCreate) {
1803 Initialize();
1804 MockQuicData socket_data(version_);
1805 socket_data.AddSocketDataToFactory(socket_factory_.get());
1806
1807 host_resolver_->rules()->AddSimulatedFailure(kDefaultServerHostName);
1808
1809 RequestBuilder builder(this);
1810 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
1811 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
1812
1813 socket_data.ExpectAllReadDataConsumed();
1814 socket_data.ExpectAllWriteDataConsumed();
1815 }
1816
1817 // This test uses synchronous QUIC session creation.
TEST_P(QuicSessionPoolTest,SyncConnectErrorInCreate)1818 TEST_P(QuicSessionPoolTest, SyncConnectErrorInCreate) {
1819 base::test::ScopedFeatureList scoped_feature_list;
1820 scoped_feature_list.InitAndDisableFeature(net::features::kAsyncQuicSession);
1821 Initialize();
1822
1823 MockQuicData socket_data(version_);
1824 socket_data.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
1825 socket_data.AddSocketDataToFactory(socket_factory_.get());
1826
1827 RequestBuilder builder(this);
1828 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
1829 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_ADDRESS_IN_USE));
1830
1831 socket_data.ExpectAllReadDataConsumed();
1832 socket_data.ExpectAllWriteDataConsumed();
1833 }
1834
TEST_P(QuicSessionPoolTest,AsyncConnectErrorInCreate)1835 TEST_P(QuicSessionPoolTest, AsyncConnectErrorInCreate) {
1836 Initialize();
1837
1838 MockQuicData socket_data(version_);
1839 socket_data.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
1840 socket_data.AddSocketDataToFactory(socket_factory_.get());
1841
1842 RequestBuilder builder(this);
1843 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
1844 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_ADDRESS_IN_USE));
1845
1846 socket_data.ExpectAllReadDataConsumed();
1847 socket_data.ExpectAllWriteDataConsumed();
1848 }
1849
1850 // This test uses synchronous QUIC session creation.
TEST_P(QuicSessionPoolTest,SyncCancelCreate)1851 TEST_P(QuicSessionPoolTest, SyncCancelCreate) {
1852 base::test::ScopedFeatureList scoped_feature_list;
1853 scoped_feature_list.InitAndDisableFeature(net::features::kAsyncQuicSession);
1854 Initialize();
1855 MockQuicData socket_data(version_);
1856 socket_data.AddReadPauseForever();
1857 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
1858 socket_data.AddSocketDataToFactory(socket_factory_.get());
1859 {
1860 RequestBuilder builder(this);
1861 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
1862 }
1863
1864 base::RunLoop().RunUntilIdle();
1865
1866 RequestBuilder builder2(this);
1867 EXPECT_EQ(OK, builder2.CallRequest());
1868 std::unique_ptr<HttpStream> stream = CreateStream(&builder2.request);
1869
1870 EXPECT_TRUE(stream.get());
1871 stream.reset();
1872
1873 socket_data.ExpectAllReadDataConsumed();
1874 socket_data.ExpectAllWriteDataConsumed();
1875 }
1876
TEST_P(QuicSessionPoolTest,AsyncCancelCreate)1877 TEST_P(QuicSessionPoolTest, AsyncCancelCreate) {
1878 Initialize();
1879 MockQuicData socket_data(version_);
1880 socket_data.AddReadPauseForever();
1881 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
1882 socket_data.AddSocketDataToFactory(socket_factory_.get());
1883 {
1884 RequestBuilder builder(this);
1885 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
1886 }
1887
1888 base::RunLoop().RunUntilIdle();
1889
1890 RequestBuilder builder2(this);
1891 EXPECT_EQ(OK, builder2.CallRequest());
1892 std::unique_ptr<HttpStream> stream = CreateStream(&builder2.request);
1893
1894 EXPECT_TRUE(stream.get());
1895 stream.reset();
1896
1897 socket_data.ExpectAllReadDataConsumed();
1898 socket_data.ExpectAllWriteDataConsumed();
1899 }
1900
TEST_P(QuicSessionPoolTest,CloseAllSessions)1901 TEST_P(QuicSessionPoolTest, CloseAllSessions) {
1902 Initialize();
1903 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1904 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1905 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1906
1907 MockQuicData socket_data(version_);
1908 socket_data.AddReadPauseForever();
1909 int packet_num = 1;
1910 socket_data.AddWrite(SYNCHRONOUS,
1911 ConstructInitialSettingsPacket(packet_num++));
1912 socket_data.AddWrite(
1913 SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
1914 packet_num++, quic::QUIC_PEER_GOING_AWAY, "net error"));
1915 socket_data.AddSocketDataToFactory(socket_factory_.get());
1916
1917 client_maker_.Reset();
1918 MockQuicData socket_data2(version_);
1919 socket_data2.AddReadPauseForever();
1920 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
1921 socket_data2.AddSocketDataToFactory(socket_factory_.get());
1922
1923 RequestBuilder builder(this);
1924 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
1925 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1926 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
1927 HttpRequestInfo request_info;
1928 request_info.traffic_annotation =
1929 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1930 stream->RegisterRequest(&request_info);
1931 EXPECT_EQ(OK, stream->InitializeStream(false, DEFAULT_PRIORITY, net_log_,
1932 CompletionOnceCallback()));
1933
1934 // Close the session and verify that stream saw the error.
1935 factory_->CloseAllSessions(ERR_INTERNET_DISCONNECTED,
1936 quic::QUIC_PEER_GOING_AWAY);
1937 EXPECT_EQ(ERR_INTERNET_DISCONNECTED,
1938 stream->ReadResponseHeaders(callback_.callback()));
1939
1940 // Now attempting to request a stream to the same origin should create
1941 // a new session.
1942
1943 RequestBuilder builder2(this);
1944 EXPECT_EQ(ERR_IO_PENDING, builder2.CallRequest());
1945 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1946 stream = CreateStream(&builder2.request);
1947 stream.reset(); // Will reset stream 3.
1948
1949 socket_data.ExpectAllReadDataConsumed();
1950 socket_data.ExpectAllWriteDataConsumed();
1951 socket_data2.ExpectAllReadDataConsumed();
1952 socket_data2.ExpectAllWriteDataConsumed();
1953 }
1954
1955 // Regression test for crbug.com/700617. Test a write error during the
1956 // crypto handshake will not hang QuicSessionPool::Job and should
1957 // report QUIC_HANDSHAKE_FAILED to upper layers. Subsequent
1958 // QuicSessionRequest should succeed without hanging.
TEST_P(QuicSessionPoolTest,WriteErrorInCryptoConnectWithAsyncHostResolutionSyncSessionCreation)1959 TEST_P(QuicSessionPoolTest,
1960 WriteErrorInCryptoConnectWithAsyncHostResolutionSyncSessionCreation) {
1961 base::test::ScopedFeatureList scoped_feature_list;
1962 scoped_feature_list.InitAndDisableFeature(net::features::kAsyncQuicSession);
1963 Initialize();
1964 // Use unmocked crypto stream to do crypto connect.
1965 crypto_client_stream_factory_.set_handshake_mode(
1966 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
1967
1968 MockQuicData socket_data(version_);
1969 socket_data.AddReadPauseForever();
1970 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
1971 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
1972 socket_data.AddSocketDataToFactory(socket_factory_.get());
1973
1974 // Create request, should fail after the write of the CHLO fails.
1975 RequestBuilder builder(this);
1976 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
1977 EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED, callback_.WaitForResult());
1978 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
1979 EXPECT_FALSE(HasActiveJob(kDefaultDestination, PRIVACY_MODE_DISABLED));
1980
1981 // Verify new requests can be sent normally without hanging.
1982 crypto_client_stream_factory_.set_handshake_mode(
1983 MockCryptoClientStream::COLD_START);
1984 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1985 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1986 client_maker_.Reset();
1987 MockQuicData socket_data2(version_);
1988 socket_data2.AddReadPauseForever();
1989 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
1990 socket_data2.AddSocketDataToFactory(socket_factory_.get());
1991
1992 RequestBuilder builder2(this);
1993 EXPECT_EQ(ERR_IO_PENDING, builder2.CallRequest());
1994 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
1995 EXPECT_TRUE(HasActiveJob(kDefaultDestination, PRIVACY_MODE_DISABLED));
1996 // Run the message loop to complete host resolution.
1997 base::RunLoop().RunUntilIdle();
1998
1999 // Complete handshake. QuicSessionPool::Job should complete and succeed.
2000 crypto_client_stream_factory_.last_stream()
2001 ->NotifySessionOneRttKeyAvailable();
2002 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2003 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
2004 EXPECT_FALSE(HasActiveJob(kDefaultDestination, PRIVACY_MODE_DISABLED));
2005
2006 // Create QuicHttpStream.
2007 std::unique_ptr<HttpStream> stream = CreateStream(&builder2.request);
2008 EXPECT_TRUE(stream.get());
2009 stream.reset();
2010 socket_data.ExpectAllReadDataConsumed();
2011 socket_data.ExpectAllWriteDataConsumed();
2012 socket_data2.ExpectAllReadDataConsumed();
2013 socket_data2.ExpectAllWriteDataConsumed();
2014 }
2015
TEST_P(QuicSessionPoolTest,WriteErrorInCryptoConnectWithAsyncHostResolutionAsyncSessionCreation)2016 TEST_P(QuicSessionPoolTest,
2017 WriteErrorInCryptoConnectWithAsyncHostResolutionAsyncSessionCreation) {
2018 Initialize();
2019 // Use unmocked crypto stream to do crypto connect.
2020 crypto_client_stream_factory_.set_handshake_mode(
2021 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2022
2023 MockQuicData socket_data(version_);
2024 socket_data.AddReadPauseForever();
2025 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
2026 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
2027 socket_data.AddSocketDataToFactory(socket_factory_.get());
2028
2029 // Create request, should fail after the write of the CHLO fails.
2030 RequestBuilder builder(this);
2031 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
2032 EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED, callback_.WaitForResult());
2033 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
2034 EXPECT_FALSE(HasActiveJob(kDefaultDestination, PRIVACY_MODE_DISABLED));
2035
2036 // Verify new requests can be sent normally without hanging.
2037 crypto_client_stream_factory_.set_handshake_mode(
2038 MockCryptoClientStream::COLD_START);
2039 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2040 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2041 client_maker_.Reset();
2042 MockQuicData socket_data2(version_);
2043 socket_data2.AddReadPauseForever();
2044 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
2045 socket_data2.AddSocketDataToFactory(socket_factory_.get());
2046
2047 RequestBuilder builder2(this);
2048 EXPECT_EQ(ERR_IO_PENDING, builder2.CallRequest());
2049 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
2050 EXPECT_TRUE(HasActiveJob(kDefaultDestination, PRIVACY_MODE_DISABLED));
2051 // Run the message loop to complete host resolution.
2052 base::RunLoop().RunUntilIdle();
2053
2054 // Complete handshake. QuicSessionPool::Job should complete and succeed.
2055 crypto_client_stream_factory_.last_stream()
2056 ->NotifySessionOneRttKeyAvailable();
2057 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2058 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
2059 EXPECT_FALSE(HasActiveJob(kDefaultDestination, PRIVACY_MODE_DISABLED));
2060
2061 // Create QuicHttpStream.
2062 std::unique_ptr<HttpStream> stream = CreateStream(&builder2.request);
2063 EXPECT_TRUE(stream.get());
2064 stream.reset();
2065 socket_data.ExpectAllReadDataConsumed();
2066 socket_data.ExpectAllWriteDataConsumed();
2067 socket_data2.ExpectAllReadDataConsumed();
2068 socket_data2.ExpectAllWriteDataConsumed();
2069 }
2070
TEST_P(QuicSessionPoolTest,WriteErrorInCryptoConnectWithSyncHostResolutionSyncQuicSession)2071 TEST_P(QuicSessionPoolTest,
2072 WriteErrorInCryptoConnectWithSyncHostResolutionSyncQuicSession) {
2073 base::test::ScopedFeatureList scoped_feature_list;
2074 scoped_feature_list.InitAndDisableFeature(net::features::kAsyncQuicSession);
2075 Initialize();
2076 // Use unmocked crypto stream to do crypto connect.
2077 crypto_client_stream_factory_.set_handshake_mode(
2078 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2079 host_resolver_->set_synchronous_mode(true);
2080 host_resolver_->rules()->AddIPLiteralRule(kDefaultServerHostName,
2081 "192.168.0.1", "");
2082
2083 MockQuicData socket_data(version_);
2084 socket_data.AddReadPauseForever();
2085 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
2086 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
2087 socket_data.AddSocketDataToFactory(socket_factory_.get());
2088
2089 // Create request, should fail immediately.
2090 RequestBuilder builder(this);
2091 EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED, builder.CallRequest());
2092 // Check no active session, or active jobs left for this server.
2093 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
2094 EXPECT_FALSE(HasActiveJob(kDefaultDestination, PRIVACY_MODE_DISABLED));
2095
2096 // Verify new requests can be sent normally without hanging.
2097 crypto_client_stream_factory_.set_handshake_mode(
2098 MockCryptoClientStream::COLD_START);
2099 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2100 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2101 client_maker_.Reset();
2102 MockQuicData socket_data2(version_);
2103 socket_data2.AddReadPauseForever();
2104 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
2105 socket_data2.AddSocketDataToFactory(socket_factory_.get());
2106
2107 RequestBuilder builder2(this);
2108 EXPECT_EQ(ERR_IO_PENDING, builder2.CallRequest());
2109 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
2110 EXPECT_TRUE(HasActiveJob(kDefaultDestination, PRIVACY_MODE_DISABLED));
2111
2112 base::RunLoop().RunUntilIdle();
2113 // Complete handshake.
2114 crypto_client_stream_factory_.last_stream()
2115 ->NotifySessionOneRttKeyAvailable();
2116 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2117 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
2118 EXPECT_FALSE(HasActiveJob(kDefaultDestination, PRIVACY_MODE_DISABLED));
2119
2120 // Create QuicHttpStream.
2121 std::unique_ptr<HttpStream> stream = CreateStream(&builder2.request);
2122 EXPECT_TRUE(stream.get());
2123 stream.reset();
2124 socket_data.ExpectAllReadDataConsumed();
2125 socket_data.ExpectAllWriteDataConsumed();
2126 socket_data2.ExpectAllReadDataConsumed();
2127 socket_data2.ExpectAllWriteDataConsumed();
2128 }
2129
TEST_P(QuicSessionPoolTest,WriteErrorInCryptoConnectWithSyncHostResolutionAsyncQuicSession)2130 TEST_P(QuicSessionPoolTest,
2131 WriteErrorInCryptoConnectWithSyncHostResolutionAsyncQuicSession) {
2132 Initialize();
2133 // Use unmocked crypto stream to do crypto connect.
2134 crypto_client_stream_factory_.set_handshake_mode(
2135 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2136 host_resolver_->set_synchronous_mode(true);
2137 host_resolver_->rules()->AddIPLiteralRule(kDefaultServerHostName,
2138 "192.168.0.1", "");
2139
2140 MockQuicData socket_data(version_);
2141 socket_data.AddReadPauseForever();
2142 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
2143 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
2144 socket_data.AddSocketDataToFactory(socket_factory_.get());
2145
2146 // Create request, should fail immediately.
2147 RequestBuilder builder(this);
2148 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
2149 EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED, callback_.WaitForResult());
2150 // Check no active session, or active jobs left for this server.
2151 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
2152 EXPECT_FALSE(HasActiveJob(kDefaultDestination, PRIVACY_MODE_DISABLED));
2153
2154 // Verify new requests can be sent normally without hanging.
2155 crypto_client_stream_factory_.set_handshake_mode(
2156 MockCryptoClientStream::COLD_START);
2157 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2158 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2159 client_maker_.Reset();
2160 MockQuicData socket_data2(version_);
2161 socket_data2.AddReadPauseForever();
2162 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
2163 socket_data2.AddSocketDataToFactory(socket_factory_.get());
2164
2165 RequestBuilder builder2(this);
2166 EXPECT_EQ(ERR_IO_PENDING, builder2.CallRequest());
2167 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
2168 EXPECT_TRUE(HasActiveJob(kDefaultDestination, PRIVACY_MODE_DISABLED));
2169
2170 base::RunLoop().RunUntilIdle();
2171 // Complete handshake.
2172 crypto_client_stream_factory_.last_stream()
2173 ->NotifySessionOneRttKeyAvailable();
2174 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2175 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
2176 EXPECT_FALSE(HasActiveJob(kDefaultDestination, PRIVACY_MODE_DISABLED));
2177
2178 // Create QuicHttpStream.
2179 std::unique_ptr<HttpStream> stream = CreateStream(&builder2.request);
2180 EXPECT_TRUE(stream.get());
2181 stream.reset();
2182 socket_data.ExpectAllReadDataConsumed();
2183 socket_data.ExpectAllWriteDataConsumed();
2184 socket_data2.ExpectAllReadDataConsumed();
2185 socket_data2.ExpectAllWriteDataConsumed();
2186 }
2187
2188 // Regression test for crbug.com/1409382. Test that OnCreateSessionComplete()
2189 // will not crash if sessions are closed after FinishCreateSession runs.
TEST_P(QuicSessionPoolTest,CloseSessionDuringCreation)2190 TEST_P(QuicSessionPoolTest, CloseSessionDuringCreation) {
2191 quic_params_->close_sessions_on_ip_change = true;
2192 // close_sessions_on_ip_change == true requires
2193 // migrate_sessions_on_network_change_v2 == false.
2194 quic_params_->migrate_sessions_on_network_change_v2 = false;
2195 auto factory = MockQuicSessionPool(
2196 net_log_.net_log(), host_resolver_.get(), &ssl_config_service_,
2197 socket_factory_.get(), http_server_properties_.get(),
2198 cert_verifier_.get(), &transport_security_state_, proxy_delegate_.get(),
2199 /*sct_auditing_delegate=*/nullptr,
2200 /*SocketPerformanceWatcherFactory*/ nullptr,
2201 &crypto_client_stream_factory_, &context_);
2202
2203 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2204 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2205
2206 MockQuicData socket_data(version_);
2207 socket_data.AddReadPauseForever();
2208 int packet_num = 1;
2209 if (VersionUsesHttp3(version_.transport_version)) {
2210 socket_data.AddWrite(SYNCHRONOUS,
2211 ConstructInitialSettingsPacket(packet_num++));
2212 }
2213 socket_data.AddWrite(
2214 SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
2215 packet_num, quic::QUIC_IP_ADDRESS_CHANGED, "net error"));
2216 socket_data.AddSocketDataToFactory(socket_factory_.get());
2217
2218 RequestBuilder builder(this, &factory);
2219 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
2220
2221 // QuicSessionPool should be notified of IP address change after
2222 // FinishConnectAndConfigureSocket runs FinishCreateSession.
2223 EXPECT_CALL(factory, MockFinishConnectAndConfigureSocket()).WillOnce([] {
2224 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
2225 });
2226
2227 // Session should have been created before the factory is notified of IP
2228 // address change.
2229 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2230 quic::QuicServerId server_id(kDefaultServerHostName, kDefaultServerPort,
2231 false);
2232 EXPECT_TRUE(QuicSessionPoolPeer::HasActiveSession(&factory, server_id,
2233 NetworkAnonymizationKey()));
2234 QuicChromiumClientSession* session = QuicSessionPoolPeer::GetActiveSession(
2235 &factory, server_id, NetworkAnonymizationKey());
2236 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(&factory, session));
2237
2238 base::RunLoop().RunUntilIdle();
2239
2240 // Session should now be closed.
2241 EXPECT_FALSE(QuicSessionPoolPeer::HasActiveSession(
2242 &factory, server_id, NetworkAnonymizationKey()));
2243 }
2244
TEST_P(QuicSessionPoolTest,CloseSessionsOnIPAddressChanged)2245 TEST_P(QuicSessionPoolTest, CloseSessionsOnIPAddressChanged) {
2246 quic_params_->close_sessions_on_ip_change = true;
2247 // close_sessions_on_ip_change == true requires
2248 // migrate_sessions_on_network_change_v2 == false.
2249 quic_params_->migrate_sessions_on_network_change_v2 = false;
2250 Initialize();
2251 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2252 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2253 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2254
2255 MockQuicData socket_data(version_);
2256 socket_data.AddReadPauseForever();
2257 int packet_num = 1;
2258 socket_data.AddWrite(SYNCHRONOUS,
2259 ConstructInitialSettingsPacket(packet_num++));
2260 socket_data.AddWrite(
2261 SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
2262 packet_num, quic::QUIC_IP_ADDRESS_CHANGED, "net error"));
2263 socket_data.AddSocketDataToFactory(socket_factory_.get());
2264
2265 client_maker_.Reset();
2266 MockQuicData socket_data2(version_);
2267 socket_data2.AddReadPauseForever();
2268 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
2269 socket_data2.AddSocketDataToFactory(socket_factory_.get());
2270
2271 RequestBuilder builder(this);
2272 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
2273 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2274 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
2275 HttpRequestInfo request_info;
2276 request_info.traffic_annotation =
2277 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2278 stream->RegisterRequest(&request_info);
2279 EXPECT_EQ(OK, stream->InitializeStream(false, DEFAULT_PRIORITY, net_log_,
2280 CompletionOnceCallback()));
2281
2282 // Check an active session exists for the destination.
2283 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
2284 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
2285 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
2286
2287 EXPECT_TRUE(http_server_properties_->HasLastLocalAddressWhenQuicWorked());
2288 // Change the IP address and verify that stream saw the error and the active
2289 // session is closed.
2290 NotifyIPAddressChanged();
2291 EXPECT_EQ(ERR_NETWORK_CHANGED,
2292 stream->ReadResponseHeaders(callback_.callback()));
2293 EXPECT_FALSE(factory_->is_quic_known_to_work_on_current_network());
2294 EXPECT_FALSE(http_server_properties_->HasLastLocalAddressWhenQuicWorked());
2295 // Check no active session exists for the destination.
2296 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
2297
2298 // Now attempting to request a stream to the same origin should create
2299 // a new session.
2300 RequestBuilder builder2(this);
2301 EXPECT_EQ(ERR_IO_PENDING, builder2.CallRequest());
2302 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2303 stream = CreateStream(&builder2.request);
2304
2305 // Check a new active session exists for the destination and the old session
2306 // is no longer live.
2307 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
2308 QuicChromiumClientSession* session2 = GetActiveSession(kDefaultDestination);
2309 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session2));
2310
2311 stream.reset(); // Will reset stream 3.
2312 socket_data.ExpectAllReadDataConsumed();
2313 socket_data.ExpectAllWriteDataConsumed();
2314 socket_data2.ExpectAllReadDataConsumed();
2315 socket_data2.ExpectAllWriteDataConsumed();
2316 }
2317
2318 // Test that if goaway_session_on_ip_change is set, old sessions will be marked
2319 // as going away on IP address change instead of being closed. New requests will
2320 // go to a new connection.
TEST_P(QuicSessionPoolTest,GoAwaySessionsOnIPAddressChanged)2321 TEST_P(QuicSessionPoolTest, GoAwaySessionsOnIPAddressChanged) {
2322 quic_params_->goaway_sessions_on_ip_change = true;
2323 // close_sessions_on_ip_change == true requires
2324 // migrate_sessions_on_network_change_v2 == false.
2325 quic_params_->migrate_sessions_on_network_change_v2 = false;
2326 Initialize();
2327 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2328 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2329 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2330
2331 MockQuicData quic_data1(version_);
2332 int packet_num = 1;
2333 quic_data1.AddWrite(SYNCHRONOUS,
2334 ConstructInitialSettingsPacket(packet_num++));
2335 quic_data1.AddWrite(
2336 SYNCHRONOUS,
2337 ConstructGetRequestPacket(
2338 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true));
2339 quic_data1.AddReadPause();
2340 quic_data1.AddRead(
2341 ASYNC, ConstructOkResponsePacket(
2342 1, GetNthClientInitiatedBidirectionalStreamId(0), true));
2343 quic_data1.AddReadPauseForever();
2344 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2345
2346 client_maker_.Reset();
2347 MockQuicData quic_data2(version_);
2348 quic_data2.AddReadPauseForever();
2349 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
2350 quic_data2.AddSocketDataToFactory(socket_factory_.get());
2351
2352 // Create request and QuicHttpStream.
2353 RequestBuilder builder(this);
2354 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
2355 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2356 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
2357 EXPECT_TRUE(stream.get());
2358
2359 // Cause QUIC stream to be created.
2360 HttpRequestInfo request_info;
2361 request_info.method = "GET";
2362 request_info.url = GURL(kDefaultUrl);
2363 request_info.traffic_annotation =
2364 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2365 stream->RegisterRequest(&request_info);
2366 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
2367 CompletionOnceCallback()));
2368
2369 // Ensure that session is alive and active.
2370 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
2371 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
2372 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
2373
2374 // Send GET request on stream.
2375 HttpResponseInfo response;
2376 HttpRequestHeaders request_headers;
2377 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
2378 callback_.callback()));
2379
2380 // Receive an IP address change notification.
2381 NotifyIPAddressChanged();
2382
2383 // The connection should still be alive, but marked as going away.
2384 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
2385 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
2386 EXPECT_EQ(1u, session->GetNumActiveStreams());
2387
2388 // Resume the data, response should be read from the original connection.
2389 quic_data1.Resume();
2390 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
2391 EXPECT_EQ(200, response.headers->response_code());
2392 EXPECT_EQ(0u, session->GetNumActiveStreams());
2393
2394 // Second request should be sent on a new connection.
2395 RequestBuilder builder2(this);
2396 EXPECT_EQ(ERR_IO_PENDING, builder2.CallRequest());
2397 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2398 std::unique_ptr<HttpStream> stream2 = CreateStream(&builder2.request);
2399 EXPECT_TRUE(stream2.get());
2400
2401 // Check an active session exists for the destination.
2402 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
2403 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
2404 QuicChromiumClientSession* session2 = GetActiveSession(kDefaultDestination);
2405 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session2));
2406
2407 stream.reset();
2408 stream2.reset();
2409 quic_data1.ExpectAllReadDataConsumed();
2410 quic_data1.ExpectAllWriteDataConsumed();
2411 quic_data2.ExpectAllReadDataConsumed();
2412 quic_data2.ExpectAllWriteDataConsumed();
2413 }
2414
TEST_P(QuicSessionPoolTest,OnIPAddressChangedWithConnectionMigration)2415 TEST_P(QuicSessionPoolTest, OnIPAddressChangedWithConnectionMigration) {
2416 InitializeConnectionMigrationV2Test(
2417 {kDefaultNetworkForTests, kNewNetworkForTests});
2418 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2419 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2420 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2421
2422 MockQuicData socket_data(version_);
2423 socket_data.AddReadPauseForever();
2424 int packet_num = 1;
2425 socket_data.AddWrite(SYNCHRONOUS,
2426 ConstructInitialSettingsPacket(packet_num++));
2427 socket_data.AddWrite(SYNCHRONOUS,
2428 client_maker_.MakeDataPacket(
2429 packet_num++, GetQpackDecoderStreamId(), false,
2430 StreamCancellationQpackDecoderInstruction(0)));
2431 socket_data.AddWrite(
2432 SYNCHRONOUS,
2433 ConstructClientRstPacket(packet_num, quic::QUIC_STREAM_CANCELLED));
2434 socket_data.AddSocketDataToFactory(socket_factory_.get());
2435
2436 RequestBuilder builder(this);
2437 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
2438 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2439 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
2440 HttpRequestInfo request_info;
2441 request_info.traffic_annotation =
2442 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2443 stream->RegisterRequest(&request_info);
2444 EXPECT_EQ(OK, stream->InitializeStream(false, DEFAULT_PRIORITY, net_log_,
2445 CompletionOnceCallback()));
2446
2447 EXPECT_TRUE(http_server_properties_->HasLastLocalAddressWhenQuicWorked());
2448
2449 // Change the IP address and verify that the connection is unaffected.
2450 NotifyIPAddressChanged();
2451 EXPECT_TRUE(factory_->is_quic_known_to_work_on_current_network());
2452 EXPECT_TRUE(http_server_properties_->HasLastLocalAddressWhenQuicWorked());
2453
2454 // Attempting a new request to the same origin uses the same connection.
2455 RequestBuilder builder2(this);
2456 EXPECT_EQ(OK, builder2.CallRequest());
2457 stream = CreateStream(&builder2.request);
2458
2459 stream.reset();
2460 socket_data.ExpectAllReadDataConsumed();
2461 socket_data.ExpectAllWriteDataConsumed();
2462 }
2463
TEST_P(QuicSessionPoolTest,MigrateOnNetworkMadeDefaultWithSynchronousWrite)2464 TEST_P(QuicSessionPoolTest, MigrateOnNetworkMadeDefaultWithSynchronousWrite) {
2465 TestMigrationOnNetworkMadeDefault(SYNCHRONOUS);
2466 }
2467
TEST_P(QuicSessionPoolTest,MigrateOnNetworkMadeDefaultWithAsyncWrite)2468 TEST_P(QuicSessionPoolTest, MigrateOnNetworkMadeDefaultWithAsyncWrite) {
2469 TestMigrationOnNetworkMadeDefault(ASYNC);
2470 }
2471
2472 // Sets up a test which attempts connection migration successfully after probing
2473 // when a new network is made as default and the old default is still available.
2474 // |write_mode| specifies the write mode for the last write before
2475 // OnNetworkMadeDefault is delivered to session.
TestMigrationOnNetworkMadeDefault(IoMode write_mode)2476 void QuicSessionPoolTest::TestMigrationOnNetworkMadeDefault(IoMode write_mode) {
2477 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
2478 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2479 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2480 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2481 client_maker_.set_save_packet_frames(true);
2482
2483 // Using a testing task runner so that we can control time.
2484 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
2485 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
2486
2487 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2488 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
2489
2490 MockQuicData quic_data1(version_);
2491 quic_data1.AddReadPauseForever();
2492 int packet_num = 1;
2493 quic_data1.AddWrite(SYNCHRONOUS,
2494 ConstructInitialSettingsPacket(packet_num++));
2495 quic_data1.AddWrite(
2496 write_mode,
2497 ConstructGetRequestPacket(
2498 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true));
2499 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2500
2501 // Set up the second socket data provider that is used after migration.
2502 // The response to the earlier request is read on the new socket.
2503 quic::QuicConnectionId cid_on_new_path =
2504 quic::test::TestConnectionId(12345678);
2505 client_maker_.set_connection_id(cid_on_new_path);
2506 MockQuicData quic_data2(version_);
2507 // Connectivity probe to be sent on the new path.
2508 quic_data2.AddWrite(
2509 SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(packet_num++));
2510 quic_data2.AddReadPause();
2511 // Connectivity probe to receive from the server.
2512 quic_data2.AddRead(ASYNC, server_maker_.MakeConnectivityProbingPacket(1));
2513 // in-flight SETTINGS and requests will be retransmitted. Since data is
2514 // already sent on the new address, ping will no longer be sent.
2515 quic_data2.AddWrite(ASYNC,
2516 client_maker_.MakeCombinedRetransmissionPacket(
2517 /*original_packet_numbers=*/{1, 2}, packet_num++));
2518 quic_data2.AddRead(
2519 ASYNC, ConstructOkResponsePacket(
2520 2, GetNthClientInitiatedBidirectionalStreamId(0), false));
2521 quic_data2.AddReadPauseForever();
2522 quic_data2.AddWrite(SYNCHRONOUS,
2523 client_maker_.MakeAckAndDataPacket(
2524 packet_num++, GetQpackDecoderStreamId(), 2, 2, false,
2525 StreamCancellationQpackDecoderInstruction(0)));
2526 quic_data2.AddWrite(
2527 SYNCHRONOUS,
2528 client_maker_.MakeRstPacket(packet_num++,
2529 GetNthClientInitiatedBidirectionalStreamId(0),
2530 quic::QUIC_STREAM_CANCELLED));
2531 quic_data2.AddSocketDataToFactory(socket_factory_.get());
2532
2533 // Create request and QuicHttpStream.
2534 RequestBuilder builder(this);
2535 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
2536 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2537 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
2538 EXPECT_TRUE(stream.get());
2539
2540 // Cause QUIC stream to be created.
2541 HttpRequestInfo request_info;
2542 request_info.method = "GET";
2543 request_info.url = GURL(kDefaultUrl);
2544 request_info.traffic_annotation =
2545 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2546 stream->RegisterRequest(&request_info);
2547 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
2548 CompletionOnceCallback()));
2549
2550 // Ensure that session is alive and active.
2551 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
2552 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
2553 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
2554 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
2555
2556 // Send GET request on stream.
2557 HttpResponseInfo response;
2558 HttpRequestHeaders request_headers;
2559 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
2560 callback_.callback()));
2561
2562 // Deliver a signal that a alternate network is connected now, this should
2563 // cause the connection to start early migration on path degrading.
2564 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2565 ->SetConnectedNetworksList(
2566 {kDefaultNetworkForTests, kNewNetworkForTests});
2567 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2568 ->NotifyNetworkConnected(kNewNetworkForTests);
2569
2570 // Cause the connection to report path degrading to the session.
2571 // Due to lack of alternate network, session will not migrate connection.
2572 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2573 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2574
2575 // A task was posted to migrate to the new default network. Execute that task.
2576 task_runner->RunUntilIdle();
2577
2578 // The connection should still be alive, and not marked as going away.
2579 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
2580 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
2581 EXPECT_EQ(1u, session->GetNumActiveStreams());
2582 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
2583
2584 // Resume quic data and a connectivity probe response will be read on the new
2585 // socket, declare probing as successful. And a new task to WriteToNewSocket
2586 // will be posted to complete migration.
2587 quic_data2.Resume();
2588
2589 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
2590 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
2591 EXPECT_EQ(1u, session->GetNumActiveStreams());
2592
2593 // There should be a task that will complete the migration to the new network.
2594 task_runner->RunUntilIdle();
2595
2596 // Response headers are received over the new network.
2597 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2598 EXPECT_EQ(200, response.headers->response_code());
2599
2600 // Verify that the session is still alive.
2601 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
2602 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
2603
2604 stream.reset();
2605 quic_data1.ExpectAllReadDataConsumed();
2606 quic_data1.ExpectAllWriteDataConsumed();
2607 quic_data2.ExpectAllReadDataConsumed();
2608 quic_data2.ExpectAllWriteDataConsumed();
2609 }
2610
2611 // Regression test for http://859674.
2612 // This test veries that a writer will not attempt to write packets until being
2613 // unblocked on both socket level and network level. In this test, a probing
2614 // writer is used to send two connectivity probes to the peer: where the first
2615 // one completes successfully, while a connectivity response is received before
2616 // completes sending the second one. The connection migration attempt will
2617 // proceed while the probing writer is blocked at the socket level, which will
2618 // block the writer on the network level. Once connection migration completes
2619 // successfully, the probing writer will be unblocked on the network level, it
2620 // will not attempt to write new packets until the socket level is unblocked.
TEST_P(QuicSessionPoolTest,MigratedToBlockedSocketAfterProbing)2621 TEST_P(QuicSessionPoolTest, MigratedToBlockedSocketAfterProbing) {
2622 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
2623 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2624 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2625 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2626 client_maker_.set_save_packet_frames(true);
2627
2628 // Using a testing task runner so that we can control time.
2629 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
2630 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
2631
2632 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2633 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
2634
2635 MockQuicData quic_data1(version_);
2636 quic_data1.AddReadPauseForever();
2637 int packet_num = 1;
2638 quic_data1.AddWrite(SYNCHRONOUS,
2639 ConstructInitialSettingsPacket(packet_num++));
2640 quic_data1.AddWrite(
2641 SYNCHRONOUS,
2642 ConstructGetRequestPacket(
2643 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true));
2644 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2645
2646 // Set up the second socket data provider that is used after migration.
2647 // The response to the earlier request is read on the new socket.
2648 quic::QuicConnectionId cid_on_new_path =
2649 quic::test::TestConnectionId(12345678);
2650 client_maker_.set_connection_id(cid_on_new_path);
2651 MockQuicData quic_data2(version_);
2652 // First connectivity probe to be sent on the new path.
2653 quic_data2.AddWrite(
2654 SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(packet_num++));
2655 quic_data2.AddRead(ASYNC,
2656 ERR_IO_PENDING); // Pause so that we can control time.
2657 // Connectivity probe to receive from the server.
2658 quic_data2.AddRead(ASYNC, server_maker_.MakeConnectivityProbingPacket(1));
2659 // Second connectivity probe which will complete asynchronously.
2660 quic_data2.AddWrite(
2661 ASYNC, client_maker_.MakeConnectivityProbingPacket(packet_num++));
2662 quic_data2.AddRead(
2663 ASYNC, ConstructOkResponsePacket(
2664 2, GetNthClientInitiatedBidirectionalStreamId(0), false));
2665 quic_data2.AddReadPauseForever();
2666
2667 quic_data2.AddWrite(ASYNC,
2668 client_maker_.MakeCombinedRetransmissionPacket(
2669 /*original_packet_numbers=*/{1, 2}, packet_num++));
2670 quic_data2.AddWrite(
2671 SYNCHRONOUS,
2672 client_maker_.MakeAckAndRetireConnectionIdPacket(packet_num++, 2, 1, 0u));
2673 quic_data2.AddWrite(SYNCHRONOUS,
2674 client_maker_.MakeDataPacket(
2675 packet_num++, GetQpackDecoderStreamId(), false,
2676 StreamCancellationQpackDecoderInstruction(0)));
2677 quic_data2.AddWrite(
2678 SYNCHRONOUS,
2679 client_maker_.MakeRstPacket(packet_num++,
2680 GetNthClientInitiatedBidirectionalStreamId(0),
2681 quic::QUIC_STREAM_CANCELLED));
2682
2683 quic_data2.AddSocketDataToFactory(socket_factory_.get());
2684
2685 // Create request and QuicHttpStream.
2686 RequestBuilder builder(this);
2687 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
2688 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2689 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
2690 EXPECT_TRUE(stream.get());
2691
2692 // Cause QUIC stream to be created.
2693 HttpRequestInfo request_info;
2694 request_info.method = "GET";
2695 request_info.url = GURL(kDefaultUrl);
2696 request_info.traffic_annotation =
2697 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2698 stream->RegisterRequest(&request_info);
2699 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
2700 CompletionOnceCallback()));
2701
2702 // Ensure that session is alive and active.
2703 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
2704 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
2705 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
2706 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
2707
2708 // Send GET request on stream.
2709 HttpResponseInfo response;
2710 HttpRequestHeaders request_headers;
2711 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
2712 callback_.callback()));
2713
2714 // Deliver a signal that a alternate network is connected now, this should
2715 // cause the connection to start early migration on path degrading.
2716 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2717 ->SetConnectedNetworksList(
2718 {kDefaultNetworkForTests, kNewNetworkForTests});
2719 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2720 ->NotifyNetworkConnected(kNewNetworkForTests);
2721
2722 // Cause the connection to report path degrading to the session.
2723 // Due to lack of alternate network, session will not mgirate connection.
2724 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2725 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2726
2727 // A task was posted to migrate to the new default network. Execute that task.
2728 task_runner->RunUntilIdle();
2729
2730 // Manually trigger retransmission of PATH_CHALLENGE.
2731 auto* path_validator =
2732 quic::test::QuicConnectionPeer::path_validator(session->connection());
2733 quic::test::QuicPathValidatorPeer::retry_timer(path_validator)->Cancel();
2734 path_validator->OnRetryTimeout();
2735
2736 // Resume quic data and a connectivity probe response will be read on the new
2737 // socket, declare probing as successful.
2738 quic_data2.Resume();
2739
2740 // The connection should still be alive, and not marked as going away.
2741 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
2742 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
2743 EXPECT_EQ(1u, session->GetNumActiveStreams());
2744 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
2745
2746 // There should be a task that will complete the migration to the new network.
2747 task_runner->RunUntilIdle();
2748
2749 // Response headers are received over the new network.
2750 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2751 EXPECT_EQ(200, response.headers->response_code());
2752
2753 // Run the message loop to complete the asynchronous write of ack and ping.
2754 base::RunLoop().RunUntilIdle();
2755
2756 // Verify that the session is still alive.
2757 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
2758 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
2759
2760 stream.reset();
2761 quic_data1.ExpectAllReadDataConsumed();
2762 quic_data1.ExpectAllWriteDataConsumed();
2763 quic_data2.ExpectAllReadDataConsumed();
2764 quic_data2.ExpectAllWriteDataConsumed();
2765 }
2766
2767 // This test verifies that session times out connection migration attempt
2768 // with signals delivered in the following order (no alternate network is
2769 // available):
2770 // - default network disconnected is delivered: session attempts connection
2771 // migration but found not alternate network. Session waits for a new network
2772 // comes up in the next kWaitTimeForNewNetworkSecs seconds.
2773 // - no new network is connected, migration times out. Session is closed.
TEST_P(QuicSessionPoolTest,MigrationTimeoutWithNoNewNetwork)2774 TEST_P(QuicSessionPoolTest, MigrationTimeoutWithNoNewNetwork) {
2775 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
2776 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2777 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2778
2779 // Using a testing task runner so that we can control time.
2780 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
2781 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
2782
2783 MockQuicData socket_data(version_);
2784 socket_data.AddReadPauseForever();
2785 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
2786 socket_data.AddSocketDataToFactory(socket_factory_.get());
2787
2788 // Create request and QuicHttpStream.
2789 RequestBuilder builder(this);
2790 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
2791 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2792 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
2793 EXPECT_TRUE(stream.get());
2794
2795 // Cause QUIC stream to be created.
2796 HttpRequestInfo request_info;
2797 request_info.traffic_annotation =
2798 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2799 stream->RegisterRequest(&request_info);
2800 EXPECT_EQ(OK, stream->InitializeStream(false, DEFAULT_PRIORITY, net_log_,
2801 CompletionOnceCallback()));
2802
2803 // Ensure that session is alive and active.
2804 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
2805 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
2806 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
2807
2808 // Trigger connection migration. Since there are no networks
2809 // to migrate to, this should cause the session to wait for a new network.
2810 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2811 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
2812
2813 // The migration will not fail until the migration alarm timeout.
2814 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
2815 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
2816 EXPECT_EQ(1u, session->GetNumActiveStreams());
2817 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
2818 EXPECT_EQ(true, session->connection()->writer()->IsWriteBlocked());
2819
2820 // Migration will be timed out after kWaitTimeForNewNetwokSecs.
2821 task_runner->FastForwardBy(base::Seconds(kWaitTimeForNewNetworkSecs));
2822
2823 // The connection should now be closed. A request for response
2824 // headers should fail.
2825 EXPECT_FALSE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
2826 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
2827 EXPECT_EQ(ERR_INTERNET_DISCONNECTED, callback_.WaitForResult());
2828
2829 socket_data.ExpectAllReadDataConsumed();
2830 socket_data.ExpectAllWriteDataConsumed();
2831 }
2832
2833 // This test verifies that connectivity probes will be sent even if there is
2834 // a non-migratable stream. However, when connection migrates to the
2835 // successfully probed path, any non-migratable streams will be reset.
TEST_P(QuicSessionPoolTest,OnNetworkMadeDefaultNonMigratableStream_MigrateIdleSessions)2836 TEST_P(QuicSessionPoolTest,
2837 OnNetworkMadeDefaultNonMigratableStream_MigrateIdleSessions) {
2838 TestOnNetworkMadeDefaultNonMigratableStream(true);
2839 }
2840
2841 // This test verifies that connectivity probes will be sent even if there is
2842 // a non-migratable stream. However, when connection migrates to the
2843 // successfully probed path, any non-migratable stream will be reset. And if
2844 // the connection becomes idle then, close the connection.
TEST_P(QuicSessionPoolTest,OnNetworkMadeDefaultNonMigratableStream_DoNotMigrateIdleSessions)2845 TEST_P(QuicSessionPoolTest,
2846 OnNetworkMadeDefaultNonMigratableStream_DoNotMigrateIdleSessions) {
2847 TestOnNetworkMadeDefaultNonMigratableStream(false);
2848 }
2849
TestOnNetworkMadeDefaultNonMigratableStream(bool migrate_idle_sessions)2850 void QuicSessionPoolTest::TestOnNetworkMadeDefaultNonMigratableStream(
2851 bool migrate_idle_sessions) {
2852 quic_params_->migrate_idle_sessions = migrate_idle_sessions;
2853 InitializeConnectionMigrationV2Test(
2854 {kDefaultNetworkForTests, kNewNetworkForTests});
2855 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2856 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2857 client_maker_.set_save_packet_frames(true);
2858
2859 MockQuicData socket_data(version_);
2860 socket_data.AddReadPauseForever();
2861 int packet_num = 1;
2862 socket_data.AddWrite(SYNCHRONOUS,
2863 ConstructInitialSettingsPacket(packet_num++));
2864
2865 // Set up the second socket data provider that is used for probing.
2866 quic::QuicConnectionId cid_on_old_path =
2867 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator());
2868 quic::QuicConnectionId cid_on_new_path =
2869 quic::test::TestConnectionId(12345678);
2870 client_maker_.set_connection_id(cid_on_new_path);
2871 MockQuicData quic_data1(version_);
2872 // Connectivity probe to be sent on the new path.
2873 quic_data1.AddWrite(
2874 SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(packet_num++));
2875 quic_data1.AddReadPause();
2876 // Connectivity probe to receive from the server.
2877 quic_data1.AddRead(ASYNC, server_maker_.MakeConnectivityProbingPacket(1));
2878
2879 if (migrate_idle_sessions) {
2880 quic_data1.AddReadPauseForever();
2881 // A RESET will be sent to the peer to cancel the non-migratable stream.
2882 quic_data1.AddWrite(SYNCHRONOUS,
2883 client_maker_.MakeDataAndRstPacket(
2884 packet_num++, GetQpackDecoderStreamId(),
2885 StreamCancellationQpackDecoderInstruction(0),
2886 GetNthClientInitiatedBidirectionalStreamId(0),
2887 quic::QUIC_STREAM_CANCELLED));
2888 quic_data1.AddWrite(
2889 SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(1, packet_num++));
2890 // Ping packet to send after migration is completed.
2891 quic_data1.AddWrite(SYNCHRONOUS,
2892 client_maker_.MakePingPacket(packet_num++));
2893 quic_data1.AddWrite(SYNCHRONOUS, client_maker_.MakeRetireConnectionIdPacket(
2894 packet_num++, 0u));
2895 } else {
2896 client_maker_.set_connection_id(cid_on_old_path);
2897 socket_data.AddWrite(
2898 SYNCHRONOUS, client_maker_.MakeDataRstAckAndConnectionClosePacket(
2899 packet_num++, GetQpackDecoderStreamId(),
2900 StreamCancellationQpackDecoderInstruction(0),
2901 GetNthClientInitiatedBidirectionalStreamId(0),
2902 quic::QUIC_STREAM_CANCELLED, 1, 1,
2903 quic::QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS,
2904 "net error", /*path_response_frame*/ 0x1b));
2905 }
2906
2907 socket_data.AddSocketDataToFactory(socket_factory_.get());
2908 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2909
2910 // Create request and QuicHttpStream.
2911 RequestBuilder builder(this);
2912 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
2913 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2914 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
2915 EXPECT_TRUE(stream.get());
2916
2917 // Cause QUIC stream to be created, but marked as non-migratable.
2918 HttpRequestInfo request_info;
2919 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
2920 request_info.traffic_annotation =
2921 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2922 stream->RegisterRequest(&request_info);
2923 EXPECT_EQ(OK, stream->InitializeStream(false, DEFAULT_PRIORITY, net_log_,
2924 CompletionOnceCallback()));
2925
2926 // Ensure that session is alive and active.
2927 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
2928 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
2929 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
2930 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
2931
2932 // Trigger connection migration. Session will start to probe the alternative
2933 // network. Although there is a non-migratable stream, session will still be
2934 // active until probing is declared as successful.
2935 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2936 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2937
2938 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
2939 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
2940 EXPECT_EQ(1u, session->GetNumActiveStreams());
2941
2942 // Resume data to read a connectivity probing response, which will cause
2943 // non-migtable streams to be closed.
2944 quic_data1.Resume();
2945 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
2946 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(kDefaultDestination));
2947 EXPECT_EQ(0u, session->GetNumActiveStreams());
2948
2949 base::RunLoop().RunUntilIdle();
2950
2951 quic_data1.ExpectAllReadDataConsumed();
2952 quic_data1.ExpectAllWriteDataConsumed();
2953 socket_data.ExpectAllReadDataConsumed();
2954 socket_data.ExpectAllWriteDataConsumed();
2955 }
2956
TEST_P(QuicSessionPoolTest,OnNetworkMadeDefaultConnectionMigrationDisabled)2957 TEST_P(QuicSessionPoolTest, OnNetworkMadeDefaultConnectionMigrationDisabled) {
2958 InitializeConnectionMigrationV2Test(
2959 {kDefaultNetworkForTests, kNewNetworkForTests});
2960 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2961 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2962
2963 MockQuicData socket_data(version_);
2964 socket_data.AddReadPauseForever();
2965 int packet_num = 1;
2966 socket_data.AddWrite(SYNCHRONOUS,
2967 ConstructInitialSettingsPacket(packet_num++));
2968 socket_data.AddWrite(SYNCHRONOUS,
2969 client_maker_.MakeDataPacket(
2970 packet_num++, GetQpackDecoderStreamId(), false,
2971 StreamCancellationQpackDecoderInstruction(0)));
2972 socket_data.AddWrite(
2973 SYNCHRONOUS,
2974 client_maker_.MakeRstPacket(packet_num++,
2975 GetNthClientInitiatedBidirectionalStreamId(0),
2976 quic::QUIC_STREAM_CANCELLED));
2977 socket_data.AddSocketDataToFactory(socket_factory_.get());
2978
2979 // Create request and QuicHttpStream.
2980 RequestBuilder builder(this);
2981 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
2982 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2983 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
2984 EXPECT_TRUE(stream.get());
2985
2986 // Cause QUIC stream to be created.
2987 HttpRequestInfo request_info;
2988 request_info.traffic_annotation =
2989 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2990 stream->RegisterRequest(&request_info);
2991 EXPECT_EQ(OK, stream->InitializeStream(false, DEFAULT_PRIORITY, net_log_,
2992 CompletionOnceCallback()));
2993
2994 // Ensure that session is alive and active.
2995 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
2996 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
2997 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
2998
2999 // Set session config to have connection migration disabled.
3000 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
3001 session->config());
3002 EXPECT_TRUE(session->config()->DisableConnectionMigration());
3003
3004 // Trigger connection migration. Since there is a non-migratable stream,
3005 // this should cause session to continue but be marked as going away.
3006 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3007 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3008
3009 base::RunLoop().RunUntilIdle();
3010 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
3011 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
3012 EXPECT_EQ(1u, session->GetNumActiveStreams());
3013
3014 stream.reset();
3015
3016 socket_data.ExpectAllReadDataConsumed();
3017 socket_data.ExpectAllWriteDataConsumed();
3018 }
3019
TEST_P(QuicSessionPoolTest,OnNetworkDisconnectedNonMigratableStream_DoNotMigrateIdleSessions)3020 TEST_P(QuicSessionPoolTest,
3021 OnNetworkDisconnectedNonMigratableStream_DoNotMigrateIdleSessions) {
3022 TestOnNetworkDisconnectedNonMigratableStream(false);
3023 }
3024
TEST_P(QuicSessionPoolTest,OnNetworkDisconnectedNonMigratableStream_MigrateIdleSessions)3025 TEST_P(QuicSessionPoolTest,
3026 OnNetworkDisconnectedNonMigratableStream_MigrateIdleSessions) {
3027 TestOnNetworkDisconnectedNonMigratableStream(true);
3028 }
3029
TestOnNetworkDisconnectedNonMigratableStream(bool migrate_idle_sessions)3030 void QuicSessionPoolTest::TestOnNetworkDisconnectedNonMigratableStream(
3031 bool migrate_idle_sessions) {
3032 quic_params_->migrate_idle_sessions = migrate_idle_sessions;
3033 InitializeConnectionMigrationV2Test(
3034 {kDefaultNetworkForTests, kNewNetworkForTests});
3035 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3036 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3037 client_maker_.set_save_packet_frames(true);
3038
3039 MockQuicData failed_socket_data(version_);
3040 quic::QuicConnectionId cid_on_old_path =
3041 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator());
3042 quic::QuicConnectionId cid_on_new_path =
3043 quic::test::TestConnectionId(12345678);
3044 MockQuicData socket_data(version_);
3045 if (migrate_idle_sessions) {
3046 failed_socket_data.AddReadPauseForever();
3047 int packet_num = 1;
3048 failed_socket_data.AddWrite(SYNCHRONOUS,
3049 ConstructInitialSettingsPacket(packet_num++));
3050 // A RESET will be sent to the peer to cancel the non-migratable stream.
3051 failed_socket_data.AddWrite(
3052 SYNCHRONOUS, client_maker_.MakeDataPacket(
3053 packet_num++, GetQpackDecoderStreamId(), false,
3054 StreamCancellationQpackDecoderInstruction(0)));
3055 failed_socket_data.AddWrite(
3056 SYNCHRONOUS,
3057 client_maker_.MakeRstPacket(
3058 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
3059 quic::QUIC_STREAM_CANCELLED));
3060 failed_socket_data.AddSocketDataToFactory(socket_factory_.get());
3061
3062 // Set up second socket data provider that is used after migration.
3063 client_maker_.set_connection_id(cid_on_new_path);
3064 socket_data.AddReadPauseForever();
3065 socket_data.AddWrite(SYNCHRONOUS,
3066 client_maker_.MakeCombinedRetransmissionPacket(
3067 {3, 1, 2}, packet_num++));
3068 // Ping packet to send after migration.
3069 socket_data.AddWrite(SYNCHRONOUS,
3070 client_maker_.MakePingPacket(packet_num++));
3071 socket_data.AddWrite(
3072 SYNCHRONOUS,
3073 client_maker_.MakeRetireConnectionIdPacket(packet_num++, 0u));
3074 socket_data.AddSocketDataToFactory(socket_factory_.get());
3075 } else {
3076 socket_data.AddReadPauseForever();
3077 int packet_num = 1;
3078 socket_data.AddWrite(SYNCHRONOUS,
3079 ConstructInitialSettingsPacket(packet_num++));
3080 socket_data.AddWrite(SYNCHRONOUS,
3081 client_maker_.MakeDataPacket(
3082 packet_num++, GetQpackDecoderStreamId(), false,
3083 StreamCancellationQpackDecoderInstruction(0)));
3084 socket_data.AddWrite(
3085 SYNCHRONOUS,
3086 client_maker_.MakeRstPacket(
3087 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
3088 quic::QUIC_STREAM_CANCELLED));
3089 socket_data.AddSocketDataToFactory(socket_factory_.get());
3090 }
3091
3092 // Create request and QuicHttpStream.
3093 RequestBuilder builder(this);
3094 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
3095 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3096 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
3097 EXPECT_TRUE(stream.get());
3098
3099 // Cause QUIC stream to be created, but marked as non-migratable.
3100 HttpRequestInfo request_info;
3101 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
3102 request_info.traffic_annotation =
3103 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3104 stream->RegisterRequest(&request_info);
3105 EXPECT_EQ(OK, stream->InitializeStream(false, DEFAULT_PRIORITY, net_log_,
3106 CompletionOnceCallback()));
3107
3108 // Ensure that session is alive and active.
3109 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
3110 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
3111 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
3112 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
3113
3114 // Trigger connection migration. Since there is a non-migratable stream,
3115 // this should cause a RST_STREAM frame to be emitted with
3116 // quic::QUIC_STREAM_CANCELLED error code.
3117 // If migrate idle session, the connection will then be migrated to the
3118 // alternate network. Otherwise, the connection will be closed.
3119 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3120 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
3121
3122 EXPECT_EQ(migrate_idle_sessions,
3123 QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
3124 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(kDefaultDestination));
3125
3126 if (migrate_idle_sessions) {
3127 EXPECT_EQ(0u, session->GetNumActiveStreams());
3128 base::RunLoop().RunUntilIdle();
3129
3130 failed_socket_data.ExpectAllReadDataConsumed();
3131 failed_socket_data.ExpectAllWriteDataConsumed();
3132 }
3133 socket_data.ExpectAllReadDataConsumed();
3134 socket_data.ExpectAllWriteDataConsumed();
3135 }
3136
TEST_P(QuicSessionPoolTest,OnNetworkDisconnectedConnectionMigrationDisabled)3137 TEST_P(QuicSessionPoolTest, OnNetworkDisconnectedConnectionMigrationDisabled) {
3138 InitializeConnectionMigrationV2Test(
3139 {kDefaultNetworkForTests, kNewNetworkForTests});
3140 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3141 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3142
3143 MockQuicData socket_data(version_);
3144 socket_data.AddReadPauseForever();
3145 int packet_num = 1;
3146 socket_data.AddWrite(SYNCHRONOUS,
3147 ConstructInitialSettingsPacket(packet_num++));
3148 socket_data.AddSocketDataToFactory(socket_factory_.get());
3149
3150 // Create request and QuicHttpStream.
3151 RequestBuilder builder(this);
3152 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
3153 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3154 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
3155 EXPECT_TRUE(stream.get());
3156
3157 // Cause QUIC stream to be created.
3158 HttpRequestInfo request_info;
3159 request_info.traffic_annotation =
3160 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3161 stream->RegisterRequest(&request_info);
3162 EXPECT_EQ(OK, stream->InitializeStream(false, DEFAULT_PRIORITY, net_log_,
3163 CompletionOnceCallback()));
3164
3165 // Ensure that session is alive and active.
3166 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
3167 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
3168 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
3169
3170 // Set session config to have connection migration disabled.
3171 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
3172 session->config());
3173 EXPECT_TRUE(session->config()->DisableConnectionMigration());
3174
3175 // Trigger connection migration.
3176 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3177 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
3178
3179 EXPECT_FALSE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
3180 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
3181
3182 socket_data.ExpectAllReadDataConsumed();
3183 socket_data.ExpectAllWriteDataConsumed();
3184 }
3185
TEST_P(QuicSessionPoolTest,OnNetworkMadeDefaultNoOpenStreams_DoNotMigrateIdleSessions)3186 TEST_P(QuicSessionPoolTest,
3187 OnNetworkMadeDefaultNoOpenStreams_DoNotMigrateIdleSessions) {
3188 TestOnNetworkMadeDefaultNoOpenStreams(false);
3189 }
3190
TEST_P(QuicSessionPoolTest,OnNetworkMadeDefaultNoOpenStreams_MigrateIdleSessions)3191 TEST_P(QuicSessionPoolTest,
3192 OnNetworkMadeDefaultNoOpenStreams_MigrateIdleSessions) {
3193 TestOnNetworkMadeDefaultNoOpenStreams(true);
3194 }
3195
TestOnNetworkMadeDefaultNoOpenStreams(bool migrate_idle_sessions)3196 void QuicSessionPoolTest::TestOnNetworkMadeDefaultNoOpenStreams(
3197 bool migrate_idle_sessions) {
3198 quic_params_->migrate_idle_sessions = migrate_idle_sessions;
3199 InitializeConnectionMigrationV2Test(
3200 {kDefaultNetworkForTests, kNewNetworkForTests});
3201 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3202 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3203 client_maker_.set_save_packet_frames(true);
3204
3205 MockQuicData socket_data(version_);
3206 socket_data.AddReadPauseForever();
3207 int packet_num = 1;
3208 socket_data.AddWrite(SYNCHRONOUS,
3209 ConstructInitialSettingsPacket(packet_num++));
3210 if (!migrate_idle_sessions) {
3211 socket_data.AddWrite(
3212 SYNCHRONOUS,
3213 client_maker_.MakeConnectionClosePacket(
3214 packet_num, quic::QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS,
3215 "net error"));
3216 }
3217 socket_data.AddSocketDataToFactory(socket_factory_.get());
3218
3219 quic::QuicConnectionId cid_on_new_path =
3220 quic::test::TestConnectionId(12345678);
3221 MockQuicData quic_data1(version_);
3222 if (migrate_idle_sessions) {
3223 client_maker_.set_connection_id(cid_on_new_path);
3224 // Set up the second socket data provider that is used for probing.
3225 // Connectivity probe to be sent on the new path.
3226 quic_data1.AddWrite(
3227 SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(packet_num++));
3228 quic_data1.AddReadPause();
3229 // Connectivity probe to receive from the server.
3230 quic_data1.AddRead(ASYNC, server_maker_.MakeConnectivityProbingPacket(1));
3231 quic_data1.AddReadPauseForever();
3232 // in-flight SETTINGS and requests will be retransmitted. Since data is
3233 // already sent on the new address, ping will no longer be sent.
3234 quic_data1.AddWrite(ASYNC, client_maker_.MakeRetransmissionPacket(
3235 /*original_packet_number=*/1, packet_num++));
3236 quic_data1.AddWrite(SYNCHRONOUS, client_maker_.MakeRetireConnectionIdPacket(
3237 packet_num++, 0u));
3238 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3239 }
3240
3241 // Create request and QuicHttpStream.
3242 RequestBuilder builder(this);
3243 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
3244 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3245 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
3246 EXPECT_TRUE(stream.get());
3247
3248 // Ensure that session is alive and active.
3249 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
3250 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
3251 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
3252 EXPECT_FALSE(session->HasActiveRequestStreams());
3253 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
3254
3255 // Trigger connection migration.
3256 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3257 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3258 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(kDefaultDestination));
3259
3260 if (migrate_idle_sessions) {
3261 quic_data1.Resume();
3262 base::RunLoop().RunUntilIdle();
3263 quic_data1.ExpectAllReadDataConsumed();
3264 quic_data1.ExpectAllWriteDataConsumed();
3265 }
3266 socket_data.ExpectAllReadDataConsumed();
3267 socket_data.ExpectAllWriteDataConsumed();
3268 }
3269
TEST_P(QuicSessionPoolTest,OnNetworkDisconnectedNoOpenStreams_DoNotMigateIdleSessions)3270 TEST_P(QuicSessionPoolTest,
3271 OnNetworkDisconnectedNoOpenStreams_DoNotMigateIdleSessions) {
3272 TestOnNetworkDisconnectedNoOpenStreams(false);
3273 }
3274
TEST_P(QuicSessionPoolTest,OnNetworkDisconnectedNoOpenStreams_MigateIdleSessions)3275 TEST_P(QuicSessionPoolTest,
3276 OnNetworkDisconnectedNoOpenStreams_MigateIdleSessions) {
3277 TestOnNetworkDisconnectedNoOpenStreams(true);
3278 }
3279
TestOnNetworkDisconnectedNoOpenStreams(bool migrate_idle_sessions)3280 void QuicSessionPoolTest::TestOnNetworkDisconnectedNoOpenStreams(
3281 bool migrate_idle_sessions) {
3282 quic_params_->migrate_idle_sessions = migrate_idle_sessions;
3283 InitializeConnectionMigrationV2Test(
3284 {kDefaultNetworkForTests, kNewNetworkForTests});
3285 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3286 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3287 client_maker_.set_save_packet_frames(true);
3288
3289 MockQuicData default_socket_data(version_);
3290 default_socket_data.AddReadPauseForever();
3291 int packet_num = 1;
3292 default_socket_data.AddWrite(SYNCHRONOUS,
3293 ConstructInitialSettingsPacket(packet_num++));
3294 default_socket_data.AddSocketDataToFactory(socket_factory_.get());
3295
3296 MockQuicData alternate_socket_data(version_);
3297 quic::QuicConnectionId cid_on_new_path =
3298 quic::test::TestConnectionId(12345678);
3299 if (migrate_idle_sessions) {
3300 client_maker_.set_connection_id(cid_on_new_path);
3301 // Set up second socket data provider that is used after migration.
3302 alternate_socket_data.AddRead(SYNCHRONOUS,
3303 ERR_IO_PENDING); // Hanging read.
3304 alternate_socket_data.AddWrite(
3305 SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(1, packet_num++));
3306 // Ping packet to send after migration.
3307 alternate_socket_data.AddWrite(SYNCHRONOUS,
3308 client_maker_.MakePingPacket(packet_num++));
3309 alternate_socket_data.AddWrite(
3310 SYNCHRONOUS,
3311 client_maker_.MakeRetireConnectionIdPacket(packet_num++, 0u));
3312 alternate_socket_data.AddSocketDataToFactory(socket_factory_.get());
3313 }
3314
3315 // Create request and QuicHttpStream.
3316 RequestBuilder builder(this);
3317 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
3318 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3319 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
3320 EXPECT_TRUE(stream.get());
3321
3322 // Ensure that session is active.
3323 auto* session = GetActiveSession(kDefaultDestination);
3324 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
3325
3326 // Trigger connection migration. Since there are no active streams,
3327 // the session will be closed.
3328 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3329 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
3330
3331 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(kDefaultDestination));
3332
3333 default_socket_data.ExpectAllReadDataConsumed();
3334 default_socket_data.ExpectAllWriteDataConsumed();
3335 if (migrate_idle_sessions) {
3336 alternate_socket_data.ExpectAllReadDataConsumed();
3337 alternate_socket_data.ExpectAllWriteDataConsumed();
3338 }
3339 }
3340
3341 // This test verifies session migrates to the alternate network immediately when
3342 // default network disconnects with a synchronous write before migration.
TEST_P(QuicSessionPoolTest,MigrateOnDefaultNetworkDisconnectedSync)3343 TEST_P(QuicSessionPoolTest, MigrateOnDefaultNetworkDisconnectedSync) {
3344 TestMigrationOnNetworkDisconnected(/*async_write_before*/ false);
3345 }
3346
3347 // This test verifies session migrates to the alternate network immediately when
3348 // default network disconnects with an asynchronously write before migration.
TEST_P(QuicSessionPoolTest,MigrateOnDefaultNetworkDisconnectedAsync)3349 TEST_P(QuicSessionPoolTest, MigrateOnDefaultNetworkDisconnectedAsync) {
3350 TestMigrationOnNetworkDisconnected(/*async_write_before*/ true);
3351 }
3352
TestMigrationOnNetworkDisconnected(bool async_write_before)3353 void QuicSessionPoolTest::TestMigrationOnNetworkDisconnected(
3354 bool async_write_before) {
3355 InitializeConnectionMigrationV2Test(
3356 {kDefaultNetworkForTests, kNewNetworkForTests});
3357 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3358 ->NotifyNetworkMadeDefault(kDefaultNetworkForTests);
3359 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3360 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3361 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3362 client_maker_.set_save_packet_frames(true);
3363
3364 // Use the test task runner.
3365 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), runner_.get());
3366
3367 int packet_number = 1;
3368 MockQuicData socket_data(version_);
3369 socket_data.AddReadPauseForever();
3370 socket_data.AddWrite(SYNCHRONOUS,
3371 ConstructInitialSettingsPacket(packet_number++));
3372 socket_data.AddWrite(
3373 SYNCHRONOUS, ConstructGetRequestPacket(
3374 packet_number++,
3375 GetNthClientInitiatedBidirectionalStreamId(0), true));
3376 if (async_write_before) {
3377 socket_data.AddWrite(ASYNC, OK);
3378 packet_number++;
3379 }
3380 socket_data.AddSocketDataToFactory(socket_factory_.get());
3381
3382 // Create request and QuicHttpStream.
3383 RequestBuilder builder(this);
3384 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
3385 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3386 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
3387 EXPECT_TRUE(stream.get());
3388
3389 // Cause QUIC stream to be created.
3390 HttpRequestInfo request_info;
3391 request_info.method = "GET";
3392 request_info.url = GURL(kDefaultUrl);
3393 request_info.traffic_annotation =
3394 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3395 stream->RegisterRequest(&request_info);
3396 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
3397 CompletionOnceCallback()));
3398
3399 // Ensure that session is alive and active.
3400 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
3401 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
3402 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
3403 quic::QuicConnectionId cid_on_new_path =
3404 quic::test::TestConnectionId(12345678);
3405 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
3406
3407 // Send GET request on stream.
3408 HttpResponseInfo response;
3409 HttpRequestHeaders request_headers;
3410 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3411 callback_.callback()));
3412
3413 if (async_write_before) {
3414 session->connection()->SendPing();
3415 }
3416
3417 // Set up second socket data provider that is used after migration.
3418 // The response to the earlier request is read on this new socket.
3419 MockQuicData socket_data1(version_);
3420 client_maker_.set_connection_id(cid_on_new_path);
3421 socket_data1.AddWrite(
3422 SYNCHRONOUS,
3423 client_maker_.MakeCombinedRetransmissionPacket({1, 2}, packet_number++));
3424 socket_data1.AddWrite(SYNCHRONOUS,
3425 client_maker_.MakePingPacket(packet_number++));
3426 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakeRetireConnectionIdPacket(
3427 packet_number++, 0u));
3428 socket_data1.AddRead(
3429 ASYNC, ConstructOkResponsePacket(
3430 1, GetNthClientInitiatedBidirectionalStreamId(0), false));
3431 socket_data1.AddReadPauseForever();
3432 socket_data1.AddWrite(
3433 SYNCHRONOUS,
3434 client_maker_.MakeDataPacket(
3435 packet_number++, GetQpackDecoderStreamId(),
3436 /*fin=*/false, StreamCancellationQpackDecoderInstruction(0)));
3437 socket_data1.AddWrite(
3438 SYNCHRONOUS,
3439 client_maker_.MakeRstPacket(packet_number++,
3440 GetNthClientInitiatedBidirectionalStreamId(0),
3441 quic::QUIC_STREAM_CANCELLED));
3442 socket_data1.AddSocketDataToFactory(socket_factory_.get());
3443
3444 // Trigger connection migration.
3445 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3446 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
3447 base::RunLoop().RunUntilIdle();
3448 // The connection should still be alive, not marked as going away.
3449 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
3450 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
3451 EXPECT_EQ(1u, session->GetNumActiveStreams());
3452 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3453
3454 // Ensure that the session is still alive.
3455 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
3456 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
3457 EXPECT_EQ(1u, session->GetNumActiveStreams());
3458
3459 // Run the message loop so that data queued in the new socket is read by the
3460 // packet reader.
3461 runner_->RunNextTask();
3462
3463 // Response headers are received over the new network.
3464 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3465 EXPECT_EQ(200, response.headers->response_code());
3466
3467 // Check that the session is still alive.
3468 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
3469 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
3470
3471 // There should be posted tasks not executed, which is to migrate back to
3472 // default network.
3473 EXPECT_FALSE(runner_->GetPostedTasks().empty());
3474
3475 // Receive signal to mark new network as default.
3476 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3477 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3478
3479 stream.reset();
3480 socket_data.ExpectAllReadDataConsumed();
3481 socket_data.ExpectAllWriteDataConsumed();
3482 socket_data1.ExpectAllReadDataConsumed();
3483 socket_data1.ExpectAllWriteDataConsumed();
3484 }
3485
3486 // This test receives NCN signals in the following order:
3487 // - default network disconnected
3488 // - after a pause, new network is connected.
3489 // - new network is made default.
TEST_P(QuicSessionPoolTest,NewNetworkConnectedAfterNoNetwork)3490 TEST_P(QuicSessionPoolTest, NewNetworkConnectedAfterNoNetwork) {
3491 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
3492 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3493 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3494 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3495 client_maker_.set_save_packet_frames(true);
3496
3497 // Use the test task runner.
3498 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), runner_.get());
3499
3500 MockQuicData socket_data(version_);
3501 socket_data.AddReadPauseForever();
3502 int packet_num = 1;
3503 socket_data.AddWrite(SYNCHRONOUS,
3504 ConstructInitialSettingsPacket(packet_num++));
3505 socket_data.AddWrite(
3506 SYNCHRONOUS,
3507 ConstructGetRequestPacket(
3508 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true));
3509 socket_data.AddSocketDataToFactory(socket_factory_.get());
3510
3511 // Create request and QuicHttpStream.
3512 RequestBuilder builder(this);
3513 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
3514 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3515 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
3516 EXPECT_TRUE(stream.get());
3517
3518 // Cause QUIC stream to be created.
3519 HttpRequestInfo request_info;
3520 request_info.method = "GET";
3521 request_info.url = GURL(kDefaultUrl);
3522 request_info.traffic_annotation =
3523 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3524 stream->RegisterRequest(&request_info);
3525 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
3526 CompletionOnceCallback()));
3527
3528 // Ensure that session is alive and active.
3529 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
3530 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
3531 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
3532 quic::QuicConnectionId cid_on_new_path =
3533 quic::test::TestConnectionId(12345678);
3534 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
3535
3536 // Send GET request on stream.
3537 HttpResponseInfo response;
3538 HttpRequestHeaders request_headers;
3539 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3540 callback_.callback()));
3541
3542 // Trigger connection migration. Since there are no networks
3543 // to migrate to, this should cause the session to wait for a new network.
3544 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3545 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
3546
3547 // The connection should still be alive, not marked as going away.
3548 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
3549 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
3550 EXPECT_EQ(1u, session->GetNumActiveStreams());
3551 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3552
3553 // Set up second socket data provider that is used after migration.
3554 // The response to the earlier request is read on this new socket.
3555 MockQuicData socket_data1(version_);
3556 client_maker_.set_connection_id(cid_on_new_path);
3557 socket_data1.AddWrite(
3558 SYNCHRONOUS,
3559 client_maker_.MakeCombinedRetransmissionPacket({1, 2}, packet_num++));
3560 socket_data1.AddWrite(SYNCHRONOUS,
3561 client_maker_.MakePingPacket(packet_num++));
3562 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakeRetireConnectionIdPacket(
3563 packet_num++, 0u));
3564 socket_data1.AddRead(
3565 ASYNC, ConstructOkResponsePacket(
3566 1, GetNthClientInitiatedBidirectionalStreamId(0), false));
3567 socket_data1.AddReadPauseForever();
3568 socket_data1.AddWrite(
3569 SYNCHRONOUS,
3570 client_maker_.MakeDataPacket(
3571 packet_num++, GetQpackDecoderStreamId(),
3572 /*fin=*/false, StreamCancellationQpackDecoderInstruction(0)));
3573 socket_data1.AddWrite(
3574 SYNCHRONOUS,
3575 client_maker_.MakeRstPacket(packet_num++,
3576 GetNthClientInitiatedBidirectionalStreamId(0),
3577 quic::QUIC_STREAM_CANCELLED));
3578 socket_data1.AddSocketDataToFactory(socket_factory_.get());
3579
3580 // Add a new network and notify the stream factory of a new connected network.
3581 // This causes a PING packet to be sent over the new network.
3582 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3583 ->SetConnectedNetworksList({kNewNetworkForTests});
3584 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3585 ->NotifyNetworkConnected(kNewNetworkForTests);
3586
3587 // Ensure that the session is still alive.
3588 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
3589 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
3590 EXPECT_EQ(1u, session->GetNumActiveStreams());
3591
3592 // Run the message loop so that data queued in the new socket is read by the
3593 // packet reader.
3594 runner_->RunNextTask();
3595
3596 // Response headers are received over the new network.
3597 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3598 EXPECT_EQ(200, response.headers->response_code());
3599
3600 // Check that the session is still alive.
3601 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
3602 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
3603
3604 // There should posted tasks not executed, which is to migrate back to default
3605 // network.
3606 EXPECT_FALSE(runner_->GetPostedTasks().empty());
3607
3608 // Receive signal to mark new network as default.
3609 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3610 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3611
3612 stream.reset();
3613 socket_data.ExpectAllReadDataConsumed();
3614 socket_data.ExpectAllWriteDataConsumed();
3615 socket_data1.ExpectAllReadDataConsumed();
3616 socket_data1.ExpectAllWriteDataConsumed();
3617 }
3618
3619 // Regression test for http://crbug.com/872011.
3620 // This test verifies that migrate to the probing socket will not trigger
3621 // new packets being read synchronously and generate ACK frame while
3622 // processing the initial connectivity probe response, which may cause a
3623 // connection being closed with INTERNAL_ERROR as pending ACK frame is not
3624 // allowed when processing a new packet.
TEST_P(QuicSessionPoolTest,MigrateToProbingSocket)3625 TEST_P(QuicSessionPoolTest, MigrateToProbingSocket) {
3626 InitializeConnectionMigrationV2Test(
3627 {kDefaultNetworkForTests, kNewNetworkForTests});
3628 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3629 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3630 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3631 client_maker_.set_save_packet_frames(true);
3632
3633 // Using a testing task runner so that we can control time.
3634 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3635 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
3636
3637 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3638 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3639
3640 int packet_number = 1;
3641 MockQuicData quic_data1(version_);
3642 quic_data1.AddReadPauseForever();
3643 quic_data1.AddWrite(SYNCHRONOUS,
3644 ConstructInitialSettingsPacket(packet_number++));
3645 quic_data1.AddWrite(SYNCHRONOUS,
3646 ConstructGetRequestPacket(
3647 packet_number++,
3648 GetNthClientInitiatedBidirectionalStreamId(0), true));
3649 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3650
3651 // Set up the second socket data provider that is used for probing on the
3652 // alternate network.
3653 MockQuicData quic_data2(version_);
3654 quic::QuicConnectionId cid_on_new_path =
3655 quic::test::TestConnectionId(12345678);
3656 client_maker_.set_connection_id(cid_on_new_path);
3657 // Connectivity probe to be sent on the new path.
3658 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(
3659 packet_number++));
3660 quic_data2.AddReadPause();
3661 // First connectivity probe to receive from the server, which will complete
3662 // connection migraiton on path degrading.
3663 quic_data2.AddRead(ASYNC, server_maker_.MakeConnectivityProbingPacket(1));
3664 // Read multiple connectivity probes synchronously.
3665 quic_data2.AddRead(SYNCHRONOUS,
3666 server_maker_.MakeConnectivityProbingPacket(2));
3667 quic_data2.AddRead(SYNCHRONOUS,
3668 server_maker_.MakeConnectivityProbingPacket(3));
3669 quic_data2.AddRead(SYNCHRONOUS,
3670 server_maker_.MakeConnectivityProbingPacket(4));
3671 quic_data2.AddWrite(ASYNC, client_maker_.MakeAckAndRetransmissionPacket(
3672 packet_number++, 1, 4, 1, {1, 2}));
3673 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeRetireConnectionIdPacket(
3674 packet_number++, 0u));
3675 quic_data2.AddRead(
3676 ASYNC, ConstructOkResponsePacket(
3677 5, GetNthClientInitiatedBidirectionalStreamId(0), false));
3678 quic_data2.AddReadPauseForever();
3679 quic_data2.AddWrite(
3680 SYNCHRONOUS, client_maker_.MakeAckAndDataPacket(
3681 packet_number++, GetQpackDecoderStreamId(), 5, 1, false,
3682 StreamCancellationQpackDecoderInstruction(0)));
3683 quic_data2.AddWrite(
3684 SYNCHRONOUS,
3685 client_maker_.MakeRstPacket(packet_number++,
3686 GetNthClientInitiatedBidirectionalStreamId(0),
3687 quic::QUIC_STREAM_CANCELLED));
3688 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3689
3690 // Create request and QuicHttpStream.
3691 RequestBuilder builder(this);
3692 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
3693 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3694 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
3695 EXPECT_TRUE(stream.get());
3696
3697 // Cause QUIC stream to be created.
3698 HttpRequestInfo request_info;
3699 request_info.method = "GET";
3700 request_info.url = GURL(kDefaultUrl);
3701 request_info.traffic_annotation =
3702 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3703 stream->RegisterRequest(&request_info);
3704 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
3705 CompletionOnceCallback()));
3706
3707 // Ensure that session is alive and active.
3708 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
3709 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
3710 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
3711 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
3712
3713 // Send GET request on stream.
3714 HttpResponseInfo response;
3715 HttpRequestHeaders request_headers;
3716 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3717 callback_.callback()));
3718
3719 EXPECT_EQ(0u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
3720 // Cause the connection to report path degrading to the session.
3721 // Session will start to probe the alternate network.
3722 session->connection()->OnPathDegradingDetected();
3723 base::RunLoop().RunUntilIdle();
3724 EXPECT_EQ(1u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
3725
3726 // The connection should still be alive, and not marked as going away.
3727 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
3728 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
3729 EXPECT_EQ(1u, session->GetNumActiveStreams());
3730 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3731
3732 // Resume quic data and a connectivity probe response will be read on the new
3733 // socket.
3734 quic_data2.Resume();
3735
3736 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
3737 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
3738 EXPECT_EQ(1u, session->GetNumActiveStreams());
3739
3740 // There should be a task that will complete the migration to the new network.
3741 task_runner->RunUntilIdle();
3742
3743 EXPECT_EQ(1u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
3744
3745 // Response headers are received over the new network.
3746 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3747 EXPECT_EQ(200, response.headers->response_code());
3748
3749 // Deliver a signal that the alternate network now becomes default to session,
3750 // this will cancel migrate back to default network timer.
3751 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3752 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3753
3754 EXPECT_EQ(0u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
3755
3756 task_runner->FastForwardBy(base::Seconds(kMinRetryTimeForDefaultNetworkSecs));
3757
3758 // Verify that the session is still alive.
3759 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
3760 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
3761
3762 stream.reset();
3763 quic_data1.ExpectAllReadDataConsumed();
3764 quic_data1.ExpectAllWriteDataConsumed();
3765 quic_data2.ExpectAllReadDataConsumed();
3766 quic_data2.ExpectAllWriteDataConsumed();
3767 }
3768
3769 // This test verifies that the connection migrates to the alternate network
3770 // early when path degrading is detected with an ASYNCHRONOUS write before
3771 // migration.
TEST_P(QuicSessionPoolTest,MigrateEarlyOnPathDegradingAsync)3772 TEST_P(QuicSessionPoolTest, MigrateEarlyOnPathDegradingAsync) {
3773 TestMigrationOnPathDegrading(/*async_write_before_migration*/ true);
3774 }
3775
3776 // This test verifies that the connection migrates to the alternate network
3777 // early when path degrading is detected with a SYNCHRONOUS write before
3778 // migration.
TEST_P(QuicSessionPoolTest,MigrateEarlyOnPathDegradingSync)3779 TEST_P(QuicSessionPoolTest, MigrateEarlyOnPathDegradingSync) {
3780 TestMigrationOnPathDegrading(/*async_write_before_migration*/ false);
3781 }
3782
TestMigrationOnPathDegrading(bool async_write_before)3783 void QuicSessionPoolTest::TestMigrationOnPathDegrading(
3784 bool async_write_before) {
3785 InitializeConnectionMigrationV2Test(
3786 {kDefaultNetworkForTests, kNewNetworkForTests});
3787 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3788 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3789 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3790 client_maker_.set_save_packet_frames(true);
3791
3792 // Using a testing task runner so that we can control time.
3793 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3794 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
3795
3796 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3797 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3798
3799 int packet_number = 1;
3800 MockQuicData quic_data1(version_);
3801 quic_data1.AddReadPauseForever();
3802 quic_data1.AddWrite(SYNCHRONOUS,
3803 ConstructInitialSettingsPacket(packet_number++));
3804 quic_data1.AddWrite(SYNCHRONOUS,
3805 ConstructGetRequestPacket(
3806 packet_number++,
3807 GetNthClientInitiatedBidirectionalStreamId(0), true));
3808 if (async_write_before) {
3809 quic_data1.AddWrite(ASYNC, OK);
3810 packet_number++;
3811 }
3812 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3813
3814 // Set up the second socket data provider that is used after migration.
3815 // The response to the earlier request is read on the new socket.
3816 MockQuicData quic_data2(version_);
3817 quic::QuicConnectionId cid_on_new_path =
3818 quic::test::TestConnectionId(12345678);
3819 client_maker_.set_connection_id(cid_on_new_path);
3820 // Connectivity probe to be sent on the new path.
3821 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(
3822 packet_number++));
3823 quic_data2.AddReadPause();
3824 // Connectivity probe to receive from the server.
3825 quic_data2.AddRead(ASYNC, server_maker_.MakeConnectivityProbingPacket(1));
3826 // in-flight SETTINGS and requests will be retransmitted. Since data is
3827 // already sent on the new address, ping will no longer be sent.
3828 quic_data2.AddWrite(ASYNC,
3829 client_maker_.MakeCombinedRetransmissionPacket(
3830 /*original_packet_numbers=*/{1, 2}, packet_number++));
3831 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeRetireConnectionIdPacket(
3832 packet_number++, 0u));
3833 quic_data2.AddRead(
3834 ASYNC, ConstructOkResponsePacket(
3835 2, GetNthClientInitiatedBidirectionalStreamId(0), false));
3836 quic_data2.AddReadPauseForever();
3837 quic_data2.AddWrite(
3838 SYNCHRONOUS, client_maker_.MakeAckAndDataPacket(
3839 packet_number++, GetQpackDecoderStreamId(), 2, 2, false,
3840 StreamCancellationQpackDecoderInstruction(0)));
3841 quic_data2.AddWrite(
3842 SYNCHRONOUS,
3843 client_maker_.MakeRstPacket(packet_number++,
3844 GetNthClientInitiatedBidirectionalStreamId(0),
3845 quic::QUIC_STREAM_CANCELLED));
3846 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3847
3848 // Create request and QuicHttpStream.
3849 RequestBuilder builder(this);
3850 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
3851 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3852 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
3853 EXPECT_TRUE(stream.get());
3854
3855 // Cause QUIC stream to be created.
3856 HttpRequestInfo request_info;
3857 request_info.method = "GET";
3858 request_info.url = GURL(kDefaultUrl);
3859 request_info.traffic_annotation =
3860 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3861 stream->RegisterRequest(&request_info);
3862 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
3863 CompletionOnceCallback()));
3864
3865 // Ensure that session is alive and active.
3866 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
3867 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
3868 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
3869 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
3870
3871 // Send GET request on stream.
3872 HttpResponseInfo response;
3873 HttpRequestHeaders request_headers;
3874 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3875 callback_.callback()));
3876
3877 if (async_write_before) {
3878 session->connection()->SendPing();
3879 }
3880
3881 EXPECT_EQ(0u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
3882 // Cause the connection to report path degrading to the session.
3883 // Session will start to probe the alternate network.
3884 session->connection()->OnPathDegradingDetected();
3885 base::RunLoop().RunUntilIdle();
3886 EXPECT_EQ(1u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
3887
3888 // The connection should still be alive, and not marked as going away.
3889 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
3890 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
3891 EXPECT_EQ(1u, session->GetNumActiveStreams());
3892 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3893
3894 // Resume quic data and a connectivity probe response will be read on the new
3895 // socket.
3896 quic_data2.Resume();
3897
3898 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
3899 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
3900 EXPECT_EQ(1u, session->GetNumActiveStreams());
3901
3902 // There should be a task that will complete the migration to the new network.
3903 task_runner->RunUntilIdle();
3904
3905 EXPECT_EQ(1u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
3906
3907 // Response headers are received over the new network.
3908 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3909 EXPECT_EQ(200, response.headers->response_code());
3910
3911 EXPECT_EQ(1u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
3912
3913 // Deliver a signal that the alternate network now becomes default to session,
3914 // this will cancel mgirate back to default network timer.
3915 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3916 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3917
3918 EXPECT_EQ(0u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
3919
3920 task_runner->FastForwardBy(base::Seconds(kMinRetryTimeForDefaultNetworkSecs));
3921
3922 // Verify that the session is still alive.
3923 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
3924 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
3925
3926 stream.reset();
3927 quic_data1.ExpectAllReadDataConsumed();
3928 quic_data1.ExpectAllWriteDataConsumed();
3929 quic_data2.ExpectAllReadDataConsumed();
3930 quic_data2.ExpectAllWriteDataConsumed();
3931 }
3932
TEST_P(QuicSessionPoolTest,MigrateSessionEarlyProbingWriterError)3933 TEST_P(QuicSessionPoolTest, MigrateSessionEarlyProbingWriterError) {
3934 InitializeConnectionMigrationV2Test(
3935 {kDefaultNetworkForTests, kNewNetworkForTests});
3936 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3937 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3938 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3939
3940 // Using a testing task runner so that we can control time.
3941 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3942 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
3943
3944 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3945 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3946
3947 int packet_number = 1;
3948 MockQuicData quic_data1(version_);
3949 quic_data1.AddWrite(SYNCHRONOUS,
3950 ConstructInitialSettingsPacket(packet_number++));
3951 quic_data1.AddWrite(SYNCHRONOUS,
3952 ConstructGetRequestPacket(
3953 packet_number++,
3954 GetNthClientInitiatedBidirectionalStreamId(0), true));
3955 quic_data1.AddReadPause();
3956 quic_data1.AddRead(
3957 ASYNC, ConstructOkResponsePacket(
3958 1, GetNthClientInitiatedBidirectionalStreamId(0), true));
3959 quic_data1.AddReadPauseForever();
3960
3961 // Set up the second socket data provider that is used for path validation.
3962 MockQuicData quic_data2(version_);
3963 quic::QuicConnectionId cid_on_old_path =
3964 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator());
3965 quic::QuicConnectionId cid_on_new_path =
3966 quic::test::TestConnectionId(12345678);
3967 client_maker_.set_connection_id(cid_on_new_path);
3968 // Connectivity probe to be sent on the new path.
3969 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
3970 ++packet_number; // Account for the packet encountering write error.
3971 quic_data2.AddReadPause();
3972 quic_data2.AddRead(ASYNC, server_maker_.MakeConnectivityProbingPacket(1));
3973
3974 // Connection ID is retired on the old path.
3975 client_maker_.set_connection_id(cid_on_old_path);
3976 quic_data1.AddWrite(SYNCHRONOUS, client_maker_.MakeRetireConnectionIdPacket(
3977 packet_number++,
3978 /*sequence_number=*/1u));
3979
3980 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3981 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3982
3983 // Create request and QuicHttpStream.
3984 RequestBuilder builder(this);
3985 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
3986 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3987 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
3988 EXPECT_TRUE(stream.get());
3989
3990 // Cause QUIC stream to be created.
3991 HttpRequestInfo request_info;
3992 request_info.method = "GET";
3993 request_info.url = GURL(kDefaultUrl);
3994 request_info.traffic_annotation =
3995 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3996 stream->RegisterRequest(&request_info);
3997 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
3998 CompletionOnceCallback()));
3999
4000 // Ensure that session is alive and active.
4001 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
4002 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
4003 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
4004 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
4005
4006 // Send GET request on stream.
4007 HttpResponseInfo response;
4008 HttpRequestHeaders request_headers;
4009 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
4010 callback_.callback()));
4011
4012 EXPECT_EQ(0u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
4013 // Cause the connection to report path degrading to the session.
4014 // Session will start to probe the alternate network.
4015 // However, the probing writer will fail. This should result in a failed probe
4016 // but no connection close.
4017 session->connection()->OnPathDegradingDetected();
4018 base::RunLoop().RunUntilIdle();
4019 EXPECT_EQ(1u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
4020
4021 // The connection should still be alive, and not marked as going away.
4022 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
4023 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
4024 EXPECT_EQ(1u, session->GetNumActiveStreams());
4025 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
4026
4027 // There should be one task of notifying the session that probing failed, and
4028 // a second as a DoNothingAs callback.
4029 EXPECT_TRUE(session->connection()->HasPendingPathValidation());
4030 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
4031 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
4032 EXPECT_EQ(base::TimeDelta(), next_task_delay);
4033 task_runner->FastForwardBy(next_task_delay);
4034 // Verify that path validation is cancelled.
4035 EXPECT_FALSE(session->connection()->HasPendingPathValidation());
4036
4037 EXPECT_EQ(1u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
4038 quic_data1.Resume();
4039 // Response headers are received on the original network..
4040 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4041 EXPECT_EQ(200, response.headers->response_code());
4042
4043 // Verify that the session is still alive.
4044 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
4045 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
4046
4047 stream.reset();
4048 quic_data1.ExpectAllReadDataConsumed();
4049 quic_data1.ExpectAllWriteDataConsumed();
4050 quic_data2.ExpectAllWriteDataConsumed();
4051 }
4052
TEST_P(QuicSessionPoolTest,MigrateSessionEarlyProbingWriterErrorThreeNetworks)4053 TEST_P(QuicSessionPoolTest,
4054 MigrateSessionEarlyProbingWriterErrorThreeNetworks) {
4055 InitializeConnectionMigrationV2Test(
4056 {kDefaultNetworkForTests, kNewNetworkForTests});
4057
4058 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4059 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4060 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4061
4062 // Using a testing task runner so that we can control time.
4063 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4064 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
4065
4066 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4067 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
4068 base::RunLoop().RunUntilIdle();
4069
4070 quic::QuicConnectionId cid_on_path1 =
4071 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator());
4072 quic::QuicConnectionId cid_on_path2 = quic::test::TestConnectionId(12345678);
4073
4074 int packet_number = 1;
4075 MockQuicData quic_data1(version_);
4076 quic_data1.AddWrite(SYNCHRONOUS,
4077 ConstructInitialSettingsPacket(packet_number++));
4078 quic_data1.AddWrite(SYNCHRONOUS,
4079 ConstructGetRequestPacket(
4080 packet_number++,
4081 GetNthClientInitiatedBidirectionalStreamId(0), true));
4082 quic_data1.AddReadPause();
4083 quic_data1.AddRead(
4084 ASYNC, ConstructOkResponsePacket(
4085 1, GetNthClientInitiatedBidirectionalStreamId(0), true));
4086 quic_data1.AddReadPauseForever();
4087
4088 // Set up the second socket data provider that is used for path validation.
4089 MockQuicData quic_data2(version_);
4090 client_maker_.set_connection_id(cid_on_path2);
4091 // Connectivity probe to be sent on the new path.
4092 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
4093 quic_data2.AddReadPause();
4094 quic_data2.AddRead(ASYNC, server_maker_.MakeConnectivityProbingPacket(1));
4095 packet_number++; // Account for packet encountering write error.
4096
4097 // Connection ID is retired on the old path.
4098 client_maker_.set_connection_id(cid_on_path1);
4099 quic_data1.AddWrite(ASYNC, client_maker_.MakeRetireConnectionIdPacket(
4100 packet_number++,
4101 /*sequence_number=*/1u));
4102
4103 // A socket will be created for a new path, but there would be no write
4104 // due to lack of new connection ID.
4105 MockQuicData quic_data3(version_);
4106 quic_data3.AddReadPauseForever();
4107
4108 quic_data1.AddSocketDataToFactory(socket_factory_.get());
4109 quic_data2.AddSocketDataToFactory(socket_factory_.get());
4110 quic_data3.AddSocketDataToFactory(socket_factory_.get());
4111
4112 // Create request and QuicHttpStream.
4113 RequestBuilder builder(this);
4114 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
4115 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4116 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
4117 EXPECT_TRUE(stream.get());
4118
4119 // Cause QUIC stream to be created.
4120 HttpRequestInfo request_info;
4121 request_info.method = "GET";
4122 request_info.url = GURL(kDefaultUrl);
4123 request_info.traffic_annotation =
4124 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4125 stream->RegisterRequest(&request_info);
4126 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
4127 CompletionOnceCallback()));
4128
4129 // Ensure that session is alive and active.
4130 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
4131 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
4132 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
4133 MaybeMakeNewConnectionIdAvailableToSession(cid_on_path2, session);
4134 base::RunLoop().RunUntilIdle();
4135 // Send GET request on stream.
4136 HttpResponseInfo response;
4137 HttpRequestHeaders request_headers;
4138 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
4139 callback_.callback()));
4140
4141 EXPECT_EQ(0u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
4142 // Cause the connection to report path degrading to the session.
4143 // Session will start to probe the alternate network.
4144 // However, the probing writer will fail. This should result in a failed probe
4145 // but no connection close.
4146 session->connection()->OnPathDegradingDetected();
4147 base::RunLoop().RunUntilIdle();
4148 EXPECT_EQ(1u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
4149
4150 // The connection should still be alive, and not marked as going away.
4151 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
4152 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
4153 EXPECT_EQ(1u, session->GetNumActiveStreams());
4154 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
4155
4156 // There should be one task of notifying the session that probing failed, and
4157 // one that was posted as a DoNothingAs callback.
4158 EXPECT_TRUE(session->connection()->HasPendingPathValidation());
4159 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
4160
4161 // Trigger another path degrading, but this time another network is available.
4162 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4163 ->SetConnectedNetworksList({kDefaultNetworkForTests, 3});
4164 session->connection()->OnPathDegradingDetected();
4165 base::RunLoop().RunUntilIdle();
4166
4167 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
4168 EXPECT_EQ(base::TimeDelta(), next_task_delay);
4169 task_runner->FastForwardBy(next_task_delay);
4170 // Verify that the task is executed.
4171 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4172 // No pending path validation as there is no connection ID available.
4173 EXPECT_FALSE(session->connection()->HasPendingPathValidation());
4174
4175 EXPECT_EQ(1u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
4176 quic_data1.Resume();
4177 // Response headers are received on the original network..
4178 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4179 EXPECT_EQ(200, response.headers->response_code());
4180
4181 base::RunLoop().RunUntilIdle();
4182 // Verify that the session is still alive.
4183 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
4184 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
4185 base::RunLoop().RunUntilIdle();
4186 stream.reset();
4187 quic_data1.ExpectAllReadDataConsumed();
4188 quic_data1.ExpectAllWriteDataConsumed();
4189 quic_data2.ExpectAllWriteDataConsumed();
4190 }
4191
TEST_P(QuicSessionPoolTest,MultiPortSessionWithMigration)4192 TEST_P(QuicSessionPoolTest, MultiPortSessionWithMigration) {
4193 // Turning on both MPQC and MPQM will implicitly turn on port migration.
4194 quic_params_->client_connection_options.push_back(quic::kMPQC);
4195 quic_params_->client_connection_options.push_back(quic::kMPQM);
4196 socket_factory_ = std::make_unique<TestPortMigrationSocketFactory>();
4197 Initialize();
4198
4199 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4200 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4201
4202 // Using a testing task runner so that we can control time.
4203 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4204 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
4205
4206 MockQuicData quic_data1(version_);
4207 quic_data1.AddReadPauseForever();
4208 quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
4209 quic_data1.AddWrite(
4210 SYNCHRONOUS, ConstructGetRequestPacket(
4211 3, GetNthClientInitiatedBidirectionalStreamId(0), true));
4212 quic_data1.AddSocketDataToFactory(socket_factory_.get());
4213
4214 // Set up the second socket data provider that is used for multi-port
4215 MockQuicData quic_data2(version_);
4216 quic::QuicConnectionId cid_on_new_path =
4217 quic::test::TestConnectionId(12345678);
4218
4219 client_maker_.set_connection_id(cid_on_new_path);
4220 // Connectivity probe to be sent on the new path.
4221 quic_data2.AddWrite(SYNCHRONOUS,
4222 client_maker_.MakeConnectivityProbingPacket(2));
4223 quic_data2.AddReadPause();
4224 // Connectivity probe to receive from the server.
4225 quic_data2.AddRead(ASYNC, server_maker_.MakeConnectivityProbingPacket(1));
4226 quic_data2.AddReadPause();
4227 quic_data2.AddRead(
4228 ASYNC, ConstructOkResponsePacket(
4229 2, GetNthClientInitiatedBidirectionalStreamId(0), false));
4230 quic_data2.AddReadPause();
4231 quic_data2.AddWrite(
4232 ASYNC, client_maker_.MakeAckAndPingPacket(4,
4233 /*largest_received=*/2,
4234 /*smallest_received=*/1));
4235 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeRetireConnectionIdPacket(
4236 5, /*sequence_number=*/0u));
4237 quic_data2.AddRead(ASYNC, server_maker_.MakeAckPacket(3, 5, 1));
4238 quic_data2.AddReadPauseForever();
4239 quic_data2.AddWrite(ASYNC, client_maker_.MakeDataPacket(
4240 6, GetQpackDecoderStreamId(), false,
4241 StreamCancellationQpackDecoderInstruction(0)));
4242 quic_data2.AddWrite(ASYNC,
4243 client_maker_.MakeRstPacket(
4244 7, GetNthClientInitiatedBidirectionalStreamId(0),
4245 quic::QUIC_STREAM_CANCELLED));
4246
4247 quic_data2.AddSocketDataToFactory(socket_factory_.get());
4248
4249 // Create request and QuicHttpStream.
4250 RequestBuilder builder(this);
4251 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
4252 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4253 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
4254 EXPECT_TRUE(stream.get());
4255
4256 // Cause QUIC stream to be created.
4257 HttpRequestInfo request_info;
4258 request_info.method = "GET";
4259 request_info.url = GURL(kDefaultUrl);
4260 request_info.traffic_annotation =
4261 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4262 stream->RegisterRequest(&request_info);
4263 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
4264 CompletionOnceCallback()));
4265
4266 // Ensure that session is alive and active.
4267 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
4268 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
4269 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
4270 // Manually initialize the connection's self address. In real life, the
4271 // initialization will be done during crypto handshake.
4272 IPEndPoint ip;
4273 session->GetDefaultSocket()->GetLocalAddress(&ip);
4274 quic::test::QuicConnectionPeer::SetSelfAddress(session->connection(),
4275 ToQuicSocketAddress(ip));
4276
4277 // This will trigger multi-port path creation.
4278 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
4279 base::RunLoop().RunUntilIdle();
4280
4281 // Send GET request on stream.
4282 HttpResponseInfo response;
4283 HttpRequestHeaders request_headers;
4284 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
4285 callback_.callback()));
4286 // Disable connection migration on the request streams.
4287 // This should have no effect for port migration.
4288 QuicChromiumClientStream* chrome_stream =
4289 static_cast<QuicChromiumClientStream*>(
4290 quic::test::QuicSessionPeer::GetStream(
4291 session, GetNthClientInitiatedBidirectionalStreamId(0)));
4292 EXPECT_TRUE(chrome_stream);
4293 chrome_stream->DisableConnectionMigrationToCellularNetwork();
4294
4295 // Resume quic data and a connectivity probe response will be read on the new
4296 // socket. This makes the multi-port path ready to migrate.
4297 quic_data2.Resume();
4298
4299 EXPECT_EQ(0u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
4300
4301 // Cause the connection to report path degrading to the session.
4302 // Session will start migrate to multi-port path immediately.
4303 session->connection()->OnPathDegradingDetected();
4304 base::RunLoop().RunUntilIdle();
4305 // The connection should still be degrading because no new packets are
4306 // received from the new path.
4307 EXPECT_EQ(1u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
4308
4309 // The response is received on the new path.
4310 quic_data2.Resume();
4311 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
4312 EXPECT_EQ(200, response.headers->response_code());
4313 task_runner->RunUntilIdle();
4314 base::RunLoop().RunUntilIdle();
4315
4316 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
4317 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
4318 EXPECT_EQ(1u, session->GetNumActiveStreams());
4319
4320 // Receives an ack from the server, this will be considered forward progress.
4321 quic_data2.Resume();
4322 task_runner->RunUntilIdle();
4323 base::RunLoop().RunUntilIdle();
4324 EXPECT_EQ(0u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
4325
4326 stream.reset();
4327 task_runner->RunUntilIdle();
4328 base::RunLoop().RunUntilIdle();
4329 quic_data1.ExpectAllReadDataConsumed();
4330 quic_data1.ExpectAllWriteDataConsumed();
4331 quic_data2.ExpectAllReadDataConsumed();
4332 quic_data2.ExpectAllWriteDataConsumed();
4333 }
4334
TEST_P(QuicSessionPoolTest,SuccessfullyMigratedToServerPreferredAddress)4335 TEST_P(QuicSessionPoolTest, SuccessfullyMigratedToServerPreferredAddress) {
4336 IPEndPoint server_preferred_address = IPEndPoint(IPAddress(1, 2, 3, 4), 123);
4337 FLAGS_quic_enable_chaos_protection = false;
4338 quic_params_->connection_options.push_back(quic::kSPAD);
4339 socket_factory_ = std::make_unique<TestPortMigrationSocketFactory>();
4340 Initialize();
4341
4342 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4343 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4344 quic::QuicConfig config;
4345 config.SetIPv4AlternateServerAddressToSend(
4346 ToQuicSocketAddress(server_preferred_address));
4347 quic::test::QuicConfigPeer::SetPreferredAddressConnectionIdAndToken(
4348 &config, kNewCID, quic::QuicUtils::GenerateStatelessResetToken(kNewCID));
4349 crypto_client_stream_factory_.SetConfig(config);
4350 // Use cold start mode to send crypto message for handshake.
4351 crypto_client_stream_factory_.set_handshake_mode(
4352 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
4353
4354 int packet_number = 1;
4355 MockQuicData quic_data1(version_);
4356 quic_data1.AddReadPauseForever();
4357 quic_data1.AddWrite(ASYNC,
4358 client_maker_.MakeDummyCHLOPacket(packet_number++));
4359 // Change the encryption level after handshake is confirmed.
4360 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
4361 quic_data1.AddWrite(SYNCHRONOUS,
4362 ConstructInitialSettingsPacket(packet_number++));
4363 quic_data1.AddSocketDataToFactory(socket_factory_.get());
4364
4365 // Set up the second socket data provider that is used to validate server
4366 // preferred address.
4367 MockQuicData quic_data2(version_);
4368 client_maker_.set_connection_id(kNewCID);
4369 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(
4370 packet_number++));
4371 quic_data2.AddReadPause();
4372 quic_data2.AddRead(ASYNC, server_maker_.MakeConnectivityProbingPacket(1));
4373 quic_data2.AddReadPauseForever();
4374 quic_data2.AddSocketDataToFactory(socket_factory_.get());
4375
4376 // Create request.
4377 RequestBuilder builder(this);
4378 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
4379 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
4380 EXPECT_TRUE(HasActiveJob(kDefaultDestination, PRIVACY_MODE_DISABLED));
4381 base::RunLoop().RunUntilIdle();
4382
4383 crypto_client_stream_factory_.last_stream()
4384 ->NotifySessionOneRttKeyAvailable();
4385 base::RunLoop().RunUntilIdle();
4386 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4387 ASSERT_TRUE(HasActiveSession(kDefaultDestination));
4388 EXPECT_FALSE(HasActiveJob(kDefaultDestination, PRIVACY_MODE_DISABLED));
4389 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
4390 EXPECT_FALSE(
4391 session->connection()->GetStats().server_preferred_address_validated);
4392 EXPECT_FALSE(session->connection()
4393 ->GetStats()
4394 .failed_to_validate_server_preferred_address);
4395 const quic::QuicSocketAddress peer_address = session->peer_address();
4396
4397 quic_data2.Resume();
4398 EXPECT_FALSE(session->connection()->HasPendingPathValidation());
4399 EXPECT_TRUE(
4400 session->connection()->GetStats().server_preferred_address_validated);
4401 EXPECT_FALSE(session->connection()
4402 ->GetStats()
4403 .failed_to_validate_server_preferred_address);
4404 EXPECT_NE(session->peer_address(), peer_address);
4405 EXPECT_EQ(session->peer_address(),
4406 ToQuicSocketAddress(server_preferred_address));
4407
4408 quic_data1.ExpectAllReadDataConsumed();
4409 quic_data1.ExpectAllWriteDataConsumed();
4410 quic_data2.ExpectAllReadDataConsumed();
4411 quic_data2.ExpectAllWriteDataConsumed();
4412 }
4413
TEST_P(QuicSessionPoolTest,FailedToValidateServerPreferredAddress)4414 TEST_P(QuicSessionPoolTest, FailedToValidateServerPreferredAddress) {
4415 IPEndPoint server_preferred_address = IPEndPoint(IPAddress(1, 2, 3, 4), 123);
4416 FLAGS_quic_enable_chaos_protection = false;
4417 quic_params_->connection_options.push_back(quic::kSPAD);
4418 socket_factory_ = std::make_unique<TestPortMigrationSocketFactory>();
4419 Initialize();
4420
4421 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4422 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4423 quic::QuicConfig config;
4424 config.SetIPv4AlternateServerAddressToSend(
4425 ToQuicSocketAddress(server_preferred_address));
4426 quic::test::QuicConfigPeer::SetPreferredAddressConnectionIdAndToken(
4427 &config, kNewCID, quic::QuicUtils::GenerateStatelessResetToken(kNewCID));
4428 crypto_client_stream_factory_.SetConfig(config);
4429 // Use cold start mode to send crypto message for handshake.
4430 crypto_client_stream_factory_.set_handshake_mode(
4431 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
4432
4433 int packet_number = 1;
4434 MockQuicData quic_data1(version_);
4435 quic_data1.AddReadPauseForever();
4436 quic_data1.AddWrite(ASYNC,
4437 client_maker_.MakeDummyCHLOPacket(packet_number++));
4438 // Change the encryption level after handshake is confirmed.
4439 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
4440 quic_data1.AddWrite(SYNCHRONOUS,
4441 ConstructInitialSettingsPacket(packet_number++));
4442 quic_data1.AddSocketDataToFactory(socket_factory_.get());
4443
4444 // Set up the second socket data provider that is used to validate server
4445 // preferred address.
4446 MockQuicData quic_data2(version_);
4447 client_maker_.set_connection_id(kNewCID);
4448 quic_data2.AddReadPauseForever();
4449 // One PATH_CHALLENGE + 2 retires.
4450 for (size_t i = 0; i < quic::QuicPathValidator::kMaxRetryTimes + 1; ++i) {
4451 quic_data2.AddWrite(
4452 SYNCHRONOUS,
4453 client_maker_.MakeConnectivityProbingPacket(packet_number++));
4454 }
4455 quic_data2.AddSocketDataToFactory(socket_factory_.get());
4456
4457 // Create request.
4458 RequestBuilder builder(this);
4459 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
4460 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
4461 EXPECT_TRUE(HasActiveJob(kDefaultDestination, PRIVACY_MODE_DISABLED));
4462 base::RunLoop().RunUntilIdle();
4463
4464 crypto_client_stream_factory_.last_stream()
4465 ->NotifySessionOneRttKeyAvailable();
4466 base::RunLoop().RunUntilIdle();
4467 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4468 ASSERT_TRUE(HasActiveSession(kDefaultDestination));
4469 EXPECT_FALSE(HasActiveJob(kDefaultDestination, PRIVACY_MODE_DISABLED));
4470 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
4471 EXPECT_FALSE(
4472 session->connection()->GetStats().server_preferred_address_validated);
4473 EXPECT_FALSE(session->connection()
4474 ->GetStats()
4475 .failed_to_validate_server_preferred_address);
4476 const quic::QuicSocketAddress peer_address = session->peer_address();
4477
4478 auto* path_validator =
4479 quic::test::QuicConnectionPeer::path_validator(session->connection());
4480 for (size_t i = 0; i < quic::QuicPathValidator::kMaxRetryTimes + 1; ++i) {
4481 quic::test::QuicPathValidatorPeer::retry_timer(path_validator)->Cancel();
4482 path_validator->OnRetryTimeout();
4483 }
4484
4485 EXPECT_FALSE(session->connection()->HasPendingPathValidation());
4486 EXPECT_FALSE(
4487 session->connection()->GetStats().server_preferred_address_validated);
4488 EXPECT_TRUE(session->connection()
4489 ->GetStats()
4490 .failed_to_validate_server_preferred_address);
4491 EXPECT_EQ(session->peer_address(), peer_address);
4492 EXPECT_NE(session->peer_address(),
4493 ToQuicSocketAddress(server_preferred_address));
4494
4495 quic_data1.ExpectAllReadDataConsumed();
4496 quic_data1.ExpectAllWriteDataConsumed();
4497 quic_data2.ExpectAllReadDataConsumed();
4498 quic_data2.ExpectAllWriteDataConsumed();
4499 }
4500
TEST_P(QuicSessionPoolTest,MigratePortOnPathDegrading_WithoutNetworkHandle_PathValidator)4501 TEST_P(QuicSessionPoolTest,
4502 MigratePortOnPathDegrading_WithoutNetworkHandle_PathValidator) {
4503 socket_factory_ = std::make_unique<TestPortMigrationSocketFactory>();
4504 Initialize();
4505
4506 TestSimplePortMigrationOnPathDegrading();
4507 }
4508
TEST_P(QuicSessionPoolTest,PortMigrationDisabledOnPathDegrading)4509 TEST_P(QuicSessionPoolTest, PortMigrationDisabledOnPathDegrading) {
4510 socket_factory_ = std::make_unique<TestPortMigrationSocketFactory>();
4511 Initialize();
4512
4513 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4514 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4515 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4516
4517 int packet_number = 1;
4518 MockQuicData quic_data1(version_);
4519 quic_data1.AddReadPauseForever();
4520 quic_data1.AddWrite(SYNCHRONOUS,
4521 ConstructInitialSettingsPacket(packet_number++));
4522 quic_data1.AddWrite(SYNCHRONOUS,
4523 ConstructGetRequestPacket(
4524 packet_number++,
4525 GetNthClientInitiatedBidirectionalStreamId(0), true));
4526 quic_data1.AddWrite(SYNCHRONOUS,
4527 client_maker_.MakeDataPacket(
4528 packet_number++, GetQpackDecoderStreamId(), false,
4529 StreamCancellationQpackDecoderInstruction(0)));
4530 quic_data1.AddWrite(
4531 SYNCHRONOUS,
4532 client_maker_.MakeRstPacket(packet_number++,
4533 GetNthClientInitiatedBidirectionalStreamId(0),
4534 quic::QUIC_STREAM_CANCELLED));
4535 quic_data1.AddSocketDataToFactory(socket_factory_.get());
4536
4537 // Create request and QuicHttpStream.
4538 RequestBuilder builder(this);
4539 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
4540 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4541 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
4542 EXPECT_TRUE(stream.get());
4543
4544 // Cause QUIC stream to be created.
4545 HttpRequestInfo request_info;
4546 request_info.method = "GET";
4547 request_info.url = GURL(kDefaultUrl);
4548 request_info.traffic_annotation =
4549 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4550 stream->RegisterRequest(&request_info);
4551 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
4552 CompletionOnceCallback()));
4553
4554 // Ensure that session is alive and active.
4555 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
4556 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
4557 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
4558
4559 // Send GET request on stream.
4560 HttpResponseInfo response;
4561 HttpRequestHeaders request_headers;
4562 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
4563 callback_.callback()));
4564 // Disable connection migration on the request streams.
4565 // This should have no effect for port migration.
4566 QuicChromiumClientStream* chrome_stream =
4567 static_cast<QuicChromiumClientStream*>(
4568 quic::test::QuicSessionPeer::GetStream(
4569 session, GetNthClientInitiatedBidirectionalStreamId(0)));
4570 EXPECT_TRUE(chrome_stream);
4571 chrome_stream->DisableConnectionMigrationToCellularNetwork();
4572
4573 EXPECT_EQ(0u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
4574
4575 // Manually initialize the connection's self address. In real life, the
4576 // initialization will be done during crypto handshake.
4577 IPEndPoint ip;
4578 session->GetDefaultSocket()->GetLocalAddress(&ip);
4579 quic::test::QuicConnectionPeer::SetSelfAddress(session->connection(),
4580 ToQuicSocketAddress(ip));
4581
4582 // Set session config to have active migration disabled.
4583 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
4584 session->config());
4585 EXPECT_TRUE(session->config()->DisableConnectionMigration());
4586
4587 // Cause the connection to report path degrading to the session.
4588 // Session will start to probe a different port.
4589 session->connection()->OnPathDegradingDetected();
4590 base::RunLoop().RunUntilIdle();
4591
4592 // The session should stay alive as if nothing happened.
4593 EXPECT_EQ(1u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
4594 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
4595 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
4596 EXPECT_EQ(1u, session->GetNumActiveStreams());
4597
4598 stream.reset();
4599 quic_data1.ExpectAllReadDataConsumed();
4600 quic_data1.ExpectAllWriteDataConsumed();
4601 }
4602
TEST_P(QuicSessionPoolTest,PortMigrationProbingReceivedStatelessReset_PathValidator)4603 TEST_P(QuicSessionPoolTest,
4604 PortMigrationProbingReceivedStatelessReset_PathValidator) {
4605 socket_factory_ = std::make_unique<TestPortMigrationSocketFactory>();
4606 Initialize();
4607 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4608 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4609 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4610
4611 // Using a testing task runner so that we can control time.
4612 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4613 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
4614
4615 int packet_number = 1;
4616 MockQuicData quic_data1(version_);
4617 quic_data1.AddReadPauseForever();
4618 quic_data1.AddWrite(SYNCHRONOUS,
4619 ConstructInitialSettingsPacket(packet_number++));
4620 quic_data1.AddWrite(SYNCHRONOUS,
4621 ConstructGetRequestPacket(
4622 packet_number++,
4623 GetNthClientInitiatedBidirectionalStreamId(0), true));
4624 quic_data1.AddWrite(SYNCHRONOUS,
4625 client_maker_.MakeDataPacket(
4626 packet_number + 1, GetQpackDecoderStreamId(), false,
4627 StreamCancellationQpackDecoderInstruction(0)));
4628 quic_data1.AddWrite(
4629 SYNCHRONOUS,
4630 client_maker_.MakeRstPacket(packet_number + 2,
4631 GetNthClientInitiatedBidirectionalStreamId(0),
4632 quic::QUIC_STREAM_CANCELLED));
4633 quic_data1.AddSocketDataToFactory(socket_factory_.get());
4634
4635 // Set up the second socket data provider that is used for migration probing.
4636 MockQuicData quic_data2(version_);
4637 quic::QuicConnectionId cid_on_new_path =
4638 quic::test::TestConnectionId(12345678);
4639 client_maker_.set_connection_id(cid_on_new_path);
4640 // Connectivity probe to be sent on the new path.
4641 quic_data2.AddWrite(
4642 SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(packet_number));
4643 quic_data2.AddReadPause();
4644 // Stateless reset to receive from the server.
4645 quic_data2.AddRead(ASYNC, server_maker_.MakeStatelessResetPacket());
4646 quic_data2.AddSocketDataToFactory(socket_factory_.get());
4647
4648 // Create request and QuicHttpStream.
4649 RequestBuilder builder(this);
4650 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
4651 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4652 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
4653 EXPECT_TRUE(stream.get());
4654
4655 // Cause QUIC stream to be created.
4656 HttpRequestInfo request_info;
4657 request_info.method = "GET";
4658 request_info.url = GURL(kDefaultUrl);
4659 request_info.traffic_annotation =
4660 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4661 stream->RegisterRequest(&request_info);
4662 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
4663 CompletionOnceCallback()));
4664
4665 // Ensure that session is alive and active.
4666 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
4667 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
4668 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
4669 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
4670
4671 // Send GET request on stream.
4672 HttpResponseInfo response;
4673 HttpRequestHeaders request_headers;
4674 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
4675 callback_.callback()));
4676
4677 // Manually initialize the connection's self address. In real life, the
4678 // initialization will be done during crypto handshake.
4679 IPEndPoint ip;
4680 session->GetDefaultSocket()->GetLocalAddress(&ip);
4681 quic::test::QuicConnectionPeer::SetSelfAddress(session->connection(),
4682 ToQuicSocketAddress(ip));
4683
4684 EXPECT_EQ(0u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
4685
4686 // Cause the connection to report path degrading to the session.
4687 // Session will start to probe a different port.
4688 session->connection()->OnPathDegradingDetected();
4689 base::RunLoop().RunUntilIdle();
4690
4691 EXPECT_EQ(1u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
4692
4693 // The connection should still be alive, and not marked as going away.
4694 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
4695 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
4696 EXPECT_EQ(1u, session->GetNumActiveStreams());
4697 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
4698
4699 // Resume quic data and a STATELESS_RESET is read from the probing path.
4700 quic_data2.Resume();
4701
4702 EXPECT_EQ(1u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
4703
4704 // Verify that the session is still active, and the request stream is active.
4705 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
4706 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
4707 EXPECT_EQ(1u, session->GetNumActiveStreams());
4708
4709 stream.reset();
4710 quic_data1.ExpectAllReadDataConsumed();
4711 quic_data1.ExpectAllWriteDataConsumed();
4712 quic_data2.ExpectAllReadDataConsumed();
4713 quic_data2.ExpectAllWriteDataConsumed();
4714 }
4715
TEST_P(QuicSessionPoolTest,MigratePortOnPathDegrading_WithNetworkHandle_PathValidator)4716 TEST_P(QuicSessionPoolTest,
4717 MigratePortOnPathDegrading_WithNetworkHandle_PathValidator) {
4718 scoped_mock_network_change_notifier_ =
4719 std::make_unique<ScopedMockNetworkChangeNotifier>();
4720 MockNetworkChangeNotifier* mock_ncn =
4721 scoped_mock_network_change_notifier_->mock_network_change_notifier();
4722 mock_ncn->ForceNetworkHandlesSupported();
4723 mock_ncn->SetConnectedNetworksList({kDefaultNetworkForTests});
4724 socket_factory_ = std::make_unique<TestPortMigrationSocketFactory>();
4725 Initialize();
4726
4727 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4728 ->NotifyNetworkMadeDefault(kDefaultNetworkForTests);
4729
4730 TestSimplePortMigrationOnPathDegrading();
4731 }
4732
TEST_P(QuicSessionPoolTest,MigratePortOnPathDegrading_WithMigration_PathValidator)4733 TEST_P(QuicSessionPoolTest,
4734 MigratePortOnPathDegrading_WithMigration_PathValidator) {
4735 scoped_mock_network_change_notifier_ =
4736 std::make_unique<ScopedMockNetworkChangeNotifier>();
4737 MockNetworkChangeNotifier* mock_ncn =
4738 scoped_mock_network_change_notifier_->mock_network_change_notifier();
4739 mock_ncn->ForceNetworkHandlesSupported();
4740 mock_ncn->SetConnectedNetworksList({kDefaultNetworkForTests});
4741 // Enable migration on network change.
4742 quic_params_->migrate_sessions_on_network_change_v2 = true;
4743 socket_factory_ = std::make_unique<TestPortMigrationSocketFactory>();
4744 Initialize();
4745
4746 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4747 ->NotifyNetworkMadeDefault(kDefaultNetworkForTests);
4748
4749 TestSimplePortMigrationOnPathDegrading();
4750 }
4751
TEST_P(QuicSessionPoolTest,TestPostNetworkOnMadeDefaultWhileConnectionMigrationFailOnUnexpectedErrorTwoDifferentSessions)4752 TEST_P(
4753 QuicSessionPoolTest,
4754 TestPostNetworkOnMadeDefaultWhileConnectionMigrationFailOnUnexpectedErrorTwoDifferentSessions) {
4755 scoped_mock_network_change_notifier_ =
4756 std::make_unique<ScopedMockNetworkChangeNotifier>();
4757 MockNetworkChangeNotifier* mock_ncn =
4758 scoped_mock_network_change_notifier_->mock_network_change_notifier();
4759 mock_ncn->ForceNetworkHandlesSupported();
4760 mock_ncn->SetConnectedNetworksList({kDefaultNetworkForTests});
4761 // Enable migration on network change.
4762 quic_params_->migrate_sessions_on_network_change_v2 = true;
4763 socket_factory_ = std::make_unique<TestPortMigrationSocketFactory>();
4764 Initialize();
4765
4766 MockQuicData socket_data1(version_);
4767 socket_data1.AddReadPauseForever();
4768 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
4769 socket_data1.AddWrite(ASYNC, OK);
4770 socket_data1.AddSocketDataToFactory(socket_factory_.get());
4771 client_maker_.Reset();
4772 MockQuicData socket_data2(version_);
4773 socket_data2.AddReadPauseForever();
4774 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
4775 socket_data2.AddWrite(ASYNC, OK);
4776 socket_data2.AddSocketDataToFactory(socket_factory_.get());
4777 // Add new sockets to use post migration. Those are bad sockets and will cause
4778 // migration to fail.
4779 MockConnect connect_result = MockConnect(ASYNC, ERR_UNEXPECTED);
4780 SequencedSocketData socket_data3(connect_result, base::span<MockRead>(),
4781 base::span<MockWrite>());
4782 socket_factory_->AddSocketDataProvider(&socket_data3);
4783 SequencedSocketData socket_data4(connect_result, base::span<MockRead>(),
4784 base::span<MockWrite>());
4785 socket_factory_->AddSocketDataProvider(&socket_data4);
4786
4787 url::SchemeHostPort server1(url::kHttpsScheme, kDefaultServerHostName, 443);
4788 url::SchemeHostPort server2(url::kHttpsScheme, kServer2HostName, 443);
4789
4790 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4791 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4792 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4793
4794 host_resolver_->set_synchronous_mode(true);
4795 host_resolver_->rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
4796 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.2", "");
4797
4798 // Create request and QuicHttpStream to create session1.
4799 RequestBuilder builder1(this);
4800 builder1.destination = server1;
4801 EXPECT_EQ(ERR_IO_PENDING, builder1.CallRequest());
4802 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4803 std::unique_ptr<HttpStream> stream1 = CreateStream(&builder1.request);
4804 EXPECT_TRUE(stream1.get());
4805
4806 // Create request and QuicHttpStream to create session2.
4807 RequestBuilder builder2(this);
4808 builder2.destination = server2;
4809 builder2.url = GURL(kServer2Url);
4810 EXPECT_EQ(ERR_IO_PENDING, builder2.CallRequest());
4811 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4812 std::unique_ptr<HttpStream> stream2 = CreateStream(&builder2.request);
4813 EXPECT_TRUE(stream2.get());
4814
4815 QuicChromiumClientSession* session1 = GetActiveSession(server1);
4816 QuicChromiumClientSession* session2 = GetActiveSession(server2);
4817 EXPECT_NE(session1, session2);
4818
4819 // Cause QUIC stream to be created and send GET so session1 has an open
4820 // stream.
4821 HttpRequestInfo request_info1;
4822 request_info1.method = "GET";
4823 request_info1.url = GURL(kDefaultUrl);
4824 request_info1.traffic_annotation =
4825 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4826 stream1->RegisterRequest(&request_info1);
4827 EXPECT_EQ(OK, stream1->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
4828 CompletionOnceCallback()));
4829 HttpResponseInfo response1;
4830 HttpRequestHeaders request_headers1;
4831 EXPECT_EQ(OK, stream1->SendRequest(request_headers1, &response1,
4832 callback_.callback()));
4833
4834 // Cause QUIC stream to be created and send GET so session2 has an open
4835 // stream.
4836 HttpRequestInfo request_info2;
4837 request_info2.method = "GET";
4838 request_info2.url = GURL(kDefaultUrl);
4839 request_info2.traffic_annotation =
4840 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4841 stream2->RegisterRequest(&request_info2);
4842 EXPECT_EQ(OK, stream2->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
4843 CompletionOnceCallback()));
4844 HttpResponseInfo response2;
4845 HttpRequestHeaders request_headers2;
4846 EXPECT_EQ(OK, stream2->SendRequest(request_headers2, &response2,
4847 callback_.callback()));
4848
4849 EXPECT_EQ(2u, crypto_client_stream_factory_.streams().size());
4850
4851 crypto_client_stream_factory_.streams()[0]->setHandshakeConfirmedForce(false);
4852 crypto_client_stream_factory_.streams()[1]->setHandshakeConfirmedForce(false);
4853
4854 std::unique_ptr<QuicChromiumClientSession::Handle> handle1 =
4855 session1->CreateHandle(server1);
4856 std::unique_ptr<QuicChromiumClientSession::Handle> handle2 =
4857 session2->CreateHandle(server2);
4858 mock_ncn->NotifyNetworkDisconnected(kDefaultNetworkForTests);
4859 mock_ncn->NotifyNetworkMadeDefault(kNewNetworkForTests);
4860
4861 NetErrorDetails details;
4862 handle1->PopulateNetErrorDetails(&details);
4863 EXPECT_EQ(
4864 quic::QuicErrorCode::QUIC_CONNECTION_MIGRATION_HANDSHAKE_UNCONFIRMED,
4865 details.quic_connection_error);
4866 EXPECT_EQ(false, details.quic_connection_migration_successful);
4867
4868 handle2->PopulateNetErrorDetails(&details);
4869 EXPECT_EQ(
4870 quic::QuicErrorCode::QUIC_CONNECTION_MIGRATION_HANDSHAKE_UNCONFIRMED,
4871 details.quic_connection_error);
4872 EXPECT_EQ(false, details.quic_connection_migration_successful);
4873 }
4874
TEST_P(QuicSessionPoolTest,TestPostNetworkMadeDefaultWhileConnectionMigrationFailBeforeHandshake)4875 TEST_P(QuicSessionPoolTest,
4876 TestPostNetworkMadeDefaultWhileConnectionMigrationFailBeforeHandshake) {
4877 scoped_mock_network_change_notifier_ =
4878 std::make_unique<ScopedMockNetworkChangeNotifier>();
4879 MockNetworkChangeNotifier* mock_ncn =
4880 scoped_mock_network_change_notifier_->mock_network_change_notifier();
4881 mock_ncn->ForceNetworkHandlesSupported();
4882 mock_ncn->SetConnectedNetworksList({kDefaultNetworkForTests});
4883 // Enable migration on network change.
4884 quic_params_->migrate_sessions_on_network_change_v2 = true;
4885 socket_factory_ = std::make_unique<TestPortMigrationSocketFactory>();
4886 Initialize();
4887 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4888 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4889
4890 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4891 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
4892
4893 int packet_num = 1;
4894 MockQuicData quic_data(version_);
4895 quic_data.AddReadPauseForever();
4896 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(packet_num++));
4897 quic_data.AddReadPauseForever();
4898
4899 quic_data.AddSocketDataToFactory(socket_factory_.get());
4900
4901 // Create request and QuicHttpStream.
4902 RequestBuilder builder(this);
4903 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
4904 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4905
4906 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
4907 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
4908 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
4909
4910 crypto_client_stream_factory_.last_stream()->setHandshakeConfirmedForce(
4911 false);
4912
4913 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
4914 session->CreateHandle(kDefaultDestination);
4915 mock_ncn->NotifyNetworkDisconnected(kDefaultNetworkForTests);
4916 mock_ncn->NotifyNetworkConnected(kNewNetworkForTests);
4917 mock_ncn->NotifyNetworkMadeDefault(kNewNetworkForTests);
4918
4919 NetErrorDetails details;
4920 handle->PopulateNetErrorDetails(&details);
4921 EXPECT_EQ(
4922 quic::QuicErrorCode::QUIC_CONNECTION_MIGRATION_HANDSHAKE_UNCONFIRMED,
4923 details.quic_connection_error);
4924 EXPECT_EQ(false, details.quic_connection_migration_successful);
4925 }
4926
4927 // See crbug/1465889 for more details on what scenario is being tested.
TEST_P(QuicSessionPoolTest,TestPostNetworkOnMadeDefaultWhileConnectionMigrationFailOnNoActiveStreams)4928 TEST_P(
4929 QuicSessionPoolTest,
4930 TestPostNetworkOnMadeDefaultWhileConnectionMigrationFailOnNoActiveStreams) {
4931 scoped_mock_network_change_notifier_ =
4932 std::make_unique<ScopedMockNetworkChangeNotifier>();
4933 MockNetworkChangeNotifier* mock_ncn =
4934 scoped_mock_network_change_notifier_->mock_network_change_notifier();
4935 mock_ncn->ForceNetworkHandlesSupported();
4936 mock_ncn->SetConnectedNetworksList({kDefaultNetworkForTests});
4937 // Enable migration on network change.
4938 quic_params_->migrate_sessions_on_network_change_v2 = true;
4939 socket_factory_ = std::make_unique<TestPortMigrationSocketFactory>();
4940 Initialize();
4941 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4942 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4943 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4944
4945 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4946 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
4947
4948 int packet_num = 1;
4949 MockQuicData quic_data(version_);
4950 quic_data.AddReadPauseForever();
4951 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(packet_num++));
4952 quic_data.AddWrite(
4953 SYNCHRONOUS,
4954 client_maker_.MakeConnectionClosePacket(
4955 packet_num, quic::QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS,
4956 "net error"));
4957
4958 quic_data.AddSocketDataToFactory(socket_factory_.get());
4959
4960 // Create request and QuicHttpStream.
4961 RequestBuilder builder(this);
4962 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
4963 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4964 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
4965 EXPECT_TRUE(stream.get());
4966
4967 // Ensure that session is alive and active.
4968 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
4969 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
4970 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
4971 EXPECT_FALSE(session->HasActiveRequestStreams());
4972
4973 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
4974 session->CreateHandle(kDefaultDestination);
4975 mock_ncn->NotifyNetworkDisconnected(kDefaultNetworkForTests);
4976 mock_ncn->NotifyNetworkConnected(kNewNetworkForTests);
4977 mock_ncn->NotifyNetworkMadeDefault(kNewNetworkForTests);
4978
4979 NetErrorDetails details;
4980 handle->PopulateNetErrorDetails(&details);
4981 EXPECT_EQ(
4982 quic::QuicErrorCode::QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS,
4983 details.quic_connection_error);
4984 EXPECT_EQ(false, details.quic_connection_migration_successful);
4985 }
4986
4987 // See crbug/1465889 for more details on what scenario is being tested.
TEST_P(QuicSessionPoolTest,TestPostNetworkOnMadeDefaultWhileConnectionMigrationFailOnUnexpectedError)4988 TEST_P(
4989 QuicSessionPoolTest,
4990 TestPostNetworkOnMadeDefaultWhileConnectionMigrationFailOnUnexpectedError) {
4991 scoped_mock_network_change_notifier_ =
4992 std::make_unique<ScopedMockNetworkChangeNotifier>();
4993 MockNetworkChangeNotifier* mock_ncn =
4994 scoped_mock_network_change_notifier_->mock_network_change_notifier();
4995 mock_ncn->ForceNetworkHandlesSupported();
4996 mock_ncn->SetConnectedNetworksList({kDefaultNetworkForTests});
4997 // Enable migration on network change.
4998 quic_params_->migrate_sessions_on_network_change_v2 = true;
4999 socket_factory_ = std::make_unique<TestPortMigrationSocketFactory>();
5000 Initialize();
5001 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5002 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5003 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5004
5005 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
5006 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
5007
5008 int packet_num = 1;
5009 MockQuicData quic_data(version_);
5010 quic_data.AddReadPauseForever();
5011 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(packet_num++));
5012 quic_data.AddWrite(
5013 SYNCHRONOUS,
5014 ConstructGetRequestPacket(
5015 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true));
5016 quic_data.AddReadPauseForever();
5017
5018 MockQuicData quic_data2(version_);
5019 quic_data2.AddConnect(ASYNC, ERR_UNEXPECTED);
5020
5021 quic_data.AddSocketDataToFactory(socket_factory_.get());
5022 quic_data2.AddSocketDataToFactory(socket_factory_.get());
5023
5024 // Create request and QuicHttpStream.
5025 RequestBuilder builder(this);
5026 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
5027 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5028 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
5029 EXPECT_TRUE(stream.get());
5030
5031 // Cause QUIC stream to be created.
5032 HttpRequestInfo request_info;
5033 request_info.method = "GET";
5034 request_info.url = GURL(kDefaultUrl);
5035 request_info.traffic_annotation =
5036 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5037 stream->RegisterRequest(&request_info);
5038 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
5039 CompletionOnceCallback()));
5040
5041 // Ensure that session is alive and active.
5042 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
5043 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
5044 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
5045
5046 // Send GET request on stream.
5047 HttpResponseInfo response;
5048 HttpRequestHeaders request_headers;
5049 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5050 callback_.callback()));
5051
5052 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
5053 session->CreateHandle(kDefaultDestination);
5054 mock_ncn->NotifyNetworkDisconnected(kDefaultNetworkForTests);
5055 mock_ncn->NotifyNetworkConnected(kNewNetworkForTests);
5056 mock_ncn->NotifyNetworkMadeDefault(kNewNetworkForTests);
5057
5058 NetErrorDetails details;
5059 handle->PopulateNetErrorDetails(&details);
5060 EXPECT_EQ(quic::QuicErrorCode::QUIC_CONNECTION_MIGRATION_INTERNAL_ERROR,
5061 details.quic_connection_error);
5062 EXPECT_EQ(false, details.quic_connection_migration_successful);
5063 }
5064
5065 // See crbug/1465889 for more details on what scenario is being tested.
TEST_P(QuicSessionPoolTest,TestPostNetworkOnMadeDefaultWhileConnectionMigrationIsFailing)5066 TEST_P(QuicSessionPoolTest,
5067 TestPostNetworkOnMadeDefaultWhileConnectionMigrationIsFailing) {
5068 scoped_mock_network_change_notifier_ =
5069 std::make_unique<ScopedMockNetworkChangeNotifier>();
5070 MockNetworkChangeNotifier* mock_ncn =
5071 scoped_mock_network_change_notifier_->mock_network_change_notifier();
5072 mock_ncn->ForceNetworkHandlesSupported();
5073 mock_ncn->SetConnectedNetworksList({kDefaultNetworkForTests});
5074 // Enable migration on network change.
5075 quic_params_->migrate_sessions_on_network_change_v2 = true;
5076 socket_factory_ = std::make_unique<TestPortMigrationSocketFactory>();
5077 Initialize();
5078 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5079 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5080 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5081
5082 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
5083 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
5084
5085 int packet_num = 1;
5086 MockQuicData quic_data(version_);
5087 quic_data.AddReadPauseForever();
5088 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(packet_num++));
5089 quic_data.AddWrite(
5090 SYNCHRONOUS,
5091 ConstructGetRequestPacket(
5092 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true));
5093 quic_data.AddReadPauseForever();
5094
5095 MockQuicData quic_data2(version_);
5096 quic_data2.AddReadPauseForever();
5097
5098 quic_data.AddSocketDataToFactory(socket_factory_.get());
5099 quic_data2.AddSocketDataToFactory(socket_factory_.get());
5100
5101 // Create request and QuicHttpStream.
5102 RequestBuilder builder(this);
5103 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
5104 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5105 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
5106 EXPECT_TRUE(stream.get());
5107
5108 // Cause QUIC stream to be created.
5109 HttpRequestInfo request_info;
5110 request_info.method = "GET";
5111 request_info.url = GURL(kDefaultUrl);
5112 request_info.traffic_annotation =
5113 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5114 stream->RegisterRequest(&request_info);
5115 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
5116 CompletionOnceCallback()));
5117
5118 // Ensure that session is alive and active.
5119 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
5120 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
5121 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
5122
5123 // Send GET request on stream.
5124 HttpResponseInfo response;
5125 HttpRequestHeaders request_headers;
5126 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5127 callback_.callback()));
5128
5129 std::unique_ptr<QuicChromiumClientSession::Handle> handle =
5130 session->CreateHandle(kDefaultDestination);
5131 mock_ncn->NotifyNetworkDisconnected(kDefaultNetworkForTests);
5132 mock_ncn->NotifyNetworkConnected(kNewNetworkForTests);
5133 mock_ncn->NotifyNetworkMadeDefault(kNewNetworkForTests);
5134
5135 NetErrorDetails details;
5136 handle->PopulateNetErrorDetails(&details);
5137 EXPECT_EQ(quic::QuicErrorCode::QUIC_CONNECTION_MIGRATION_TOO_MANY_CHANGES,
5138 details.quic_connection_error);
5139 EXPECT_EQ(false, details.quic_connection_migration_successful);
5140 }
5141
5142 // Regression test for https://crbug.com/1465889
5143 // Note: This test can be deleted once every instance of
5144 // CloseSessionOnErrorLater has been deleted.
TEST_P(QuicSessionPoolTest,TestCloseSessionOnErrorLaterThenConnectionMigrationMigrateToSocket)5145 TEST_P(QuicSessionPoolTest,
5146 TestCloseSessionOnErrorLaterThenConnectionMigrationMigrateToSocket) {
5147 scoped_mock_network_change_notifier_ =
5148 std::make_unique<ScopedMockNetworkChangeNotifier>();
5149 MockNetworkChangeNotifier* mock_ncn =
5150 scoped_mock_network_change_notifier_->mock_network_change_notifier();
5151 mock_ncn->ForceNetworkHandlesSupported();
5152 mock_ncn->SetConnectedNetworksList(
5153 {kDefaultNetworkForTests, kNewNetworkForTests});
5154 // Enable migration on network change.
5155 quic_params_->migrate_sessions_on_network_change_v2 = true;
5156 socket_factory_ = std::make_unique<TestPortMigrationSocketFactory>();
5157 Initialize();
5158 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5159 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5160
5161 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
5162 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
5163
5164 int packet_num = 1;
5165 MockQuicData quic_data(version_);
5166 quic_data.AddReadPauseForever();
5167 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(packet_num++));
5168 quic_data.AddWrite(
5169 SYNCHRONOUS,
5170 ConstructGetRequestPacket(
5171 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true));
5172 quic_data.AddReadPauseForever();
5173 quic_data.AddSocketDataToFactory(socket_factory_.get());
5174
5175 // Create request and QuicHttpStream.
5176 RequestBuilder builder(this);
5177 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
5178 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5179 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
5180 EXPECT_TRUE(stream.get());
5181
5182 // Cause QUIC stream to be created.
5183 HttpRequestInfo request_info;
5184 request_info.method = "GET";
5185 request_info.url = GURL(kDefaultUrl);
5186 request_info.traffic_annotation =
5187 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5188 stream->RegisterRequest(&request_info);
5189 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
5190 CompletionOnceCallback()));
5191
5192 // Ensure that session is alive and active.
5193 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
5194 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
5195 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
5196
5197 // Send GET request on stream.
5198 HttpResponseInfo response;
5199 HttpRequestHeaders request_headers;
5200 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5201 callback_.callback()));
5202 session->CloseSessionOnErrorLater(
5203 0, quic::QUIC_TOO_MANY_RTOS, quic::ConnectionCloseBehavior::SILENT_CLOSE);
5204 session->MigrateToSocket(
5205 quic::QuicSocketAddress(), quic::QuicSocketAddress(), nullptr,
5206 std::make_unique<QuicChromiumPacketWriter>(nullptr, task_runner.get()));
5207 }
5208
5209 // Regression test for https://crbug.com/1465889
5210 // Note: This test can be deleted once every instance of
5211 // CloseSessionOnErrorLater has been deleted.
TEST_P(QuicSessionPoolTest,TestCloseSessionOnErrorLaterThenConnectionMigrationMigrate)5212 TEST_P(QuicSessionPoolTest,
5213 TestCloseSessionOnErrorLaterThenConnectionMigrationMigrate) {
5214 scoped_mock_network_change_notifier_ =
5215 std::make_unique<ScopedMockNetworkChangeNotifier>();
5216 MockNetworkChangeNotifier* mock_ncn =
5217 scoped_mock_network_change_notifier_->mock_network_change_notifier();
5218 mock_ncn->ForceNetworkHandlesSupported();
5219 mock_ncn->SetConnectedNetworksList(
5220 {kDefaultNetworkForTests, kNewNetworkForTests});
5221 // Enable migration on network change.
5222 quic_params_->migrate_sessions_on_network_change_v2 = true;
5223 socket_factory_ = std::make_unique<TestPortMigrationSocketFactory>();
5224 Initialize();
5225 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5226 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5227
5228 int packet_num = 1;
5229 MockQuicData quic_data(version_);
5230 quic_data.AddReadPauseForever();
5231 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(packet_num++));
5232 quic_data.AddWrite(
5233 SYNCHRONOUS,
5234 ConstructGetRequestPacket(
5235 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true));
5236 quic_data.AddReadPauseForever();
5237
5238 MockQuicData quic_data2(version_);
5239 quic_data2.AddReadPauseForever();
5240
5241 quic_data.AddSocketDataToFactory(socket_factory_.get());
5242 quic_data2.AddSocketDataToFactory(socket_factory_.get());
5243
5244 // Create request and QuicHttpStream.
5245 RequestBuilder builder(this);
5246 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
5247 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5248 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
5249 EXPECT_TRUE(stream.get());
5250
5251 // Cause QUIC stream to be created.
5252 HttpRequestInfo request_info;
5253 request_info.method = "GET";
5254 request_info.url = GURL(kDefaultUrl);
5255 request_info.traffic_annotation =
5256 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5257 stream->RegisterRequest(&request_info);
5258 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
5259 CompletionOnceCallback()));
5260
5261 // Ensure that session is alive and active.
5262 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
5263 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
5264 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
5265
5266 // Send GET request on stream.
5267 HttpResponseInfo response;
5268 HttpRequestHeaders request_headers;
5269 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5270 callback_.callback()));
5271
5272 std::unique_ptr<DatagramClientSocket> socket(
5273 factory_->CreateSocket(net_log_.net_log(), net_log_.source()));
5274 DatagramClientSocket* socket_ptr = socket.get();
5275 factory_->ConnectAndConfigureSocket(
5276 base::BindLambdaForTesting([&session, &socket](int rv) {
5277 session->CloseSessionOnErrorLater(
5278 0, quic::QUIC_TOO_MANY_RTOS,
5279 quic::ConnectionCloseBehavior::SILENT_CLOSE);
5280 // The QuicSession is closed so FinishMigrate will fail to migrate the
5281 // socket. Hence the callback should never be called.
5282 session->FinishMigrate(
5283 std::move(socket),
5284 ToIPEndPoint(session->connection()->peer_address()), true,
5285 base::BindLambdaForTesting(
5286 [](MigrationResult result) { NOTREACHED_NORETURN(); }),
5287 /* RV = OK */ 0);
5288 }),
5289 socket_ptr, ToIPEndPoint(session->connection()->peer_address()),
5290 kNewNetworkForTests, SocketTag());
5291 base::RunLoop().RunUntilIdle();
5292 }
5293
5294 void QuicSessionPoolTest::
TestThatBlackHoleIsDisabledOnNoNewNetworkThenResumedAfterConnectingToANetwork(bool is_blackhole_disabled_after_disconnecting)5295 TestThatBlackHoleIsDisabledOnNoNewNetworkThenResumedAfterConnectingToANetwork(
5296 bool is_blackhole_disabled_after_disconnecting) {
5297 scoped_mock_network_change_notifier_ =
5298 std::make_unique<ScopedMockNetworkChangeNotifier>();
5299 MockNetworkChangeNotifier* mock_ncn =
5300 scoped_mock_network_change_notifier_->mock_network_change_notifier();
5301 mock_ncn->ForceNetworkHandlesSupported();
5302 mock_ncn->SetConnectedNetworksList({kDefaultNetworkForTests});
5303 // Enable migration on network change.
5304 quic_params_->migrate_sessions_on_network_change_v2 = true;
5305 socket_factory_ = std::make_unique<TestPortMigrationSocketFactory>();
5306 Initialize();
5307 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5308 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5309 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5310
5311 // Using a testing task runner so that we can control time.
5312 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
5313 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
5314
5315 int packet_num = 1;
5316 MockQuicData quic_data(version_);
5317 quic_data.AddReadPauseForever();
5318 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(packet_num++));
5319 quic_data.AddWrite(
5320 SYNCHRONOUS,
5321 ConstructGetRequestPacket(
5322 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true));
5323 quic_data.AddReadPauseForever();
5324 MockQuicData quic_data2(version_);
5325 quic::QuicConnectionId cid_on_new_path =
5326 quic::test::TestConnectionId(12345678);
5327 client_maker_.set_connection_id(cid_on_new_path);
5328 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(packet_num++));
5329 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeRetireConnectionIdPacket(
5330 packet_num++, /*sequence_number=*/0u));
5331
5332 quic_data2.AddRead(
5333 ASYNC, ConstructOkResponsePacket(
5334 1, GetNthClientInitiatedBidirectionalStreamId(0), false));
5335 quic_data2.AddReadPauseForever();
5336 quic_data2.AddWrite(SYNCHRONOUS,
5337 client_maker_.MakeDataPacket(
5338 packet_num++, GetQpackDecoderStreamId(), false,
5339 StreamCancellationQpackDecoderInstruction(0)));
5340 quic_data2.AddWrite(
5341 SYNCHRONOUS,
5342 client_maker_.MakeRstPacket(packet_num++,
5343 GetNthClientInitiatedBidirectionalStreamId(0),
5344 quic::QUIC_STREAM_CANCELLED));
5345
5346 quic_data.AddSocketDataToFactory(socket_factory_.get());
5347 quic_data2.AddSocketDataToFactory(socket_factory_.get());
5348
5349 // Create request and QuicHttpStream.
5350 RequestBuilder builder(this);
5351 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
5352 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5353 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
5354 EXPECT_TRUE(stream.get());
5355
5356 // Cause QUIC stream to be created.
5357 HttpRequestInfo request_info;
5358 request_info.method = "GET";
5359 request_info.url = GURL(kDefaultUrl);
5360 request_info.traffic_annotation =
5361 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5362 stream->RegisterRequest(&request_info);
5363 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
5364 CompletionOnceCallback()));
5365
5366 // Ensure that session is alive and active.
5367 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
5368 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
5369 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
5370 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
5371 // Send GET request on stream.
5372 HttpResponseInfo response;
5373 HttpRequestHeaders request_headers;
5374 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5375 callback_.callback()));
5376 handles::NetworkHandle old_network = session->GetCurrentNetwork();
5377 // Forcefully disconnect the current network. This should stop the blackhole
5378 // detector since there is no other available network.
5379 mock_ncn->NotifyNetworkDisconnected(kDefaultNetworkForTests);
5380
5381 if (is_blackhole_disabled_after_disconnecting) {
5382 EXPECT_FALSE(
5383 session->connection()->blackhole_detector().IsDetectionInProgress());
5384 } else {
5385 EXPECT_TRUE(
5386 session->connection()->blackhole_detector().IsDetectionInProgress());
5387 }
5388
5389 // This will fire migrateImmediately which will connect to a new socket on the
5390 // new network.
5391 mock_ncn->NotifyNetworkConnected(kNewNetworkForTests);
5392
5393 // Execute the tasks that are added to the task runner from
5394 // NotifyNetworkConnected.
5395 task_runner->RunUntilIdle();
5396 base::RunLoop().RunUntilIdle();
5397
5398 // Verify that we are on the new network.
5399 EXPECT_TRUE(old_network != session->GetCurrentNetwork());
5400 EXPECT_TRUE(session->GetCurrentNetwork() == kNewNetworkForTests);
5401
5402 // Verify that blackhole detector is still active.
5403 EXPECT_TRUE(
5404 session->connection()->blackhole_detector().IsDetectionInProgress());
5405
5406 // Verify that we also received the response on the new path.
5407 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
5408 EXPECT_EQ(200, response.headers->response_code());
5409 }
5410 // When the feature is disabled, the blackhole detector should stay enabled
5411 // when there is no available network. resumed once a new network has been
5412 // connected to.
TEST_P(QuicSessionPoolTest,VerifyThatBlackHoleIsDisabledOnNoAvailableNetworkThenResumedAfterConnectingToNewNetwork_FeatureDisabled)5413 TEST_P(
5414 QuicSessionPoolTest,
5415 VerifyThatBlackHoleIsDisabledOnNoAvailableNetworkThenResumedAfterConnectingToNewNetwork_FeatureDisabled) {
5416 TestThatBlackHoleIsDisabledOnNoNewNetworkThenResumedAfterConnectingToANetwork(
5417 false);
5418 }
5419
5420 // When the feature is enabled, the blackhole detector should be disabled
5421 // when there is no available network. resumed once a new network has been
5422 // connected to.
TEST_P(QuicSessionPoolTest,VerifyThatBlackHoleIsDisabledOnNoAvailableNetworkThenResumedAfterConnectingToNewNetwork_FeatureEnabled)5423 TEST_P(
5424 QuicSessionPoolTest,
5425 VerifyThatBlackHoleIsDisabledOnNoAvailableNetworkThenResumedAfterConnectingToNewNetwork_FeatureEnabled) {
5426 base::test::ScopedFeatureList feature_list;
5427 feature_list.InitWithFeatures(
5428 // enabled_features
5429 {features::kDisableBlackholeOnNoNewNetwork},
5430 // disabled_features
5431 {});
5432 TestThatBlackHoleIsDisabledOnNoNewNetworkThenResumedAfterConnectingToANetwork(
5433 true);
5434 }
5435
TestSimplePortMigrationOnPathDegrading()5436 void QuicSessionPoolTest::TestSimplePortMigrationOnPathDegrading() {
5437 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5438 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5439 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5440
5441 // Using a testing task runner so that we can control time.
5442 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
5443 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
5444
5445 int packet_number = 1;
5446 MockQuicData quic_data1(version_);
5447 quic_data1.AddReadPauseForever();
5448 quic_data1.AddWrite(SYNCHRONOUS,
5449 ConstructInitialSettingsPacket(packet_number++));
5450 quic_data1.AddWrite(SYNCHRONOUS,
5451 ConstructGetRequestPacket(
5452 packet_number++,
5453 GetNthClientInitiatedBidirectionalStreamId(0), true));
5454 quic_data1.AddSocketDataToFactory(socket_factory_.get());
5455
5456 // Set up the second socket data provider that is used after migration.
5457 // The response to the earlier request is read on the new socket.
5458 MockQuicData quic_data2(version_);
5459 quic::QuicConnectionId cid_on_new_path =
5460 quic::test::TestConnectionId(12345678);
5461
5462 client_maker_.set_connection_id(cid_on_new_path);
5463 // Connectivity probe to be sent on the new path.
5464 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(
5465 packet_number++));
5466 quic_data2.AddReadPause();
5467 // Connectivity probe to receive from the server.
5468 quic_data2.AddRead(ASYNC, server_maker_.MakeConnectivityProbingPacket(1));
5469 // Ping packet to send after migration is completed.
5470 quic_data2.AddWrite(ASYNC, client_maker_.MakePingPacket(packet_number++));
5471 quic_data2.AddRead(
5472 ASYNC, ConstructOkResponsePacket(
5473 2, GetNthClientInitiatedBidirectionalStreamId(0), false));
5474 quic_data2.AddReadPauseForever();
5475 quic_data2.AddWrite(SYNCHRONOUS,
5476 client_maker_.MakeAckAndRetireConnectionIdPacket(
5477 packet_number++,
5478 /*largest_received=*/2,
5479 /*smallest_received=*/1, /*sequence_number=*/0u));
5480 quic_data2.AddWrite(
5481 SYNCHRONOUS,
5482 client_maker_.MakeDataPacket(
5483 packet_number++, GetQpackDecoderStreamId(),
5484 /*fin=*/false, StreamCancellationQpackDecoderInstruction(0)));
5485 quic_data2.AddWrite(
5486 SYNCHRONOUS,
5487 client_maker_.MakeRstPacket(packet_number++,
5488 GetNthClientInitiatedBidirectionalStreamId(0),
5489 quic::QUIC_STREAM_CANCELLED));
5490 quic_data2.AddSocketDataToFactory(socket_factory_.get());
5491
5492 // Create request and QuicHttpStream.
5493 RequestBuilder builder(this);
5494 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
5495 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5496 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
5497 EXPECT_TRUE(stream.get());
5498
5499 // Cause QUIC stream to be created.
5500 HttpRequestInfo request_info;
5501 request_info.method = "GET";
5502 request_info.url = GURL(kDefaultUrl);
5503 request_info.traffic_annotation =
5504 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5505 stream->RegisterRequest(&request_info);
5506 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
5507 CompletionOnceCallback()));
5508
5509 // Ensure that session is alive and active.
5510 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
5511 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
5512 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
5513 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
5514
5515 // Send GET request on stream.
5516 HttpResponseInfo response;
5517 HttpRequestHeaders request_headers;
5518 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5519 callback_.callback()));
5520 // Disable connection migration on the request streams.
5521 // This should have no effect for port migration.
5522 QuicChromiumClientStream* chrome_stream =
5523 static_cast<QuicChromiumClientStream*>(
5524 quic::test::QuicSessionPeer::GetStream(
5525 session, GetNthClientInitiatedBidirectionalStreamId(0)));
5526 EXPECT_TRUE(chrome_stream);
5527 chrome_stream->DisableConnectionMigrationToCellularNetwork();
5528
5529 EXPECT_EQ(0u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
5530
5531 // Manually initialize the connection's self address. In real life, the
5532 // initialization will be done during crypto handshake.
5533 IPEndPoint ip;
5534 session->GetDefaultSocket()->GetLocalAddress(&ip);
5535 quic::test::QuicConnectionPeer::SetSelfAddress(session->connection(),
5536 ToQuicSocketAddress(ip));
5537
5538 // Cause the connection to report path degrading to the session.
5539 // Session will start to probe a different port.
5540 session->connection()->OnPathDegradingDetected();
5541 base::RunLoop().RunUntilIdle();
5542
5543 EXPECT_EQ(1u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
5544
5545 // There should be one pending task as the probe posted a DoNothingAs
5546 // callback.
5547 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
5548 task_runner->ClearPendingTasks();
5549
5550 // The connection should still be alive, and not marked as going away.
5551 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
5552 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
5553 EXPECT_EQ(1u, session->GetNumActiveStreams());
5554 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
5555
5556 // Resume quic data and a connectivity probe response will be read on the new
5557 // socket.
5558 quic_data2.Resume();
5559
5560 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
5561 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
5562 EXPECT_EQ(1u, session->GetNumActiveStreams());
5563 // Successful port migration causes the path no longer degrading on the same
5564 // network.
5565 EXPECT_EQ(0u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
5566
5567 // There should be pending tasks, the nearest one will complete
5568 // migration to the new port.
5569 task_runner->RunUntilIdle();
5570
5571 // Fire any outstanding quic alarms.
5572 base::RunLoop().RunUntilIdle();
5573
5574 // Response headers are received over the new port.
5575 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5576 EXPECT_EQ(200, response.headers->response_code());
5577
5578 EXPECT_EQ(0u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
5579
5580 // Now there may be one pending task to send connectivity probe that has been
5581 // cancelled due to successful migration.
5582 task_runner->FastForwardUntilNoTasksRemain();
5583
5584 // Verify that the session is still alive, and the request stream is still
5585 // alive.
5586 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
5587 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
5588 chrome_stream = static_cast<QuicChromiumClientStream*>(
5589 quic::test::QuicSessionPeer::GetStream(
5590 session, GetNthClientInitiatedBidirectionalStreamId(0)));
5591 EXPECT_TRUE(chrome_stream);
5592
5593 stream.reset();
5594 quic_data1.ExpectAllReadDataConsumed();
5595 quic_data1.ExpectAllWriteDataConsumed();
5596 quic_data2.ExpectAllReadDataConsumed();
5597 quic_data2.ExpectAllWriteDataConsumed();
5598 }
5599
TEST_P(QuicSessionPoolTest,MultiplePortMigrationsExceedsMaxLimit_iQUICStyle)5600 TEST_P(QuicSessionPoolTest, MultiplePortMigrationsExceedsMaxLimit_iQUICStyle) {
5601 socket_factory_ = std::make_unique<TestPortMigrationSocketFactory>();
5602 Initialize();
5603
5604 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5605 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5606 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5607
5608 // Using a testing task runner so that we can control time.
5609 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
5610 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
5611
5612 int packet_number = 1;
5613 MockQuicData quic_data1(version_);
5614 quic_data1.AddReadPauseForever();
5615 quic_data1.AddWrite(SYNCHRONOUS,
5616 ConstructInitialSettingsPacket(packet_number++));
5617 quic_data1.AddWrite(SYNCHRONOUS,
5618 ConstructGetRequestPacket(
5619 packet_number++,
5620 GetNthClientInitiatedBidirectionalStreamId(0), true));
5621 quic_data1.AddSocketDataToFactory(socket_factory_.get());
5622
5623 // Create request and QuicHttpStream.
5624 RequestBuilder builder(this);
5625 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
5626 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5627 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
5628 EXPECT_TRUE(stream.get());
5629
5630 // Cause QUIC stream to be created.
5631 HttpRequestInfo request_info;
5632 request_info.method = "GET";
5633 request_info.url = GURL(kDefaultUrl);
5634 request_info.traffic_annotation =
5635 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5636 stream->RegisterRequest(&request_info);
5637 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
5638 CompletionOnceCallback()));
5639
5640 // Ensure that session is alive and active.
5641 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
5642 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
5643 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
5644
5645 // Send GET request on stream.
5646 HttpResponseInfo response;
5647 HttpRequestHeaders request_headers;
5648 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5649 callback_.callback()));
5650
5651 int server_packet_num = 1;
5652 // Perform 4 round of successful migration, and the 5th round will
5653 // cancel after successful probing due to hitting the limit.
5654 for (int i = 0; i <= 4; i++) {
5655 // Set up a different socket data provider that is used for
5656 // probing and migration.
5657 MockQuicData quic_data2(version_);
5658 // Connectivity probe to be sent on the new path.
5659 uint64_t new_cid = 12345678;
5660 quic::QuicConnectionId cid_on_new_path =
5661 quic::test::TestConnectionId(new_cid + i);
5662 client_maker_.set_connection_id(cid_on_new_path);
5663 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session, i + 1);
5664 quic_data2.AddWrite(
5665 SYNCHRONOUS,
5666 client_maker_.MakeConnectivityProbingPacket(packet_number));
5667 packet_number++;
5668 quic_data2.AddReadPause();
5669 // Connectivity probe to receive from the server.
5670 quic_data2.AddRead(ASYNC, server_maker_.MakeConnectivityProbingPacket(
5671 server_packet_num++));
5672 if (i == 0) {
5673 // Retire old connection id and send ping packet after migration is
5674 // completed.
5675 quic_data2.AddWrite(
5676 SYNCHRONOUS,
5677 client_maker_.MakeRetireConnectionIdPacket(packet_number++,
5678 /*sequence_number=*/0u));
5679 quic_data2.AddWrite(SYNCHRONOUS,
5680 client_maker_.MakePingPacket(packet_number++));
5681 } else if (i != 4) {
5682 quic_data2.AddWrite(SYNCHRONOUS,
5683 client_maker_.MakeAckAndRetireConnectionIdPacket(
5684 packet_number++, 1 + 2 * i, 1 + 2 * i, i));
5685 quic_data2.AddWrite(SYNCHRONOUS,
5686 client_maker_.MakePingPacket(packet_number++));
5687 }
5688
5689 if (i == 4) {
5690 // Add one more synchronous read on the last probing reader. The
5691 // reader should be deleted on the read before this one.
5692 // The test will verify this read is not consumed.
5693 quic_data2.AddRead(
5694 SYNCHRONOUS,
5695 server_maker_.MakeConnectivityProbingPacket(server_packet_num++));
5696 } else {
5697 quic_data2.AddRead(ASYNC, server_maker_.MakeConnectivityProbingPacket(
5698 server_packet_num++));
5699 }
5700
5701 if (i == 3) {
5702 // On the last allowed port migration, read one more packet so
5703 // that ACK is sent. The next round of migration (which hits the limit)
5704 // will not send any proactive ACK when reading the successful probing
5705 // response.
5706 quic_data2.AddRead(ASYNC, server_maker_.MakeConnectivityProbingPacket(
5707 server_packet_num++));
5708 quic_data2.AddWrite(SYNCHRONOUS,
5709 client_maker_.MakeAckPacket(packet_number++, 9, 9));
5710 }
5711 quic_data2.AddReadPauseForever();
5712 quic_data2.AddSocketDataToFactory(socket_factory_.get());
5713
5714 EXPECT_EQ(0u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
5715
5716 // Cause the connection to report path degrading to the session.
5717 // Session will start to probe a different port.
5718 session->connection()->OnPathDegradingDetected();
5719 base::RunLoop().RunUntilIdle();
5720
5721 EXPECT_EQ(1u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
5722
5723 // The retry mechanism is internal to path validator.
5724 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
5725
5726 // The connection should still be alive, and not marked as going away.
5727 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
5728 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
5729 EXPECT_EQ(1u, session->GetNumActiveStreams());
5730
5731 // Resume quic data and a connectivity probe response will be read on the
5732 // new socket.
5733 quic_data2.Resume();
5734 base::RunLoop().RunUntilIdle();
5735
5736 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
5737 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
5738 EXPECT_EQ(1u, session->GetNumActiveStreams());
5739
5740 if (i < 4) {
5741 // There's a pending task to complete migration to the new port.
5742 task_runner->RunUntilIdle();
5743 } else {
5744 // Last attempt to migrate will abort due to hitting the limit of max
5745 // number of allowed migrations.
5746 task_runner->FastForwardUntilNoTasksRemain();
5747 }
5748
5749 quic_data2.ExpectAllWriteDataConsumed();
5750 // The last round of migration will abort upon reading the probing response.
5751 // Future reads in the same socket is ignored.
5752 if (i != 4) {
5753 quic_data2.ExpectAllReadDataConsumed();
5754 } else {
5755 EXPECT_FALSE(quic_data2.AllReadDataConsumed());
5756 }
5757 }
5758
5759 // Verify that the session is still alive.
5760 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
5761 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
5762
5763 stream.reset();
5764 quic_data1.ExpectAllReadDataConsumed();
5765 quic_data1.ExpectAllWriteDataConsumed();
5766 }
5767
TEST_P(QuicSessionPoolTest,MigratePortOnPathDegrading_MigrateIdleSession_PathValidator)5768 TEST_P(QuicSessionPoolTest,
5769 MigratePortOnPathDegrading_MigrateIdleSession_PathValidator) {
5770 scoped_mock_network_change_notifier_ =
5771 std::make_unique<ScopedMockNetworkChangeNotifier>();
5772 MockNetworkChangeNotifier* mock_ncn =
5773 scoped_mock_network_change_notifier_->mock_network_change_notifier();
5774 mock_ncn->ForceNetworkHandlesSupported();
5775 mock_ncn->SetConnectedNetworksList({kDefaultNetworkForTests});
5776 // Enable migration on network change.
5777 quic_params_->migrate_sessions_on_network_change_v2 = true;
5778 quic_params_->migrate_idle_sessions = true;
5779 socket_factory_ = std::make_unique<TestPortMigrationSocketFactory>();
5780 Initialize();
5781
5782 scoped_mock_network_change_notifier_->mock_network_change_notifier()
5783 ->NotifyNetworkMadeDefault(kDefaultNetworkForTests);
5784
5785 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5786 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5787 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5788
5789 // Using a testing task runner so that we can control time.
5790 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
5791 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
5792
5793 int packet_number = 1;
5794 MockQuicData quic_data1(version_);
5795 quic_data1.AddWrite(SYNCHRONOUS,
5796 ConstructInitialSettingsPacket(packet_number++));
5797 quic_data1.AddWrite(SYNCHRONOUS,
5798 ConstructGetRequestPacket(
5799 packet_number++,
5800 GetNthClientInitiatedBidirectionalStreamId(0), true));
5801 quic_data1.AddReadPause();
5802 // The client session will receive the response first and closes its only
5803 // stream.
5804 quic_data1.AddRead(ASYNC,
5805 ConstructOkResponsePacket(
5806 1, GetNthClientInitiatedBidirectionalStreamId(0),
5807 /*fin = */ true));
5808 quic_data1.AddReadPauseForever();
5809 quic_data1.AddSocketDataToFactory(socket_factory_.get());
5810
5811 // Set up the second socket data provider that is used after migration.
5812 // The response to the earlier request is read on the new socket.
5813 MockQuicData quic_data2(version_);
5814 quic::QuicConnectionId cid_on_new_path =
5815 quic::test::TestConnectionId(12345678);
5816 client_maker_.set_connection_id(cid_on_new_path);
5817 // Connectivity probe to be sent on the new path.
5818 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(
5819 packet_number++));
5820 quic_data2.AddReadPause();
5821 // Connectivity probe to receive from the server.
5822 quic_data2.AddRead(ASYNC, server_maker_.MakeConnectivityProbingPacket(2));
5823 quic_data2.AddReadPauseForever();
5824 // Ping packet to send after migration is completed.
5825 quic_data2.AddWrite(
5826 ASYNC, client_maker_.MakeAckAndPingPacket(packet_number++, 2, 1));
5827
5828 quic_data2.AddWrite(SYNCHRONOUS,
5829 client_maker_.MakeRetireConnectionIdPacket(
5830 packet_number++, /*sequence_number=*/0u));
5831 quic_data2.AddSocketDataToFactory(socket_factory_.get());
5832
5833 // Create request and QuicHttpStream.
5834 RequestBuilder builder(this);
5835 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
5836 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5837 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
5838 EXPECT_TRUE(stream.get());
5839
5840 // Cause QUIC stream to be created.
5841 HttpRequestInfo request_info;
5842 request_info.method = "GET";
5843 request_info.url = GURL(kDefaultUrl);
5844 request_info.traffic_annotation =
5845 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5846 stream->RegisterRequest(&request_info);
5847 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
5848 CompletionOnceCallback()));
5849
5850 // Ensure that session is alive and active.
5851 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
5852 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
5853 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
5854 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
5855
5856 // Send GET request on stream.
5857 HttpResponseInfo response;
5858 HttpRequestHeaders request_headers;
5859 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5860 callback_.callback()));
5861 // Disable connection migration on the request streams.
5862 // This should have no effect for port migration.
5863 QuicChromiumClientStream* chrome_stream =
5864 static_cast<QuicChromiumClientStream*>(
5865 quic::test::QuicSessionPeer::GetStream(
5866 session, GetNthClientInitiatedBidirectionalStreamId(0)));
5867 EXPECT_TRUE(chrome_stream);
5868 chrome_stream->DisableConnectionMigrationToCellularNetwork();
5869
5870 EXPECT_EQ(0u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
5871
5872 // Manually initialize the connection's self address. In real life, the
5873 // initialization will be done during crypto handshake.
5874 IPEndPoint ip;
5875 session->GetDefaultSocket()->GetLocalAddress(&ip);
5876 quic::test::QuicConnectionPeer::SetSelfAddress(session->connection(),
5877 ToQuicSocketAddress(ip));
5878
5879 // Cause the connection to report path degrading to the session.
5880 // Session will start to probe a different port.
5881 session->connection()->OnPathDegradingDetected();
5882 base::RunLoop().RunUntilIdle();
5883 EXPECT_EQ(1u, session->GetNumActiveStreams());
5884 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
5885 // A response will be received on the current path and closes the request
5886 // stream.
5887 quic_data1.Resume();
5888 base::RunLoop().RunUntilIdle();
5889 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5890 EXPECT_EQ(200, response.headers->response_code());
5891 EXPECT_EQ(0u, session->GetNumActiveStreams());
5892
5893 EXPECT_EQ(1u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
5894
5895 // There should be one pending task as the probe posted a DoNothingAs
5896 // callback.
5897 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
5898 task_runner->ClearPendingTasks();
5899
5900 // The connection should still be alive, and not marked as going away.
5901 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
5902 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
5903
5904 // Resume quic data and a connectivity probe response will be read on the new
5905 // socket.
5906 quic_data2.Resume();
5907
5908 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
5909 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
5910 // Successful port migration causes the path no longer degrading on the same
5911 // network.
5912 EXPECT_EQ(0u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
5913
5914 // There should be pending tasks, the nearest one will complete
5915 // migration to the new port.
5916 task_runner->RunUntilIdle();
5917
5918 // Fire any outstanding quic alarms.
5919 base::RunLoop().RunUntilIdle();
5920
5921 // Now there may be one pending task to send connectivity probe that has been
5922 // cancelled due to successful migration.
5923 task_runner->FastForwardUntilNoTasksRemain();
5924
5925 // Verify that the session is still alive.
5926 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
5927 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
5928
5929 quic_data1.ExpectAllReadDataConsumed();
5930 quic_data1.ExpectAllWriteDataConsumed();
5931 quic_data2.ExpectAllReadDataConsumed();
5932 quic_data2.ExpectAllWriteDataConsumed();
5933 }
5934
5935 // This test verifies that the connection will not migrate to a bad socket
5936 // when path degrading is detected.
TEST_P(QuicSessionPoolTest,DoNotMigrateToBadSocketOnPathDegrading)5937 TEST_P(QuicSessionPoolTest, DoNotMigrateToBadSocketOnPathDegrading) {
5938 InitializeConnectionMigrationV2Test(
5939 {kDefaultNetworkForTests, kNewNetworkForTests});
5940 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5941 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5942 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5943
5944 // Using a testing task runner so that we can control time.
5945 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
5946 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
5947
5948 scoped_mock_network_change_notifier_->mock_network_change_notifier()
5949 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
5950
5951 MockQuicData quic_data(version_);
5952 int packet_num = 1;
5953 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(packet_num++));
5954 quic_data.AddWrite(
5955 SYNCHRONOUS,
5956 ConstructGetRequestPacket(
5957 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true));
5958 quic_data.AddReadPause();
5959 quic_data.AddRead(
5960 ASYNC, ConstructOkResponsePacket(
5961 1, GetNthClientInitiatedBidirectionalStreamId(0), false));
5962 quic_data.AddReadPauseForever();
5963 quic_data.AddWrite(SYNCHRONOUS,
5964 client_maker_.MakeAckAndDataPacket(
5965 packet_num++, GetQpackDecoderStreamId(), 1, 1, false,
5966 StreamCancellationQpackDecoderInstruction(0)));
5967 quic_data.AddWrite(
5968 SYNCHRONOUS,
5969 client_maker_.MakeRstPacket(packet_num++,
5970 GetNthClientInitiatedBidirectionalStreamId(0),
5971 quic::QUIC_STREAM_CANCELLED));
5972 quic_data.AddSocketDataToFactory(socket_factory_.get());
5973
5974 // Set up second socket that will immediately return disconnected.
5975 // The stream factory will abort probe the alternate network.
5976 MockConnect bad_connect = MockConnect(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
5977 SequencedSocketData socket_data(bad_connect, base::span<MockRead>(),
5978 base::span<MockWrite>());
5979 socket_factory_->AddSocketDataProvider(&socket_data);
5980
5981 // Create request and QuicHttpStream.
5982 RequestBuilder builder(this);
5983 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
5984 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5985 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
5986 EXPECT_TRUE(stream.get());
5987
5988 // Cause QUIC stream to be created.
5989 HttpRequestInfo request_info;
5990 request_info.method = "GET";
5991 request_info.url = GURL(kDefaultUrl);
5992 request_info.traffic_annotation =
5993 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5994 stream->RegisterRequest(&request_info);
5995 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
5996 CompletionOnceCallback()));
5997
5998 // Ensure that session is alive and active.
5999 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
6000 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
6001 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
6002
6003 // Send GET request on stream.
6004 HttpResponseInfo response;
6005 HttpRequestHeaders request_headers;
6006 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6007 callback_.callback()));
6008
6009 EXPECT_EQ(0u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
6010 // Cause the connection to report path degrading to the session.
6011 // Session will start to probe the alternate network.
6012 session->connection()->OnPathDegradingDetected();
6013 base::RunLoop().RunUntilIdle();
6014 EXPECT_EQ(1u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
6015
6016 // The connection should still be alive, and not marked as going away.
6017 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
6018 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
6019 EXPECT_EQ(1u, session->GetNumActiveStreams());
6020 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
6021
6022 // Resume the data, and response header is received over the original network.
6023 quic_data.Resume();
6024 EXPECT_THAT(callback_.WaitForResult(), IsOk());
6025 EXPECT_EQ(200, response.headers->response_code());
6026 // There should be one pending task left as the probe posted a
6027 // DoNothingAsCallback.
6028 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
6029
6030 // Verify that the session is still alive.
6031 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
6032 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
6033
6034 stream.reset();
6035 quic_data.ExpectAllReadDataConsumed();
6036 quic_data.ExpectAllWriteDataConsumed();
6037 }
6038
6039 // Regression test for http://crbug.com/847569.
6040 // This test verifies that the connection migrates to the alternate network
6041 // early when there is no active stream but a draining stream.
6042 // The first packet being written after migration is a synchrnous write, which
6043 // will cause a PING packet being sent.
TEST_P(QuicSessionPoolTest,MigrateSessionWithDrainingStreamSync)6044 TEST_P(QuicSessionPoolTest, MigrateSessionWithDrainingStreamSync) {
6045 TestMigrateSessionWithDrainingStream(SYNCHRONOUS);
6046 }
6047
6048 // Regression test for http://crbug.com/847569.
6049 // This test verifies that the connection migrates to the alternate network
6050 // early when there is no active stream but a draining stream.
6051 // The first packet being written after migration is an asynchronous write, no
6052 // PING packet will be sent.
TEST_P(QuicSessionPoolTest,MigrateSessionWithDrainingStreamAsync)6053 TEST_P(QuicSessionPoolTest, MigrateSessionWithDrainingStreamAsync) {
6054 TestMigrateSessionWithDrainingStream(ASYNC);
6055 }
6056
TestMigrateSessionWithDrainingStream(IoMode write_mode_for_queued_packet)6057 void QuicSessionPoolTest::TestMigrateSessionWithDrainingStream(
6058 IoMode write_mode_for_queued_packet) {
6059 InitializeConnectionMigrationV2Test(
6060 {kDefaultNetworkForTests, kNewNetworkForTests});
6061 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6062 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6063 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6064 client_maker_.set_save_packet_frames(true);
6065
6066 // Using a testing task runner so that we can control time.
6067 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
6068 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
6069
6070 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6071 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
6072
6073 int packet_number = 1;
6074 MockQuicData quic_data1(version_);
6075 quic_data1.AddWrite(SYNCHRONOUS,
6076 ConstructInitialSettingsPacket(packet_number++));
6077 quic_data1.AddWrite(SYNCHRONOUS,
6078 ConstructGetRequestPacket(
6079 packet_number++,
6080 GetNthClientInitiatedBidirectionalStreamId(0), true));
6081 // Read an out of order packet with FIN to drain the stream.
6082 quic_data1.AddRead(ASYNC,
6083 ConstructOkResponsePacket(
6084 2, GetNthClientInitiatedBidirectionalStreamId(0),
6085 true)); // keep sending version.
6086 quic_data1.AddReadPauseForever();
6087 quic_data1.AddSocketDataToFactory(socket_factory_.get());
6088
6089 // Set up the second socket data provider that is used after migration.
6090 MockQuicData quic_data2(version_);
6091 quic::QuicConnectionId cid_on_new_path =
6092 quic::test::TestConnectionId(12345678);
6093 client_maker_.set_connection_id(cid_on_new_path);
6094 // Connectivity probe to be sent on the new path.
6095 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(
6096 packet_number++));
6097 quic_data2.AddReadPause();
6098 // Connectivity probe to receive from the server.
6099 quic_data2.AddRead(ASYNC, server_maker_.MakeConnectivityProbingPacket(3));
6100 // Ping packet to send after migration is completed.
6101 quic_data2.AddWrite(write_mode_for_queued_packet,
6102 client_maker_.MakeAckAndRetransmissionPacket(
6103 packet_number++, 2, 3, 3, {1, 2}));
6104 if (write_mode_for_queued_packet == SYNCHRONOUS) {
6105 quic_data2.AddWrite(ASYNC, client_maker_.MakePingPacket(packet_number++));
6106 }
6107 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeRetireConnectionIdPacket(
6108 packet_number++, 0u));
6109 server_maker_.Reset();
6110 quic_data2.AddRead(
6111 ASYNC, ConstructOkResponsePacket(
6112 1, GetNthClientInitiatedBidirectionalStreamId(0), false));
6113 quic_data2.AddWrite(SYNCHRONOUS,
6114 client_maker_.MakeAckPacket(packet_number++, 1, 3, 1));
6115 quic_data2.AddReadPauseForever();
6116 quic_data2.AddSocketDataToFactory(socket_factory_.get());
6117
6118 // Create request and QuicHttpStream.
6119 RequestBuilder builder(this);
6120 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
6121 EXPECT_THAT(callback_.WaitForResult(), IsOk());
6122 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
6123 EXPECT_TRUE(stream.get());
6124
6125 // Cause QUIC stream to be created.
6126 HttpRequestInfo request_info;
6127 request_info.method = "GET";
6128 request_info.url = GURL(kDefaultUrl);
6129 request_info.traffic_annotation =
6130 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6131 stream->RegisterRequest(&request_info);
6132 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
6133 CompletionOnceCallback()));
6134
6135 // Ensure that session is alive and active.
6136 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
6137 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
6138 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
6139 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
6140
6141 // Send GET request on stream.
6142 HttpResponseInfo response;
6143 HttpRequestHeaders request_headers;
6144 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6145 callback_.callback()));
6146
6147 // Run the message loop to receive the out of order packet which contains a
6148 // FIN and drains the stream.
6149 base::RunLoop().RunUntilIdle();
6150 EXPECT_EQ(0u, session->GetNumActiveStreams());
6151
6152 EXPECT_EQ(0u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
6153 // Cause the connection to report path degrading to the session.
6154 // Session should still start to probe the alternate network.
6155 session->connection()->OnPathDegradingDetected();
6156 base::RunLoop().RunUntilIdle();
6157 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
6158 EXPECT_EQ(1u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
6159
6160 // The connection should still be alive, and not marked as going away.
6161 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
6162
6163 // Resume quic data and a connectivity probe response will be read on the new
6164 // socket.
6165 quic_data2.Resume();
6166
6167 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
6168 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
6169 EXPECT_EQ(0u, session->GetNumActiveStreams());
6170 EXPECT_TRUE(session->HasActiveRequestStreams());
6171
6172 // There should be a task that will complete the migration to the new network.
6173 task_runner->RunUntilIdle();
6174
6175 // Deliver a signal that the alternate network now becomes default to session,
6176 // this will cancel mgirate back to default network timer.
6177 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6178 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
6179
6180 task_runner->FastForwardBy(base::Seconds(kMinRetryTimeForDefaultNetworkSecs));
6181
6182 // Verify that the session is still alive.
6183 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
6184 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
6185 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6186
6187 stream.reset();
6188 quic_data1.ExpectAllReadDataConsumed();
6189 quic_data1.ExpectAllWriteDataConsumed();
6190 quic_data2.ExpectAllReadDataConsumed();
6191 quic_data2.ExpectAllWriteDataConsumed();
6192 }
6193
6194 // Regression test for http://crbug.com/835444.
6195 // This test verifies that the connection migrates to the alternate network
6196 // when the alternate network is connected after path has been degrading.
TEST_P(QuicSessionPoolTest,MigrateOnNewNetworkConnectAfterPathDegrading)6197 TEST_P(QuicSessionPoolTest, MigrateOnNewNetworkConnectAfterPathDegrading) {
6198 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
6199 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6200 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6201 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6202 client_maker_.set_save_packet_frames(true);
6203
6204 // Using a testing task runner so that we can control time.
6205 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
6206 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
6207
6208 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6209 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
6210
6211 MockQuicData quic_data1(version_);
6212 quic_data1.AddReadPauseForever();
6213 int packet_num = 1;
6214 quic_data1.AddWrite(SYNCHRONOUS,
6215 ConstructInitialSettingsPacket(packet_num++));
6216 quic_data1.AddWrite(
6217 SYNCHRONOUS,
6218 ConstructGetRequestPacket(
6219 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true));
6220 quic_data1.AddSocketDataToFactory(socket_factory_.get());
6221
6222 // Set up the second socket data provider that is used after migration.
6223 // The response to the earlier request is read on the new socket.
6224 MockQuicData quic_data2(version_);
6225 quic::QuicConnectionId cid_on_new_path =
6226 quic::test::TestConnectionId(12345678);
6227 client_maker_.set_connection_id(cid_on_new_path);
6228 // Connectivity probe to be sent on the new path.
6229 quic_data2.AddWrite(
6230 SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(packet_num++));
6231 quic_data2.AddReadPause();
6232 // Connectivity probe to receive from the server.
6233 quic_data2.AddRead(ASYNC, server_maker_.MakeConnectivityProbingPacket(1));
6234 // in-flight SETTINGS and requests will be retransmitted. Since data is
6235 // already sent on the new address, ping will no longer be sent.
6236 quic_data2.AddWrite(ASYNC,
6237 client_maker_.MakeCombinedRetransmissionPacket(
6238 /*original_packet_numbers=*/{1, 2}, packet_num++));
6239 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeRetireConnectionIdPacket(
6240 packet_num++, 0u));
6241 quic_data2.AddRead(
6242 ASYNC, ConstructOkResponsePacket(
6243 2, GetNthClientInitiatedBidirectionalStreamId(0), false));
6244 quic_data2.AddReadPauseForever();
6245 quic_data2.AddWrite(SYNCHRONOUS,
6246 client_maker_.MakeAckAndDataPacket(
6247 packet_num++, GetQpackDecoderStreamId(), 2, 2, false,
6248 StreamCancellationQpackDecoderInstruction(0)));
6249 quic_data2.AddWrite(
6250 SYNCHRONOUS,
6251 client_maker_.MakeRstPacket(packet_num++,
6252 GetNthClientInitiatedBidirectionalStreamId(0),
6253 quic::QUIC_STREAM_CANCELLED));
6254
6255 quic_data2.AddSocketDataToFactory(socket_factory_.get());
6256
6257 // Create request and QuicHttpStream.
6258 RequestBuilder builder(this);
6259 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
6260 EXPECT_THAT(callback_.WaitForResult(), IsOk());
6261 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
6262 EXPECT_TRUE(stream.get());
6263
6264 // Cause QUIC stream to be created.
6265 HttpRequestInfo request_info;
6266 request_info.method = "GET";
6267 request_info.url = GURL(kDefaultUrl);
6268 request_info.traffic_annotation =
6269 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6270 stream->RegisterRequest(&request_info);
6271 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
6272 CompletionOnceCallback()));
6273
6274 // Ensure that session is alive and active.
6275 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
6276 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
6277 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
6278 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
6279
6280 // Send GET request on stream.
6281 HttpResponseInfo response;
6282 HttpRequestHeaders request_headers;
6283 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6284 callback_.callback()));
6285
6286 EXPECT_EQ(0u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
6287
6288 // Cause the connection to report path degrading to the session.
6289 // Due to lack of alternate network, session will not mgirate connection.
6290 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
6291 EXPECT_EQ(0u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
6292 session->connection()->OnPathDegradingDetected();
6293 base::RunLoop().RunUntilIdle();
6294 EXPECT_EQ(1u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
6295 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
6296
6297 EXPECT_EQ(1u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
6298
6299 // Deliver a signal that a alternate network is connected now, this should
6300 // cause the connection to start early migration on path degrading.
6301 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6302 ->SetConnectedNetworksList(
6303 {kDefaultNetworkForTests, kNewNetworkForTests});
6304 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6305 ->NotifyNetworkConnected(kNewNetworkForTests);
6306
6307 // The connection should still be alive, and not marked as going away.
6308 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
6309 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
6310 EXPECT_EQ(1u, session->GetNumActiveStreams());
6311 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
6312
6313 // Resume quic data and a connectivity probe response will be read on the new
6314 // socket.
6315 quic_data2.Resume();
6316
6317 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
6318 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
6319 EXPECT_EQ(1u, session->GetNumActiveStreams());
6320
6321 // There should be a task that will complete the migration to the new network.
6322 task_runner->RunUntilIdle();
6323
6324 // Although the session successfully migrates, it is still considered
6325 // degrading sessions.
6326 EXPECT_EQ(1u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
6327
6328 // Response headers are received over the new network.
6329 EXPECT_THAT(callback_.WaitForResult(), IsOk());
6330 EXPECT_EQ(200, response.headers->response_code());
6331
6332 // Deliver a signal that the alternate network now becomes default to session,
6333 // this will cancel mgirate back to default network timer.
6334 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6335 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
6336
6337 // There's one more task to mgirate back to the default network in 0.4s.
6338 task_runner->FastForwardBy(base::Seconds(kMinRetryTimeForDefaultNetworkSecs));
6339
6340 // Verify that the session is still alive.
6341 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
6342 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
6343
6344 stream.reset();
6345 quic_data1.ExpectAllReadDataConsumed();
6346 quic_data1.ExpectAllWriteDataConsumed();
6347 quic_data2.ExpectAllReadDataConsumed();
6348 quic_data2.ExpectAllWriteDataConsumed();
6349 }
6350
6351 // This test verifies that multiple sessions are migrated on connection
6352 // migration signal.
TEST_P(QuicSessionPoolTest,MigrateMultipleSessionsToBadSocketsAfterDisconnected)6353 TEST_P(QuicSessionPoolTest,
6354 MigrateMultipleSessionsToBadSocketsAfterDisconnected) {
6355 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
6356
6357 MockQuicData socket_data1(version_);
6358 socket_data1.AddReadPauseForever();
6359 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
6360 socket_data1.AddWrite(ASYNC, OK);
6361 socket_data1.AddSocketDataToFactory(socket_factory_.get());
6362 client_maker_.Reset();
6363 MockQuicData socket_data2(version_);
6364 socket_data2.AddReadPauseForever();
6365 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
6366 socket_data2.AddWrite(ASYNC, OK);
6367 socket_data2.AddSocketDataToFactory(socket_factory_.get());
6368
6369 url::SchemeHostPort server1(url::kHttpsScheme, kDefaultServerHostName, 443);
6370 url::SchemeHostPort server2(url::kHttpsScheme, kServer2HostName, 443);
6371
6372 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6373 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6374 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6375
6376 host_resolver_->set_synchronous_mode(true);
6377 host_resolver_->rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
6378 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.2", "");
6379
6380 // Create request and QuicHttpStream to create session1.
6381 RequestBuilder builder1(this);
6382 builder1.destination = server1;
6383 EXPECT_EQ(ERR_IO_PENDING, builder1.CallRequest());
6384 EXPECT_THAT(callback_.WaitForResult(), IsOk());
6385 std::unique_ptr<HttpStream> stream1 = CreateStream(&builder1.request);
6386 EXPECT_TRUE(stream1.get());
6387
6388 // Create request and QuicHttpStream to create session2.
6389 RequestBuilder builder2(this);
6390 builder2.destination = server2;
6391 builder2.url = GURL(kServer2Url);
6392 EXPECT_EQ(ERR_IO_PENDING, builder2.CallRequest());
6393 EXPECT_THAT(callback_.WaitForResult(), IsOk());
6394 std::unique_ptr<HttpStream> stream2 = CreateStream(&builder2.request);
6395 EXPECT_TRUE(stream2.get());
6396
6397 QuicChromiumClientSession* session1 = GetActiveSession(server1);
6398 QuicChromiumClientSession* session2 = GetActiveSession(server2);
6399 EXPECT_NE(session1, session2);
6400
6401 // Cause QUIC stream to be created and send GET so session1 has an open
6402 // stream.
6403 HttpRequestInfo request_info1;
6404 request_info1.method = "GET";
6405 request_info1.url = GURL(kDefaultUrl);
6406 request_info1.traffic_annotation =
6407 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6408 stream1->RegisterRequest(&request_info1);
6409 EXPECT_EQ(OK, stream1->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
6410 CompletionOnceCallback()));
6411 HttpResponseInfo response1;
6412 HttpRequestHeaders request_headers1;
6413 EXPECT_EQ(OK, stream1->SendRequest(request_headers1, &response1,
6414 callback_.callback()));
6415
6416 // Cause QUIC stream to be created and send GET so session2 has an open
6417 // stream.
6418 HttpRequestInfo request_info2;
6419 request_info2.method = "GET";
6420 request_info2.url = GURL(kDefaultUrl);
6421 request_info2.traffic_annotation =
6422 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6423 stream2->RegisterRequest(&request_info2);
6424 EXPECT_EQ(OK, stream2->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
6425 CompletionOnceCallback()));
6426 HttpResponseInfo response2;
6427 HttpRequestHeaders request_headers2;
6428 EXPECT_EQ(OK, stream2->SendRequest(request_headers2, &response2,
6429 callback_.callback()));
6430
6431 // Cause both sessions to be paused due to DISCONNECTED.
6432 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6433 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
6434
6435 // Ensure that both sessions are paused but alive.
6436 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session1));
6437 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session2));
6438
6439 // Add new sockets to use post migration. Those are bad sockets and will cause
6440 // migration to fail.
6441 MockConnect connect_result =
6442 MockConnect(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
6443 SequencedSocketData socket_data3(connect_result, base::span<MockRead>(),
6444 base::span<MockWrite>());
6445 socket_factory_->AddSocketDataProvider(&socket_data3);
6446 SequencedSocketData socket_data4(connect_result, base::span<MockRead>(),
6447 base::span<MockWrite>());
6448 socket_factory_->AddSocketDataProvider(&socket_data4);
6449
6450 // Connect the new network and cause migration to bad sockets, causing
6451 // sessions to close.
6452 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6453 ->SetConnectedNetworksList({kNewNetworkForTests});
6454 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6455 ->NotifyNetworkConnected(kNewNetworkForTests);
6456
6457 EXPECT_FALSE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session1));
6458 EXPECT_FALSE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session2));
6459
6460 socket_data1.ExpectAllReadDataConsumed();
6461 socket_data1.ExpectAllWriteDataConsumed();
6462 socket_data2.ExpectAllReadDataConsumed();
6463 socket_data2.ExpectAllWriteDataConsumed();
6464 }
6465
6466 // This test verifies that session attempts connection migration with signals
6467 // delivered in the following order (no alternate network is available):
6468 // - path degrading is detected: session attempts connection migration but no
6469 // alternate network is available, session caches path degrading signal in
6470 // connection and stays on the original network.
6471 // - original network backs up, request is served in the orignal network,
6472 // session is not marked as going away.
TEST_P(QuicSessionPoolTest,MigrateOnPathDegradingWithNoNewNetwork)6473 TEST_P(QuicSessionPoolTest, MigrateOnPathDegradingWithNoNewNetwork) {
6474 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
6475 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6476 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6477
6478 MockQuicData quic_data(version_);
6479 int packet_num = 1;
6480 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(packet_num++));
6481 quic_data.AddWrite(
6482 SYNCHRONOUS,
6483 ConstructGetRequestPacket(
6484 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true));
6485 quic_data.AddReadPause();
6486
6487 // The rest of the data will still flow in the original socket as there is no
6488 // new network after path degrading.
6489 quic_data.AddRead(
6490 ASYNC, ConstructOkResponsePacket(
6491 1, GetNthClientInitiatedBidirectionalStreamId(0), false));
6492 quic_data.AddReadPauseForever();
6493 quic_data.AddWrite(SYNCHRONOUS,
6494 client_maker_.MakeAckAndDataPacket(
6495 packet_num++, GetQpackDecoderStreamId(), 1, 1, false,
6496 StreamCancellationQpackDecoderInstruction(0)));
6497 quic_data.AddWrite(
6498 SYNCHRONOUS,
6499 client_maker_.MakeRstPacket(packet_num++,
6500 GetNthClientInitiatedBidirectionalStreamId(0),
6501 quic::QUIC_STREAM_CANCELLED));
6502 quic_data.AddSocketDataToFactory(socket_factory_.get());
6503
6504 // Create request and QuicHttpStream.
6505 RequestBuilder builder(this);
6506 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
6507 EXPECT_THAT(callback_.WaitForResult(), IsOk());
6508 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
6509 EXPECT_TRUE(stream.get());
6510
6511 // Cause QUIC stream to be created.
6512 HttpRequestInfo request_info;
6513 request_info.method = "GET";
6514 request_info.url = GURL(kDefaultUrl);
6515 request_info.traffic_annotation =
6516 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6517 stream->RegisterRequest(&request_info);
6518 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
6519 CompletionOnceCallback()));
6520
6521 // Ensure that session is alive and active.
6522 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
6523 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
6524 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
6525
6526 // Send GET request on stream.
6527 HttpResponseInfo response;
6528 HttpRequestHeaders request_headers;
6529 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6530 callback_.callback()));
6531
6532 // Trigger connection migration on path degrading. Since there are no networks
6533 // to migrate to, the session will remain on the original network, not marked
6534 // as going away.
6535 EXPECT_EQ(0u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
6536 session->connection()->OnPathDegradingDetected();
6537 base::RunLoop().RunUntilIdle();
6538 EXPECT_TRUE(session->connection()->IsPathDegrading());
6539 EXPECT_EQ(1u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
6540
6541 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
6542 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
6543 EXPECT_EQ(1u, session->GetNumActiveStreams());
6544 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
6545
6546 // Resume so that rest of the data will flow in the original socket.
6547 quic_data.Resume();
6548
6549 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
6550 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
6551 EXPECT_EQ(1u, session->GetNumActiveStreams());
6552
6553 stream.reset();
6554 quic_data.ExpectAllReadDataConsumed();
6555 quic_data.ExpectAllWriteDataConsumed();
6556 }
6557
6558 // This test verifies that session with non-migratable stream will probe the
6559 // alternate network on path degrading, and close the non-migratable streams
6560 // when probe is successful.
TEST_P(QuicSessionPoolTest,MigrateSessionEarlyNonMigratableStream_DoNotMigrateIdleSessions)6561 TEST_P(QuicSessionPoolTest,
6562 MigrateSessionEarlyNonMigratableStream_DoNotMigrateIdleSessions) {
6563 TestMigrateSessionEarlyNonMigratableStream(false);
6564 }
6565
TEST_P(QuicSessionPoolTest,MigrateSessionEarlyNonMigratableStream_MigrateIdleSessions)6566 TEST_P(QuicSessionPoolTest,
6567 MigrateSessionEarlyNonMigratableStream_MigrateIdleSessions) {
6568 TestMigrateSessionEarlyNonMigratableStream(true);
6569 }
6570
TestMigrateSessionEarlyNonMigratableStream(bool migrate_idle_sessions)6571 void QuicSessionPoolTest::TestMigrateSessionEarlyNonMigratableStream(
6572 bool migrate_idle_sessions) {
6573 quic_params_->migrate_idle_sessions = migrate_idle_sessions;
6574 InitializeConnectionMigrationV2Test(
6575 {kDefaultNetworkForTests, kNewNetworkForTests});
6576 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6577 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6578 client_maker_.set_save_packet_frames(true);
6579
6580 MockQuicData socket_data(version_);
6581 socket_data.AddReadPauseForever();
6582 int packet_num = 1;
6583 socket_data.AddWrite(SYNCHRONOUS,
6584 ConstructInitialSettingsPacket(packet_num++));
6585
6586 // Set up the second socket data provider that is used for probing.
6587 MockQuicData quic_data1(version_);
6588 quic::QuicConnectionId cid_on_old_path =
6589 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator());
6590 quic::QuicConnectionId cid_on_new_path =
6591 quic::test::TestConnectionId(12345678);
6592 client_maker_.set_connection_id(cid_on_new_path);
6593 // Connectivity probe to be sent on the new path.
6594 quic_data1.AddWrite(
6595 SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(packet_num++));
6596 quic_data1.AddReadPause();
6597 // Connectivity probe to receive from the server.
6598 quic_data1.AddRead(ASYNC, server_maker_.MakeConnectivityProbingPacket(1));
6599
6600 if (migrate_idle_sessions) {
6601 quic_data1.AddReadPauseForever();
6602 // A RESET will be sent to the peer to cancel the non-migratable stream.
6603 quic_data1.AddWrite(SYNCHRONOUS,
6604 client_maker_.MakeDataAndRstPacket(
6605 packet_num++, GetQpackDecoderStreamId(),
6606 StreamCancellationQpackDecoderInstruction(0),
6607 GetNthClientInitiatedBidirectionalStreamId(0),
6608 quic::QUIC_STREAM_CANCELLED));
6609 quic_data1.AddWrite(
6610 SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(1, packet_num++));
6611 // Ping packet to send after migration is completed.
6612 quic_data1.AddWrite(SYNCHRONOUS,
6613 client_maker_.MakePingPacket(packet_num++));
6614 quic_data1.AddWrite(SYNCHRONOUS, client_maker_.MakeRetireConnectionIdPacket(
6615 packet_num++, 0u));
6616 } else {
6617 client_maker_.set_connection_id(cid_on_old_path);
6618 socket_data.AddWrite(
6619 SYNCHRONOUS, client_maker_.MakeDataRstAckAndConnectionClosePacket(
6620 packet_num++, GetQpackDecoderStreamId(),
6621 StreamCancellationQpackDecoderInstruction(0),
6622 GetNthClientInitiatedBidirectionalStreamId(0),
6623 quic::QUIC_STREAM_CANCELLED, 1, 1,
6624 quic::QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS,
6625 "net error", /*path_response_frame*/ 0x1b));
6626 }
6627
6628 socket_data.AddSocketDataToFactory(socket_factory_.get());
6629 quic_data1.AddSocketDataToFactory(socket_factory_.get());
6630
6631 // Create request and QuicHttpStream.
6632 RequestBuilder builder(this);
6633 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
6634 EXPECT_THAT(callback_.WaitForResult(), IsOk());
6635 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
6636 EXPECT_TRUE(stream.get());
6637
6638 // Cause QUIC stream to be created, but marked as non-migratable.
6639 HttpRequestInfo request_info;
6640 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
6641 request_info.traffic_annotation =
6642 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6643 stream->RegisterRequest(&request_info);
6644 EXPECT_EQ(OK, stream->InitializeStream(false, DEFAULT_PRIORITY, net_log_,
6645 CompletionOnceCallback()));
6646
6647 // Ensure that session is alive and active.
6648 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
6649 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
6650 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
6651 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
6652
6653 // Trigger connection migration. Since there is a non-migratable stream,
6654 // this should cause session to migrate.
6655 session->OnPathDegrading();
6656
6657 // Run the message loop so that data queued in the new socket is read by the
6658 // packet reader.
6659 base::RunLoop().RunUntilIdle();
6660
6661 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
6662 EXPECT_EQ(1u, session->GetNumActiveStreams());
6663
6664 // Resume the data to read the connectivity probing response to declare probe
6665 // as successful. Non-migratable streams will be closed.
6666 quic_data1.Resume();
6667 if (migrate_idle_sessions) {
6668 base::RunLoop().RunUntilIdle();
6669 }
6670
6671 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(kDefaultDestination));
6672 EXPECT_EQ(0u, session->GetNumActiveStreams());
6673
6674 quic_data1.ExpectAllReadDataConsumed();
6675 quic_data1.ExpectAllWriteDataConsumed();
6676 socket_data.ExpectAllReadDataConsumed();
6677 socket_data.ExpectAllWriteDataConsumed();
6678 }
6679
TEST_P(QuicSessionPoolTest,MigrateSessionEarlyConnectionMigrationDisabled)6680 TEST_P(QuicSessionPoolTest, MigrateSessionEarlyConnectionMigrationDisabled) {
6681 InitializeConnectionMigrationV2Test(
6682 {kDefaultNetworkForTests, kNewNetworkForTests});
6683 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6684 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6685
6686 MockQuicData socket_data(version_);
6687 socket_data.AddReadPauseForever();
6688 int packet_num = 1;
6689 socket_data.AddWrite(SYNCHRONOUS,
6690 ConstructInitialSettingsPacket(packet_num++));
6691 socket_data.AddWrite(SYNCHRONOUS,
6692 client_maker_.MakeDataPacket(
6693 packet_num++, GetQpackDecoderStreamId(), false,
6694 StreamCancellationQpackDecoderInstruction(0)));
6695 socket_data.AddWrite(
6696 SYNCHRONOUS,
6697 client_maker_.MakeRstPacket(packet_num++,
6698 GetNthClientInitiatedBidirectionalStreamId(0),
6699 quic::QUIC_STREAM_CANCELLED));
6700 socket_data.AddSocketDataToFactory(socket_factory_.get());
6701
6702 // Create request and QuicHttpStream.
6703 RequestBuilder builder(this);
6704 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
6705 EXPECT_THAT(callback_.WaitForResult(), IsOk());
6706 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
6707 EXPECT_TRUE(stream.get());
6708
6709 // Cause QUIC stream to be created.
6710 HttpRequestInfo request_info;
6711 request_info.traffic_annotation =
6712 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6713 stream->RegisterRequest(&request_info);
6714 EXPECT_EQ(OK, stream->InitializeStream(false, DEFAULT_PRIORITY, net_log_,
6715 CompletionOnceCallback()));
6716
6717 // Ensure that session is alive and active.
6718 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
6719 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
6720 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
6721
6722 // Set session config to have connection migration disabled.
6723 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
6724 session->config());
6725 EXPECT_TRUE(session->config()->DisableConnectionMigration());
6726
6727 // Trigger connection migration. Since there is a non-migratable stream,
6728 // this should cause session to be continue without migrating.
6729 session->OnPathDegrading();
6730
6731 // Run the message loop so that data queued in the new socket is read by the
6732 // packet reader.
6733 base::RunLoop().RunUntilIdle();
6734
6735 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
6736 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
6737 EXPECT_EQ(1u, session->GetNumActiveStreams());
6738
6739 stream.reset();
6740
6741 socket_data.ExpectAllReadDataConsumed();
6742 socket_data.ExpectAllWriteDataConsumed();
6743 }
6744
6745 // Regression test for http://crbug.com/791886.
6746 // This test verifies that the old packet writer which encountered an
6747 // asynchronous write error will be blocked during migration on write error. New
6748 // packets would not be written until the one with write error is rewritten on
6749 // the new network.
TEST_P(QuicSessionPoolTest,MigrateSessionOnAsyncWriteError)6750 TEST_P(QuicSessionPoolTest, MigrateSessionOnAsyncWriteError) {
6751 InitializeConnectionMigrationV2Test(
6752 {kDefaultNetworkForTests, kNewNetworkForTests});
6753 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6754 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6755 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6756 client_maker_.set_save_packet_frames(true);
6757
6758 // Using a testing task runner so that we can control time.
6759 // base::RunLoop() controls mocked socket writes and reads.
6760 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
6761 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
6762
6763 MockQuicData socket_data(version_);
6764 socket_data.AddReadPauseForever();
6765 int packet_num = 1;
6766 socket_data.AddWrite(SYNCHRONOUS,
6767 ConstructInitialSettingsPacket(packet_num++));
6768 socket_data.AddWrite(ASYNC, ERR_ADDRESS_UNREACHABLE);
6769 socket_data.AddSocketDataToFactory(socket_factory_.get());
6770
6771 // Set up second socket data provider that is used after
6772 // migration. The request is rewritten to this new socket, and the
6773 // response to the request is read on this new socket.
6774 MockQuicData socket_data1(version_);
6775 quic::QuicConnectionId cid_on_new_path =
6776 quic::test::TestConnectionId(12345678);
6777 client_maker_.set_connection_id(cid_on_new_path);
6778 ConstructGetRequestPacket(
6779 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true);
6780 spdy::Http2HeaderBlock headers =
6781 client_maker_.GetRequestHeaders("GET", "https", "/");
6782 spdy::SpdyPriority priority =
6783 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
6784 size_t spdy_headers_frame_len;
6785 socket_data1.AddWrite(
6786 SYNCHRONOUS,
6787 client_maker_.MakeRetransmissionAndRequestHeadersPacket(
6788 {1, 2}, packet_num++, GetNthClientInitiatedBidirectionalStreamId(1),
6789 true, priority, std::move(headers), &spdy_headers_frame_len));
6790 socket_data1.AddWrite(SYNCHRONOUS,
6791 client_maker_.MakePingPacket(packet_num++));
6792 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakeRetireConnectionIdPacket(
6793 packet_num++,
6794 /*sequence_number=*/0u));
6795 socket_data1.AddRead(
6796 ASYNC, ConstructOkResponsePacket(
6797 1, GetNthClientInitiatedBidirectionalStreamId(0), false));
6798 socket_data1.AddReadPauseForever();
6799 socket_data1.AddWrite(
6800 SYNCHRONOUS,
6801 client_maker_.MakeDataPacket(
6802 packet_num++, GetQpackDecoderStreamId(),
6803 /*fin=*/false, StreamCancellationQpackDecoderInstruction(0)));
6804 socket_data1.AddWrite(
6805 SYNCHRONOUS,
6806 client_maker_.MakeRstPacket(packet_num++,
6807 GetNthClientInitiatedBidirectionalStreamId(0),
6808 quic::QUIC_STREAM_CANCELLED));
6809
6810 socket_data1.AddWrite(
6811 SYNCHRONOUS, client_maker_.MakeDataPacket(
6812 packet_num++, GetQpackDecoderStreamId(),
6813 /* fin = */ false,
6814 StreamCancellationQpackDecoderInstruction(1, false)));
6815 socket_data1.AddWrite(
6816 SYNCHRONOUS,
6817 client_maker_.MakeRstPacket(packet_num++,
6818 GetNthClientInitiatedBidirectionalStreamId(1),
6819 quic::QUIC_STREAM_CANCELLED,
6820 /*include_stop_sending_if_v99=*/true));
6821
6822 socket_data1.AddSocketDataToFactory(socket_factory_.get());
6823
6824 // Create request #1 and QuicHttpStream.
6825 RequestBuilder builder1(this);
6826 EXPECT_EQ(ERR_IO_PENDING, builder1.CallRequest());
6827 EXPECT_THAT(callback_.WaitForResult(), IsOk());
6828 std::unique_ptr<HttpStream> stream1 = CreateStream(&builder1.request);
6829 EXPECT_TRUE(stream1.get());
6830
6831 HttpRequestInfo request_info1;
6832 request_info1.method = "GET";
6833 request_info1.url = GURL("https://www.example.org/");
6834 request_info1.traffic_annotation =
6835 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6836 stream1->RegisterRequest(&request_info1);
6837 EXPECT_EQ(OK, stream1->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
6838 CompletionOnceCallback()));
6839
6840 // Request #2 returns synchronously because it pools to existing session.
6841 TestCompletionCallback callback2;
6842 RequestBuilder builder2(this);
6843 builder2.callback = callback2.callback();
6844 EXPECT_EQ(OK, builder2.CallRequest());
6845 std::unique_ptr<HttpStream> stream2 = CreateStream(&builder2.request);
6846 EXPECT_TRUE(stream2.get());
6847
6848 HttpRequestInfo request_info2;
6849 request_info2.method = "GET";
6850 request_info2.url = GURL("https://www.example.org/");
6851 request_info2.traffic_annotation =
6852 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6853 stream2->RegisterRequest(&request_info2);
6854 EXPECT_EQ(OK, stream2->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
6855 CompletionOnceCallback()));
6856
6857 // Ensure that session is alive and active.
6858 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
6859 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
6860 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
6861 EXPECT_EQ(2u, session->GetNumActiveStreams());
6862 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
6863
6864 // Send GET request on stream1. This should cause an async write error.
6865 HttpResponseInfo response;
6866 HttpRequestHeaders request_headers;
6867 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
6868 callback_.callback()));
6869 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
6870
6871 // Run the message loop so that asynchronous write completes and a connection
6872 // migration on write error attempt is posted in QuicSessionPool's task
6873 // runner.
6874 base::RunLoop().RunUntilIdle();
6875 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
6876
6877 // Send GET request on stream. This will cause another write attempt before
6878 // migration on write error is exectued.
6879 HttpResponseInfo response2;
6880 HttpRequestHeaders request_headers2;
6881 EXPECT_EQ(OK, stream2->SendRequest(request_headers2, &response2,
6882 callback2.callback()));
6883
6884 // Run the task runner so that migration on write error is finally executed.
6885 task_runner->RunUntilIdle();
6886 // Fire the retire connection ID alarm.
6887 base::RunLoop().RunUntilIdle();
6888
6889 // Verify the session is still alive and not marked as going away.
6890 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
6891 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
6892 EXPECT_EQ(2u, session->GetNumActiveStreams());
6893 // There should be one task posted to migrate back to the default network in
6894 // kMinRetryTimeForDefaultNetworkSecs.
6895 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
6896 EXPECT_EQ(base::Seconds(kMinRetryTimeForDefaultNetworkSecs),
6897 task_runner->NextPendingTaskDelay());
6898
6899 // Verify that response headers on the migrated socket were delivered to the
6900 // stream.
6901 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
6902 EXPECT_EQ(200, response.headers->response_code());
6903
6904 stream1.reset();
6905 stream2.reset();
6906
6907 socket_data.ExpectAllReadDataConsumed();
6908 socket_data.ExpectAllWriteDataConsumed();
6909 socket_data1.ExpectAllReadDataConsumed();
6910 socket_data1.ExpectAllWriteDataConsumed();
6911 }
6912
6913 // Verify session is not marked as going away after connection migration on
6914 // write error and migrate back to default network logic is applied to bring the
6915 // migrated session back to the default network. Migration singals delivered
6916 // in the following order (alternate network is always availabe):
6917 // - session on the default network encountered a write error;
6918 // - session successfully migrated to the non-default network;
6919 // - session attempts to migrate back to default network post migration;
6920 // - migration back to the default network is successful.
TEST_P(QuicSessionPoolTest,MigrateBackToDefaultPostMigrationOnWriteError)6921 TEST_P(QuicSessionPoolTest, MigrateBackToDefaultPostMigrationOnWriteError) {
6922 InitializeConnectionMigrationV2Test(
6923 {kDefaultNetworkForTests, kNewNetworkForTests});
6924 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6925 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6926 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6927 client_maker_.set_save_packet_frames(true);
6928
6929 // Using a testing task runner so that we can control time.
6930 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
6931 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
6932
6933 MockQuicData socket_data(version_);
6934 socket_data.AddReadPauseForever();
6935 int packet_num = 1;
6936 int peer_packet_num = 1;
6937 socket_data.AddWrite(SYNCHRONOUS,
6938 ConstructInitialSettingsPacket(packet_num++));
6939 socket_data.AddWrite(ASYNC, ERR_ADDRESS_UNREACHABLE);
6940 socket_data.AddSocketDataToFactory(socket_factory_.get());
6941
6942 // Set up second socket data provider that is used after
6943 // migration. The request is rewritten to this new socket, and the
6944 // response to the request is read on this new socket.
6945 MockQuicData quic_data2(version_);
6946 quic::QuicConnectionId cid1 = quic::test::TestConnectionId(12345678);
6947 quic::QuicConnectionId cid2 = quic::test::TestConnectionId(87654321);
6948
6949 client_maker_.set_connection_id(cid1);
6950 // Increment packet number to account for packet write error on the old
6951 // path. Also save the packet in client_maker_ for constructing the
6952 // retransmission packet.
6953 ConstructGetRequestPacket(packet_num++,
6954 GetNthClientInitiatedBidirectionalStreamId(0),
6955 /*fin=*/true);
6956 quic_data2.AddWrite(SYNCHRONOUS,
6957 client_maker_.MakeCombinedRetransmissionPacket(
6958 /*original_packet_numbers=*/{1, 2}, packet_num++));
6959 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(packet_num++));
6960 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeRetireConnectionIdPacket(
6961 packet_num++,
6962 /*sequence_number=*/0u));
6963 quic_data2.AddRead(ASYNC, server_maker_.MakeAckAndNewConnectionIdPacket(
6964 peer_packet_num++, packet_num - 1, 1u, cid2,
6965 /*sequence_number=*/2u,
6966 /*retire_prior_to=*/1u));
6967 quic_data2.AddRead(ASYNC,
6968 ConstructOkResponsePacket(
6969 peer_packet_num++,
6970 GetNthClientInitiatedBidirectionalStreamId(0), false));
6971 quic_data2.AddReadPauseForever();
6972 quic_data2.AddSocketDataToFactory(socket_factory_.get());
6973
6974 // Create request QuicHttpStream.
6975 RequestBuilder builder1(this);
6976 EXPECT_EQ(ERR_IO_PENDING, builder1.CallRequest());
6977 EXPECT_THAT(callback_.WaitForResult(), IsOk());
6978 std::unique_ptr<HttpStream> stream1 = CreateStream(&builder1.request);
6979 EXPECT_TRUE(stream1.get());
6980
6981 HttpRequestInfo request_info1;
6982 request_info1.method = "GET";
6983 request_info1.url = GURL("https://www.example.org/");
6984 request_info1.traffic_annotation =
6985 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6986 stream1->RegisterRequest(&request_info1);
6987 EXPECT_EQ(OK, stream1->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
6988 CompletionOnceCallback()));
6989
6990 // Ensure that session is alive and active.
6991 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
6992 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
6993 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
6994 EXPECT_EQ(1u, session->GetNumActiveStreams());
6995 MaybeMakeNewConnectionIdAvailableToSession(cid1, session);
6996
6997 // Send GET request. This should cause an async write error.
6998 HttpResponseInfo response;
6999 HttpRequestHeaders request_headers;
7000 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
7001 callback_.callback()));
7002 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
7003
7004 // Run the message loop so that asynchronous write completes and a connection
7005 // migration on write error attempt is posted in QuicSessionPool's task
7006 // runner.
7007 base::RunLoop().RunUntilIdle();
7008 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
7009
7010 // Run the task runner so that migration on write error is finally executed.
7011 task_runner->RunUntilIdle();
7012 // Make sure the alarm that retires connection ID on the old path is fired.
7013 base::RunLoop().RunUntilIdle();
7014
7015 // Verify the session is still alive and not marked as going away.
7016 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
7017 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
7018 EXPECT_EQ(1u, session->GetNumActiveStreams());
7019 // There should be one task posted to migrate back to the default network in
7020 // kMinRetryTimeForDefaultNetworkSecs.
7021 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
7022 base::TimeDelta expected_delay =
7023 base::Seconds(kMinRetryTimeForDefaultNetworkSecs);
7024 EXPECT_EQ(expected_delay, task_runner->NextPendingTaskDelay());
7025
7026 // Verify that response headers on the migrated socket were delivered to the
7027 // stream.
7028 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
7029 EXPECT_EQ(200, response.headers->response_code());
7030
7031 // Set up the third socket data provider for migrate back to default network.
7032 MockQuicData quic_data3(version_);
7033 client_maker_.set_connection_id(cid2);
7034 // Connectivity probe to be sent on the new path.
7035 quic_data3.AddWrite(
7036 SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(packet_num++));
7037 // Connectivity probe to receive from the server.
7038 quic_data3.AddRead(
7039 ASYNC, server_maker_.MakeConnectivityProbingPacket(peer_packet_num++));
7040 quic_data3.AddReadPauseForever();
7041 // There is no other data to retransmit as they have been acknowledged by
7042 // the packet containing NEW_CONNECTION_ID frame from the server.
7043 quic_data3.AddWrite(ASYNC, client_maker_.MakeAckPacket(
7044 packet_num++,
7045 /*first_received=*/1,
7046 /*largest_received=*/peer_packet_num - 1,
7047 /*smallest_received=*/1));
7048
7049 quic_data3.AddWrite(SYNCHRONOUS,
7050 client_maker_.MakeDataPacket(
7051 packet_num++, GetQpackDecoderStreamId(), false,
7052 StreamCancellationQpackDecoderInstruction(0)));
7053 quic_data3.AddWrite(
7054 SYNCHRONOUS,
7055 client_maker_.MakeRstPacket(packet_num++,
7056 GetNthClientInitiatedBidirectionalStreamId(0),
7057 quic::QUIC_STREAM_CANCELLED,
7058 /*include_stop_sending_if_v99=*/true));
7059 quic_data3.AddSocketDataToFactory(socket_factory_.get());
7060
7061 // Fast forward to fire the migrate back timer and verify the session
7062 // successfully migrates back to the default network.
7063 task_runner->FastForwardBy(expected_delay);
7064
7065 // Verify the session is still alive and not marked as going away.
7066 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
7067 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
7068 EXPECT_EQ(1u, session->GetNumActiveStreams());
7069
7070 // There should be one task posted to one will resend a connectivity probe and
7071 // the other will retry migrate back, both are cancelled.
7072 task_runner->FastForwardUntilNoTasksRemain();
7073
7074 // Verify the session is still alive and not marked as going away.
7075 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
7076 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
7077 EXPECT_EQ(1u, session->GetNumActiveStreams());
7078
7079 stream1.reset();
7080 socket_data.ExpectAllReadDataConsumed();
7081 socket_data.ExpectAllWriteDataConsumed();
7082 quic_data2.ExpectAllReadDataConsumed();
7083 quic_data2.ExpectAllWriteDataConsumed();
7084 quic_data3.ExpectAllReadDataConsumed();
7085 quic_data3.ExpectAllWriteDataConsumed();
7086 }
7087
7088 // This test verifies that the connection will not attempt connection migration
7089 // (send connectivity probes on alternate path) when path degrading is detected
7090 // and handshake is not confirmed.
TEST_P(QuicSessionPoolTest,NoMigrationOnPathDegradingBeforeHandshakeConfirmed)7091 TEST_P(QuicSessionPoolTest,
7092 NoMigrationOnPathDegradingBeforeHandshakeConfirmed) {
7093 FLAGS_quic_enable_chaos_protection = false;
7094 InitializeConnectionMigrationV2Test(
7095 {kDefaultNetworkForTests, kNewNetworkForTests});
7096
7097 // Using a testing task runner.
7098 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7099 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
7100
7101 // Use cold start mode to send crypto message for handshake.
7102 crypto_client_stream_factory_.set_handshake_mode(
7103 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
7104
7105 MockQuicData socket_data(version_);
7106 socket_data.AddReadPauseForever();
7107 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
7108 socket_data.AddSocketDataToFactory(socket_factory_.get());
7109
7110 // Create request and QuicHttpStream.
7111 RequestBuilder builder(this);
7112 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
7113
7114 base::RunLoop().RunUntilIdle();
7115
7116 // Ensure that session is alive but not active.
7117 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
7118 EXPECT_TRUE(HasActiveJob(kDefaultDestination, PRIVACY_MODE_DISABLED));
7119 QuicChromiumClientSession* session = GetPendingSession(kDefaultDestination);
7120 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
7121 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
7122
7123 // Cause the connection to report path degrading to the session.
7124 // Session will ignore the signal as handshake is not completed.
7125 EXPECT_EQ(0u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
7126 session->connection()->OnPathDegradingDetected();
7127 base::RunLoop().RunUntilIdle();
7128 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
7129 EXPECT_EQ(1u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
7130
7131 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
7132 EXPECT_TRUE(HasActiveJob(kDefaultDestination, PRIVACY_MODE_DISABLED));
7133 socket_data.ExpectAllReadDataConsumed();
7134 socket_data.ExpectAllWriteDataConsumed();
7135 }
7136
7137 // This test verifies that if a connection is closed with
7138 // QUIC_NETWORK_IDLE_TIMEOUT before handshake is completed and there is no
7139 // alternate network, no new connection will be created.
TEST_P(QuicSessionPoolTest,NoAlternateNetworkBeforeHandshakeOnIdleTimeout)7140 TEST_P(QuicSessionPoolTest, NoAlternateNetworkBeforeHandshakeOnIdleTimeout) {
7141 TestNoAlternateNetworkBeforeHandshake(quic::QUIC_NETWORK_IDLE_TIMEOUT);
7142 }
7143
7144 // This test verifies that if a connection is closed with QUIC_HANDSHAKE_TIMEOUT
7145 // and there is no alternate network, no new connection will be created.
TEST_P(QuicSessionPoolTest,NoAlternateNetworkOnHandshakeTimeout)7146 TEST_P(QuicSessionPoolTest, NoAlternateNetworkOnHandshakeTimeout) {
7147 TestNoAlternateNetworkBeforeHandshake(quic::QUIC_HANDSHAKE_TIMEOUT);
7148 }
7149
TestNoAlternateNetworkBeforeHandshake(quic::QuicErrorCode quic_error)7150 void QuicSessionPoolTest::TestNoAlternateNetworkBeforeHandshake(
7151 quic::QuicErrorCode quic_error) {
7152 FLAGS_quic_enable_chaos_protection = false;
7153 DCHECK(quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT ||
7154 quic_error == quic::QUIC_HANDSHAKE_TIMEOUT);
7155 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
7156
7157 // Using a testing task runner.
7158 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7159 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
7160
7161 // Use cold start mode to send crypto message for handshake.
7162 crypto_client_stream_factory_.set_handshake_mode(
7163 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
7164
7165 MockQuicData socket_data(version_);
7166 socket_data.AddReadPauseForever();
7167 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
7168 socket_data.AddSocketDataToFactory(socket_factory_.get());
7169
7170 // Create request.
7171 RequestBuilder builder(this);
7172 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
7173
7174 base::RunLoop().RunUntilIdle();
7175
7176 // Ensure that session is alive but not active.
7177 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
7178 EXPECT_TRUE(HasActiveJob(kDefaultDestination, PRIVACY_MODE_DISABLED));
7179 QuicChromiumClientSession* session = GetPendingSession(kDefaultDestination);
7180 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
7181 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
7182
7183 EXPECT_EQ(0u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
7184 // Cause the connection to report path degrading to the session.
7185 // Session will ignore the signal as handshake is not completed.
7186 session->connection()->OnPathDegradingDetected();
7187 base::RunLoop().RunUntilIdle();
7188 EXPECT_EQ(1u, QuicSessionPoolPeer::GetNumDegradingSessions(factory_.get()));
7189 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
7190 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
7191 EXPECT_TRUE(HasActiveJob(kDefaultDestination, PRIVACY_MODE_DISABLED));
7192
7193 // Cause the connection to close due to |quic_error| before handshake.
7194 std::string error_details;
7195 if (quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT) {
7196 error_details = "No recent network activity.";
7197 } else {
7198 error_details = "Handshake timeout expired.";
7199 }
7200 session->connection()->CloseConnection(
7201 quic_error, error_details, quic::ConnectionCloseBehavior::SILENT_CLOSE);
7202
7203 // A task will be posted to clean up the session in the factory.
7204 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
7205 task_runner->FastForwardUntilNoTasksRemain();
7206
7207 // No new session should be created as there is no alternate network.
7208 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
7209 EXPECT_FALSE(HasActiveJob(kDefaultDestination, PRIVACY_MODE_DISABLED));
7210 socket_data.ExpectAllReadDataConsumed();
7211 socket_data.ExpectAllWriteDataConsumed();
7212 }
7213
TEST_P(QuicSessionPoolTest,NewConnectionBeforeHandshakeAfterIdleTimeout)7214 TEST_P(QuicSessionPoolTest, NewConnectionBeforeHandshakeAfterIdleTimeout) {
7215 TestNewConnectionOnAlternateNetworkBeforeHandshake(
7216 quic::QUIC_NETWORK_IDLE_TIMEOUT);
7217 }
7218
TEST_P(QuicSessionPoolTest,NewConnectionAfterHandshakeTimeout)7219 TEST_P(QuicSessionPoolTest, NewConnectionAfterHandshakeTimeout) {
7220 TestNewConnectionOnAlternateNetworkBeforeHandshake(
7221 quic::QUIC_HANDSHAKE_TIMEOUT);
7222 }
7223
7224 // Sets up a test to verify that a new connection will be created on the
7225 // alternate network after the initial connection fails before handshake with
7226 // signals delivered in the following order (alternate network is available):
7227 // - the default network is not able to complete crypto handshake;
7228 // - the original connection is closed with |quic_error|;
7229 // - a new connection is created on the alternate network and is able to finish
7230 // crypto handshake;
7231 // - the new session on the alternate network attempts to migrate back to the
7232 // default network by sending probes;
7233 // - default network being disconnected is delivered: session will stop probing
7234 // the original network.
7235 // - alternate network is made by default.
TestNewConnectionOnAlternateNetworkBeforeHandshake(quic::QuicErrorCode quic_error)7236 void QuicSessionPoolTest::TestNewConnectionOnAlternateNetworkBeforeHandshake(
7237 quic::QuicErrorCode quic_error) {
7238 DCHECK(quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT ||
7239 quic_error == quic::QUIC_HANDSHAKE_TIMEOUT);
7240 FLAGS_quic_enable_chaos_protection = false;
7241 // TODO(https://crbug.com/1295460): Make this test work with asynchronous QUIC
7242 // session creation. This test only works with synchronous session creation
7243 // for now.
7244 base::test::ScopedFeatureList scoped_feature_list;
7245 scoped_feature_list.InitAndDisableFeature(net::features::kAsyncQuicSession);
7246
7247 quic_params_->retry_on_alternate_network_before_handshake = true;
7248 InitializeConnectionMigrationV2Test(
7249 {kDefaultNetworkForTests, kNewNetworkForTests});
7250
7251 // Using a testing task runner.
7252 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7253 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
7254
7255 // Use cold start mode to send crypto message for handshake.
7256 crypto_client_stream_factory_.set_handshake_mode(
7257 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
7258
7259 // Socket data for connection on the default network.
7260 MockQuicData socket_data(version_);
7261 socket_data.AddReadPauseForever();
7262 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
7263 socket_data.AddSocketDataToFactory(socket_factory_.get());
7264
7265 // Socket data for connection on the alternate network.
7266 MockQuicData socket_data2(version_);
7267 int packet_num = 1;
7268 socket_data2.AddWrite(SYNCHRONOUS,
7269 client_maker_.MakeDummyCHLOPacket(packet_num++));
7270 socket_data2.AddReadPause();
7271 // Change the encryption level after handshake is confirmed.
7272 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
7273 socket_data2.AddWrite(ASYNC, ConstructInitialSettingsPacket(packet_num++));
7274 socket_data2.AddWrite(
7275 ASYNC,
7276 ConstructGetRequestPacket(
7277 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true));
7278 socket_data2.AddRead(
7279 ASYNC, ConstructOkResponsePacket(
7280 1, GetNthClientInitiatedBidirectionalStreamId(0), false));
7281 socket_data2.AddReadPauseForever();
7282 int probing_packet_num = packet_num++;
7283 socket_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeRetireConnectionIdPacket(
7284 packet_num++,
7285 /*sequence_number=*/1u));
7286 socket_data2.AddWrite(
7287 SYNCHRONOUS, client_maker_.MakeDataPacket(
7288 packet_num++, GetQpackDecoderStreamId(), /*fin=*/false,
7289 StreamCancellationQpackDecoderInstruction(0)));
7290 socket_data2.AddWrite(
7291 SYNCHRONOUS,
7292 client_maker_.MakeRstPacket(packet_num++,
7293 GetNthClientInitiatedBidirectionalStreamId(0),
7294 quic::QUIC_STREAM_CANCELLED));
7295 socket_data2.AddSocketDataToFactory(socket_factory_.get());
7296
7297 // Socket data for probing on the default network.
7298 MockQuicData probing_data(version_);
7299 quic::QuicConnectionId cid_on_path1 = quic::test::TestConnectionId(1234567);
7300 client_maker_.set_connection_id(cid_on_path1);
7301 probing_data.AddReadPauseForever();
7302 probing_data.AddWrite(
7303 SYNCHRONOUS,
7304 client_maker_.MakeConnectivityProbingPacket(probing_packet_num));
7305 probing_data.AddSocketDataToFactory(socket_factory_.get());
7306
7307 // Create request and QuicHttpStream.
7308 RequestBuilder builder(this);
7309 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
7310
7311 base::RunLoop().RunUntilIdle();
7312
7313 // Ensure that session is alive but not active.
7314 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
7315 EXPECT_TRUE(HasActiveJob(kDefaultDestination, PRIVACY_MODE_DISABLED));
7316 QuicChromiumClientSession* session = GetPendingSession(kDefaultDestination);
7317 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
7318 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
7319 EXPECT_FALSE(failed_on_default_network_);
7320
7321 std::string error_details;
7322 if (quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT) {
7323 error_details = "No recent network activity.";
7324 } else {
7325 error_details = "Handshake timeout expired.";
7326 }
7327 session->connection()->CloseConnection(
7328 quic_error, error_details, quic::ConnectionCloseBehavior::SILENT_CLOSE);
7329
7330 // A task will be posted to clean up the session in the factory.
7331 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
7332 task_runner->FastForwardUntilNoTasksRemain();
7333
7334 // Verify a new session is created on the alternate network.
7335 EXPECT_TRUE(HasActiveJob(kDefaultDestination, PRIVACY_MODE_DISABLED));
7336 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
7337 QuicChromiumClientSession* session2 = GetPendingSession(kDefaultDestination);
7338 EXPECT_NE(session, session2);
7339 EXPECT_TRUE(failed_on_default_network_);
7340
7341 // Confirm the handshake on the alternate network.
7342 crypto_client_stream_factory_.last_stream()
7343 ->NotifySessionOneRttKeyAvailable();
7344 EXPECT_THAT(callback_.WaitForResult(), IsOk());
7345 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
7346 MaybeMakeNewConnectionIdAvailableToSession(cid_on_path1, session2);
7347 // Resume the data now so that data can be sent and read.
7348 socket_data2.Resume();
7349
7350 // Create the stream.
7351 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
7352 EXPECT_TRUE(stream.get());
7353 HttpRequestInfo request_info;
7354 request_info.method = "GET";
7355 request_info.url = GURL("https://www.example.org/");
7356 request_info.traffic_annotation =
7357 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7358 stream->RegisterRequest(&request_info);
7359 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
7360 CompletionOnceCallback()));
7361 // Send the request.
7362 HttpResponseInfo response;
7363 HttpRequestHeaders request_headers;
7364 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7365 callback_.callback()));
7366 // Run the message loop to finish asynchronous mock write.
7367 base::RunLoop().RunUntilIdle();
7368 // Read the response.
7369 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
7370 EXPECT_EQ(200, response.headers->response_code());
7371
7372 // There should be a new task posted to migrate back to the default network.
7373 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
7374 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
7375 EXPECT_EQ(base::Seconds(kMinRetryTimeForDefaultNetworkSecs), next_task_delay);
7376 task_runner->FastForwardBy(next_task_delay);
7377
7378 // Deliver the signal that the default network is disconnected.
7379 scoped_mock_network_change_notifier_->mock_network_change_notifier()
7380 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
7381 // Verify no connectivity probes will be sent as probing will be cancelled.
7382 task_runner->FastForwardUntilNoTasksRemain();
7383 // Deliver the signal that the alternate network is made default.
7384 scoped_mock_network_change_notifier_->mock_network_change_notifier()
7385 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
7386 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
7387
7388 stream.reset();
7389 socket_data.ExpectAllReadDataConsumed();
7390 socket_data.ExpectAllWriteDataConsumed();
7391 socket_data2.ExpectAllReadDataConsumed();
7392 socket_data2.ExpectAllWriteDataConsumed();
7393 }
7394
7395 // Test that connection will be closed with PACKET_WRITE_ERROR if a write error
7396 // is triggered before handshake is confirmed and connection migration is turned
7397 // on.
TEST_P(QuicSessionPoolTest,MigrationOnWriteErrorBeforeHandshakeConfirmed)7398 TEST_P(QuicSessionPoolTest, MigrationOnWriteErrorBeforeHandshakeConfirmed) {
7399 DCHECK(!quic_params_->retry_on_alternate_network_before_handshake);
7400 InitializeConnectionMigrationV2Test(
7401 {kDefaultNetworkForTests, kNewNetworkForTests});
7402
7403 // Use unmocked crypto stream to do crypto connect.
7404 crypto_client_stream_factory_.set_handshake_mode(
7405 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
7406
7407 MockQuicData socket_data(version_);
7408 socket_data.AddReadPauseForever();
7409 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
7410 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
7411 socket_data.AddSocketDataToFactory(socket_factory_.get());
7412
7413 // Create request, should fail after the write of the CHLO fails.
7414 RequestBuilder builder(this);
7415 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
7416 EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED, callback_.WaitForResult());
7417 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
7418 EXPECT_FALSE(HasActiveJob(kDefaultDestination, PRIVACY_MODE_DISABLED));
7419
7420 // Verify new requests can be sent normally.
7421 crypto_client_stream_factory_.set_handshake_mode(
7422 MockCryptoClientStream::COLD_START);
7423 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7424 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7425 client_maker_.Reset();
7426 MockQuicData socket_data2(version_);
7427 socket_data2.AddReadPauseForever();
7428 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
7429 socket_data2.AddSocketDataToFactory(socket_factory_.get());
7430
7431 RequestBuilder builder2(this);
7432 EXPECT_EQ(ERR_IO_PENDING, builder2.CallRequest());
7433 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
7434 EXPECT_TRUE(HasActiveJob(kDefaultDestination, PRIVACY_MODE_DISABLED));
7435 // Run the message loop to complete host resolution.
7436 base::RunLoop().RunUntilIdle();
7437
7438 // Complete handshake. QuicSessionPool::Job should complete and succeed.
7439 crypto_client_stream_factory_.last_stream()
7440 ->NotifySessionOneRttKeyAvailable();
7441 EXPECT_THAT(callback_.WaitForResult(), IsOk());
7442 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
7443 EXPECT_FALSE(HasActiveJob(kDefaultDestination, PRIVACY_MODE_DISABLED));
7444
7445 // Create QuicHttpStream.
7446 std::unique_ptr<HttpStream> stream = CreateStream(&builder2.request);
7447 EXPECT_TRUE(stream.get());
7448 stream.reset();
7449 socket_data.ExpectAllReadDataConsumed();
7450 socket_data.ExpectAllWriteDataConsumed();
7451 socket_data2.ExpectAllReadDataConsumed();
7452 socket_data2.ExpectAllWriteDataConsumed();
7453 }
7454
7455 // Test that if the original connection is closed with QUIC_PACKET_WRITE_ERROR
7456 // before handshake is confirmed and new connection before handshake is turned
7457 // on, a new connection will be retried on the alternate network.
TEST_P(QuicSessionPoolTest,RetryConnectionOnWriteErrorBeforeHandshakeConfirmed)7458 TEST_P(QuicSessionPoolTest,
7459 RetryConnectionOnWriteErrorBeforeHandshakeConfirmed) {
7460 FLAGS_quic_enable_chaos_protection = false;
7461 quic_params_->retry_on_alternate_network_before_handshake = true;
7462 InitializeConnectionMigrationV2Test(
7463 {kDefaultNetworkForTests, kNewNetworkForTests});
7464
7465 // Use unmocked crypto stream to do crypto connect.
7466 crypto_client_stream_factory_.set_handshake_mode(
7467 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
7468
7469 // Socket data for connection on the default network.
7470 MockQuicData socket_data(version_);
7471 socket_data.AddReadPauseForever();
7472 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
7473 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
7474 socket_data.AddSocketDataToFactory(socket_factory_.get());
7475
7476 // Socket data for connection on the alternate network.
7477 MockQuicData socket_data2(version_);
7478 int packet_num = 1;
7479 socket_data2.AddWrite(SYNCHRONOUS,
7480 client_maker_.MakeDummyCHLOPacket(packet_num++));
7481 socket_data2.AddReadPause();
7482 // Change the encryption level after handshake is confirmed.
7483 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
7484 socket_data2.AddWrite(ASYNC, ConstructInitialSettingsPacket(packet_num++));
7485 socket_data2.AddWrite(
7486 ASYNC,
7487 ConstructGetRequestPacket(
7488 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true));
7489 socket_data2.AddRead(
7490 ASYNC, ConstructOkResponsePacket(
7491 1, GetNthClientInitiatedBidirectionalStreamId(0), false));
7492 socket_data2.AddReadPauseForever();
7493 socket_data2.AddWrite(
7494 SYNCHRONOUS, client_maker_.MakeAckAndDataPacket(
7495 packet_num++, GetQpackDecoderStreamId(), 1, 1, false,
7496 StreamCancellationQpackDecoderInstruction(0)));
7497 socket_data2.AddWrite(
7498 SYNCHRONOUS,
7499 client_maker_.MakeRstPacket(packet_num++,
7500 GetNthClientInitiatedBidirectionalStreamId(0),
7501 quic::QUIC_STREAM_CANCELLED));
7502 socket_data2.AddSocketDataToFactory(socket_factory_.get());
7503
7504 // Create request, should fail after the write of the CHLO fails.
7505 RequestBuilder builder(this);
7506 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
7507 // Ensure that the session is alive but not active.
7508 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
7509 EXPECT_TRUE(HasActiveJob(kDefaultDestination, PRIVACY_MODE_DISABLED));
7510 base::RunLoop().RunUntilIdle();
7511 QuicChromiumClientSession* session = GetPendingSession(kDefaultDestination);
7512 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
7513
7514 // Confirm the handshake on the alternate network.
7515 crypto_client_stream_factory_.last_stream()
7516 ->NotifySessionOneRttKeyAvailable();
7517 EXPECT_THAT(callback_.WaitForResult(), IsOk());
7518 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
7519
7520 // Resume the data now so that data can be sent and read.
7521 socket_data2.Resume();
7522
7523 // Create the stream.
7524 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
7525 EXPECT_TRUE(stream.get());
7526 HttpRequestInfo request_info;
7527 request_info.method = "GET";
7528 request_info.url = GURL("https://www.example.org/");
7529 request_info.traffic_annotation =
7530 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7531 stream->RegisterRequest(&request_info);
7532 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
7533 CompletionOnceCallback()));
7534 // Send the request.
7535 HttpResponseInfo response;
7536 HttpRequestHeaders request_headers;
7537 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7538 callback_.callback()));
7539 // Run the message loop to finish asynchronous mock write.
7540 base::RunLoop().RunUntilIdle();
7541 // Read the response.
7542 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
7543 EXPECT_EQ(200, response.headers->response_code());
7544
7545 stream.reset();
7546 socket_data.ExpectAllReadDataConsumed();
7547 socket_data.ExpectAllWriteDataConsumed();
7548 socket_data2.ExpectAllReadDataConsumed();
7549 socket_data2.ExpectAllWriteDataConsumed();
7550 }
7551
TestMigrationOnWriteError(IoMode write_error_mode)7552 void QuicSessionPoolTest::TestMigrationOnWriteError(IoMode write_error_mode) {
7553 InitializeConnectionMigrationV2Test(
7554 {kDefaultNetworkForTests, kNewNetworkForTests});
7555 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7556 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7557 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7558 client_maker_.set_save_packet_frames(true);
7559
7560 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7561
7562 MockQuicData socket_data(version_);
7563 socket_data.AddReadPauseForever();
7564 int packet_num = 1;
7565 socket_data.AddWrite(SYNCHRONOUS,
7566 ConstructInitialSettingsPacket(packet_num++));
7567 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
7568 socket_data.AddSocketDataToFactory(socket_factory_.get());
7569
7570 // Create request and QuicHttpStream.
7571 RequestBuilder builder(this);
7572 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
7573 EXPECT_EQ(OK, callback_.WaitForResult());
7574 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
7575 EXPECT_TRUE(stream.get());
7576
7577 // Cause QUIC stream to be created.
7578 HttpRequestInfo request_info;
7579 request_info.method = "GET";
7580 request_info.url = GURL("https://www.example.org/");
7581 request_info.traffic_annotation =
7582 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7583 stream->RegisterRequest(&request_info);
7584 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
7585 CompletionOnceCallback()));
7586
7587 // Ensure that session is alive and active.
7588 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
7589 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
7590 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
7591 quic::QuicConnectionId cid_on_new_path =
7592 quic::test::TestConnectionId(12345678);
7593 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
7594
7595 // Set up second socket data provider that is used after
7596 // migration. The request is rewritten to this new socket, and the
7597 // response to the request is read on this new socket.
7598 MockQuicData socket_data1(version_);
7599 client_maker_.set_connection_id(cid_on_new_path);
7600 // Increment packet number to account for packet write error on the old
7601 // path. Also save the packet in client_maker_ for constructing the
7602 // retransmission packet.
7603 ConstructGetRequestPacket(packet_num++,
7604 GetNthClientInitiatedBidirectionalStreamId(0),
7605 /*fin=*/true);
7606 socket_data1.AddWrite(SYNCHRONOUS,
7607 client_maker_.MakeCombinedRetransmissionPacket(
7608 /*original_packet_numbers=*/{1, 2}, packet_num++));
7609 socket_data1.AddWrite(ASYNC, client_maker_.MakePingPacket(packet_num++));
7610 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakeRetireConnectionIdPacket(
7611 packet_num++, /*sequence_number=*/0u));
7612 socket_data1.AddRead(
7613 ASYNC, ConstructOkResponsePacket(
7614 1, GetNthClientInitiatedBidirectionalStreamId(0), false));
7615 socket_data1.AddReadPauseForever();
7616 socket_data1.AddWrite(
7617 SYNCHRONOUS,
7618 client_maker_.MakeDataPacket(
7619 packet_num++, GetQpackDecoderStreamId(),
7620 /*fin=*/false, StreamCancellationQpackDecoderInstruction(0)));
7621 socket_data1.AddWrite(
7622 SYNCHRONOUS,
7623 client_maker_.MakeRstPacket(packet_num++,
7624 GetNthClientInitiatedBidirectionalStreamId(0),
7625 quic::QUIC_STREAM_CANCELLED));
7626 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7627
7628 // Send GET request on stream. This should cause a write error, which triggers
7629 // a connection migration attempt.
7630 HttpResponseInfo response;
7631 HttpRequestHeaders request_headers;
7632 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7633 callback_.callback()));
7634
7635 // Run the message loop so that the migration attempt is executed and
7636 // data queued in the new socket is read by the packet reader.
7637 base::RunLoop().RunUntilIdle();
7638
7639 // Verify that session is alive and not marked as going away.
7640 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
7641 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
7642 EXPECT_EQ(1u, session->GetNumActiveStreams());
7643
7644 // Verify that response headers on the migrated socket were delivered to the
7645 // stream.
7646 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
7647 EXPECT_EQ(200, response.headers->response_code());
7648
7649 stream.reset();
7650
7651 socket_data.ExpectAllReadDataConsumed();
7652 socket_data.ExpectAllWriteDataConsumed();
7653 socket_data1.ExpectAllReadDataConsumed();
7654 socket_data1.ExpectAllWriteDataConsumed();
7655 }
7656
TEST_P(QuicSessionPoolTest,MigrateSessionOnWriteErrorSynchronous)7657 TEST_P(QuicSessionPoolTest, MigrateSessionOnWriteErrorSynchronous) {
7658 TestMigrationOnWriteError(SYNCHRONOUS);
7659 }
7660
TEST_P(QuicSessionPoolTest,MigrateSessionOnWriteErrorAsync)7661 TEST_P(QuicSessionPoolTest, MigrateSessionOnWriteErrorAsync) {
7662 TestMigrationOnWriteError(ASYNC);
7663 }
7664
TestMigrationOnWriteErrorNoNewNetwork(IoMode write_error_mode)7665 void QuicSessionPoolTest::TestMigrationOnWriteErrorNoNewNetwork(
7666 IoMode write_error_mode) {
7667 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
7668 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7669 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7670
7671 // Use the test task runner, to force the migration alarm timeout later.
7672 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), runner_.get());
7673
7674 MockQuicData socket_data(version_);
7675 socket_data.AddReadPauseForever();
7676 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
7677 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
7678 socket_data.AddSocketDataToFactory(socket_factory_.get());
7679
7680 // Create request and QuicHttpStream.
7681 RequestBuilder builder(this);
7682 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
7683 EXPECT_EQ(OK, callback_.WaitForResult());
7684 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
7685 EXPECT_TRUE(stream.get());
7686
7687 // Cause QUIC stream to be created.
7688 HttpRequestInfo request_info;
7689 request_info.method = "GET";
7690 request_info.url = GURL("https://www.example.org/");
7691 request_info.traffic_annotation =
7692 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7693 stream->RegisterRequest(&request_info);
7694 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
7695 CompletionOnceCallback()));
7696
7697 // Ensure that session is alive and active.
7698 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
7699 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
7700 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
7701
7702 // Send GET request on stream. This causes a write error, which triggers
7703 // a connection migration attempt. Since there are no networks
7704 // to migrate to, this causes the session to wait for a new network.
7705 HttpResponseInfo response;
7706 HttpRequestHeaders request_headers;
7707 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7708 callback_.callback()));
7709
7710 // Complete any pending writes. Pending async MockQuicData writes
7711 // are run on the message loop, not on the test runner.
7712 base::RunLoop().RunUntilIdle();
7713
7714 // Write error causes migration task to be posted. Spin the loop.
7715 if (write_error_mode == ASYNC) {
7716 runner_->RunNextTask();
7717 }
7718
7719 // Migration has not yet failed. The session should be alive and active.
7720 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
7721 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
7722 EXPECT_EQ(1u, session->GetNumActiveStreams());
7723 EXPECT_TRUE(session->connection()->writer()->IsWriteBlocked());
7724
7725 // The migration will not fail until the migration alarm timeout.
7726 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
7727 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
7728 EXPECT_EQ(1u, session->GetNumActiveStreams());
7729 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
7730
7731 // Force migration alarm timeout to run.
7732 RunTestLoopUntilIdle();
7733
7734 // The connection should be closed. A request for response headers
7735 // should fail.
7736 EXPECT_FALSE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
7737 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
7738 EXPECT_EQ(ERR_NETWORK_CHANGED, callback_.WaitForResult());
7739 EXPECT_EQ(ERR_NETWORK_CHANGED,
7740 stream->ReadResponseHeaders(callback_.callback()));
7741
7742 NetErrorDetails error_details;
7743 stream->PopulateNetErrorDetails(&error_details);
7744 EXPECT_EQ(error_details.quic_connection_error,
7745 quic::QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK);
7746
7747 socket_data.ExpectAllReadDataConsumed();
7748 socket_data.ExpectAllWriteDataConsumed();
7749 }
7750
TEST_P(QuicSessionPoolTest,MigrateSessionOnWriteErrorNoNewNetworkSynchronous)7751 TEST_P(QuicSessionPoolTest, MigrateSessionOnWriteErrorNoNewNetworkSynchronous) {
7752 TestMigrationOnWriteErrorNoNewNetwork(SYNCHRONOUS);
7753 }
7754
TEST_P(QuicSessionPoolTest,MigrateSessionOnWriteErrorNoNewNetworkAsync)7755 TEST_P(QuicSessionPoolTest, MigrateSessionOnWriteErrorNoNewNetworkAsync) {
7756 TestMigrationOnWriteErrorNoNewNetwork(ASYNC);
7757 }
7758
TEST_P(QuicSessionPoolTest,MigrateSessionOnWriteErrorWithMultipleRequestsSync)7759 TEST_P(QuicSessionPoolTest,
7760 MigrateSessionOnWriteErrorWithMultipleRequestsSync) {
7761 TestMigrationOnWriteErrorWithMultipleRequests(SYNCHRONOUS);
7762 }
7763
TEST_P(QuicSessionPoolTest,MigrateSessionOnWriteErrorWithMultipleRequestsAsync)7764 TEST_P(QuicSessionPoolTest,
7765 MigrateSessionOnWriteErrorWithMultipleRequestsAsync) {
7766 TestMigrationOnWriteErrorWithMultipleRequests(ASYNC);
7767 }
7768
7769 // Sets up a test which verifies that connection migration on write error can
7770 // eventually succeed and rewrite the packet on the new network with *multiple*
7771 // migratable streams.
TestMigrationOnWriteErrorWithMultipleRequests(IoMode write_error_mode)7772 void QuicSessionPoolTest::TestMigrationOnWriteErrorWithMultipleRequests(
7773 IoMode write_error_mode) {
7774 InitializeConnectionMigrationV2Test(
7775 {kDefaultNetworkForTests, kNewNetworkForTests});
7776 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7777 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7778 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7779 client_maker_.set_save_packet_frames(true);
7780
7781 MockQuicData socket_data(version_);
7782 socket_data.AddReadPauseForever();
7783 int packet_num = 1;
7784 socket_data.AddWrite(SYNCHRONOUS,
7785 ConstructInitialSettingsPacket(packet_num++));
7786 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
7787 socket_data.AddSocketDataToFactory(socket_factory_.get());
7788
7789 // Set up second socket data provider that is used after
7790 // migration. The request is rewritten to this new socket, and the
7791 // response to the request is read on this new socket.
7792 MockQuicData socket_data1(version_);
7793 quic::QuicConnectionId cid_on_new_path =
7794 quic::test::TestConnectionId(12345678);
7795 client_maker_.set_connection_id(cid_on_new_path);
7796 // Increment packet number to account for packet write error on the old
7797 // path. Also save the packet in client_maker_ for constructing the
7798 // retransmission packet.
7799 ConstructGetRequestPacket(packet_num++,
7800 GetNthClientInitiatedBidirectionalStreamId(0),
7801 /*fin=*/true);
7802 socket_data1.AddWrite(SYNCHRONOUS,
7803 client_maker_.MakeCombinedRetransmissionPacket(
7804 /*original_packet_numbers=*/{1, 2}, packet_num++));
7805 socket_data1.AddWrite(SYNCHRONOUS,
7806 client_maker_.MakePingPacket(packet_num++));
7807 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakeRetireConnectionIdPacket(
7808 packet_num++,
7809 /*sequence_number=*/0u));
7810 socket_data1.AddRead(
7811 ASYNC, ConstructOkResponsePacket(
7812 1, GetNthClientInitiatedBidirectionalStreamId(0), false));
7813 socket_data1.AddReadPauseForever();
7814 socket_data1.AddWrite(
7815 SYNCHRONOUS,
7816 client_maker_.MakeDataPacket(
7817 packet_num++, GetQpackDecoderStreamId(),
7818 /*fin=*/false, StreamCancellationQpackDecoderInstruction(0)));
7819 socket_data1.AddWrite(
7820 SYNCHRONOUS,
7821 client_maker_.MakeRstPacket(packet_num++,
7822 GetNthClientInitiatedBidirectionalStreamId(0),
7823 quic::QUIC_STREAM_CANCELLED));
7824
7825 socket_data1.AddWrite(
7826 SYNCHRONOUS, client_maker_.MakeDataPacket(
7827 packet_num++, GetQpackDecoderStreamId(), false,
7828 StreamCancellationQpackDecoderInstruction(1, false)));
7829 socket_data1.AddWrite(
7830 SYNCHRONOUS,
7831 client_maker_.MakeRstPacket(packet_num++,
7832 GetNthClientInitiatedBidirectionalStreamId(1),
7833 quic::QUIC_STREAM_CANCELLED,
7834 /*include_stop_sending_if_v99=*/true));
7835
7836 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7837
7838 // Create request #1 and QuicHttpStream.
7839 RequestBuilder builder1(this);
7840 EXPECT_EQ(ERR_IO_PENDING, builder1.CallRequest());
7841 EXPECT_THAT(callback_.WaitForResult(), IsOk());
7842 std::unique_ptr<HttpStream> stream1 = CreateStream(&builder1.request);
7843 EXPECT_TRUE(stream1.get());
7844
7845 HttpRequestInfo request_info1;
7846 request_info1.method = "GET";
7847 request_info1.url = GURL("https://www.example.org/");
7848 request_info1.traffic_annotation =
7849 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7850 stream1->RegisterRequest(&request_info1);
7851 EXPECT_EQ(OK, stream1->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
7852 CompletionOnceCallback()));
7853
7854 // Second request returns synchronously because it pools to existing session.
7855 TestCompletionCallback callback2;
7856 RequestBuilder builder2(this);
7857 EXPECT_EQ(OK, builder2.CallRequest());
7858 std::unique_ptr<HttpStream> stream2 = CreateStream(&builder2.request);
7859 EXPECT_TRUE(stream2.get());
7860 HttpRequestInfo request_info2;
7861 request_info2.method = "GET";
7862 request_info2.url = GURL("https://www.example.org/");
7863 request_info2.traffic_annotation =
7864 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7865 stream2->RegisterRequest(&request_info2);
7866 EXPECT_EQ(OK, stream2->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
7867 CompletionOnceCallback()));
7868
7869 // Ensure that session is alive and active.
7870 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
7871 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
7872 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
7873 EXPECT_EQ(2u, session->GetNumActiveStreams());
7874 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
7875
7876 // Send GET request on stream. This should cause a write error, which triggers
7877 // a connection migration attempt.
7878 HttpResponseInfo response;
7879 HttpRequestHeaders request_headers;
7880 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
7881 callback_.callback()));
7882
7883 // Run the message loop so that the migration attempt is executed and
7884 // data queued in the new socket is read by the packet reader.
7885 base::RunLoop().RunUntilIdle();
7886
7887 // Verify session is still alive and not marked as going away.
7888 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
7889 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
7890 EXPECT_EQ(2u, session->GetNumActiveStreams());
7891
7892 // Verify that response headers on the migrated socket were delivered to the
7893 // stream.
7894 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
7895 EXPECT_EQ(200, response.headers->response_code());
7896
7897 stream1.reset();
7898 stream2.reset();
7899
7900 socket_data.ExpectAllReadDataConsumed();
7901 socket_data.ExpectAllWriteDataConsumed();
7902 socket_data1.ExpectAllReadDataConsumed();
7903 socket_data1.ExpectAllWriteDataConsumed();
7904 }
7905
TEST_P(QuicSessionPoolTest,MigrateOnWriteErrorWithMixedRequestsSync)7906 TEST_P(QuicSessionPoolTest, MigrateOnWriteErrorWithMixedRequestsSync) {
7907 TestMigrationOnWriteErrorMixedStreams(SYNCHRONOUS);
7908 }
7909
TEST_P(QuicSessionPoolTest,MigrateOnWriteErrorWithMixedRequestsAsync)7910 TEST_P(QuicSessionPoolTest, MigrateOnWriteErrorWithMixedRequestsAsync) {
7911 TestMigrationOnWriteErrorMixedStreams(ASYNC);
7912 }
7913
7914 // Sets up a test that verifies connection migration manages to migrate to
7915 // alternate network after encountering a SYNC/ASYNC write error based on
7916 // |write_error_mode| on the original network.
7917 // Note there are mixed types of unfinished requests before migration: one
7918 // migratable and one non-migratable. The *migratable* one triggers write
7919 // error.
TestMigrationOnWriteErrorMixedStreams(IoMode write_error_mode)7920 void QuicSessionPoolTest::TestMigrationOnWriteErrorMixedStreams(
7921 IoMode write_error_mode) {
7922 InitializeConnectionMigrationV2Test(
7923 {kDefaultNetworkForTests, kNewNetworkForTests});
7924 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7925 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7926 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7927 client_maker_.set_save_packet_frames(true);
7928
7929 int packet_number = 1;
7930 MockQuicData socket_data(version_);
7931
7932 socket_data.AddReadPauseForever();
7933 socket_data.AddWrite(SYNCHRONOUS,
7934 ConstructInitialSettingsPacket(packet_number++));
7935 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
7936 socket_data.AddSocketDataToFactory(socket_factory_.get());
7937
7938 // Set up second socket data provider that is used after
7939 // migration. The request is rewritten to this new socket, and the
7940 // response to the request is read on this new socket.
7941 MockQuicData socket_data1(version_);
7942 quic::QuicConnectionId cid_on_new_path =
7943 quic::test::TestConnectionId(1234567);
7944 client_maker_.set_connection_id(cid_on_new_path);
7945 // Increment packet number to account for packet write error on the old
7946 // path. Also save the packet in client_maker_ for constructing the
7947 // retransmission packet.
7948 ConstructGetRequestPacket(packet_number++,
7949 GetNthClientInitiatedBidirectionalStreamId(0),
7950 /*fin=*/true);
7951 socket_data1.AddWrite(
7952 SYNCHRONOUS, client_maker_.MakeRetransmissionRstAndDataPacket(
7953 /*original_packet_numbers=*/{1, 2}, packet_number++,
7954 GetNthClientInitiatedBidirectionalStreamId(1),
7955 quic::QUIC_STREAM_CANCELLED, GetQpackDecoderStreamId(),
7956 StreamCancellationQpackDecoderInstruction(1)));
7957 socket_data1.AddWrite(SYNCHRONOUS,
7958 client_maker_.MakePingPacket(packet_number++));
7959 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakeRetireConnectionIdPacket(
7960 packet_number++,
7961 /*sequence_number=*/0u));
7962 socket_data1.AddRead(
7963 ASYNC, ConstructOkResponsePacket(
7964 1, GetNthClientInitiatedBidirectionalStreamId(0), false));
7965 socket_data1.AddReadPauseForever();
7966 socket_data1.AddWrite(
7967 SYNCHRONOUS,
7968 client_maker_.MakeDataPacket(
7969 packet_number++, GetQpackDecoderStreamId(),
7970 /*fin=*/false, StreamCancellationQpackDecoderInstruction(0, false)));
7971 socket_data1.AddWrite(
7972 SYNCHRONOUS,
7973 client_maker_.MakeRstPacket(packet_number++,
7974 GetNthClientInitiatedBidirectionalStreamId(0),
7975 quic::QUIC_STREAM_CANCELLED));
7976 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7977
7978 // Create request #1 and QuicHttpStream.
7979 RequestBuilder builder1(this);
7980 EXPECT_EQ(ERR_IO_PENDING, builder1.CallRequest());
7981 EXPECT_THAT(callback_.WaitForResult(), IsOk());
7982 std::unique_ptr<HttpStream> stream1 = CreateStream(&builder1.request);
7983 EXPECT_TRUE(stream1.get());
7984
7985 HttpRequestInfo request_info1;
7986 request_info1.method = "GET";
7987 request_info1.url = GURL("https://www.example.org/");
7988 request_info1.traffic_annotation =
7989 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7990 stream1->RegisterRequest(&request_info1);
7991 EXPECT_EQ(OK, stream1->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
7992 CompletionOnceCallback()));
7993
7994 // Second request returns synchronously because it pools to existing session.
7995 TestCompletionCallback callback2;
7996 RequestBuilder builder2(this);
7997 builder2.callback = callback2.callback();
7998 EXPECT_EQ(OK, builder2.CallRequest());
7999 std::unique_ptr<HttpStream> stream2 = CreateStream(&builder2.request);
8000 EXPECT_TRUE(stream2.get());
8001
8002 HttpRequestInfo request_info2;
8003 request_info2.method = "GET";
8004 request_info2.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
8005 request_info2.url = GURL("https://www.example.org/");
8006 request_info2.traffic_annotation =
8007 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8008 stream2->RegisterRequest(&request_info2);
8009 EXPECT_EQ(OK, stream2->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
8010 CompletionOnceCallback()));
8011
8012 // Ensure that session is alive and active.
8013 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
8014 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
8015 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
8016 EXPECT_EQ(2u, session->GetNumActiveStreams());
8017 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
8018
8019 // Send GET request on stream 1. This should cause a write error, which
8020 // triggers a connection migration attempt.
8021 HttpResponseInfo response;
8022 HttpRequestHeaders request_headers;
8023 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
8024 callback_.callback()));
8025
8026 // Run the message loop so that the migration attempt is executed and
8027 // data queued in the new socket is read by the packet reader.
8028 base::RunLoop().RunUntilIdle();
8029
8030 // Verify that the session is still alive and not marked as going away.
8031 // Non-migratable stream should be closed due to migration.
8032 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
8033 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
8034 EXPECT_EQ(1u, session->GetNumActiveStreams());
8035
8036 // Verify that response headers on the migrated socket were delivered to the
8037 // stream.
8038 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
8039 EXPECT_EQ(200, response.headers->response_code());
8040
8041 stream1.reset();
8042
8043 socket_data.ExpectAllReadDataConsumed();
8044 socket_data.ExpectAllWriteDataConsumed();
8045 socket_data1.ExpectAllReadDataConsumed();
8046 socket_data1.ExpectAllWriteDataConsumed();
8047 }
8048
TEST_P(QuicSessionPoolTest,MigrateOnWriteErrorWithMixedRequests2Sync)8049 TEST_P(QuicSessionPoolTest, MigrateOnWriteErrorWithMixedRequests2Sync) {
8050 TestMigrationOnWriteErrorMixedStreams2(SYNCHRONOUS);
8051 }
8052
TEST_P(QuicSessionPoolTest,MigrateOnWriteErrorWithMixedRequests2Async)8053 TEST_P(QuicSessionPoolTest, MigrateOnWriteErrorWithMixedRequests2Async) {
8054 TestMigrationOnWriteErrorMixedStreams2(ASYNC);
8055 }
8056
8057 // The one triggers write error is a non-migratable stream.
8058 // Sets up a test that verifies connection migration manages to migrate to
8059 // alternate network after encountering a SYNC/ASYNC write error based on
8060 // |write_error_mode| on the original network.
8061 // Note there are mixed types of unfinished requests before migration: one
8062 // migratable and one non-migratable. The *non-migratable* one triggers write
8063 // error.
TestMigrationOnWriteErrorMixedStreams2(IoMode write_error_mode)8064 void QuicSessionPoolTest::TestMigrationOnWriteErrorMixedStreams2(
8065 IoMode write_error_mode) {
8066 InitializeConnectionMigrationV2Test(
8067 {kDefaultNetworkForTests, kNewNetworkForTests});
8068 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8069 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8070 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8071 client_maker_.set_save_packet_frames(true);
8072
8073 int packet_number = 1;
8074 MockQuicData socket_data(version_);
8075 socket_data.AddReadPauseForever();
8076 socket_data.AddWrite(SYNCHRONOUS,
8077 ConstructInitialSettingsPacket(packet_number++));
8078 socket_data.AddWrite(write_error_mode,
8079 ERR_ADDRESS_UNREACHABLE); // Write error.
8080 socket_data.AddSocketDataToFactory(socket_factory_.get());
8081
8082 // Set up second socket data provider that is used after migration. The
8083 // request is rewritten to this new socket, and the response to the request is
8084 // read on this new socket.
8085 MockQuicData socket_data1(version_);
8086 quic::QuicConnectionId cid_on_new_path =
8087 quic::test::TestConnectionId(12345678);
8088 client_maker_.set_connection_id(cid_on_new_path);
8089 // Increment packet number to account for packet write error on the old
8090 // path. Also save the packet in client_maker_ for constructing the
8091 // retransmission packet.
8092 ConstructGetRequestPacket(packet_number++,
8093 GetNthClientInitiatedBidirectionalStreamId(1),
8094 /*fin=*/true);
8095 std::vector<uint64_t> original_packet_numbers = {1};
8096 uint64_t retransmit_frame_count = 2;
8097 original_packet_numbers.push_back(2);
8098 socket_data1.AddWrite(
8099 SYNCHRONOUS, client_maker_.MakeRetransmissionRstAndDataPacket(
8100 original_packet_numbers, packet_number++,
8101 GetNthClientInitiatedBidirectionalStreamId(1),
8102 quic::QUIC_STREAM_CANCELLED, GetQpackDecoderStreamId(),
8103 StreamCancellationQpackDecoderInstruction(1),
8104 retransmit_frame_count));
8105 socket_data1.AddWrite(SYNCHRONOUS,
8106 client_maker_.MakePingPacket(packet_number++));
8107 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakeRetireConnectionIdPacket(
8108 packet_number++,
8109 /*sequence_number=*/0u));
8110 socket_data1.AddWrite(
8111 SYNCHRONOUS, ConstructGetRequestPacket(
8112 packet_number++,
8113 GetNthClientInitiatedBidirectionalStreamId(0), true));
8114 socket_data1.AddRead(
8115 ASYNC, ConstructOkResponsePacket(
8116 1, GetNthClientInitiatedBidirectionalStreamId(0), false));
8117 socket_data1.AddReadPauseForever();
8118 socket_data1.AddWrite(
8119 SYNCHRONOUS,
8120 client_maker_.MakeDataPacket(
8121 packet_number++, GetQpackDecoderStreamId(),
8122 /*fin=*/false, StreamCancellationQpackDecoderInstruction(0, false)));
8123 socket_data1.AddWrite(
8124 SYNCHRONOUS,
8125 client_maker_.MakeRstPacket(packet_number++,
8126 GetNthClientInitiatedBidirectionalStreamId(0),
8127 quic::QUIC_STREAM_CANCELLED));
8128 socket_data1.AddSocketDataToFactory(socket_factory_.get());
8129
8130 // Create request #1 and QuicHttpStream.
8131 RequestBuilder builder1(this);
8132 EXPECT_EQ(ERR_IO_PENDING, builder1.CallRequest());
8133 EXPECT_THAT(callback_.WaitForResult(), IsOk());
8134 std::unique_ptr<HttpStream> stream1 = CreateStream(&builder1.request);
8135 EXPECT_TRUE(stream1.get());
8136
8137 HttpRequestInfo request_info1;
8138 request_info1.method = "GET";
8139 request_info1.url = GURL("https://www.example.org/");
8140 request_info1.traffic_annotation =
8141 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8142 stream1->RegisterRequest(&request_info1);
8143 EXPECT_EQ(OK, stream1->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
8144 CompletionOnceCallback()));
8145
8146 // Second request returns synchronously because it pools to existing session.
8147 TestCompletionCallback callback2;
8148 RequestBuilder builder2(this);
8149 builder2.callback = callback2.callback();
8150 EXPECT_EQ(OK, builder2.CallRequest());
8151 std::unique_ptr<HttpStream> stream2 = CreateStream(&builder2.request);
8152 EXPECT_TRUE(stream2.get());
8153
8154 HttpRequestInfo request_info2;
8155 request_info2.method = "GET";
8156 request_info2.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
8157 request_info2.url = GURL("https://www.example.org/");
8158 request_info2.traffic_annotation =
8159 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8160 stream2->RegisterRequest(&request_info2);
8161 EXPECT_EQ(OK, stream2->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
8162 CompletionOnceCallback()));
8163
8164 // Ensure that session is alive and active.
8165 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
8166 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
8167 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
8168 EXPECT_EQ(2u, session->GetNumActiveStreams());
8169 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
8170
8171 // Send GET request on stream 2 which is non-migratable. This should cause a
8172 // write error, which triggers a connection migration attempt.
8173 HttpResponseInfo response2;
8174 HttpRequestHeaders request_headers2;
8175 EXPECT_EQ(OK, stream2->SendRequest(request_headers2, &response2,
8176 callback2.callback()));
8177
8178 // Run the message loop so that the migration attempt is executed and
8179 // data queued in the new socket is read by the packet reader. Session is
8180 // still alive and not marked as going away, non-migratable stream will be
8181 // closed.
8182 base::RunLoop().RunUntilIdle();
8183 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
8184 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
8185 EXPECT_EQ(1u, session->GetNumActiveStreams());
8186
8187 // Send GET request on stream 1.
8188 HttpResponseInfo response;
8189 HttpRequestHeaders request_headers;
8190 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
8191 callback_.callback()));
8192
8193 base::RunLoop().RunUntilIdle();
8194
8195 // Verify that response headers on the migrated socket were delivered to the
8196 // stream.
8197 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
8198 EXPECT_EQ(200, response.headers->response_code());
8199
8200 stream1.reset();
8201
8202 socket_data.ExpectAllReadDataConsumed();
8203 socket_data.ExpectAllWriteDataConsumed();
8204 socket_data1.ExpectAllReadDataConsumed();
8205 socket_data1.ExpectAllWriteDataConsumed();
8206 }
8207
8208 // This test verifies that when a connection encounters a packet write error, it
8209 // will cancel non-migratable streams, and migrate to the alternate network.
TestMigrationOnWriteErrorNonMigratableStream(IoMode write_error_mode,bool migrate_idle_sessions)8210 void QuicSessionPoolTest::TestMigrationOnWriteErrorNonMigratableStream(
8211 IoMode write_error_mode,
8212 bool migrate_idle_sessions) {
8213 quic_params_->migrate_idle_sessions = migrate_idle_sessions;
8214 InitializeConnectionMigrationV2Test(
8215 {kDefaultNetworkForTests, kNewNetworkForTests});
8216 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8217 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8218 client_maker_.set_save_packet_frames(true);
8219
8220 MockQuicData failed_socket_data(version_);
8221 MockQuicData socket_data(version_);
8222 quic::QuicConnectionId cid_on_new_path =
8223 quic::test::TestConnectionId(12345678);
8224 int packet_num = 1;
8225 if (migrate_idle_sessions) {
8226 // The socket data provider for the original socket before migration.
8227 failed_socket_data.AddReadPauseForever();
8228 failed_socket_data.AddWrite(SYNCHRONOUS,
8229 ConstructInitialSettingsPacket(packet_num++));
8230 failed_socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
8231 failed_socket_data.AddSocketDataToFactory(socket_factory_.get());
8232
8233 // Set up second socket data provider that is used after migration.
8234 socket_data.AddReadPauseForever();
8235 client_maker_.set_connection_id(cid_on_new_path);
8236 // Increment packet number to account for packet write error on the old
8237 // path. Also save the packet in client_maker_ for constructing the
8238 // retransmission packet.
8239 ConstructGetRequestPacket(packet_num++,
8240 GetNthClientInitiatedBidirectionalStreamId(0),
8241 /*fin=*/true);
8242 std::vector<uint64_t> original_packet_numbers = {1};
8243 uint64_t retransmit_frame_count = 2;
8244 original_packet_numbers.push_back(2);
8245 socket_data.AddWrite(
8246 SYNCHRONOUS, client_maker_.MakeRetransmissionRstAndDataPacket(
8247 original_packet_numbers, packet_num++,
8248 GetNthClientInitiatedBidirectionalStreamId(0),
8249 quic::QUIC_STREAM_CANCELLED, GetQpackDecoderStreamId(),
8250 StreamCancellationQpackDecoderInstruction(0),
8251 retransmit_frame_count));
8252 socket_data.AddWrite(SYNCHRONOUS,
8253 client_maker_.MakePingPacket(packet_num++));
8254 socket_data.AddWrite(
8255 SYNCHRONOUS,
8256 client_maker_.MakeRetireConnectionIdPacket(packet_num++,
8257 /*sequence_number=*/0u));
8258 socket_data.AddSocketDataToFactory(socket_factory_.get());
8259 } else {
8260 socket_data.AddReadPauseForever();
8261 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
8262 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
8263 socket_data.AddSocketDataToFactory(socket_factory_.get());
8264 }
8265
8266 // Create request and QuicHttpStream.
8267 RequestBuilder builder(this);
8268 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
8269 EXPECT_EQ(OK, callback_.WaitForResult());
8270 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
8271 EXPECT_TRUE(stream.get());
8272
8273 // Cause QUIC stream to be created, but marked as non-migratable.
8274 HttpRequestInfo request_info;
8275 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
8276 request_info.method = "GET";
8277 request_info.url = GURL("https://www.example.org/");
8278 request_info.traffic_annotation =
8279 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8280 stream->RegisterRequest(&request_info);
8281 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
8282 CompletionOnceCallback()));
8283
8284 // Ensure that session is alive and active.
8285 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
8286 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
8287 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
8288 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
8289
8290 // Send GET request on stream. This should cause a write error, which triggers
8291 // a connection migration attempt.
8292 HttpResponseInfo response;
8293 HttpRequestHeaders request_headers;
8294 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
8295 callback_.callback()));
8296
8297 // Run message loop to execute migration attempt.
8298 base::RunLoop().RunUntilIdle();
8299
8300 // Migration closes the non-migratable stream and:
8301 // if migrate idle session is enabled, it migrates to the alternate network
8302 // successfully; otherwise the connection is closed.
8303 EXPECT_EQ(migrate_idle_sessions,
8304 QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
8305 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(kDefaultDestination));
8306
8307 if (migrate_idle_sessions) {
8308 failed_socket_data.ExpectAllReadDataConsumed();
8309 failed_socket_data.ExpectAllWriteDataConsumed();
8310 }
8311 socket_data.ExpectAllReadDataConsumed();
8312 socket_data.ExpectAllWriteDataConsumed();
8313 }
8314
TEST_P(QuicSessionPoolTest,MigrateSessionOnWriteErrorNonMigratableStreamSync_DoNotMigrateIdleSessions)8315 TEST_P(
8316 QuicSessionPoolTest,
8317 MigrateSessionOnWriteErrorNonMigratableStreamSync_DoNotMigrateIdleSessions) {
8318 TestMigrationOnWriteErrorNonMigratableStream(SYNCHRONOUS, false);
8319 }
8320
TEST_P(QuicSessionPoolTest,MigrateSessionOnWriteErrorNonMigratableStreamAsync_DoNotMigrateIdleSessions)8321 TEST_P(
8322 QuicSessionPoolTest,
8323 MigrateSessionOnWriteErrorNonMigratableStreamAsync_DoNotMigrateIdleSessions) {
8324 TestMigrationOnWriteErrorNonMigratableStream(ASYNC, false);
8325 }
8326
TEST_P(QuicSessionPoolTest,MigrateSessionOnWriteErrorNonMigratableStreamSync_MigrateIdleSessions)8327 TEST_P(QuicSessionPoolTest,
8328 MigrateSessionOnWriteErrorNonMigratableStreamSync_MigrateIdleSessions) {
8329 TestMigrationOnWriteErrorNonMigratableStream(SYNCHRONOUS, true);
8330 }
8331
TEST_P(QuicSessionPoolTest,MigrateSessionOnWriteErrorNonMigratableStreamAsync_MigrateIdleSessions)8332 TEST_P(QuicSessionPoolTest,
8333 MigrateSessionOnWriteErrorNonMigratableStreamAsync_MigrateIdleSessions) {
8334 TestMigrationOnWriteErrorNonMigratableStream(ASYNC, true);
8335 }
8336
TestMigrationOnWriteErrorMigrationDisabled(IoMode write_error_mode)8337 void QuicSessionPoolTest::TestMigrationOnWriteErrorMigrationDisabled(
8338 IoMode write_error_mode) {
8339 InitializeConnectionMigrationV2Test(
8340 {kDefaultNetworkForTests, kNewNetworkForTests});
8341 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8342 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8343
8344 MockQuicData socket_data(version_);
8345 socket_data.AddReadPauseForever();
8346 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
8347 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
8348 socket_data.AddSocketDataToFactory(socket_factory_.get());
8349
8350 // Create request and QuicHttpStream.
8351 RequestBuilder builder(this);
8352 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
8353 EXPECT_EQ(OK, callback_.WaitForResult());
8354 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
8355 EXPECT_TRUE(stream.get());
8356
8357 // Cause QUIC stream to be created.
8358 HttpRequestInfo request_info;
8359 request_info.method = "GET";
8360 request_info.url = GURL("https://www.example.org/");
8361 request_info.traffic_annotation =
8362 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8363 stream->RegisterRequest(&request_info);
8364 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
8365 CompletionOnceCallback()));
8366
8367 // Ensure that session is alive and active.
8368 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
8369 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
8370 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
8371
8372 // Set session config to have connection migration disabled.
8373 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
8374 session->config());
8375 EXPECT_TRUE(session->config()->DisableConnectionMigration());
8376
8377 // Send GET request on stream. This should cause a write error, which triggers
8378 // a connection migration attempt.
8379 HttpResponseInfo response;
8380 HttpRequestHeaders request_headers;
8381 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
8382 callback_.callback()));
8383 // Run message loop to execute migration attempt.
8384 base::RunLoop().RunUntilIdle();
8385 // Migration fails, and session is closed and deleted.
8386 EXPECT_FALSE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
8387 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
8388 socket_data.ExpectAllReadDataConsumed();
8389 socket_data.ExpectAllWriteDataConsumed();
8390 }
8391
TEST_P(QuicSessionPoolTest,MigrateSessionOnWriteErrorMigrationDisabledSynchronous)8392 TEST_P(QuicSessionPoolTest,
8393 MigrateSessionOnWriteErrorMigrationDisabledSynchronous) {
8394 TestMigrationOnWriteErrorMigrationDisabled(SYNCHRONOUS);
8395 }
8396
TEST_P(QuicSessionPoolTest,MigrateSessionOnWriteErrorMigrationDisabledAsync)8397 TEST_P(QuicSessionPoolTest, MigrateSessionOnWriteErrorMigrationDisabledAsync) {
8398 TestMigrationOnWriteErrorMigrationDisabled(ASYNC);
8399 }
8400
8401 // For IETF QUIC, this test the following scenario:
8402 // - original network encounters a SYNC/ASYNC write error based on
8403 // |write_error_mode_on_old_network|, the packet failed to be written is
8404 // cached, session migrates immediately to the alternate network.
8405 // - an immediate SYNC/ASYNC write error based on
8406 // |write_error_mode_on_new_network| is encountered after migration to the
8407 // alternate network, session migrates immediately to the original network.
8408 // - After a new socket for the original network is created and starts to read,
8409 // connection migration fails due to lack of unused connection ID and
8410 // connection is closed.
8411 // TODO(zhongyi): once https://crbug.com/855666 is fixed, this test should be
8412 // modified to test that session is closed early if hopping between networks
8413 // with consecutive write errors is detected.
TestMigrationOnMultipleWriteErrors(IoMode write_error_mode_on_old_network,IoMode write_error_mode_on_new_network)8414 void QuicSessionPoolTest::TestMigrationOnMultipleWriteErrors(
8415 IoMode write_error_mode_on_old_network,
8416 IoMode write_error_mode_on_new_network) {
8417 InitializeConnectionMigrationV2Test(
8418 {kDefaultNetworkForTests, kNewNetworkForTests});
8419 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8420 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8421 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8422 client_maker_.set_save_packet_frames(true);
8423
8424 // Set up the socket data used by the original network, which encounters a
8425 // write error.
8426 MockQuicData socket_data1(version_);
8427 socket_data1.AddReadPauseForever();
8428 int packet_num = 1;
8429 socket_data1.AddWrite(SYNCHRONOUS,
8430 ConstructInitialSettingsPacket(packet_num++));
8431 socket_data1.AddWrite(write_error_mode_on_old_network,
8432 ERR_ADDRESS_UNREACHABLE); // Write Error
8433 socket_data1.AddSocketDataToFactory(socket_factory_.get());
8434
8435 // Set up the socket data used by the alternate network, which
8436 // - is not used to write as migration fails due to lack of connection ID.
8437 // - encounters a write error in gQUIC.
8438 MockQuicData failed_quic_data2(version_);
8439 quic::QuicConnectionId cid_on_new_path =
8440 quic::test::TestConnectionId(12345678);
8441 failed_quic_data2.AddReadPauseForever();
8442 failed_quic_data2.AddWrite(write_error_mode_on_new_network, ERR_FAILED);
8443 failed_quic_data2.AddSocketDataToFactory(socket_factory_.get());
8444
8445 // Set up the third socket data used by original network, which
8446 // - encounters a write error again.
8447 MockQuicData failed_quic_data1(version_);
8448 failed_quic_data1.AddReadPauseForever();
8449 failed_quic_data1.AddSocketDataToFactory(socket_factory_.get());
8450
8451 // Create request and QuicHttpStream.
8452 RequestBuilder builder(this);
8453 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
8454 EXPECT_EQ(OK, callback_.WaitForResult());
8455 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
8456 EXPECT_TRUE(stream.get());
8457
8458 // Cause QUIC stream to be created.
8459 HttpRequestInfo request_info;
8460 request_info.method = "GET";
8461 request_info.url = GURL("https://www.example.org/");
8462 request_info.traffic_annotation =
8463 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8464 stream->RegisterRequest(&request_info);
8465 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
8466 CompletionOnceCallback()));
8467
8468 // Ensure that session is alive and active.
8469 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
8470 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
8471 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
8472 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
8473
8474 // Send GET request on stream.
8475 // This should encounter a write error on network 1,
8476 // then migrate to network 2, which encounters another write error,
8477 // and migrate again to network 1, which encoutners one more write error.
8478 HttpResponseInfo response;
8479 HttpRequestHeaders request_headers;
8480 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
8481 callback_.callback()));
8482 base::RunLoop().RunUntilIdle();
8483 // Connection is closed as there is no connection ID available yet for the
8484 // second migration.
8485 EXPECT_FALSE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
8486 stream.reset();
8487 socket_data1.ExpectAllReadDataConsumed();
8488 socket_data1.ExpectAllWriteDataConsumed();
8489 failed_quic_data2.ExpectAllReadDataConsumed();
8490 failed_quic_data2.ExpectAllWriteDataConsumed();
8491 failed_quic_data1.ExpectAllReadDataConsumed();
8492 failed_quic_data1.ExpectAllWriteDataConsumed();
8493 }
8494
TEST_P(QuicSessionPoolTest,MigrateSessionOnMultipleWriteErrorsSyncSync)8495 TEST_P(QuicSessionPoolTest, MigrateSessionOnMultipleWriteErrorsSyncSync) {
8496 TestMigrationOnMultipleWriteErrors(
8497 /*write_error_mode_on_old_network*/ SYNCHRONOUS,
8498 /*write_error_mode_on_new_network*/ SYNCHRONOUS);
8499 }
8500
TEST_P(QuicSessionPoolTest,MigrateSessionOnMultipleWriteErrorsSyncAsync)8501 TEST_P(QuicSessionPoolTest, MigrateSessionOnMultipleWriteErrorsSyncAsync) {
8502 TestMigrationOnMultipleWriteErrors(
8503 /*write_error_mode_on_old_network*/ SYNCHRONOUS,
8504 /*write_error_mode_on_new_network*/ ASYNC);
8505 }
8506
TEST_P(QuicSessionPoolTest,MigrateSessionOnMultipleWriteErrorsAsyncSync)8507 TEST_P(QuicSessionPoolTest, MigrateSessionOnMultipleWriteErrorsAsyncSync) {
8508 TestMigrationOnMultipleWriteErrors(
8509 /*write_error_mode_on_old_network*/ ASYNC,
8510 /*write_error_mode_on_new_network*/ SYNCHRONOUS);
8511 }
8512
TEST_P(QuicSessionPoolTest,MigrateSessionOnMultipleWriteErrorsAsyncAsync)8513 TEST_P(QuicSessionPoolTest, MigrateSessionOnMultipleWriteErrorsAsyncAsync) {
8514 TestMigrationOnMultipleWriteErrors(
8515 /*write_error_mode_on_old_network*/ ASYNC,
8516 /*write_error_mode_on_new_network*/ ASYNC);
8517 }
8518
8519 // Verifies that a connection is closed when connection migration is triggered
8520 // on network being disconnected and the handshake is not confirmed.
TEST_P(QuicSessionPoolTest,NoMigrationBeforeHandshakeOnNetworkDisconnected)8521 TEST_P(QuicSessionPoolTest, NoMigrationBeforeHandshakeOnNetworkDisconnected) {
8522 FLAGS_quic_enable_chaos_protection = false;
8523 // TODO(https://crbug.com/1295460): Make this test work with asynchronous QUIC
8524 // session creation. This test only works with synchronous session creation
8525 // for now.
8526 base::test::ScopedFeatureList scoped_feature_list;
8527 scoped_feature_list.InitAndDisableFeature(net::features::kAsyncQuicSession);
8528
8529 InitializeConnectionMigrationV2Test(
8530 {kDefaultNetworkForTests, kNewNetworkForTests});
8531
8532 // Use cold start mode to do crypto connect, and send CHLO packet on wire.
8533 crypto_client_stream_factory_.set_handshake_mode(
8534 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
8535
8536 MockQuicData socket_data(version_);
8537 socket_data.AddReadPauseForever();
8538 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
8539 socket_data.AddSocketDataToFactory(socket_factory_.get());
8540
8541 // Create request and QuicHttpStream.
8542 RequestBuilder builder(this);
8543 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
8544 // Deliver the network notification, which should cause the connection to be
8545 // closed.
8546 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8547 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
8548 EXPECT_EQ(ERR_NETWORK_CHANGED, callback_.WaitForResult());
8549
8550 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
8551 EXPECT_FALSE(HasActiveJob(kDefaultDestination, PRIVACY_MODE_DISABLED));
8552 socket_data.ExpectAllReadDataConsumed();
8553 socket_data.ExpectAllWriteDataConsumed();
8554 }
8555
8556 // Sets up the connection migration test where network change notification is
8557 // queued BEFORE connection migration attempt on write error is posted.
8558 void QuicSessionPoolTest::
TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(bool disconnected)8559 TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
8560 bool disconnected) {
8561 InitializeConnectionMigrationV2Test(
8562 {kDefaultNetworkForTests, kNewNetworkForTests});
8563 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8564 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8565 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8566 client_maker_.set_save_packet_frames(true);
8567
8568 MockQuicData socket_data(version_);
8569 socket_data.AddReadPauseForever();
8570 int packet_num = 1;
8571 socket_data.AddWrite(SYNCHRONOUS,
8572 ConstructInitialSettingsPacket(packet_num++));
8573 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8574 socket_data.AddSocketDataToFactory(socket_factory_.get());
8575
8576 // Create request and QuicHttpStream.
8577 RequestBuilder builder(this);
8578 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
8579 EXPECT_EQ(OK, callback_.WaitForResult());
8580 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
8581 EXPECT_TRUE(stream.get());
8582
8583 // Cause QUIC stream to be created.
8584 HttpRequestInfo request_info;
8585 request_info.method = "GET";
8586 request_info.url = GURL("https://www.example.org/");
8587 request_info.traffic_annotation =
8588 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8589 stream->RegisterRequest(&request_info);
8590 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
8591 CompletionOnceCallback()));
8592
8593 // Ensure that session is alive and active.
8594 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
8595 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
8596 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
8597 quic::QuicConnectionId cid_on_new_path =
8598 quic::test::TestConnectionId(12345678);
8599 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
8600
8601 // Set up second socket data provider that is used after
8602 // migration. The request is rewritten to this new socket, and the
8603 // response to the request is read on this new socket.
8604 MockQuicData socket_data1(version_);
8605 client_maker_.set_connection_id(cid_on_new_path);
8606 // Increment packet number to account for packet write error on the old
8607 // path. Also save the packet in client_maker_ for constructing the
8608 // retransmission packet.
8609 ConstructGetRequestPacket(packet_num++,
8610 GetNthClientInitiatedBidirectionalStreamId(0),
8611 /*fin=*/true);
8612 socket_data1.AddWrite(SYNCHRONOUS,
8613 client_maker_.MakeCombinedRetransmissionPacket(
8614 /*original_packet_numbers=*/{1, 2}, packet_num++));
8615 socket_data1.AddWrite(SYNCHRONOUS,
8616 client_maker_.MakePingPacket(packet_num++));
8617 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakeRetireConnectionIdPacket(
8618 packet_num++, /*sequence_number=*/0u));
8619
8620 socket_data1.AddRead(
8621 ASYNC, ConstructOkResponsePacket(
8622 1, GetNthClientInitiatedBidirectionalStreamId(0), false));
8623 socket_data1.AddReadPauseForever();
8624 socket_data1.AddWrite(
8625 SYNCHRONOUS,
8626 client_maker_.MakeDataPacket(
8627 packet_num++, GetQpackDecoderStreamId(),
8628 /*fin=*/false, StreamCancellationQpackDecoderInstruction(0)));
8629 socket_data1.AddWrite(
8630 SYNCHRONOUS,
8631 client_maker_.MakeRstPacket(packet_num++,
8632 GetNthClientInitiatedBidirectionalStreamId(0),
8633 quic::QUIC_STREAM_CANCELLED));
8634
8635 socket_data1.AddSocketDataToFactory(socket_factory_.get());
8636
8637 // First queue a network change notification in the message loop.
8638 if (disconnected) {
8639 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8640 ->QueueNetworkDisconnected(kDefaultNetworkForTests);
8641 } else {
8642 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8643 ->QueueNetworkMadeDefault(kNewNetworkForTests);
8644 }
8645 // Send GET request on stream. This should cause a write error,
8646 // which triggers a connection migration attempt. This will queue a
8647 // migration attempt behind the notification in the message loop.
8648 HttpResponseInfo response;
8649 HttpRequestHeaders request_headers;
8650 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
8651 callback_.callback()));
8652
8653 base::RunLoop().RunUntilIdle();
8654 // Verify the session is still alive and not marked as going away post
8655 // migration.
8656 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
8657 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
8658 EXPECT_EQ(1u, session->GetNumActiveStreams());
8659 // Verify that response headers on the migrated socket were delivered to the
8660 // stream.
8661 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
8662 EXPECT_EQ(200, response.headers->response_code());
8663
8664 stream.reset();
8665
8666 socket_data.ExpectAllReadDataConsumed();
8667 socket_data.ExpectAllWriteDataConsumed();
8668 socket_data1.ExpectAllReadDataConsumed();
8669 socket_data1.ExpectAllWriteDataConsumed();
8670 }
8671
8672 // This test verifies that session attempts connection migration successfully
8673 // with signals delivered in the following order (alternate network is always
8674 // available):
8675 // - a notification that default network is disconnected is queued.
8676 // - write error is triggered: session posts a task to attempt connection
8677 // migration, |migration_pending_| set to true.
8678 // - default network disconnected is delivered: session immediately migrates to
8679 // the alternate network, |migration_pending_| set to false.
8680 // - connection migration on write error attempt aborts: writer encountered
8681 // error is no longer in active use.
TEST_P(QuicSessionPoolTest,MigrateOnNetworkDisconnectedWithWriteErrorQueuedLater)8682 TEST_P(QuicSessionPoolTest,
8683 MigrateOnNetworkDisconnectedWithWriteErrorQueuedLater) {
8684 TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
8685 /*disconnected=*/true);
8686 }
8687
8688 // This test verifies that session attempts connection migration successfully
8689 // with signals delivered in the following order (alternate network is always
8690 // available):
8691 // - a notification that alternate network is made default is queued.
8692 // - write error is triggered: session posts a task to attempt connection
8693 // migration, block future migrations.
8694 // - new default notification is delivered: migrate back timer spins and task is
8695 // posted to migrate to the new default network.
8696 // - connection migration on write error attempt proceeds successfully: session
8697 // is
8698 // marked as going away, future migrations unblocked.
8699 // - migrate back to default network task executed: session is already on the
8700 // default network, no-op.
TEST_P(QuicSessionPoolTest,MigrateOnWriteErrorWithNetworkMadeDefaultQueuedEarlier)8701 TEST_P(QuicSessionPoolTest,
8702 MigrateOnWriteErrorWithNetworkMadeDefaultQueuedEarlier) {
8703 TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
8704 /*disconnected=*/false);
8705 }
8706
8707 // Sets up the connection migration test where network change notification is
8708 // queued AFTER connection migration attempt on write error is posted.
TestMigrationOnWriteErrorWithNotificationQueuedLater(bool disconnected)8709 void QuicSessionPoolTest::TestMigrationOnWriteErrorWithNotificationQueuedLater(
8710 bool disconnected) {
8711 InitializeConnectionMigrationV2Test(
8712 {kDefaultNetworkForTests, kNewNetworkForTests});
8713 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8714 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8715 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8716 client_maker_.set_save_packet_frames(true);
8717
8718 MockQuicData socket_data(version_);
8719 socket_data.AddReadPauseForever();
8720 int packet_num = 1;
8721 socket_data.AddWrite(SYNCHRONOUS,
8722 ConstructInitialSettingsPacket(packet_num++));
8723 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8724 socket_data.AddSocketDataToFactory(socket_factory_.get());
8725
8726 // Create request and QuicHttpStream.
8727 RequestBuilder builder(this);
8728 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
8729 EXPECT_EQ(OK, callback_.WaitForResult());
8730 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
8731 EXPECT_TRUE(stream.get());
8732
8733 // Cause QUIC stream to be created.
8734 HttpRequestInfo request_info;
8735 request_info.method = "GET";
8736 request_info.url = GURL("https://www.example.org/");
8737 request_info.traffic_annotation =
8738 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8739 stream->RegisterRequest(&request_info);
8740 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
8741 CompletionOnceCallback()));
8742
8743 // Ensure that session is alive and active.
8744 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
8745 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
8746 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
8747 quic::QuicConnectionId cid_on_new_path =
8748 quic::test::TestConnectionId(12345678);
8749 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
8750
8751 // Set up second socket data provider that is used after
8752 // migration. The request is rewritten to this new socket, and the
8753 // response to the request is read on this new socket.
8754 MockQuicData socket_data1(version_);
8755
8756 client_maker_.set_connection_id(cid_on_new_path);
8757 // Increment packet number to account for packet write error on the old
8758 // path. Also save the packet in client_maker_ for constructing the
8759 // retransmission packet.
8760 ConstructGetRequestPacket(packet_num++,
8761 GetNthClientInitiatedBidirectionalStreamId(0),
8762 /*fin=*/true);
8763 socket_data1.AddWrite(SYNCHRONOUS,
8764 client_maker_.MakeCombinedRetransmissionPacket(
8765 /*original_packet_numbers=*/{1, 2}, packet_num++));
8766 socket_data1.AddWrite(SYNCHRONOUS,
8767 client_maker_.MakePingPacket(packet_num++));
8768 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakeRetireConnectionIdPacket(
8769 packet_num++,
8770 /*sequence_number=*/0u));
8771 socket_data1.AddRead(
8772 ASYNC, ConstructOkResponsePacket(
8773 1, GetNthClientInitiatedBidirectionalStreamId(0), false));
8774 socket_data1.AddReadPauseForever();
8775 socket_data1.AddWrite(
8776 SYNCHRONOUS,
8777 client_maker_.MakeDataPacket(
8778 packet_num++, GetQpackDecoderStreamId(),
8779 /*fin=*/false, StreamCancellationQpackDecoderInstruction(0)));
8780 socket_data1.AddWrite(
8781 SYNCHRONOUS,
8782 client_maker_.MakeRstPacket(packet_num++,
8783 GetNthClientInitiatedBidirectionalStreamId(0),
8784 quic::QUIC_STREAM_CANCELLED));
8785
8786 socket_data1.AddSocketDataToFactory(socket_factory_.get());
8787
8788 // Send GET request on stream. This should cause a write error,
8789 // which triggers a connection migration attempt. This will queue a
8790 // migration attempt in the message loop.
8791 HttpResponseInfo response;
8792 HttpRequestHeaders request_headers;
8793 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
8794 callback_.callback()));
8795 base::RunLoop().RunUntilIdle();
8796
8797 // Now queue a network change notification in the message loop behind
8798 // the migration attempt.
8799 if (disconnected) {
8800 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8801 ->QueueNetworkDisconnected(kDefaultNetworkForTests);
8802 } else {
8803 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8804 ->QueueNetworkMadeDefault(kNewNetworkForTests);
8805 }
8806
8807 // Verify session is still alive and not marked as going away.
8808 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
8809 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
8810 EXPECT_EQ(1u, session->GetNumActiveStreams());
8811
8812 // Verify that response headers on the migrated socket were delivered to the
8813 // stream.
8814 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
8815 EXPECT_EQ(200, response.headers->response_code());
8816
8817 stream.reset();
8818
8819 socket_data.ExpectAllReadDataConsumed();
8820 socket_data.ExpectAllWriteDataConsumed();
8821 socket_data1.ExpectAllReadDataConsumed();
8822 socket_data1.ExpectAllWriteDataConsumed();
8823 }
8824
8825 // This test verifies that session attempts connection migration successfully
8826 // with signals delivered in the following order (alternate network is always
8827 // available):
8828 // - write error is triggered: session posts a task to complete connection
8829 // migration.
8830 // - a notification that alternate network is made default is queued.
8831 // - connection migration attempt proceeds successfully, session is marked as
8832 // going away.
8833 // - new default notification is delivered after connection migration has been
8834 // completed.
TEST_P(QuicSessionPoolTest,MigrateOnWriteErrorWithNetworkMadeDefaultQueuedLater)8835 TEST_P(QuicSessionPoolTest,
8836 MigrateOnWriteErrorWithNetworkMadeDefaultQueuedLater) {
8837 TestMigrationOnWriteErrorWithNotificationQueuedLater(/*disconnected=*/false);
8838 }
8839
8840 // This test verifies that session attempts connection migration successfully
8841 // with signals delivered in the following order (alternate network is always
8842 // available):
8843 // - write error is triggered: session posts a task to complete connection
8844 // migration.
8845 // - a notification that default network is diconnected is queued.
8846 // - connection migration attempt proceeds successfully, session is marked as
8847 // going away.
8848 // - disconnect notification is delivered after connection migration has been
8849 // completed.
TEST_P(QuicSessionPoolTest,MigrateOnWriteErrorWithNetworkDisconnectedQueuedLater)8850 TEST_P(QuicSessionPoolTest,
8851 MigrateOnWriteErrorWithNetworkDisconnectedQueuedLater) {
8852 TestMigrationOnWriteErrorWithNotificationQueuedLater(/*disconnected=*/true);
8853 }
8854
8855 // This tests connection migration on write error with signals delivered in the
8856 // following order:
8857 // - a synchronous/asynchronous write error is triggered base on
8858 // |write_error_mode|: connection migration attempt is posted.
8859 // - old default network disconnects, migration waits for a new network.
8860 // - after a pause, new network is connected: session will migrate to new
8861 // network immediately.
8862 // - migration on writer error is exectued and aborts as writer passed in is no
8863 // longer active in use.
8864 // - new network is made default.
TestMigrationOnWriteErrorPauseBeforeConnected(IoMode write_error_mode)8865 void QuicSessionPoolTest::TestMigrationOnWriteErrorPauseBeforeConnected(
8866 IoMode write_error_mode) {
8867 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
8868 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8869 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8870 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8871 client_maker_.set_save_packet_frames(true);
8872
8873 // Use the test task runner.
8874 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), runner_.get());
8875
8876 MockQuicData socket_data(version_);
8877 socket_data.AddReadPauseForever();
8878 int packet_num = 1;
8879 socket_data.AddWrite(SYNCHRONOUS,
8880 ConstructInitialSettingsPacket(packet_num++));
8881 socket_data.AddWrite(write_error_mode, ERR_FAILED);
8882 socket_data.AddSocketDataToFactory(socket_factory_.get());
8883
8884 // Create request and QuicHttpStream.
8885 RequestBuilder builder(this);
8886 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
8887 EXPECT_THAT(callback_.WaitForResult(), IsOk());
8888 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
8889 EXPECT_TRUE(stream.get());
8890
8891 // Cause QUIC stream to be created.
8892 HttpRequestInfo request_info;
8893 request_info.method = "GET";
8894 request_info.url = GURL(kDefaultUrl);
8895 request_info.traffic_annotation =
8896 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8897 stream->RegisterRequest(&request_info);
8898 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
8899 CompletionOnceCallback()));
8900
8901 // Ensure that session is alive and active.
8902 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
8903 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
8904 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
8905 quic::QuicConnectionId cid_on_new_path =
8906 quic::test::TestConnectionId(12345678);
8907 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
8908
8909 // Send GET request on stream.
8910 HttpResponseInfo response;
8911 HttpRequestHeaders request_headers;
8912 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
8913 callback_.callback()));
8914
8915 // The connection should still be alive, not marked as going away.
8916 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
8917 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
8918 EXPECT_EQ(1u, session->GetNumActiveStreams());
8919 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
8920
8921 // Set up second socket data provider that is used after migration.
8922 // The response to the earlier request is read on this new socket.
8923 MockQuicData socket_data1(version_);
8924 client_maker_.set_connection_id(cid_on_new_path);
8925 // Increment packet number to account for packet write error on the old
8926 // path. Also save the packet in client_maker_ for constructing the
8927 // retransmission packet.
8928 ConstructGetRequestPacket(packet_num++,
8929 GetNthClientInitiatedBidirectionalStreamId(0),
8930 /*fin=*/true);
8931 socket_data1.AddRead(
8932 ASYNC, ConstructOkResponsePacket(
8933 1, GetNthClientInitiatedBidirectionalStreamId(0), false));
8934 socket_data1.AddReadPauseForever();
8935 socket_data1.AddWrite(
8936 SYNCHRONOUS, client_maker_.MakeRetransmissionAndRetireConnectionIdPacket(
8937 packet_num++,
8938 /*original_packet_numbers=*/{1, 2},
8939 /*sequence_number=*/0u));
8940 socket_data1.AddWrite(SYNCHRONOUS,
8941 client_maker_.MakePingPacket(packet_num++));
8942 socket_data1.AddWrite(
8943 SYNCHRONOUS,
8944 client_maker_.MakeDataPacket(
8945 packet_num++, GetQpackDecoderStreamId(),
8946 /*fin=*/false, StreamCancellationQpackDecoderInstruction(0)));
8947 socket_data1.AddWrite(
8948 SYNCHRONOUS,
8949 client_maker_.MakeRstPacket(packet_num++,
8950 GetNthClientInitiatedBidirectionalStreamId(0),
8951 quic::QUIC_STREAM_CANCELLED));
8952 socket_data1.AddSocketDataToFactory(socket_factory_.get());
8953
8954 // On a DISCONNECTED notification, nothing happens.
8955 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8956 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
8957 // Add a new network and notify the stream factory of a new connected network.
8958 // This causes a PING packet to be sent over the new network.
8959 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8960 ->SetConnectedNetworksList({kNewNetworkForTests});
8961 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8962 ->NotifyNetworkConnected(kNewNetworkForTests);
8963
8964 // Ensure that the session is still alive.
8965 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
8966 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
8967 EXPECT_EQ(1u, session->GetNumActiveStreams());
8968
8969 // Run the message loop migration for write error can finish.
8970 runner_->RunUntilIdle();
8971
8972 // Response headers are received over the new network.
8973 EXPECT_THAT(callback_.WaitForResult(), IsOk());
8974 EXPECT_EQ(200, response.headers->response_code());
8975
8976 // Check that the session is still alive.
8977 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
8978 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
8979
8980 // There should be no posted tasks not executed, no way to migrate back to
8981 // default network.
8982 EXPECT_TRUE(runner_->GetPostedTasks().empty());
8983
8984 // Receive signal to mark new network as default.
8985 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8986 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
8987
8988 stream.reset();
8989 socket_data.ExpectAllReadDataConsumed();
8990 socket_data.ExpectAllWriteDataConsumed();
8991 socket_data1.ExpectAllReadDataConsumed();
8992 socket_data1.ExpectAllWriteDataConsumed();
8993 }
8994
TEST_P(QuicSessionPoolTest,MigrateSessionOnSyncWriteErrorPauseBeforeConnected)8995 TEST_P(QuicSessionPoolTest,
8996 MigrateSessionOnSyncWriteErrorPauseBeforeConnected) {
8997 TestMigrationOnWriteErrorPauseBeforeConnected(SYNCHRONOUS);
8998 }
8999
TEST_P(QuicSessionPoolTest,MigrateSessionOnAsyncWriteErrorPauseBeforeConnected)9000 TEST_P(QuicSessionPoolTest,
9001 MigrateSessionOnAsyncWriteErrorPauseBeforeConnected) {
9002 TestMigrationOnWriteErrorPauseBeforeConnected(ASYNC);
9003 }
9004
9005 // This test verifies that when session successfully migrate to the alternate
9006 // network, packet write error on the old writer will be ignored and will not
9007 // trigger connection migration on write error.
TEST_P(QuicSessionPoolTest,IgnoreWriteErrorFromOldWriterAfterMigration)9008 TEST_P(QuicSessionPoolTest, IgnoreWriteErrorFromOldWriterAfterMigration) {
9009 InitializeConnectionMigrationV2Test(
9010 {kDefaultNetworkForTests, kNewNetworkForTests});
9011 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9012 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9013 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9014 client_maker_.set_save_packet_frames(true);
9015
9016 // Using a testing task runner so that we can verify whether the migrate on
9017 // write error task is posted.
9018 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
9019 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
9020
9021 MockQuicData socket_data(version_);
9022 int packet_num = 1;
9023 socket_data.AddWrite(SYNCHRONOUS,
9024 ConstructInitialSettingsPacket(packet_num++));
9025 socket_data.AddReadPause();
9026 socket_data.AddWrite(
9027 ASYNC, ERR_ADDRESS_UNREACHABLE,
9028 ConstructGetRequestPacket(
9029 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true));
9030 socket_data.AddReadPauseForever();
9031 socket_data.AddSocketDataToFactory(socket_factory_.get());
9032
9033 // Create request and QuicHttpStream.
9034 RequestBuilder builder(this);
9035 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
9036 EXPECT_EQ(OK, callback_.WaitForResult());
9037 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
9038 EXPECT_TRUE(stream.get());
9039
9040 // Cause QUIC stream to be created.
9041 HttpRequestInfo request_info;
9042 request_info.method = "GET";
9043 request_info.url = GURL("https://www.example.org/");
9044 request_info.traffic_annotation =
9045 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9046 stream->RegisterRequest(&request_info);
9047 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
9048 CompletionOnceCallback()));
9049
9050 // Ensure that session is alive and active.
9051 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
9052 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
9053 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
9054 quic::QuicConnectionId cid_on_new_path =
9055 quic::test::TestConnectionId(12345678);
9056 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
9057
9058 // Set up second socket data provider that is used after
9059 // migration. The response to the request is read on this new socket.
9060 MockQuicData socket_data1(version_);
9061 client_maker_.set_connection_id(cid_on_new_path);
9062 socket_data1.AddWrite(
9063 SYNCHRONOUS,
9064 client_maker_.MakeCombinedRetransmissionPacket({1, 2}, packet_num++));
9065 socket_data1.AddWrite(SYNCHRONOUS,
9066 client_maker_.MakePingPacket(packet_num++));
9067 socket_data1.AddRead(
9068 ASYNC, ConstructOkResponsePacket(
9069 1, GetNthClientInitiatedBidirectionalStreamId(0), false));
9070 socket_data1.AddReadPauseForever();
9071 socket_data1.AddWrite(
9072 SYNCHRONOUS,
9073 client_maker_.MakeDataPacket(
9074 packet_num++, GetQpackDecoderStreamId(),
9075 /*fin=*/false, StreamCancellationQpackDecoderInstruction(0)));
9076 socket_data1.AddWrite(
9077 SYNCHRONOUS,
9078 client_maker_.MakeRstPacket(packet_num++,
9079 GetNthClientInitiatedBidirectionalStreamId(0),
9080 quic::QUIC_STREAM_CANCELLED));
9081 socket_data1.AddSocketDataToFactory(socket_factory_.get());
9082
9083 // Send GET request on stream.
9084 HttpResponseInfo response;
9085 HttpRequestHeaders request_headers;
9086 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
9087 callback_.callback()));
9088
9089 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
9090 // Now notify network is disconnected, cause the migration to complete
9091 // immediately.
9092 scoped_mock_network_change_notifier_->mock_network_change_notifier()
9093 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
9094 // There will be two pending task, one will complete migration with no delay
9095 // and the other will attempt to migrate back to the default network with
9096 // delay.
9097 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
9098
9099 // Complete migration.
9100 task_runner->RunUntilIdle();
9101 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
9102
9103 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
9104 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
9105 EXPECT_EQ(1u, session->GetNumActiveStreams());
9106
9107 // Verify that response headers on the migrated socket were delivered to the
9108 // stream.
9109 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
9110 EXPECT_EQ(200, response.headers->response_code());
9111
9112 // Resume the old socket data, a write error will be delivered to the old
9113 // packet writer. Verify no additional task is posted.
9114 socket_data.Resume();
9115 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
9116
9117 stream.reset();
9118 socket_data.ExpectAllWriteDataConsumed();
9119 socket_data1.ExpectAllReadDataConsumed();
9120 socket_data1.ExpectAllWriteDataConsumed();
9121 }
9122
9123 // This test verifies that when session successfully migrate to the alternate
9124 // network, packet read error on the old reader will be ignored and will not
9125 // close the connection.
TEST_P(QuicSessionPoolTest,IgnoreReadErrorFromOldReaderAfterMigration)9126 TEST_P(QuicSessionPoolTest, IgnoreReadErrorFromOldReaderAfterMigration) {
9127 InitializeConnectionMigrationV2Test(
9128 {kDefaultNetworkForTests, kNewNetworkForTests});
9129 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9130 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9131 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9132 client_maker_.set_save_packet_frames(true);
9133
9134 // Using a testing task runner.
9135 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
9136 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
9137
9138 MockQuicData socket_data(version_);
9139 int packet_num = 1;
9140 socket_data.AddWrite(SYNCHRONOUS,
9141 ConstructInitialSettingsPacket(packet_num++));
9142 socket_data.AddReadPause();
9143 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE);
9144 socket_data.AddSocketDataToFactory(socket_factory_.get());
9145
9146 // Create request and QuicHttpStream.
9147 RequestBuilder builder(this);
9148 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
9149 EXPECT_EQ(OK, callback_.WaitForResult());
9150 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
9151 EXPECT_TRUE(stream.get());
9152
9153 // Cause QUIC stream to be created.
9154 HttpRequestInfo request_info;
9155 request_info.method = "GET";
9156 request_info.url = GURL("https://www.example.org/");
9157 request_info.traffic_annotation =
9158 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9159 stream->RegisterRequest(&request_info);
9160 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
9161 CompletionOnceCallback()));
9162
9163 // Ensure that session is alive and active.
9164 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
9165 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
9166 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
9167 quic::QuicConnectionId cid_on_new_path =
9168 quic::test::TestConnectionId(12345678);
9169 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
9170
9171 // Set up second socket data provider that is used after
9172 // migration. The request is written to this new socket, and the
9173 // response to the request is read on this new socket.
9174 MockQuicData socket_data1(version_);
9175 client_maker_.set_connection_id(cid_on_new_path);
9176 socket_data1.AddWrite(
9177 SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(1, packet_num++));
9178 socket_data1.AddWrite(SYNCHRONOUS,
9179 client_maker_.MakePingPacket(packet_num++));
9180 socket_data1.AddWrite(
9181 SYNCHRONOUS,
9182 ConstructGetRequestPacket(
9183 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true));
9184 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakeRetireConnectionIdPacket(
9185 packet_num++,
9186 /*sequence_number=*/0u));
9187 socket_data1.AddRead(
9188 ASYNC, ConstructOkResponsePacket(
9189 1, GetNthClientInitiatedBidirectionalStreamId(0), false));
9190 socket_data1.AddReadPauseForever();
9191 socket_data1.AddWrite(
9192 SYNCHRONOUS,
9193 client_maker_.MakeDataPacket(
9194 packet_num++, GetQpackDecoderStreamId(),
9195 /*fin=*/false, StreamCancellationQpackDecoderInstruction(0)));
9196 socket_data1.AddWrite(
9197 SYNCHRONOUS,
9198 client_maker_.MakeRstPacket(packet_num++,
9199 GetNthClientInitiatedBidirectionalStreamId(0),
9200 quic::QUIC_STREAM_CANCELLED));
9201 socket_data1.AddSocketDataToFactory(socket_factory_.get());
9202
9203 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
9204 // Now notify network is disconnected, cause the migration to complete
9205 // immediately.
9206 scoped_mock_network_change_notifier_->mock_network_change_notifier()
9207 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
9208 // There will be two pending task, one will complete migration with no delay
9209 // and the other will attempt to migrate back to the default network with
9210 // delay.
9211 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
9212
9213 // Complete migration.
9214 task_runner->RunUntilIdle();
9215 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
9216
9217 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
9218 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
9219 EXPECT_EQ(1u, session->GetNumActiveStreams());
9220
9221 // Send GET request on stream.
9222 HttpResponseInfo response;
9223 HttpRequestHeaders request_headers;
9224 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
9225 callback_.callback()));
9226
9227 // Verify that response headers on the migrated socket were delivered to the
9228 // stream.
9229 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
9230 EXPECT_EQ(OK, callback_.WaitForResult());
9231 EXPECT_EQ(200, response.headers->response_code());
9232
9233 // Resume the old socket data, a read error will be delivered to the old
9234 // packet reader. Verify that the session is not affected.
9235 socket_data.Resume();
9236 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
9237 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
9238 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
9239 EXPECT_EQ(1u, session->GetNumActiveStreams());
9240
9241 stream.reset();
9242 socket_data.ExpectAllReadDataConsumed();
9243 socket_data.ExpectAllWriteDataConsumed();
9244 socket_data1.ExpectAllReadDataConsumed();
9245 socket_data1.ExpectAllWriteDataConsumed();
9246 }
9247
9248 // This test verifies that after migration on network is executed, packet
9249 // read error on the old reader will be ignored and will not close the
9250 // connection.
TEST_P(QuicSessionPoolTest,IgnoreReadErrorOnOldReaderDuringMigration)9251 TEST_P(QuicSessionPoolTest, IgnoreReadErrorOnOldReaderDuringMigration) {
9252 InitializeConnectionMigrationV2Test(
9253 {kDefaultNetworkForTests, kNewNetworkForTests});
9254 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9255 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9256 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9257 client_maker_.set_save_packet_frames(true);
9258
9259 // Using a testing task runner.
9260 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
9261 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
9262
9263 MockQuicData socket_data(version_);
9264 int packet_num = 1;
9265 socket_data.AddWrite(SYNCHRONOUS,
9266 ConstructInitialSettingsPacket(packet_num++));
9267 socket_data.AddReadPause();
9268 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE);
9269 socket_data.AddSocketDataToFactory(socket_factory_.get());
9270
9271 // Create request and QuicHttpStream.
9272 RequestBuilder builder(this);
9273 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
9274 EXPECT_EQ(OK, callback_.WaitForResult());
9275 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
9276 EXPECT_TRUE(stream.get());
9277
9278 // Cause QUIC stream to be created.
9279 HttpRequestInfo request_info;
9280 request_info.method = "GET";
9281 request_info.url = GURL("https://www.example.org/");
9282 request_info.traffic_annotation =
9283 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9284 stream->RegisterRequest(&request_info);
9285 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
9286 CompletionOnceCallback()));
9287
9288 // Ensure that session is alive and active.
9289 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
9290 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
9291 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
9292 quic::QuicConnectionId cid_on_new_path =
9293 quic::test::TestConnectionId(12345678);
9294 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
9295
9296 // Set up second socket data provider that is used after
9297 // migration. The request is written to this new socket, and the
9298 // response to the request is read on this new socket.
9299 MockQuicData socket_data1(version_);
9300 client_maker_.set_connection_id(cid_on_new_path);
9301 socket_data1.AddWrite(
9302 SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(1, packet_num++));
9303 socket_data1.AddWrite(SYNCHRONOUS,
9304 client_maker_.MakePingPacket(packet_num++));
9305 socket_data1.AddWrite(
9306 SYNCHRONOUS,
9307 ConstructGetRequestPacket(
9308 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true));
9309 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakeRetireConnectionIdPacket(
9310 packet_num++,
9311 /*sequence_number=*/0u));
9312 socket_data1.AddRead(
9313 ASYNC, ConstructOkResponsePacket(
9314 1, GetNthClientInitiatedBidirectionalStreamId(0), false));
9315 socket_data1.AddReadPauseForever();
9316 socket_data1.AddWrite(
9317 SYNCHRONOUS,
9318 client_maker_.MakeDataPacket(
9319 packet_num++, GetQpackDecoderStreamId(),
9320 /*fin=*/false, StreamCancellationQpackDecoderInstruction(0)));
9321 socket_data1.AddWrite(
9322 SYNCHRONOUS,
9323 client_maker_.MakeRstPacket(packet_num++,
9324 GetNthClientInitiatedBidirectionalStreamId(0),
9325 quic::QUIC_STREAM_CANCELLED));
9326
9327 socket_data1.AddSocketDataToFactory(socket_factory_.get());
9328
9329 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
9330 // Now notify network is disconnected, cause the migration to complete
9331 // immediately.
9332 scoped_mock_network_change_notifier_->mock_network_change_notifier()
9333 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
9334 // There will be two pending task, one will complete migration with no delay
9335 // and the other will attempt to migrate back to the default network with
9336 // delay.
9337 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
9338
9339 // Resume the old socket data, a read error will be delivered to the old
9340 // packet reader. Verify that the session is not affected.
9341 socket_data.Resume();
9342 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
9343 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
9344 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
9345 EXPECT_EQ(1u, session->GetNumActiveStreams());
9346
9347 // Complete migration.
9348 task_runner->RunUntilIdle();
9349 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
9350
9351 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
9352 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
9353 EXPECT_EQ(1u, session->GetNumActiveStreams());
9354
9355 // Send GET request on stream.
9356 HttpResponseInfo response;
9357 HttpRequestHeaders request_headers;
9358 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
9359 callback_.callback()));
9360
9361 // Verify that response headers on the migrated socket were delivered to the
9362 // stream.
9363 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
9364 EXPECT_EQ(OK, callback_.WaitForResult());
9365 EXPECT_EQ(200, response.headers->response_code());
9366
9367 stream.reset();
9368 socket_data.ExpectAllWriteDataConsumed();
9369 socket_data1.ExpectAllReadDataConsumed();
9370 socket_data1.ExpectAllWriteDataConsumed();
9371 }
9372
9373 // This test verifies that when connection migration on path degrading is
9374 // enabled, and no custom retransmittable on wire timeout is specified, the
9375 // default value is used.
TEST_P(QuicSessionPoolTest,DefaultRetransmittableOnWireTimeoutForMigration)9376 TEST_P(QuicSessionPoolTest, DefaultRetransmittableOnWireTimeoutForMigration) {
9377 InitializeConnectionMigrationV2Test(
9378 {kDefaultNetworkForTests, kNewNetworkForTests});
9379 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9380 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9381 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9382 client_maker_.set_save_packet_frames(true);
9383
9384 // Using a testing task runner.
9385 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
9386 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
9387 QuicSessionPoolPeer::SetAlarmFactory(
9388 factory_.get(), std::make_unique<QuicChromiumAlarmFactory>(
9389 task_runner.get(), context_.clock()));
9390
9391 quic::QuicConnectionId cid_on_new_path =
9392 quic::test::TestConnectionId(12345678);
9393 MockQuicData socket_data(version_);
9394 int packet_num = 1;
9395 int peer_packet_num = 1;
9396 socket_data.AddWrite(SYNCHRONOUS,
9397 ConstructInitialSettingsPacket(packet_num++));
9398 socket_data.AddRead(ASYNC, server_maker_.MakeNewConnectionIdPacket(
9399 peer_packet_num++, cid_on_new_path,
9400 /*sequence_number=*/1u,
9401 /*retire_prior_to=*/0u));
9402 socket_data.AddReadPause();
9403 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE);
9404 socket_data.AddSocketDataToFactory(socket_factory_.get());
9405
9406 // Set up second socket data provider that is used after
9407 // migration. The request is written to this new socket, and the
9408 // response to the request is read on this new socket.
9409 MockQuicData socket_data1(version_);
9410 client_maker_.set_connection_id(cid_on_new_path);
9411 socket_data1.AddWrite(SYNCHRONOUS,
9412 client_maker_.MakeAckAndRetransmissionPacket(
9413 packet_num++, /*first_received=*/1,
9414 /*largest_received=*/1, /*smallest_received=*/1,
9415 /*original_packet_numbers=*/{1}));
9416 // The PING packet sent post migration.
9417 socket_data1.AddWrite(SYNCHRONOUS,
9418 client_maker_.MakePingPacket(packet_num++));
9419 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakeRetireConnectionIdPacket(
9420 packet_num++, /*sequence_number=*/0u));
9421 socket_data1.AddWrite(
9422 SYNCHRONOUS,
9423 ConstructGetRequestPacket(
9424 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true));
9425 socket_data1.AddReadPause();
9426 // Read two packets so that client will send ACK immediately.
9427 socket_data1.AddRead(
9428 ASYNC, ConstructOkResponsePacket(
9429 peer_packet_num++,
9430 GetNthClientInitiatedBidirectionalStreamId(0), false));
9431 socket_data1.AddRead(ASYNC, server_maker_.MakeDataPacket(
9432 peer_packet_num++,
9433 GetNthClientInitiatedBidirectionalStreamId(0),
9434 false, "Hello World"));
9435
9436 // Read an ACK from server which acks all client data.
9437 socket_data1.AddRead(SYNCHRONOUS, server_maker_.MakeAckPacket(
9438 peer_packet_num++, packet_num, 1));
9439 socket_data1.AddWrite(
9440 ASYNC, client_maker_.MakeAckPacket(packet_num++, peer_packet_num - 2, 1));
9441 // The PING packet sent for retransmittable on wire.
9442 socket_data1.AddWrite(SYNCHRONOUS,
9443 client_maker_.MakePingPacket(packet_num++));
9444 socket_data1.AddReadPause();
9445 std::string header = ConstructDataHeader(6);
9446 socket_data1.AddRead(
9447 ASYNC, ConstructServerDataPacket(
9448 3, GetNthClientInitiatedBidirectionalStreamId(0), true,
9449 header + "hello!"));
9450 socket_data1.AddReadPauseForever();
9451 socket_data1.AddWrite(SYNCHRONOUS,
9452 client_maker_.MakeDataPacket(
9453 packet_num++, GetQpackDecoderStreamId(), false,
9454 StreamCancellationQpackDecoderInstruction(0)));
9455 socket_data1.AddWrite(
9456 SYNCHRONOUS,
9457 client_maker_.MakeRstPacket(packet_num++,
9458 GetNthClientInitiatedBidirectionalStreamId(0),
9459 quic::QUIC_STREAM_CANCELLED));
9460 socket_data1.AddSocketDataToFactory(socket_factory_.get());
9461
9462 // Create request and QuicHttpStream.
9463 RequestBuilder builder(this);
9464 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
9465 EXPECT_EQ(OK, callback_.WaitForResult());
9466 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
9467 EXPECT_TRUE(stream.get());
9468
9469 // Cause QUIC stream to be created.
9470 HttpRequestInfo request_info;
9471 request_info.method = "GET";
9472 request_info.url = GURL("https://www.example.org/");
9473 request_info.traffic_annotation =
9474 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9475 stream->RegisterRequest(&request_info);
9476 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
9477 CompletionOnceCallback()));
9478
9479 // Ensure that session is alive and active.
9480 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
9481 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
9482
9483 // Now notify network is disconnected, cause the migration to complete
9484 // immediately.
9485 scoped_mock_network_change_notifier_->mock_network_change_notifier()
9486 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
9487
9488 // Complete migration.
9489 task_runner->RunUntilIdle();
9490 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
9491 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
9492 EXPECT_EQ(1u, session->GetNumActiveStreams());
9493
9494 // Send GET request on stream.
9495 HttpResponseInfo response;
9496 HttpRequestHeaders request_headers;
9497 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
9498 callback_.callback()));
9499 socket_data1.Resume();
9500 // Spin up the message loop to read incoming data from server till the ACK.
9501 base::RunLoop().RunUntilIdle();
9502
9503 // Fire the ping alarm with retransmittable-on-wire timeout, send PING.
9504 context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(
9505 kDefaultRetransmittableOnWireTimeout.InMilliseconds()));
9506 task_runner->FastForwardBy(kDefaultRetransmittableOnWireTimeout);
9507
9508 socket_data1.Resume();
9509
9510 // Verify that response headers on the migrated socket were delivered to the
9511 // stream.
9512 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
9513 EXPECT_EQ(200, response.headers->response_code());
9514
9515 // Resume the old socket data, a read error will be delivered to the old
9516 // packet reader. Verify that the session is not affected.
9517 socket_data.Resume();
9518 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
9519 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
9520 EXPECT_EQ(1u, session->GetNumActiveStreams());
9521
9522 stream.reset();
9523 socket_data.ExpectAllReadDataConsumed();
9524 socket_data.ExpectAllWriteDataConsumed();
9525 socket_data1.ExpectAllReadDataConsumed();
9526 socket_data1.ExpectAllWriteDataConsumed();
9527 }
9528
9529 // This test verifies that when connection migration on path degrading is
9530 // enabled, and a custom retransmittable on wire timeout is specified, the
9531 // custom value is used.
TEST_P(QuicSessionPoolTest,CustomRetransmittableOnWireTimeoutForMigration)9532 TEST_P(QuicSessionPoolTest, CustomRetransmittableOnWireTimeoutForMigration) {
9533 constexpr base::TimeDelta custom_timeout_value = base::Milliseconds(200);
9534 quic_params_->retransmittable_on_wire_timeout = custom_timeout_value;
9535 InitializeConnectionMigrationV2Test(
9536 {kDefaultNetworkForTests, kNewNetworkForTests});
9537 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9538 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9539 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9540 client_maker_.set_save_packet_frames(true);
9541
9542 // Using a testing task runner.
9543 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
9544 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
9545 QuicSessionPoolPeer::SetAlarmFactory(
9546 factory_.get(), std::make_unique<QuicChromiumAlarmFactory>(
9547 task_runner.get(), context_.clock()));
9548
9549 quic::QuicConnectionId cid_on_new_path =
9550 quic::test::TestConnectionId(12345678);
9551 MockQuicData socket_data(version_);
9552 int packet_num = 1;
9553 int peer_packet_num = 1;
9554 socket_data.AddWrite(SYNCHRONOUS,
9555 ConstructInitialSettingsPacket(packet_num++));
9556 socket_data.AddRead(ASYNC, server_maker_.MakeNewConnectionIdPacket(
9557 peer_packet_num++, cid_on_new_path,
9558 /*sequence_number=*/1u,
9559 /*retire_prior_to=*/0u));
9560 socket_data.AddReadPause();
9561 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE);
9562 socket_data.AddSocketDataToFactory(socket_factory_.get());
9563
9564 // Set up second socket data provider that is used after
9565 // migration. The request is written to this new socket, and the
9566 // response to the request is read on this new socket.
9567 MockQuicData socket_data1(version_);
9568 client_maker_.set_connection_id(cid_on_new_path);
9569 socket_data1.AddWrite(SYNCHRONOUS,
9570 client_maker_.MakeAckAndRetransmissionPacket(
9571 packet_num++, /*first_received=*/1,
9572 /*largest_received=*/1, /*smallest_received=*/1,
9573 /*original_packet_numbers=*/{1}));
9574 // The PING packet sent post migration.
9575 socket_data1.AddWrite(SYNCHRONOUS,
9576 client_maker_.MakePingPacket(packet_num++));
9577 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakeRetireConnectionIdPacket(
9578 packet_num++,
9579 /*sequence_number=*/0u));
9580 socket_data1.AddWrite(
9581 SYNCHRONOUS,
9582 ConstructGetRequestPacket(
9583 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true));
9584 socket_data1.AddReadPause();
9585 // Read two packets so that client will send ACK immedaitely.
9586 socket_data1.AddRead(
9587 ASYNC, ConstructOkResponsePacket(
9588 peer_packet_num++,
9589 GetNthClientInitiatedBidirectionalStreamId(0), false));
9590 socket_data1.AddRead(ASYNC, server_maker_.MakeDataPacket(
9591 peer_packet_num++,
9592 GetNthClientInitiatedBidirectionalStreamId(0),
9593 /*fin=*/false, "Hello World"));
9594 // Read an ACK from server which acks all client data.
9595 socket_data1.AddRead(SYNCHRONOUS, server_maker_.MakeAckPacket(
9596 peer_packet_num++, packet_num, 1));
9597 socket_data1.AddWrite(
9598 ASYNC, client_maker_.MakeAckPacket(packet_num++, peer_packet_num - 2, 1));
9599 // The PING packet sent for retransmittable on wire.
9600 socket_data1.AddWrite(SYNCHRONOUS,
9601 client_maker_.MakePingPacket(packet_num++));
9602 socket_data1.AddReadPause();
9603 std::string header = ConstructDataHeader(6);
9604 socket_data1.AddRead(
9605 ASYNC, ConstructServerDataPacket(
9606 3, GetNthClientInitiatedBidirectionalStreamId(0), true,
9607 header + "hello!"));
9608 socket_data1.AddReadPauseForever();
9609 socket_data1.AddWrite(SYNCHRONOUS,
9610 client_maker_.MakeDataPacket(
9611 packet_num++, GetQpackDecoderStreamId(), false,
9612 StreamCancellationQpackDecoderInstruction(0)));
9613 socket_data1.AddWrite(
9614 SYNCHRONOUS,
9615 client_maker_.MakeRstPacket(packet_num++,
9616 GetNthClientInitiatedBidirectionalStreamId(0),
9617 quic::QUIC_STREAM_CANCELLED));
9618 socket_data1.AddSocketDataToFactory(socket_factory_.get());
9619
9620 // Create request and QuicHttpStream.
9621 RequestBuilder builder(this);
9622 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
9623 EXPECT_EQ(OK, callback_.WaitForResult());
9624 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
9625 EXPECT_TRUE(stream.get());
9626
9627 // Cause QUIC stream to be created.
9628 HttpRequestInfo request_info;
9629 request_info.method = "GET";
9630 request_info.url = GURL("https://www.example.org/");
9631 request_info.traffic_annotation =
9632 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9633 stream->RegisterRequest(&request_info);
9634 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
9635 CompletionOnceCallback()));
9636
9637 // Ensure that session is alive and active.
9638 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
9639 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
9640
9641 // Now notify network is disconnected, cause the migration to complete
9642 // immediately.
9643 scoped_mock_network_change_notifier_->mock_network_change_notifier()
9644 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
9645
9646 // Complete migration.
9647 task_runner->RunUntilIdle();
9648 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
9649 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
9650 EXPECT_EQ(1u, session->GetNumActiveStreams());
9651
9652 // Send GET request on stream.
9653 HttpResponseInfo response;
9654 HttpRequestHeaders request_headers;
9655 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
9656 callback_.callback()));
9657 socket_data1.Resume();
9658 // Spin up the message loop to read incoming data from server till the ACK.
9659 base::RunLoop().RunUntilIdle();
9660
9661 // Fire the ping alarm with retransmittable-on-wire timeout, send PING.
9662 context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(
9663 custom_timeout_value.InMilliseconds()));
9664 task_runner->FastForwardBy(custom_timeout_value);
9665
9666 socket_data1.Resume();
9667
9668 // Verify that response headers on the migrated socket were delivered to the
9669 // stream.
9670 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
9671 EXPECT_EQ(200, response.headers->response_code());
9672
9673 // Resume the old socket data, a read error will be delivered to the old
9674 // packet reader. Verify that the session is not affected.
9675 socket_data.Resume();
9676 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
9677 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
9678 EXPECT_EQ(1u, session->GetNumActiveStreams());
9679
9680 stream.reset();
9681 socket_data.ExpectAllReadDataConsumed();
9682 socket_data.ExpectAllWriteDataConsumed();
9683 socket_data1.ExpectAllReadDataConsumed();
9684 socket_data1.ExpectAllWriteDataConsumed();
9685 }
9686
9687 // This test verifies that when no migration is enabled, but a custom value for
9688 // retransmittable-on-wire timeout is specified, the ping alarm is set up to
9689 // send retransmittable pings with the custom value.
TEST_P(QuicSessionPoolTest,CustomRetransmittableOnWireTimeout)9690 TEST_P(QuicSessionPoolTest, CustomRetransmittableOnWireTimeout) {
9691 constexpr base::TimeDelta custom_timeout_value = base::Milliseconds(200);
9692 quic_params_->retransmittable_on_wire_timeout = custom_timeout_value;
9693 Initialize();
9694 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9695 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9696 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9697
9698 // Using a testing task runner.
9699 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
9700 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
9701 QuicSessionPoolPeer::SetAlarmFactory(
9702 factory_.get(), std::make_unique<QuicChromiumAlarmFactory>(
9703 task_runner.get(), context_.clock()));
9704
9705 MockQuicData socket_data1(version_);
9706 int packet_num = 1;
9707 socket_data1.AddWrite(SYNCHRONOUS,
9708 ConstructInitialSettingsPacket(packet_num++));
9709 socket_data1.AddWrite(
9710 SYNCHRONOUS,
9711 ConstructGetRequestPacket(
9712 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true));
9713 socket_data1.AddReadPause();
9714 // Read two packets so that client will send ACK immedaitely.
9715 socket_data1.AddRead(
9716 ASYNC, ConstructOkResponsePacket(
9717 1, GetNthClientInitiatedBidirectionalStreamId(0), false));
9718 socket_data1.AddRead(
9719 ASYNC, server_maker_.MakeDataPacket(
9720 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
9721 "Hello World"));
9722 // Read an ACK from server which acks all client data.
9723 socket_data1.AddRead(SYNCHRONOUS, server_maker_.MakeAckPacket(3, 2, 1));
9724 socket_data1.AddWrite(ASYNC, client_maker_.MakeAckPacket(packet_num++, 2, 1));
9725 // The PING packet sent for retransmittable on wire.
9726 socket_data1.AddWrite(SYNCHRONOUS,
9727 client_maker_.MakePingPacket(packet_num++));
9728 socket_data1.AddReadPause();
9729 std::string header = ConstructDataHeader(6);
9730 socket_data1.AddRead(
9731 ASYNC, ConstructServerDataPacket(
9732 3, GetNthClientInitiatedBidirectionalStreamId(0), true,
9733 header + "hello!"));
9734 socket_data1.AddReadPauseForever();
9735 socket_data1.AddWrite(SYNCHRONOUS,
9736 client_maker_.MakeDataPacket(
9737 packet_num++, GetQpackDecoderStreamId(), false,
9738 StreamCancellationQpackDecoderInstruction(0)));
9739 socket_data1.AddWrite(
9740 SYNCHRONOUS,
9741 client_maker_.MakeRstPacket(packet_num++,
9742 GetNthClientInitiatedBidirectionalStreamId(0),
9743 quic::QUIC_STREAM_CANCELLED));
9744 socket_data1.AddSocketDataToFactory(socket_factory_.get());
9745
9746 // Create request and QuicHttpStream.
9747 RequestBuilder builder(this);
9748 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
9749 EXPECT_EQ(OK, callback_.WaitForResult());
9750 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
9751 EXPECT_TRUE(stream.get());
9752
9753 // Cause QUIC stream to be created.
9754 HttpRequestInfo request_info;
9755 request_info.method = "GET";
9756 request_info.url = GURL("https://www.example.org/");
9757 request_info.traffic_annotation =
9758 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9759 stream->RegisterRequest(&request_info);
9760 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
9761 CompletionOnceCallback()));
9762
9763 // Ensure that session is alive and active.
9764 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
9765 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
9766
9767 // Complete migration.
9768 task_runner->RunUntilIdle();
9769 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
9770 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
9771 EXPECT_EQ(1u, session->GetNumActiveStreams());
9772
9773 // Send GET request on stream.
9774 HttpResponseInfo response;
9775 HttpRequestHeaders request_headers;
9776 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
9777 callback_.callback()));
9778 socket_data1.Resume();
9779 // Spin up the message loop to read incoming data from server till the ACK.
9780 base::RunLoop().RunUntilIdle();
9781
9782 // Fire the ping alarm with retransmittable-on-wire timeout, send PING.
9783 context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(
9784 custom_timeout_value.InMilliseconds()));
9785 task_runner->FastForwardBy(custom_timeout_value);
9786
9787 socket_data1.Resume();
9788
9789 // Verify that response headers on the migrated socket were delivered to the
9790 // stream.
9791 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
9792 EXPECT_EQ(200, response.headers->response_code());
9793
9794 // Resume the old socket data, a read error will be delivered to the old
9795 // packet reader. Verify that the session is not affected.
9796 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
9797 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
9798 EXPECT_EQ(1u, session->GetNumActiveStreams());
9799
9800 stream.reset();
9801 socket_data1.ExpectAllReadDataConsumed();
9802 socket_data1.ExpectAllWriteDataConsumed();
9803 }
9804
9805 // This test verifies that when no migration is enabled, and no custom value
9806 // for retransmittable-on-wire timeout is specified, the ping alarm will not
9807 // send any retransmittable pings.
TEST_P(QuicSessionPoolTest,NoRetransmittableOnWireTimeout)9808 TEST_P(QuicSessionPoolTest, NoRetransmittableOnWireTimeout) {
9809 // Use non-default initial srtt so that if QPACK emits additional setting
9810 // packet, it will not have the same retransmission timeout as the
9811 // default value of retransmittable-on-wire-ping timeout.
9812 ServerNetworkStats stats;
9813 stats.srtt = base::Milliseconds(200);
9814 http_server_properties_->SetServerNetworkStats(
9815 url::SchemeHostPort(GURL(kDefaultUrl)), NetworkAnonymizationKey(), stats);
9816 quic_params_->estimate_initial_rtt = true;
9817
9818 Initialize();
9819 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9820 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9821 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9822
9823 // Using a testing task runner.
9824 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
9825 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
9826 QuicSessionPoolPeer::SetAlarmFactory(
9827 factory_.get(), std::make_unique<QuicChromiumAlarmFactory>(
9828 task_runner.get(), context_.clock()));
9829
9830 MockQuicData socket_data1(version_);
9831 int packet_num = 1;
9832 socket_data1.AddWrite(SYNCHRONOUS,
9833 ConstructInitialSettingsPacket(packet_num++));
9834 socket_data1.AddWrite(
9835 SYNCHRONOUS,
9836 ConstructGetRequestPacket(
9837 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true));
9838 socket_data1.AddReadPause();
9839 // Read two packets so that client will send ACK immedaitely.
9840 socket_data1.AddRead(
9841 ASYNC, ConstructOkResponsePacket(
9842 1, GetNthClientInitiatedBidirectionalStreamId(0), false));
9843 socket_data1.AddRead(
9844 ASYNC, server_maker_.MakeDataPacket(
9845 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
9846 "Hello World"));
9847 // Read an ACK from server which acks all client data.
9848 socket_data1.AddRead(SYNCHRONOUS, server_maker_.MakeAckPacket(3, 2, 1));
9849 socket_data1.AddWrite(ASYNC, client_maker_.MakeAckPacket(packet_num++, 2, 1));
9850 std::string header = ConstructDataHeader(6);
9851 socket_data1.AddRead(
9852 ASYNC, ConstructServerDataPacket(
9853 3, GetNthClientInitiatedBidirectionalStreamId(0), true,
9854 header + "hello!"));
9855 socket_data1.AddReadPauseForever();
9856 socket_data1.AddWrite(SYNCHRONOUS,
9857 client_maker_.MakeDataPacket(
9858 packet_num++, GetQpackDecoderStreamId(), false,
9859 StreamCancellationQpackDecoderInstruction(0)));
9860 socket_data1.AddWrite(
9861 SYNCHRONOUS,
9862 client_maker_.MakeRstPacket(packet_num++,
9863 GetNthClientInitiatedBidirectionalStreamId(0),
9864 quic::QUIC_STREAM_CANCELLED));
9865 socket_data1.AddSocketDataToFactory(socket_factory_.get());
9866
9867 // Create request and QuicHttpStream.
9868 RequestBuilder builder(this);
9869 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
9870 EXPECT_EQ(OK, callback_.WaitForResult());
9871 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
9872 EXPECT_TRUE(stream.get());
9873
9874 // Cause QUIC stream to be created.
9875 HttpRequestInfo request_info;
9876 request_info.method = "GET";
9877 request_info.url = GURL("https://www.example.org/");
9878 request_info.traffic_annotation =
9879 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9880 stream->RegisterRequest(&request_info);
9881 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
9882 CompletionOnceCallback()));
9883
9884 // Ensure that session is alive and active.
9885 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
9886 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
9887
9888 // Complete migration.
9889 task_runner->RunUntilIdle();
9890 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
9891 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
9892 EXPECT_EQ(1u, session->GetNumActiveStreams());
9893
9894 // Send GET request on stream.
9895 HttpResponseInfo response;
9896 HttpRequestHeaders request_headers;
9897 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
9898 callback_.callback()));
9899 socket_data1.Resume();
9900 // Spin up the message loop to read incoming data from server till the ACK.
9901 base::RunLoop().RunUntilIdle();
9902
9903 // Verify the ping alarm is set, but not with the default timeout.
9904 const quic::QuicAlarm* const ping_alarm =
9905 quic::test::QuicConnectionPeer::GetPingAlarm(session->connection());
9906 ASSERT_TRUE(ping_alarm);
9907 ASSERT_TRUE(ping_alarm->IsSet());
9908 quic::QuicTime::Delta delay =
9909 ping_alarm->deadline() - context_.clock()->ApproximateNow();
9910 EXPECT_NE(kDefaultRetransmittableOnWireTimeout.InMilliseconds(),
9911 delay.ToMilliseconds());
9912
9913 // Verify that response headers on the migrated socket were delivered to the
9914 // stream.
9915 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
9916 EXPECT_EQ(200, response.headers->response_code());
9917
9918 // Resume the old socket data, a read error will be delivered to the old
9919 // packet reader. Verify that the session is not affected.
9920 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
9921 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
9922 EXPECT_EQ(1u, session->GetNumActiveStreams());
9923
9924 stream.reset();
9925 socket_data1.ExpectAllReadDataConsumed();
9926 socket_data1.ExpectAllWriteDataConsumed();
9927 }
9928
9929 // This test verifies that when only migration on network change is enabled, and
9930 // a custom value for retransmittable-on-wire is specified, the ping alarm will
9931 // send retransmittable pings to the peer with custom value.
TEST_P(QuicSessionPoolTest,CustomRetransmittableOnWireTimeoutWithMigrationOnNetworkChangeOnly)9932 TEST_P(QuicSessionPoolTest,
9933 CustomRetransmittableOnWireTimeoutWithMigrationOnNetworkChangeOnly) {
9934 constexpr base::TimeDelta custom_timeout_value = base::Milliseconds(200);
9935 quic_params_->retransmittable_on_wire_timeout = custom_timeout_value;
9936 quic_params_->migrate_sessions_on_network_change_v2 = true;
9937 Initialize();
9938 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9939 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9940 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9941
9942 // Using a testing task runner.
9943 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
9944 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
9945 QuicSessionPoolPeer::SetAlarmFactory(
9946 factory_.get(), std::make_unique<QuicChromiumAlarmFactory>(
9947 task_runner.get(), context_.clock()));
9948
9949 MockQuicData socket_data1(version_);
9950 int packet_num = 1;
9951 socket_data1.AddWrite(SYNCHRONOUS,
9952 ConstructInitialSettingsPacket(packet_num++));
9953 socket_data1.AddWrite(
9954 SYNCHRONOUS,
9955 ConstructGetRequestPacket(
9956 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true));
9957 socket_data1.AddReadPause();
9958 // Read two packets so that client will send ACK immedaitely.
9959 socket_data1.AddRead(
9960 ASYNC, ConstructOkResponsePacket(
9961 1, GetNthClientInitiatedBidirectionalStreamId(0), false));
9962 socket_data1.AddRead(
9963 ASYNC, server_maker_.MakeDataPacket(
9964 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
9965 "Hello World"));
9966 // Read an ACK from server which acks all client data.
9967 socket_data1.AddRead(SYNCHRONOUS, server_maker_.MakeAckPacket(3, 2, 1));
9968 socket_data1.AddWrite(ASYNC, client_maker_.MakeAckPacket(packet_num++, 2, 1));
9969 // The PING packet sent for retransmittable on wire.
9970 socket_data1.AddWrite(SYNCHRONOUS,
9971 client_maker_.MakePingPacket(packet_num++));
9972 socket_data1.AddReadPause();
9973 std::string header = ConstructDataHeader(6);
9974 socket_data1.AddRead(
9975 ASYNC, ConstructServerDataPacket(
9976 3, GetNthClientInitiatedBidirectionalStreamId(0), true,
9977 header + "hello!"));
9978 socket_data1.AddReadPauseForever();
9979 socket_data1.AddWrite(SYNCHRONOUS,
9980 client_maker_.MakeDataPacket(
9981 packet_num++, GetQpackDecoderStreamId(), false,
9982 StreamCancellationQpackDecoderInstruction(0)));
9983 socket_data1.AddWrite(
9984 SYNCHRONOUS,
9985 client_maker_.MakeRstPacket(packet_num++,
9986 GetNthClientInitiatedBidirectionalStreamId(0),
9987 quic::QUIC_STREAM_CANCELLED));
9988 socket_data1.AddSocketDataToFactory(socket_factory_.get());
9989
9990 // Create request and QuicHttpStream.
9991 RequestBuilder builder(this);
9992 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
9993 EXPECT_EQ(OK, callback_.WaitForResult());
9994 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
9995 EXPECT_TRUE(stream.get());
9996
9997 // Cause QUIC stream to be created.
9998 HttpRequestInfo request_info;
9999 request_info.method = "GET";
10000 request_info.url = GURL("https://www.example.org/");
10001 request_info.traffic_annotation =
10002 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
10003 stream->RegisterRequest(&request_info);
10004 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
10005 CompletionOnceCallback()));
10006
10007 // Ensure that session is alive and active.
10008 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
10009 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
10010
10011 // Complete migration.
10012 task_runner->RunUntilIdle();
10013 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
10014 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
10015 EXPECT_EQ(1u, session->GetNumActiveStreams());
10016
10017 // Send GET request on stream.
10018 HttpResponseInfo response;
10019 HttpRequestHeaders request_headers;
10020 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
10021 callback_.callback()));
10022 socket_data1.Resume();
10023 // Spin up the message loop to read incoming data from server till the ACK.
10024 base::RunLoop().RunUntilIdle();
10025
10026 // Fire the ping alarm with retransmittable-on-wire timeout, send PING.
10027 context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(
10028 custom_timeout_value.InMilliseconds()));
10029 task_runner->FastForwardBy(custom_timeout_value);
10030
10031 socket_data1.Resume();
10032
10033 // Verify that response headers on the migrated socket were delivered to the
10034 // stream.
10035 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
10036 EXPECT_EQ(200, response.headers->response_code());
10037
10038 // Resume the old socket data, a read error will be delivered to the old
10039 // packet reader. Verify that the session is not affected.
10040 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
10041 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
10042 EXPECT_EQ(1u, session->GetNumActiveStreams());
10043
10044 stream.reset();
10045 socket_data1.ExpectAllReadDataConsumed();
10046 socket_data1.ExpectAllWriteDataConsumed();
10047 }
10048
10049 // This test verifies that when only migration on network change is enabled, and
10050 // no custom value for retransmittable-on-wire is specified, the ping alarm will
10051 // NOT send retransmittable pings to the peer with custom value.
TEST_P(QuicSessionPoolTest,NoRetransmittableOnWireTimeoutWithMigrationOnNetworkChangeOnly)10052 TEST_P(QuicSessionPoolTest,
10053 NoRetransmittableOnWireTimeoutWithMigrationOnNetworkChangeOnly) {
10054 // Use non-default initial srtt so that if QPACK emits additional setting
10055 // packet, it will not have the same retransmission timeout as the
10056 // default value of retransmittable-on-wire-ping timeout.
10057 ServerNetworkStats stats;
10058 stats.srtt = base::Milliseconds(200);
10059 http_server_properties_->SetServerNetworkStats(
10060 url::SchemeHostPort(GURL(kDefaultUrl)), NetworkAnonymizationKey(), stats);
10061 quic_params_->estimate_initial_rtt = true;
10062 quic_params_->migrate_sessions_on_network_change_v2 = true;
10063 Initialize();
10064
10065 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10066 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10067 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10068
10069 // Using a testing task runner.
10070 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
10071 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
10072 QuicSessionPoolPeer::SetAlarmFactory(
10073 factory_.get(), std::make_unique<QuicChromiumAlarmFactory>(
10074 task_runner.get(), context_.clock()));
10075
10076 MockQuicData socket_data1(version_);
10077 int packet_num = 1;
10078 socket_data1.AddWrite(SYNCHRONOUS,
10079 ConstructInitialSettingsPacket(packet_num++));
10080 socket_data1.AddWrite(
10081 SYNCHRONOUS,
10082 ConstructGetRequestPacket(
10083 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true));
10084 socket_data1.AddReadPause();
10085 // Read two packets so that client will send ACK immedaitely.
10086 socket_data1.AddRead(
10087 ASYNC, ConstructOkResponsePacket(
10088 1, GetNthClientInitiatedBidirectionalStreamId(0), false));
10089 socket_data1.AddRead(
10090 ASYNC, server_maker_.MakeDataPacket(
10091 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
10092 "Hello World"));
10093 // Read an ACK from server which acks all client data.
10094 socket_data1.AddRead(SYNCHRONOUS, server_maker_.MakeAckPacket(3, 2, 1));
10095 socket_data1.AddWrite(ASYNC, client_maker_.MakeAckPacket(packet_num++, 2, 1));
10096 std::string header = ConstructDataHeader(6);
10097 socket_data1.AddRead(
10098 ASYNC, ConstructServerDataPacket(
10099 3, GetNthClientInitiatedBidirectionalStreamId(0), true,
10100 header + "hello!"));
10101 socket_data1.AddReadPauseForever();
10102 socket_data1.AddWrite(SYNCHRONOUS,
10103 client_maker_.MakeDataPacket(
10104 packet_num++, GetQpackDecoderStreamId(), false,
10105 StreamCancellationQpackDecoderInstruction(0)));
10106 socket_data1.AddWrite(
10107 SYNCHRONOUS,
10108 client_maker_.MakeRstPacket(packet_num++,
10109 GetNthClientInitiatedBidirectionalStreamId(0),
10110 quic::QUIC_STREAM_CANCELLED));
10111 socket_data1.AddSocketDataToFactory(socket_factory_.get());
10112
10113 // Create request and QuicHttpStream.
10114 RequestBuilder builder(this);
10115 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
10116 EXPECT_EQ(OK, callback_.WaitForResult());
10117 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
10118 EXPECT_TRUE(stream.get());
10119
10120 // Cause QUIC stream to be created.
10121 HttpRequestInfo request_info;
10122 request_info.method = "GET";
10123 request_info.url = GURL("https://www.example.org/");
10124 request_info.traffic_annotation =
10125 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
10126 stream->RegisterRequest(&request_info);
10127 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
10128 CompletionOnceCallback()));
10129
10130 // Ensure that session is alive and active.
10131 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
10132 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
10133
10134 // Complete migration.
10135 task_runner->RunUntilIdle();
10136 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
10137 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
10138 EXPECT_EQ(1u, session->GetNumActiveStreams());
10139
10140 // Send GET request on stream.
10141 HttpResponseInfo response;
10142 HttpRequestHeaders request_headers;
10143 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
10144 callback_.callback()));
10145 socket_data1.Resume();
10146 // Spin up the message loop to read incoming data from server till the ACK.
10147 base::RunLoop().RunUntilIdle();
10148
10149 // Verify the ping alarm is set, but not with the default timeout.
10150 const quic::QuicAlarm* const ping_alarm =
10151 quic::test::QuicConnectionPeer::GetPingAlarm(session->connection());
10152 ASSERT_TRUE(ping_alarm);
10153 ASSERT_TRUE(ping_alarm->IsSet());
10154 quic::QuicTime::Delta delay =
10155 ping_alarm->deadline() - context_.clock()->ApproximateNow();
10156 EXPECT_NE(kDefaultRetransmittableOnWireTimeout.InMilliseconds(),
10157 delay.ToMilliseconds());
10158
10159 // Verify that response headers on the migrated socket were delivered to the
10160 // stream.
10161 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
10162 EXPECT_EQ(200, response.headers->response_code());
10163
10164 // Resume the old socket data, a read error will be delivered to the old
10165 // packet reader. Verify that the session is not affected.
10166 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
10167 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
10168 EXPECT_EQ(1u, session->GetNumActiveStreams());
10169
10170 stream.reset();
10171 socket_data1.ExpectAllReadDataConsumed();
10172 socket_data1.ExpectAllWriteDataConsumed();
10173 }
10174
10175 // This test verifies that after migration on write error is posted, packet
10176 // read error on the old reader will be ignored and will not close the
10177 // connection.
TEST_P(QuicSessionPoolTest,IgnoreReadErrorOnOldReaderDuringPendingMigrationOnWriteError)10178 TEST_P(QuicSessionPoolTest,
10179 IgnoreReadErrorOnOldReaderDuringPendingMigrationOnWriteError) {
10180 InitializeConnectionMigrationV2Test(
10181 {kDefaultNetworkForTests, kNewNetworkForTests});
10182 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10183 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10184 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10185 client_maker_.set_save_packet_frames(true);
10186
10187 // Using a testing task runner.
10188 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
10189 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
10190
10191 MockQuicData socket_data(version_);
10192 int packet_num = 1;
10193 socket_data.AddWrite(SYNCHRONOUS,
10194 ConstructInitialSettingsPacket(packet_num++));
10195 socket_data.AddWrite(ASYNC, ERR_FAILED); // Write error.
10196 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE); // Read error.
10197 socket_data.AddSocketDataToFactory(socket_factory_.get());
10198
10199 // Create request and QuicHttpStream.
10200 RequestBuilder builder(this);
10201 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
10202 EXPECT_EQ(OK, callback_.WaitForResult());
10203 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
10204 EXPECT_TRUE(stream.get());
10205
10206 // Cause QUIC stream to be created.
10207 HttpRequestInfo request_info;
10208 request_info.method = "GET";
10209 request_info.url = GURL("https://www.example.org/");
10210 request_info.traffic_annotation =
10211 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
10212 stream->RegisterRequest(&request_info);
10213 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
10214 CompletionOnceCallback()));
10215
10216 // Ensure that session is alive and active.
10217 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
10218 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
10219 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
10220 quic::QuicConnectionId cid_on_new_path =
10221 quic::test::TestConnectionId(12345678);
10222 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
10223
10224 // Set up second socket data provider that is used after
10225 // migration. The request is written to this new socket, and the
10226 // response to the request is read on this new socket.
10227 MockQuicData socket_data1(version_);
10228 client_maker_.set_connection_id(cid_on_new_path);
10229 ConstructGetRequestPacket(packet_num++,
10230 GetNthClientInitiatedBidirectionalStreamId(0),
10231 /*fin=*/true);
10232 socket_data1.AddWrite(ASYNC,
10233 client_maker_.MakeCombinedRetransmissionPacket(
10234 /*original_packet_numbers=*/{1, 2}, packet_num++));
10235 socket_data1.AddRead(
10236 ASYNC, ConstructOkResponsePacket(
10237 1, GetNthClientInitiatedBidirectionalStreamId(0), false));
10238
10239 socket_data1.AddReadPause();
10240 socket_data1.AddRead(ASYNC, ERR_FAILED); // Read error to close connection.
10241 socket_data1.AddSocketDataToFactory(socket_factory_.get());
10242
10243 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
10244 // Send GET request on stream.
10245 HttpResponseInfo response;
10246 HttpRequestHeaders request_headers;
10247 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
10248 callback_.callback()));
10249 // Run the message loop to complete asynchronous write and read with errors.
10250 base::RunLoop().RunUntilIdle();
10251 // There will be one pending task to complete migration on write error.
10252 // Verify session is not closed with read error.
10253 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
10254 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
10255 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
10256 EXPECT_EQ(1u, session->GetNumActiveStreams());
10257
10258 // Complete migration.
10259 task_runner->RunUntilIdle();
10260 // There will be one more task posted attempting to migrate back to the
10261 // default network.
10262 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
10263 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
10264 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
10265 EXPECT_EQ(1u, session->GetNumActiveStreams());
10266
10267 // Verify that response headers on the migrated socket were delivered to the
10268 // stream.
10269 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
10270 EXPECT_EQ(200, response.headers->response_code());
10271
10272 // Resume to consume the read error on new socket, which will close
10273 // the connection.
10274 socket_data1.Resume();
10275
10276 socket_data.ExpectAllReadDataConsumed();
10277 socket_data.ExpectAllWriteDataConsumed();
10278 socket_data1.ExpectAllReadDataConsumed();
10279 socket_data1.ExpectAllWriteDataConsumed();
10280 }
10281
10282 // Migrate on asynchronous write error, old network disconnects after alternate
10283 // network connects.
TEST_P(QuicSessionPoolTest,MigrateSessionOnWriteErrorWithDisconnectAfterConnectAsync)10284 TEST_P(QuicSessionPoolTest,
10285 MigrateSessionOnWriteErrorWithDisconnectAfterConnectAsync) {
10286 TestMigrationOnWriteErrorWithMultipleNotifications(
10287 ASYNC, /*disconnect_before_connect*/ false);
10288 }
10289
10290 // Migrate on synchronous write error, old network disconnects after alternate
10291 // network connects.
TEST_P(QuicSessionPoolTest,MigrateSessionOnWriteErrorWithDisconnectAfterConnectSync)10292 TEST_P(QuicSessionPoolTest,
10293 MigrateSessionOnWriteErrorWithDisconnectAfterConnectSync) {
10294 TestMigrationOnWriteErrorWithMultipleNotifications(
10295 SYNCHRONOUS, /*disconnect_before_connect*/ false);
10296 }
10297
10298 // Migrate on asynchronous write error, old network disconnects before alternate
10299 // network connects.
TEST_P(QuicSessionPoolTest,MigrateSessionOnWriteErrorWithDisconnectBeforeConnectAsync)10300 TEST_P(QuicSessionPoolTest,
10301 MigrateSessionOnWriteErrorWithDisconnectBeforeConnectAsync) {
10302 TestMigrationOnWriteErrorWithMultipleNotifications(
10303 ASYNC, /*disconnect_before_connect*/ true);
10304 }
10305
10306 // Migrate on synchronous write error, old network disconnects before alternate
10307 // network connects.
TEST_P(QuicSessionPoolTest,MigrateSessionOnWriteErrorWithDisconnectBeforeConnectSync)10308 TEST_P(QuicSessionPoolTest,
10309 MigrateSessionOnWriteErrorWithDisconnectBeforeConnectSync) {
10310 TestMigrationOnWriteErrorWithMultipleNotifications(
10311 SYNCHRONOUS, /*disconnect_before_connect*/ true);
10312 }
10313
10314 // Sets up test which verifies that session successfully migrate to alternate
10315 // network with signals delivered in the following order:
10316 // *NOTE* Signal (A) and (B) can reverse order based on
10317 // |disconnect_before_connect|.
10318 // - (No alternate network is connected) session connects to
10319 // kDefaultNetworkForTests.
10320 // - An async/sync write error is encountered based on |write_error_mode|:
10321 // session posted task to migrate session on write error.
10322 // - Posted task is executed, miration moves to pending state due to lack of
10323 // alternate network.
10324 // - (A) An alternate network is connected, pending migration completes.
10325 // - (B) Old default network disconnects, no migration will be attempted as
10326 // session has already migrate to the alternate network.
10327 // - The alternate network is made default.
TestMigrationOnWriteErrorWithMultipleNotifications(IoMode write_error_mode,bool disconnect_before_connect)10328 void QuicSessionPoolTest::TestMigrationOnWriteErrorWithMultipleNotifications(
10329 IoMode write_error_mode,
10330 bool disconnect_before_connect) {
10331 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
10332 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10333 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10334 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10335 client_maker_.set_save_packet_frames(true);
10336
10337 MockQuicData socket_data(version_);
10338 socket_data.AddReadPauseForever();
10339 int packet_num = 1;
10340 socket_data.AddWrite(SYNCHRONOUS,
10341 ConstructInitialSettingsPacket(packet_num++));
10342 socket_data.AddWrite(write_error_mode, ERR_FAILED); // Write error.
10343 socket_data.AddSocketDataToFactory(socket_factory_.get());
10344
10345 // Create request and QuicHttpStream.
10346 RequestBuilder builder(this);
10347 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
10348 EXPECT_EQ(OK, callback_.WaitForResult());
10349 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
10350 EXPECT_TRUE(stream.get());
10351
10352 // Cause QUIC stream to be created.
10353 HttpRequestInfo request_info;
10354 request_info.method = "GET";
10355 request_info.url = GURL("https://www.example.org/");
10356 request_info.traffic_annotation =
10357 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
10358 stream->RegisterRequest(&request_info);
10359 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
10360 CompletionOnceCallback()));
10361
10362 // Ensure that session is alive and active.
10363 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
10364 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
10365 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
10366 quic::QuicConnectionId cid_on_new_path =
10367 quic::test::TestConnectionId(12345678);
10368 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
10369
10370 // Send GET request on stream. This should cause a write error, which triggers
10371 // a connection migration attempt.
10372 HttpResponseInfo response;
10373 HttpRequestHeaders request_headers;
10374 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
10375 callback_.callback()));
10376 // Run the message loop so that posted task to migrate to socket will be
10377 // executed. A new task will be posted to wait for a new network.
10378 base::RunLoop().RunUntilIdle();
10379
10380 // In this particular code path, the network will not yet be marked
10381 // as going away and the session will still be alive.
10382 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
10383 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
10384 EXPECT_EQ(1u, session->GetNumActiveStreams());
10385 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
10386
10387 // Set up second socket data provider that is used after
10388 // migration. The request is rewritten to this new socket, and the
10389 // response to the request is read on this new socket.
10390 MockQuicData socket_data1(version_);
10391 client_maker_.set_connection_id(cid_on_new_path);
10392 // Increment packet number to account for packet write error on the old
10393 // path. Also save the packet in client_maker_ for constructing the
10394 // retransmission packet.
10395 ConstructGetRequestPacket(packet_num++,
10396 GetNthClientInitiatedBidirectionalStreamId(0),
10397 /*fin=*/true);
10398 socket_data1.AddRead(
10399 ASYNC, ConstructOkResponsePacket(
10400 1, GetNthClientInitiatedBidirectionalStreamId(0), false));
10401 socket_data1.AddReadPauseForever();
10402 socket_data1.AddWrite(ASYNC,
10403 client_maker_.MakeCombinedRetransmissionPacket(
10404 /*original_packet_numbers=*/{1, 2}, packet_num++));
10405 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakeRetireConnectionIdPacket(
10406 packet_num++, /*sequence_number=*/0u));
10407 socket_data1.AddWrite(
10408 SYNCHRONOUS,
10409 client_maker_.MakeDataPacket(
10410 packet_num++, GetQpackDecoderStreamId(),
10411 /*fin=*/false, StreamCancellationQpackDecoderInstruction(0)));
10412 socket_data1.AddWrite(
10413 SYNCHRONOUS,
10414 client_maker_.MakeRstPacket(packet_num++,
10415 GetNthClientInitiatedBidirectionalStreamId(0),
10416 quic::QUIC_STREAM_CANCELLED));
10417 socket_data1.AddSocketDataToFactory(socket_factory_.get());
10418
10419 scoped_mock_network_change_notifier_->mock_network_change_notifier()
10420 ->SetConnectedNetworksList(
10421 {kDefaultNetworkForTests, kNewNetworkForTests});
10422 if (disconnect_before_connect) {
10423 // Now deliver a DISCONNECT notification.
10424 scoped_mock_network_change_notifier_->mock_network_change_notifier()
10425 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
10426
10427 // Now deliver a CONNECTED notification and completes migration.
10428 scoped_mock_network_change_notifier_->mock_network_change_notifier()
10429 ->NotifyNetworkConnected(kNewNetworkForTests);
10430 } else {
10431 // Now deliver a CONNECTED notification and completes migration.
10432 scoped_mock_network_change_notifier_->mock_network_change_notifier()
10433 ->NotifyNetworkConnected(kNewNetworkForTests);
10434
10435 // Now deliver a DISCONNECT notification.
10436 scoped_mock_network_change_notifier_->mock_network_change_notifier()
10437 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
10438 }
10439 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
10440 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
10441 EXPECT_EQ(1u, session->GetNumActiveStreams());
10442
10443 // This is the callback for the response headers that returned
10444 // pending previously, because no result was available. Check that
10445 // the result is now available due to the successful migration.
10446 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10447 EXPECT_EQ(200, response.headers->response_code());
10448
10449 // Deliver a MADEDEFAULT notification.
10450 scoped_mock_network_change_notifier_->mock_network_change_notifier()
10451 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
10452
10453 RequestBuilder builder2(this);
10454 EXPECT_EQ(OK, builder2.CallRequest());
10455 std::unique_ptr<HttpStream> stream2 = CreateStream(&builder2.request);
10456 EXPECT_TRUE(stream2.get());
10457
10458 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
10459 EXPECT_EQ(session, GetActiveSession(kDefaultDestination));
10460
10461 stream.reset();
10462 stream2.reset();
10463
10464 socket_data.ExpectAllReadDataConsumed();
10465 socket_data.ExpectAllWriteDataConsumed();
10466 socket_data1.ExpectAllReadDataConsumed();
10467 socket_data1.ExpectAllWriteDataConsumed();
10468 }
10469
10470 // This test verifies after session migrates off the default network, it keeps
10471 // retrying migrate back to the default network until successfully gets on the
10472 // default network or the idle migration period threshold is exceeded.
10473 // The default threshold is 30s.
TEST_P(QuicSessionPoolTest,DefaultIdleMigrationPeriod)10474 TEST_P(QuicSessionPoolTest, DefaultIdleMigrationPeriod) {
10475 quic_params_->migrate_idle_sessions = true;
10476 InitializeConnectionMigrationV2Test(
10477 {kDefaultNetworkForTests, kNewNetworkForTests});
10478 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10479 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10480 client_maker_.set_save_packet_frames(true);
10481
10482 // Using a testing task runner and a test tick tock.
10483 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
10484 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
10485 QuicSessionPoolPeer::SetTickClock(factory_.get(),
10486 task_runner->GetMockTickClock());
10487
10488 quic::QuicConnectionId cid1 = quic::test::TestConnectionId(1234567);
10489 quic::QuicConnectionId cid2 = quic::test::TestConnectionId(2345671);
10490 quic::QuicConnectionId cid3 = quic::test::TestConnectionId(3456712);
10491 quic::QuicConnectionId cid4 = quic::test::TestConnectionId(4567123);
10492 quic::QuicConnectionId cid5 = quic::test::TestConnectionId(5671234);
10493 quic::QuicConnectionId cid6 = quic::test::TestConnectionId(6712345);
10494 quic::QuicConnectionId cid7 = quic::test::TestConnectionId(7123456);
10495
10496 int peer_packet_num = 1;
10497 MockQuicData default_socket_data(version_);
10498 default_socket_data.AddRead(
10499 SYNCHRONOUS,
10500 server_maker_.MakeNewConnectionIdPacket(peer_packet_num++, cid1,
10501 /*sequence_number=*/1u,
10502 /*retire_prior_to=*/0u));
10503 default_socket_data.AddReadPauseForever();
10504 int packet_num = 1;
10505 default_socket_data.AddWrite(SYNCHRONOUS,
10506 ConstructInitialSettingsPacket(packet_num++));
10507 default_socket_data.AddSocketDataToFactory(socket_factory_.get());
10508
10509 // Set up second socket data provider that is used after migration.
10510 MockQuicData alternate_socket_data(version_);
10511 client_maker_.set_connection_id(cid1);
10512 alternate_socket_data.AddWrite(SYNCHRONOUS,
10513 client_maker_.MakeAckAndRetransmissionPacket(
10514 packet_num++,
10515 /*first_received=*/1,
10516 /*largest_received=*/peer_packet_num - 1,
10517 /*smallest_received=*/1,
10518 /*original_packet_numbers=*/{1}));
10519 alternate_socket_data.AddWrite(SYNCHRONOUS,
10520 client_maker_.MakePingPacket(packet_num++));
10521 alternate_socket_data.AddWrite(ASYNC,
10522 client_maker_.MakeRetireConnectionIdPacket(
10523 packet_num++, /*sequence_number=*/0u));
10524 alternate_socket_data.AddRead(
10525 ASYNC, server_maker_.MakeNewConnectionIdPacket(peer_packet_num++, cid2,
10526 /*sequence_number=*/2u,
10527 /*retire_prior_to=*/1u));
10528 ++packet_num; // Probing packet on default network encounters write error.
10529 alternate_socket_data.AddWrite(
10530 ASYNC, client_maker_.MakeAckAndRetireConnectionIdPacket(
10531 packet_num++,
10532 /*largest_received=*/peer_packet_num - 1,
10533 /*smallest_received=*/1,
10534 /*sequence_number=*/2u));
10535 alternate_socket_data.AddReadPause();
10536 alternate_socket_data.AddRead(
10537 ASYNC, server_maker_.MakeNewConnectionIdPacket(peer_packet_num++, cid3,
10538 /*sequence_number=*/3u,
10539 /*retire_prior_to=*/1u));
10540 ++packet_num; // Probing packet on default network encounters write error.
10541 alternate_socket_data.AddWrite(
10542 ASYNC, client_maker_.MakeAckAndRetireConnectionIdPacket(
10543 packet_num++,
10544 /*largest_received=*/peer_packet_num - 1,
10545 /*smallest_received=*/1,
10546 /*sequence_number=*/3u));
10547 alternate_socket_data.AddReadPause();
10548 alternate_socket_data.AddRead(
10549 ASYNC, server_maker_.MakeNewConnectionIdPacket(peer_packet_num++, cid4,
10550 /*sequence_number=*/4u,
10551 /*retire_prior_to=*/1u));
10552 ++packet_num; // Probing packet on default network encounters write error.
10553 alternate_socket_data.AddWrite(
10554 ASYNC, client_maker_.MakeAckAndRetireConnectionIdPacket(
10555 packet_num++,
10556 /*largest_received=*/peer_packet_num - 1,
10557 /*smallest_received=*/1,
10558 /*sequence_number=*/4u));
10559 alternate_socket_data.AddReadPause();
10560 alternate_socket_data.AddRead(
10561 ASYNC, server_maker_.MakeNewConnectionIdPacket(peer_packet_num++, cid5,
10562 /*sequence_number=*/5u,
10563 /*retire_prior_to=*/1u));
10564 ++packet_num; // Probing packet on default network encounters write error.
10565 alternate_socket_data.AddWrite(
10566 ASYNC, client_maker_.MakeAckAndRetireConnectionIdPacket(
10567 packet_num++,
10568 /*largest_received=*/peer_packet_num - 1,
10569 /*smallest_received=*/1,
10570 /*sequence_number=*/5u));
10571 alternate_socket_data.AddReadPause();
10572 alternate_socket_data.AddRead(
10573 ASYNC, server_maker_.MakeNewConnectionIdPacket(peer_packet_num++, cid6,
10574 /*sequence_number=*/6u,
10575 /*retire_prior_to=*/1u));
10576 ++packet_num; // Probing packet on default network encounters write error.
10577 alternate_socket_data.AddWrite(
10578 ASYNC, client_maker_.MakeAckAndRetireConnectionIdPacket(
10579 packet_num++,
10580 /*largest_received=*/peer_packet_num - 1,
10581 /*smallest_received=*/1,
10582 /*sequence_number=*/6u));
10583 alternate_socket_data.AddReadPause();
10584 alternate_socket_data.AddRead(
10585 ASYNC, server_maker_.MakeNewConnectionIdPacket(peer_packet_num++, cid7,
10586 /*sequence_number=*/7u,
10587 /*retire_prior_to=*/1u));
10588 alternate_socket_data.AddRead(SYNCHRONOUS,
10589 ERR_IO_PENDING); // Hanging read.
10590 alternate_socket_data.AddSocketDataToFactory(socket_factory_.get());
10591
10592 // Set up probing socket for migrating back to the default network.
10593 MockQuicData quic_data(version_); // retry count: 0.
10594 quic_data.AddReadPauseForever();
10595 quic_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
10596 quic_data.AddSocketDataToFactory(socket_factory_.get());
10597
10598 MockQuicData quic_data1(version_); // retry count: 1
10599 quic_data1.AddReadPauseForever();
10600 quic_data1.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
10601 quic_data1.AddSocketDataToFactory(socket_factory_.get());
10602
10603 MockQuicData quic_data2(version_); // retry count: 2
10604 quic_data2.AddReadPauseForever();
10605 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
10606 quic_data2.AddSocketDataToFactory(socket_factory_.get());
10607
10608 MockQuicData quic_data3(version_); // retry count: 3
10609 quic_data3.AddReadPauseForever();
10610 quic_data3.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
10611 quic_data3.AddSocketDataToFactory(socket_factory_.get());
10612
10613 MockQuicData quic_data4(version_); // retry count: 4
10614 quic_data4.AddReadPauseForever();
10615 quic_data4.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
10616 quic_data4.AddSocketDataToFactory(socket_factory_.get());
10617
10618 MockQuicData quic_data5(version_); // retry count: 5
10619 quic_data5.AddReadPauseForever();
10620 quic_data5.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
10621 quic_data5.AddSocketDataToFactory(socket_factory_.get());
10622
10623 // Create request and QuicHttpStream.
10624 RequestBuilder builder(this);
10625 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
10626 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10627 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
10628 EXPECT_TRUE(stream.get());
10629
10630 // Ensure that session is active.
10631 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
10632
10633 // Trigger connection migration. Since there are no active streams,
10634 // the session will be closed.
10635 scoped_mock_network_change_notifier_->mock_network_change_notifier()
10636 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
10637
10638 // The nearest task will complete migration.
10639 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
10640 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
10641 task_runner->FastForwardBy(base::TimeDelta());
10642
10643 // The migrate back timer will fire. Due to default network
10644 // being disconnected, no attempt will be exercised to migrate back.
10645 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
10646 EXPECT_EQ(base::Seconds(kMinRetryTimeForDefaultNetworkSecs),
10647 task_runner->NextPendingTaskDelay());
10648 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
10649 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
10650
10651 // Deliver the signal that the old default network now backs up.
10652 scoped_mock_network_change_notifier_->mock_network_change_notifier()
10653 ->NotifyNetworkMadeDefault(kDefaultNetworkForTests);
10654
10655 // A task is posted to migrate back to the default network immediately.
10656 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
10657 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
10658 task_runner->FastForwardBy(base::TimeDelta());
10659
10660 // Retry migrate back in 1, 2, 4, 8, 16s.
10661 // Session will be closed due to idle migration timeout.
10662 for (int i = 0; i < 5; i++) {
10663 // Fire retire connection ID alarm.
10664 base::RunLoop().RunUntilIdle();
10665 // Make new connection ID available.
10666 alternate_socket_data.Resume();
10667 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
10668 // A task is posted to migrate back to the default network in 2^i seconds.
10669 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
10670 EXPECT_EQ(base::Seconds(UINT64_C(1) << i),
10671 task_runner->NextPendingTaskDelay());
10672 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
10673 }
10674
10675 default_socket_data.ExpectAllReadDataConsumed();
10676 default_socket_data.ExpectAllWriteDataConsumed();
10677 alternate_socket_data.ExpectAllReadDataConsumed();
10678 alternate_socket_data.ExpectAllWriteDataConsumed();
10679 }
10680
TEST_P(QuicSessionPoolTest,CustomIdleMigrationPeriod)10681 TEST_P(QuicSessionPoolTest, CustomIdleMigrationPeriod) {
10682 // The customized threshold is 15s.
10683 quic_params_->migrate_idle_sessions = true;
10684 quic_params_->idle_session_migration_period = base::Seconds(15);
10685 InitializeConnectionMigrationV2Test(
10686 {kDefaultNetworkForTests, kNewNetworkForTests});
10687 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10688 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10689 client_maker_.set_save_packet_frames(true);
10690
10691 // Using a testing task runner and a test tick tock.
10692 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
10693 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), task_runner.get());
10694 QuicSessionPoolPeer::SetTickClock(factory_.get(),
10695 task_runner->GetMockTickClock());
10696
10697 quic::QuicConnectionId cid1 = quic::test::TestConnectionId(1234567);
10698 quic::QuicConnectionId cid2 = quic::test::TestConnectionId(2345671);
10699 quic::QuicConnectionId cid3 = quic::test::TestConnectionId(3456712);
10700 quic::QuicConnectionId cid4 = quic::test::TestConnectionId(4567123);
10701 quic::QuicConnectionId cid5 = quic::test::TestConnectionId(5671234);
10702 quic::QuicConnectionId cid6 = quic::test::TestConnectionId(6712345);
10703
10704 int peer_packet_num = 1;
10705 MockQuicData default_socket_data(version_);
10706 default_socket_data.AddRead(
10707 SYNCHRONOUS,
10708 server_maker_.MakeNewConnectionIdPacket(peer_packet_num++, cid1,
10709 /*sequence_number=*/1u,
10710 /*retire_prior_to=*/0u));
10711 default_socket_data.AddReadPauseForever();
10712 int packet_num = 1;
10713 default_socket_data.AddWrite(SYNCHRONOUS,
10714 ConstructInitialSettingsPacket(packet_num++));
10715 default_socket_data.AddSocketDataToFactory(socket_factory_.get());
10716
10717 // Set up second socket data provider that is used after migration.
10718 MockQuicData alternate_socket_data(version_);
10719 client_maker_.set_connection_id(cid1);
10720 alternate_socket_data.AddWrite(SYNCHRONOUS,
10721 client_maker_.MakeAckAndRetransmissionPacket(
10722 packet_num++,
10723 /*first_received=*/1,
10724 /*largest_received=*/peer_packet_num - 1,
10725 /*smallest_received=*/1,
10726 /*original_packet_numbers=*/{1}));
10727 alternate_socket_data.AddWrite(SYNCHRONOUS,
10728 client_maker_.MakePingPacket(packet_num++));
10729 alternate_socket_data.AddWrite(ASYNC,
10730 client_maker_.MakeRetireConnectionIdPacket(
10731 packet_num++, /*sequence_number=*/0u));
10732 alternate_socket_data.AddReadPause();
10733 alternate_socket_data.AddRead(
10734 ASYNC, server_maker_.MakeNewConnectionIdPacket(peer_packet_num++, cid2,
10735 /*sequence_number=*/2u,
10736 /*retire_prior_to=*/1u));
10737 ++packet_num; // Probing packet on default network encounters write error.
10738 alternate_socket_data.AddWrite(
10739 ASYNC, client_maker_.MakeAckAndRetireConnectionIdPacket(
10740 packet_num++,
10741 /*largest_received=*/peer_packet_num - 1,
10742 /*smallest_received=*/1,
10743 /*sequence_number=*/2u));
10744 alternate_socket_data.AddReadPause();
10745 alternate_socket_data.AddRead(
10746 ASYNC, server_maker_.MakeNewConnectionIdPacket(peer_packet_num++, cid3,
10747 /*sequence_number=*/3u,
10748 /*retire_prior_to=*/1u));
10749 ++packet_num; // Probing packet on default network encounters write error.
10750 alternate_socket_data.AddWrite(
10751 ASYNC, client_maker_.MakeAckAndRetireConnectionIdPacket(
10752 packet_num++,
10753 /*largest_received=*/peer_packet_num - 1,
10754 /*smallest_received=*/1,
10755 /*sequence_number=*/3u));
10756 alternate_socket_data.AddReadPause();
10757 alternate_socket_data.AddRead(
10758 ASYNC, server_maker_.MakeNewConnectionIdPacket(peer_packet_num++, cid4,
10759 /*sequence_number=*/4u,
10760 /*retire_prior_to=*/1u));
10761 ++packet_num; // Probing packet on default network encounters write error.
10762 alternate_socket_data.AddWrite(
10763 ASYNC, client_maker_.MakeAckAndRetireConnectionIdPacket(
10764 packet_num++,
10765 /*largest_received=*/peer_packet_num - 1,
10766 /*smallest_received=*/1,
10767 /*sequence_number=*/4u));
10768 alternate_socket_data.AddReadPause();
10769 alternate_socket_data.AddRead(
10770 ASYNC, server_maker_.MakeNewConnectionIdPacket(peer_packet_num++, cid5,
10771 /*sequence_number=*/5u,
10772 /*retire_prior_to=*/1u));
10773 alternate_socket_data.AddRead(SYNCHRONOUS,
10774 ERR_IO_PENDING); // Hanging read.
10775 alternate_socket_data.AddSocketDataToFactory(socket_factory_.get());
10776
10777 // Set up probing socket for migrating back to the default network.
10778 MockQuicData quic_data(version_); // retry count: 0.
10779 quic_data.AddReadPauseForever();
10780 quic_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
10781 quic_data.AddSocketDataToFactory(socket_factory_.get());
10782
10783 MockQuicData quic_data1(version_); // retry count: 1
10784 quic_data1.AddReadPauseForever();
10785 quic_data1.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
10786 quic_data1.AddSocketDataToFactory(socket_factory_.get());
10787
10788 MockQuicData quic_data2(version_); // retry count: 2
10789 quic_data2.AddReadPauseForever();
10790 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
10791 quic_data2.AddSocketDataToFactory(socket_factory_.get());
10792
10793 MockQuicData quic_data3(version_); // retry count: 3
10794 quic_data3.AddReadPauseForever();
10795 quic_data3.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
10796 quic_data3.AddSocketDataToFactory(socket_factory_.get());
10797
10798 MockQuicData quic_data4(version_); // retry count: 4
10799 quic_data4.AddReadPauseForever();
10800 quic_data4.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
10801 quic_data4.AddSocketDataToFactory(socket_factory_.get());
10802
10803 // Create request and QuicHttpStream.
10804 RequestBuilder builder(this);
10805 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
10806 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10807 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
10808 EXPECT_TRUE(stream.get());
10809
10810 // Ensure that session is active.
10811 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
10812
10813 // Trigger connection migration. Since there are no active streams,
10814 // the session will be closed.
10815 scoped_mock_network_change_notifier_->mock_network_change_notifier()
10816 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
10817
10818 // The nearest task will complete migration.
10819 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
10820 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
10821 task_runner->FastForwardBy(base::TimeDelta());
10822
10823 // The migrate back timer will fire. Due to default network
10824 // being disconnected, no attempt will be exercised to migrate back.
10825 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
10826 EXPECT_EQ(base::Seconds(kMinRetryTimeForDefaultNetworkSecs),
10827 task_runner->NextPendingTaskDelay());
10828 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
10829 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
10830
10831 // Deliver the signal that the old default network now backs up.
10832 scoped_mock_network_change_notifier_->mock_network_change_notifier()
10833 ->NotifyNetworkMadeDefault(kDefaultNetworkForTests);
10834
10835 // A task is posted to migrate back to the default network immediately.
10836 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
10837 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
10838 task_runner->FastForwardBy(base::TimeDelta());
10839
10840 // Retry migrate back in 1, 2, 4, 8s.
10841 // Session will be closed due to idle migration timeout.
10842 for (int i = 0; i < 4; i++) {
10843 // Fire retire connection ID alarm.
10844 base::RunLoop().RunUntilIdle();
10845 // Make new connection ID available.
10846 alternate_socket_data.Resume();
10847 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
10848 // A task is posted to migrate back to the default network in 2^i seconds.
10849 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
10850 EXPECT_EQ(base::Seconds(UINT64_C(1) << i),
10851 task_runner->NextPendingTaskDelay());
10852 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
10853 }
10854
10855 default_socket_data.ExpectAllReadDataConsumed();
10856 default_socket_data.ExpectAllWriteDataConsumed();
10857 alternate_socket_data.ExpectAllReadDataConsumed();
10858 alternate_socket_data.ExpectAllWriteDataConsumed();
10859 }
10860
TEST_P(QuicSessionPoolTest,ServerMigration)10861 TEST_P(QuicSessionPoolTest, ServerMigration) {
10862 quic_params_->allow_server_migration = true;
10863 Initialize();
10864
10865 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10866 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10867 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10868 client_maker_.set_save_packet_frames(true);
10869
10870 MockQuicData socket_data1(version_);
10871 socket_data1.AddReadPauseForever();
10872 int packet_num = 1;
10873 socket_data1.AddWrite(SYNCHRONOUS,
10874 ConstructInitialSettingsPacket(packet_num++));
10875 socket_data1.AddWrite(
10876 SYNCHRONOUS,
10877 ConstructGetRequestPacket(
10878 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true));
10879 socket_data1.AddSocketDataToFactory(socket_factory_.get());
10880
10881 // Create request and QuicHttpStream.
10882 RequestBuilder builder(this);
10883 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
10884 EXPECT_EQ(OK, callback_.WaitForResult());
10885 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
10886 EXPECT_TRUE(stream.get());
10887
10888 // Cause QUIC stream to be created.
10889 HttpRequestInfo request_info;
10890 request_info.method = "GET";
10891 request_info.url = GURL("https://www.example.org/");
10892 request_info.traffic_annotation =
10893 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
10894 stream->RegisterRequest(&request_info);
10895 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
10896 CompletionOnceCallback()));
10897
10898 // Ensure that session is alive and active.
10899 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
10900 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
10901 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
10902 quic::QuicConnectionId cid_on_new_path =
10903 quic::test::TestConnectionId(12345678);
10904 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
10905
10906 NetErrorDetails details;
10907 EXPECT_FALSE(details.quic_connection_migration_attempted);
10908 EXPECT_FALSE(details.quic_connection_migration_successful);
10909 session->PopulateNetErrorDetails(&details);
10910 EXPECT_FALSE(details.quic_connection_migration_attempted);
10911 EXPECT_FALSE(details.quic_connection_migration_successful);
10912
10913 // Send GET request on stream.
10914 HttpResponseInfo response;
10915 HttpRequestHeaders request_headers;
10916 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
10917 callback_.callback()));
10918
10919 IPEndPoint ip;
10920 session->GetDefaultSocket()->GetPeerAddress(&ip);
10921 DVLOG(1) << "Socket connected to: " << ip.address().ToString() << " "
10922 << ip.port();
10923
10924 // Set up second socket data provider that is used after
10925 // migration. The request is rewritten to this new socket, and the
10926 // response to the request is read on this new socket.
10927 MockQuicData socket_data2(version_);
10928 client_maker_.set_connection_id(cid_on_new_path);
10929 socket_data2.AddWrite(
10930 SYNCHRONOUS,
10931 client_maker_.MakeCombinedRetransmissionPacket({1, 2}, packet_num++));
10932 socket_data2.AddWrite(SYNCHRONOUS,
10933 client_maker_.MakePingPacket(packet_num++));
10934 socket_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeRetireConnectionIdPacket(
10935 packet_num++,
10936 /*sequence_number=*/0u));
10937 socket_data2.AddRead(
10938 ASYNC, ConstructOkResponsePacket(
10939 1, GetNthClientInitiatedBidirectionalStreamId(0), false));
10940 socket_data2.AddReadPauseForever();
10941 socket_data2.AddWrite(
10942 SYNCHRONOUS,
10943 client_maker_.MakeDataPacket(
10944 packet_num++, GetQpackDecoderStreamId(),
10945 /*fin=*/false, StreamCancellationQpackDecoderInstruction(0)));
10946 socket_data2.AddWrite(
10947 SYNCHRONOUS,
10948 client_maker_.MakeRstPacket(packet_num++,
10949 GetNthClientInitiatedBidirectionalStreamId(0),
10950 quic::QUIC_STREAM_CANCELLED));
10951 socket_data2.AddSocketDataToFactory(socket_factory_.get());
10952
10953 const uint8_t kTestIpAddress[] = {1, 2, 3, 4};
10954 const uint16_t kTestPort = 123;
10955 base::RunLoop run_loop;
10956 QuicChromiumClientSession::MigrationCallback migration_callback =
10957 base::BindLambdaForTesting(
10958 [&run_loop](MigrationResult result) { run_loop.Quit(); });
10959 session->Migrate(handles::kInvalidNetworkHandle,
10960 IPEndPoint(IPAddress(kTestIpAddress), kTestPort), true,
10961 std::move(migration_callback));
10962 run_loop.Run();
10963 session->GetDefaultSocket()->GetPeerAddress(&ip);
10964 DVLOG(1) << "Socket migrated to: " << ip.address().ToString() << " "
10965 << ip.port();
10966
10967 // The session should be alive and active.
10968 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
10969 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
10970 EXPECT_EQ(1u, session->GetNumActiveStreams());
10971
10972 session->PopulateNetErrorDetails(&details);
10973 EXPECT_TRUE(details.quic_connection_migration_attempted);
10974 EXPECT_TRUE(details.quic_connection_migration_successful);
10975
10976 // Run the message loop so that data queued in the new socket is read by the
10977 // packet reader.
10978 base::RunLoop().RunUntilIdle();
10979
10980 // Verify that response headers on the migrated socket were delivered to the
10981 // stream.
10982 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
10983 EXPECT_EQ(200, response.headers->response_code());
10984
10985 stream.reset();
10986
10987 socket_data1.ExpectAllReadDataConsumed();
10988 socket_data1.ExpectAllWriteDataConsumed();
10989 socket_data2.ExpectAllReadDataConsumed();
10990 socket_data2.ExpectAllWriteDataConsumed();
10991 }
10992
TEST_P(QuicSessionPoolTest,ServerMigrationNonMigratableStream)10993 TEST_P(QuicSessionPoolTest, ServerMigrationNonMigratableStream) {
10994 quic_params_->allow_server_migration = true;
10995 Initialize();
10996
10997 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10998 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10999 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
11000 client_maker_.set_save_packet_frames(true);
11001
11002 int packet_num = 1;
11003 MockQuicData socket_data(version_);
11004 socket_data.AddReadPauseForever();
11005 socket_data.AddWrite(SYNCHRONOUS,
11006 ConstructInitialSettingsPacket(packet_num++));
11007 socket_data.AddWrite(
11008 SYNCHRONOUS,
11009 ConstructGetRequestPacket(
11010 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true));
11011 socket_data.AddWrite(SYNCHRONOUS,
11012 client_maker_.MakeDataPacket(
11013 packet_num++, GetQpackDecoderStreamId(), false,
11014 StreamCancellationQpackDecoderInstruction(0)));
11015 socket_data.AddWrite(
11016 SYNCHRONOUS,
11017 ConstructClientRstPacket(packet_num++, quic::QUIC_STREAM_CANCELLED));
11018 socket_data.AddSocketDataToFactory(socket_factory_.get());
11019
11020 // Create request and QuicHttpStream.
11021 RequestBuilder builder(this);
11022 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
11023 EXPECT_EQ(OK, callback_.WaitForResult());
11024 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
11025 EXPECT_TRUE(stream.get());
11026
11027 // Cause QUIC stream to be created.
11028 HttpRequestInfo request_info;
11029 request_info.method = "GET";
11030 request_info.url = GURL("https://www.example.org/");
11031 request_info.traffic_annotation =
11032 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11033 stream->RegisterRequest(&request_info);
11034 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
11035 CompletionOnceCallback()));
11036
11037 // Ensure that session is alive and active.
11038 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
11039 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
11040 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
11041 quic::QuicConnectionId cid_on_new_path =
11042 quic::test::TestConnectionId(12345678);
11043 MaybeMakeNewConnectionIdAvailableToSession(cid_on_new_path, session);
11044
11045 // Disable connection migration on the request streams.
11046 QuicChromiumClientStream* chrome_stream =
11047 static_cast<QuicChromiumClientStream*>(
11048 quic::test::QuicSessionPeer::GetStream(
11049 session, GetNthClientInitiatedBidirectionalStreamId(0)));
11050 EXPECT_TRUE(chrome_stream);
11051 chrome_stream->DisableConnectionMigrationToCellularNetwork();
11052
11053 NetErrorDetails details;
11054 EXPECT_FALSE(details.quic_connection_migration_attempted);
11055 EXPECT_FALSE(details.quic_connection_migration_successful);
11056 session->PopulateNetErrorDetails(&details);
11057 EXPECT_FALSE(details.quic_connection_migration_attempted);
11058 EXPECT_FALSE(details.quic_connection_migration_successful);
11059
11060 // Send GET request on stream.
11061 HttpResponseInfo response;
11062 HttpRequestHeaders request_headers;
11063 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
11064 callback_.callback()));
11065
11066 // The specific network isn't important, we just want something !=
11067 // handles::kInvalidNetworkHandle to specify a non-default network.
11068 constexpr handles::NetworkHandle kNonDefaultNetwork = 1;
11069 constexpr uint8_t kTestIpAddress[] = {1, 2, 3, 4};
11070 constexpr uint16_t kTestPort = 123;
11071 base::RunLoop run_loop;
11072 QuicChromiumClientSession::MigrationCallback migration_callback =
11073 base::BindLambdaForTesting(
11074 [&run_loop](MigrationResult result) { run_loop.Quit(); });
11075 session->Migrate(kNonDefaultNetwork,
11076 IPEndPoint(IPAddress(kTestIpAddress), kTestPort), true,
11077 std::move(migration_callback));
11078 run_loop.Run();
11079 // The session should exist but no longer be active since its only stream has
11080 // been reset.
11081 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
11082 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
11083
11084 session->PopulateNetErrorDetails(&details);
11085 EXPECT_TRUE(details.quic_connection_migration_attempted);
11086 EXPECT_FALSE(details.quic_connection_migration_successful);
11087
11088 // Run the message loop so that data queued due to the reset is read by the
11089 // packet reader.
11090 base::RunLoop().RunUntilIdle();
11091
11092 // Verify that the request failed since connection the stream couldn't be
11093 // migrated.
11094 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR,
11095 stream->ReadResponseHeaders(callback_.callback()));
11096 EXPECT_EQ(nullptr, response.headers);
11097
11098 stream.reset();
11099
11100 socket_data.ExpectAllReadDataConsumed();
11101 socket_data.ExpectAllWriteDataConsumed();
11102 }
11103
TEST_P(QuicSessionPoolTest,ServerMigrationIPv4ToIPv4)11104 TEST_P(QuicSessionPoolTest, ServerMigrationIPv4ToIPv4) {
11105 // Add alternate IPv4 server address to config.
11106 IPEndPoint alt_address = IPEndPoint(IPAddress(1, 2, 3, 4), 123);
11107 quic::QuicConfig config;
11108 config.SetIPv4AlternateServerAddressToSend(ToQuicSocketAddress(alt_address));
11109 config.SetPreferredAddressConnectionIdAndTokenToSend(
11110 kNewCID, quic::QuicUtils::GenerateStatelessResetToken(kNewCID));
11111 VerifyServerMigration(config, alt_address);
11112 }
11113
TEST_P(QuicSessionPoolTest,ServerMigrationIPv6ToIPv6)11114 TEST_P(QuicSessionPoolTest, ServerMigrationIPv6ToIPv6) {
11115 // Add a resolver rule to make initial connection to an IPv6 address.
11116 host_resolver_->rules()->AddIPLiteralRule(kDefaultServerHostName,
11117 "fe80::aebc:32ff:febb:1e33", "");
11118 // Add alternate IPv6 server address to config.
11119 IPEndPoint alt_address = IPEndPoint(
11120 IPAddress(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), 123);
11121 quic::QuicConfig config;
11122 config.SetIPv6AlternateServerAddressToSend(ToQuicSocketAddress(alt_address));
11123 config.SetPreferredAddressConnectionIdAndTokenToSend(
11124 kNewCID, quic::QuicUtils::GenerateStatelessResetToken(kNewCID));
11125 VerifyServerMigration(config, alt_address);
11126 }
11127
TEST_P(QuicSessionPoolTest,ServerMigrationIPv6ToIPv4Fails)11128 TEST_P(QuicSessionPoolTest, ServerMigrationIPv6ToIPv4Fails) {
11129 quic_params_->allow_server_migration = true;
11130 Initialize();
11131
11132 // Add a resolver rule to make initial connection to an IPv6 address.
11133 host_resolver_->rules()->AddIPLiteralRule(kDefaultServerHostName,
11134 "fe80::aebc:32ff:febb:1e33", "");
11135 // Add alternate IPv4 server address to config.
11136 IPEndPoint alt_address = IPEndPoint(IPAddress(1, 2, 3, 4), 123);
11137 quic::QuicConfig config;
11138 config.SetIPv4AlternateServerAddressToSend(ToQuicSocketAddress(alt_address));
11139
11140 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
11141 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
11142 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
11143
11144 crypto_client_stream_factory_.SetConfig(config);
11145
11146 // Set up only socket data provider.
11147 MockQuicData socket_data1(version_);
11148 socket_data1.AddReadPauseForever();
11149 int packet_num = 1;
11150 socket_data1.AddWrite(SYNCHRONOUS,
11151 ConstructInitialSettingsPacket(packet_num++));
11152 socket_data1.AddWrite(SYNCHRONOUS,
11153 client_maker_.MakeDataPacket(
11154 packet_num++, GetQpackDecoderStreamId(), false,
11155 StreamCancellationQpackDecoderInstruction(0)));
11156 socket_data1.AddWrite(
11157 SYNCHRONOUS,
11158 client_maker_.MakeRstPacket(packet_num++,
11159 GetNthClientInitiatedBidirectionalStreamId(0),
11160 quic::QUIC_STREAM_CANCELLED));
11161 socket_data1.AddSocketDataToFactory(socket_factory_.get());
11162
11163 // Create request and QuicHttpStream.
11164 RequestBuilder builder(this);
11165 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
11166 EXPECT_EQ(OK, callback_.WaitForResult());
11167 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
11168 EXPECT_TRUE(stream.get());
11169
11170 // Cause QUIC stream to be created.
11171 HttpRequestInfo request_info;
11172 request_info.method = "GET";
11173 request_info.url = GURL("https://www.example.org/");
11174 request_info.traffic_annotation =
11175 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11176 stream->RegisterRequest(&request_info);
11177 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
11178 CompletionOnceCallback()));
11179
11180 // Ensure that session is alive and active.
11181 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
11182 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
11183 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
11184
11185 IPEndPoint actual_address;
11186 session->GetDefaultSocket()->GetPeerAddress(&actual_address);
11187 // No migration should have happened.
11188 IPEndPoint expected_address =
11189 IPEndPoint(IPAddress(0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0xae, 0xbc, 0x32, 0xff,
11190 0xfe, 0xbb, 0x1e, 0x33),
11191 kDefaultServerPort);
11192 EXPECT_EQ(actual_address, expected_address);
11193 DVLOG(1) << "Socket connected to: " << actual_address.address().ToString()
11194 << " " << actual_address.port();
11195 DVLOG(1) << "Expected address: " << expected_address.address().ToString()
11196 << " " << expected_address.port();
11197
11198 stream.reset();
11199 socket_data1.ExpectAllReadDataConsumed();
11200 socket_data1.ExpectAllWriteDataConsumed();
11201 }
11202
TEST_P(QuicSessionPoolTest,ServerMigrationIPv4ToIPv6Fails)11203 TEST_P(QuicSessionPoolTest, ServerMigrationIPv4ToIPv6Fails) {
11204 quic_params_->allow_server_migration = true;
11205 Initialize();
11206
11207 // Add a resolver rule to make initial connection to an IPv4 address.
11208 host_resolver_->rules()->AddIPLiteralRule(kDefaultServerHostName, "1.2.3.4",
11209 "");
11210 // Add alternate IPv6 server address to config.
11211 IPEndPoint alt_address = IPEndPoint(
11212 IPAddress(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), 123);
11213 quic::QuicConfig config;
11214 config.SetIPv6AlternateServerAddressToSend(ToQuicSocketAddress(alt_address));
11215
11216 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
11217 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
11218 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
11219
11220 crypto_client_stream_factory_.SetConfig(config);
11221
11222 // Set up only socket data provider.
11223 MockQuicData socket_data1(version_);
11224 socket_data1.AddReadPauseForever();
11225 int packet_num = 1;
11226 socket_data1.AddWrite(SYNCHRONOUS,
11227 ConstructInitialSettingsPacket(packet_num++));
11228 socket_data1.AddWrite(SYNCHRONOUS,
11229 client_maker_.MakeDataPacket(
11230 packet_num++, GetQpackDecoderStreamId(), false,
11231 StreamCancellationQpackDecoderInstruction(0)));
11232 socket_data1.AddWrite(
11233 SYNCHRONOUS,
11234 client_maker_.MakeRstPacket(packet_num++,
11235 GetNthClientInitiatedBidirectionalStreamId(0),
11236 quic::QUIC_STREAM_CANCELLED));
11237 socket_data1.AddSocketDataToFactory(socket_factory_.get());
11238
11239 // Create request and QuicHttpStream.
11240 RequestBuilder builder(this);
11241 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
11242 EXPECT_EQ(OK, callback_.WaitForResult());
11243 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
11244 EXPECT_TRUE(stream.get());
11245
11246 // Cause QUIC stream to be created.
11247 HttpRequestInfo request_info;
11248 request_info.method = "GET";
11249 request_info.url = GURL("https://www.example.org/");
11250 request_info.traffic_annotation =
11251 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11252 stream->RegisterRequest(&request_info);
11253 EXPECT_EQ(OK, stream->InitializeStream(true, DEFAULT_PRIORITY, net_log_,
11254 CompletionOnceCallback()));
11255
11256 // Ensure that session is alive and active.
11257 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
11258 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
11259 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
11260
11261 IPEndPoint actual_address;
11262 session->GetDefaultSocket()->GetPeerAddress(&actual_address);
11263 // No migration should have happened.
11264 IPEndPoint expected_address =
11265 IPEndPoint(IPAddress(1, 2, 3, 4), kDefaultServerPort);
11266 EXPECT_EQ(actual_address, expected_address);
11267 DVLOG(1) << "Socket connected to: " << actual_address.address().ToString()
11268 << " " << actual_address.port();
11269 DVLOG(1) << "Expected address: " << expected_address.address().ToString()
11270 << " " << expected_address.port();
11271
11272 stream.reset();
11273 socket_data1.ExpectAllReadDataConsumed();
11274 socket_data1.ExpectAllWriteDataConsumed();
11275 }
11276
TEST_P(QuicSessionPoolTest,OnCertDBChanged)11277 TEST_P(QuicSessionPoolTest, OnCertDBChanged) {
11278 Initialize();
11279 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
11280 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
11281 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
11282
11283 MockQuicData socket_data(version_);
11284 socket_data.AddReadPauseForever();
11285 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
11286 socket_data.AddSocketDataToFactory(socket_factory_.get());
11287
11288 client_maker_.Reset();
11289 MockQuicData socket_data2(version_);
11290 socket_data2.AddReadPauseForever();
11291 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
11292 socket_data2.AddSocketDataToFactory(socket_factory_.get());
11293
11294 RequestBuilder builder(this);
11295 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
11296
11297 EXPECT_THAT(callback_.WaitForResult(), IsOk());
11298 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
11299 EXPECT_TRUE(stream);
11300 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
11301
11302 // Synthesize a CertDatabase change notification and verify that stream saw
11303 // the event.
11304 CertDatabase::GetInstance()->NotifyObserversTrustStoreChanged();
11305 base::RunLoop().RunUntilIdle();
11306
11307 EXPECT_TRUE(factory_->is_quic_known_to_work_on_current_network());
11308 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
11309 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
11310
11311 // Now attempting to request a stream to the same origin should create
11312 // a new session.
11313
11314 RequestBuilder builder2(this);
11315 EXPECT_EQ(ERR_IO_PENDING, builder2.CallRequest());
11316
11317 EXPECT_THAT(callback_.WaitForResult(), IsOk());
11318 std::unique_ptr<HttpStream> stream2 = CreateStream(&builder2.request);
11319 EXPECT_TRUE(stream2);
11320 QuicChromiumClientSession* session2 = GetActiveSession(kDefaultDestination);
11321 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
11322 EXPECT_NE(session, session2);
11323 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
11324 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session2));
11325
11326 stream2.reset();
11327 stream.reset();
11328
11329 socket_data.ExpectAllReadDataConsumed();
11330 socket_data.ExpectAllWriteDataConsumed();
11331 socket_data2.ExpectAllReadDataConsumed();
11332 socket_data2.ExpectAllWriteDataConsumed();
11333 }
11334
TEST_P(QuicSessionPoolTest,OnCertVerifierChanged)11335 TEST_P(QuicSessionPoolTest, OnCertVerifierChanged) {
11336 Initialize();
11337 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
11338 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
11339 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
11340
11341 MockQuicData socket_data(version_);
11342 socket_data.AddReadPauseForever();
11343 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
11344 socket_data.AddSocketDataToFactory(socket_factory_.get());
11345
11346 client_maker_.Reset();
11347 MockQuicData socket_data2(version_);
11348 socket_data2.AddReadPauseForever();
11349 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
11350 socket_data2.AddSocketDataToFactory(socket_factory_.get());
11351
11352 RequestBuilder builder(this);
11353 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
11354
11355 EXPECT_THAT(callback_.WaitForResult(), IsOk());
11356 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
11357 EXPECT_TRUE(stream);
11358 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
11359
11360 // Synthesize a CertVerifier change notification and verify that stream saw
11361 // the event.
11362 cert_verifier_->SimulateOnCertVerifierChanged();
11363 base::RunLoop().RunUntilIdle();
11364
11365 EXPECT_TRUE(factory_->is_quic_known_to_work_on_current_network());
11366 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
11367 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
11368
11369 // Now attempting to request a stream to the same origin should create
11370 // a new session.
11371
11372 RequestBuilder builder2(this);
11373 EXPECT_EQ(ERR_IO_PENDING, builder2.CallRequest());
11374
11375 EXPECT_THAT(callback_.WaitForResult(), IsOk());
11376 std::unique_ptr<HttpStream> stream2 = CreateStream(&builder2.request);
11377 EXPECT_TRUE(stream2);
11378 QuicChromiumClientSession* session2 = GetActiveSession(kDefaultDestination);
11379 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
11380 EXPECT_NE(session, session2);
11381 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
11382 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session2));
11383
11384 stream2.reset();
11385 stream.reset();
11386
11387 socket_data.ExpectAllReadDataConsumed();
11388 socket_data.ExpectAllWriteDataConsumed();
11389 socket_data2.ExpectAllReadDataConsumed();
11390 socket_data2.ExpectAllWriteDataConsumed();
11391 }
11392
TEST_P(QuicSessionPoolTest,SharedCryptoConfig)11393 TEST_P(QuicSessionPoolTest, SharedCryptoConfig) {
11394 Initialize();
11395
11396 std::vector<string> cannoncial_suffixes;
11397 cannoncial_suffixes.emplace_back(".c.youtube.com");
11398 cannoncial_suffixes.emplace_back(".googlevideo.com");
11399
11400 for (const auto& cannoncial_suffix : cannoncial_suffixes) {
11401 string r1_host_name("r1");
11402 string r2_host_name("r2");
11403 r1_host_name.append(cannoncial_suffix);
11404 r2_host_name.append(cannoncial_suffix);
11405
11406 url::SchemeHostPort scheme_host_port1(url::kHttpsScheme, r1_host_name, 80);
11407 // Need to hold onto this through the test, to keep the
11408 // QuicCryptoClientConfig alive.
11409 std::unique_ptr<QuicCryptoClientConfigHandle> crypto_config_handle =
11410 QuicSessionPoolPeer::GetCryptoConfig(factory_.get(),
11411 NetworkAnonymizationKey());
11412 quic::QuicServerId server_id1(scheme_host_port1.host(),
11413 scheme_host_port1.port(),
11414 PRIVACY_MODE_DISABLED);
11415 quic::QuicCryptoClientConfig::CachedState* cached1 =
11416 crypto_config_handle->GetConfig()->LookupOrCreate(server_id1);
11417 EXPECT_FALSE(cached1->proof_valid());
11418 EXPECT_TRUE(cached1->source_address_token().empty());
11419
11420 // Mutate the cached1 to have different data.
11421 // TODO(rtenneti): mutate other members of CachedState.
11422 cached1->set_source_address_token(r1_host_name);
11423 cached1->SetProofValid();
11424
11425 url::SchemeHostPort scheme_host_port2(url::kHttpsScheme, r2_host_name, 80);
11426 quic::QuicServerId server_id2(scheme_host_port2.host(),
11427 scheme_host_port2.port(),
11428 PRIVACY_MODE_DISABLED);
11429 quic::QuicCryptoClientConfig::CachedState* cached2 =
11430 crypto_config_handle->GetConfig()->LookupOrCreate(server_id2);
11431 EXPECT_EQ(cached1->source_address_token(), cached2->source_address_token());
11432 EXPECT_TRUE(cached2->proof_valid());
11433 }
11434 }
11435
TEST_P(QuicSessionPoolTest,CryptoConfigWhenProofIsInvalid)11436 TEST_P(QuicSessionPoolTest, CryptoConfigWhenProofIsInvalid) {
11437 Initialize();
11438 std::vector<string> cannoncial_suffixes;
11439 cannoncial_suffixes.emplace_back(".c.youtube.com");
11440 cannoncial_suffixes.emplace_back(".googlevideo.com");
11441
11442 for (const auto& cannoncial_suffix : cannoncial_suffixes) {
11443 string r3_host_name("r3");
11444 string r4_host_name("r4");
11445 r3_host_name.append(cannoncial_suffix);
11446 r4_host_name.append(cannoncial_suffix);
11447
11448 url::SchemeHostPort scheme_host_port1(url::kHttpsScheme, r3_host_name, 80);
11449 // Need to hold onto this through the test, to keep the
11450 // QuicCryptoClientConfig alive.
11451 std::unique_ptr<QuicCryptoClientConfigHandle> crypto_config_handle =
11452 QuicSessionPoolPeer::GetCryptoConfig(factory_.get(),
11453 NetworkAnonymizationKey());
11454 quic::QuicServerId server_id1(scheme_host_port1.host(),
11455 scheme_host_port1.port(),
11456 PRIVACY_MODE_DISABLED);
11457 quic::QuicCryptoClientConfig::CachedState* cached1 =
11458 crypto_config_handle->GetConfig()->LookupOrCreate(server_id1);
11459 EXPECT_FALSE(cached1->proof_valid());
11460 EXPECT_TRUE(cached1->source_address_token().empty());
11461
11462 // Mutate the cached1 to have different data.
11463 // TODO(rtenneti): mutate other members of CachedState.
11464 cached1->set_source_address_token(r3_host_name);
11465 cached1->SetProofInvalid();
11466
11467 url::SchemeHostPort scheme_host_port2(url::kHttpsScheme, r4_host_name, 80);
11468 quic::QuicServerId server_id2(scheme_host_port2.host(),
11469 scheme_host_port2.port(),
11470 PRIVACY_MODE_DISABLED);
11471 quic::QuicCryptoClientConfig::CachedState* cached2 =
11472 crypto_config_handle->GetConfig()->LookupOrCreate(server_id2);
11473 EXPECT_NE(cached1->source_address_token(), cached2->source_address_token());
11474 EXPECT_TRUE(cached2->source_address_token().empty());
11475 EXPECT_FALSE(cached2->proof_valid());
11476 }
11477 }
11478
TEST_P(QuicSessionPoolTest,EnableNotLoadFromDiskCache)11479 TEST_P(QuicSessionPoolTest, EnableNotLoadFromDiskCache) {
11480 Initialize();
11481 factory_->set_is_quic_known_to_work_on_current_network(true);
11482 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
11483 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
11484
11485 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), runner_.get());
11486
11487 MockQuicData socket_data(version_);
11488 socket_data.AddReadPauseForever();
11489 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
11490 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
11491 socket_data.AddSocketDataToFactory(socket_factory_.get());
11492
11493 crypto_client_stream_factory_.set_handshake_mode(
11494 MockCryptoClientStream::ZERO_RTT);
11495 host_resolver_->set_synchronous_mode(true);
11496 host_resolver_->rules()->AddIPLiteralRule(kDefaultServerHostName,
11497 "192.168.0.1", "");
11498
11499 RequestBuilder builder(this);
11500 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
11501 EXPECT_THAT(callback_.WaitForResult(), IsOk());
11502
11503 // If we are waiting for disk cache, we would have posted a task. Verify that
11504 // the CancelWaitForDataReady task hasn't been posted.
11505 ASSERT_EQ(0u, runner_->GetPostedTasks().size());
11506
11507 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
11508 EXPECT_TRUE(stream.get());
11509 socket_data.ExpectAllReadDataConsumed();
11510 socket_data.ExpectAllWriteDataConsumed();
11511 }
11512
TEST_P(QuicSessionPoolTest,ReducePingTimeoutOnConnectionTimeOutOpenStreams)11513 TEST_P(QuicSessionPoolTest, ReducePingTimeoutOnConnectionTimeOutOpenStreams) {
11514 quic_params_->reduced_ping_timeout = base::Seconds(10);
11515 Initialize();
11516 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
11517 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
11518 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
11519
11520 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), runner_.get());
11521
11522 MockQuicData socket_data(version_);
11523 socket_data.AddReadPauseForever();
11524 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
11525 socket_data.AddSocketDataToFactory(socket_factory_.get());
11526
11527 client_maker_.Reset();
11528 MockQuicData socket_data2(version_);
11529 socket_data2.AddReadPauseForever();
11530 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
11531 socket_data2.AddSocketDataToFactory(socket_factory_.get());
11532
11533 url::SchemeHostPort server2(url::kHttpsScheme, kServer2HostName,
11534 kDefaultServerPort);
11535
11536 crypto_client_stream_factory_.set_handshake_mode(
11537 MockCryptoClientStream::CONFIRM_HANDSHAKE);
11538 host_resolver_->set_synchronous_mode(true);
11539 host_resolver_->rules()->AddIPLiteralRule(kDefaultServerHostName,
11540 "192.168.0.1", "");
11541 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
11542
11543 // Quic should use default PING timeout when no previous connection times out
11544 // with open stream.
11545 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(quic::kPingTimeoutSecs),
11546 QuicSessionPoolPeer::GetPingTimeout(factory_.get()));
11547 RequestBuilder builder(this);
11548 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
11549 EXPECT_THAT(callback_.WaitForResult(), IsOk());
11550
11551 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
11552
11553 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
11554 EXPECT_TRUE(stream.get());
11555 HttpRequestInfo request_info;
11556 request_info.traffic_annotation =
11557 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11558 stream->RegisterRequest(&request_info);
11559 EXPECT_EQ(OK, stream->InitializeStream(false, DEFAULT_PRIORITY, net_log_,
11560 CompletionOnceCallback()));
11561
11562 DVLOG(1)
11563 << "Created 1st session and initialized a stream. Now trigger timeout";
11564 session->connection()->CloseConnection(
11565 quic::QUIC_NETWORK_IDLE_TIMEOUT, "test",
11566 quic::ConnectionCloseBehavior::SILENT_CLOSE);
11567 // Need to spin the loop now to ensure that
11568 // QuicSessionPool::OnSessionClosed() runs.
11569 base::RunLoop run_loop;
11570 run_loop.RunUntilIdle();
11571
11572 // The first connection times out with open stream, QUIC should reduce initial
11573 // PING time for subsequent connections.
11574 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(10),
11575 QuicSessionPoolPeer::GetPingTimeout(factory_.get()));
11576
11577 // Test two-in-a-row timeouts with open streams.
11578 DVLOG(1) << "Create 2nd session and timeout with open stream";
11579 TestCompletionCallback callback2;
11580 RequestBuilder builder2(this);
11581 builder2.destination = server2;
11582 builder2.url = GURL(kServer2Url);
11583 builder2.callback = callback2.callback();
11584 EXPECT_EQ(ERR_IO_PENDING, builder2.CallRequest());
11585 EXPECT_THAT(callback2.WaitForResult(), IsOk());
11586 QuicChromiumClientSession* session2 = GetActiveSession(server2);
11587
11588 std::unique_ptr<HttpStream> stream2 = CreateStream(&builder2.request);
11589 EXPECT_TRUE(stream2.get());
11590 stream2->RegisterRequest(&request_info);
11591 EXPECT_EQ(OK, stream2->InitializeStream(false, DEFAULT_PRIORITY, net_log_,
11592 CompletionOnceCallback()));
11593 session2->connection()->CloseConnection(
11594 quic::QUIC_NETWORK_IDLE_TIMEOUT, "test",
11595 quic::ConnectionCloseBehavior::SILENT_CLOSE);
11596 // Need to spin the loop now to ensure that
11597 // QuicSessionPool::OnSessionClosed() runs.
11598 base::RunLoop run_loop2;
11599 run_loop2.RunUntilIdle();
11600
11601 socket_data.ExpectAllReadDataConsumed();
11602 socket_data.ExpectAllWriteDataConsumed();
11603 socket_data2.ExpectAllReadDataConsumed();
11604 socket_data2.ExpectAllWriteDataConsumed();
11605 }
11606
11607 // Verifies that the QUIC stream factory is initialized correctly.
TEST_P(QuicSessionPoolTest,MaybeInitialize)11608 TEST_P(QuicSessionPoolTest, MaybeInitialize) {
11609 VerifyInitialization(false /* vary_network_anonymization_key */);
11610 }
11611
TEST_P(QuicSessionPoolTest,MaybeInitializeWithNetworkAnonymizationKey)11612 TEST_P(QuicSessionPoolTest, MaybeInitializeWithNetworkAnonymizationKey) {
11613 base::test::ScopedFeatureList feature_list;
11614 feature_list.InitWithFeatures(
11615 // enabled_features
11616 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
11617 // Need to partition connections by NetworkAnonymizationKey for
11618 // QuicSessionAliasKey to include NetworkAnonymizationKeys.
11619 features::kPartitionConnectionsByNetworkIsolationKey},
11620 // disabled_features
11621 {});
11622 // Since HttpServerProperties caches the feature value, have to create a new
11623 // one.
11624 http_server_properties_ = std::make_unique<HttpServerProperties>();
11625
11626 VerifyInitialization(true /* vary_network_anonymization_key */);
11627 }
11628
11629 // Without NetworkAnonymizationKeys enabled for HttpServerProperties, there
11630 // should only be one global CryptoCache.
TEST_P(QuicSessionPoolTest,CryptoConfigCache)11631 TEST_P(QuicSessionPoolTest, CryptoConfigCache) {
11632 const char kUserAgentId[] = "spoon";
11633
11634 base::test::ScopedFeatureList feature_list;
11635 feature_list.InitAndDisableFeature(
11636 features::kPartitionHttpServerPropertiesByNetworkIsolationKey);
11637
11638 const SchemefulSite kSite1(GURL("https://foo.test/"));
11639 const auto kNetworkAnonymizationKey1 =
11640 NetworkAnonymizationKey::CreateSameSite(kSite1);
11641
11642 const SchemefulSite kSite2(GURL("https://bar.test/"));
11643 const auto kNetworkAnonymizationKey2 =
11644 NetworkAnonymizationKey::CreateSameSite(kSite2);
11645
11646 const SchemefulSite kSite3(GURL("https://baz.test/"));
11647 const auto kNetworkAnonymizationKey3 =
11648 NetworkAnonymizationKey::CreateSameSite(kSite3);
11649
11650 Initialize();
11651
11652 // Create a QuicCryptoClientConfigHandle for kNetworkAnonymizationKey1, and
11653 // set the user agent.
11654 std::unique_ptr<QuicCryptoClientConfigHandle> crypto_config_handle1 =
11655 QuicSessionPoolPeer::GetCryptoConfig(factory_.get(),
11656 kNetworkAnonymizationKey1);
11657 crypto_config_handle1->GetConfig()->set_user_agent_id(kUserAgentId);
11658 EXPECT_EQ(kUserAgentId, crypto_config_handle1->GetConfig()->user_agent_id());
11659
11660 // Create another crypto config handle using a different
11661 // NetworkAnonymizationKey while the first one is still alive should return
11662 // the same config, with the user agent that was just set.
11663 std::unique_ptr<QuicCryptoClientConfigHandle> crypto_config_handle2 =
11664 QuicSessionPoolPeer::GetCryptoConfig(factory_.get(),
11665 kNetworkAnonymizationKey2);
11666 EXPECT_EQ(kUserAgentId, crypto_config_handle2->GetConfig()->user_agent_id());
11667
11668 // Destroying both handles and creating a new one with yet another
11669 // NetworkAnonymizationKey should again return the same config.
11670 crypto_config_handle1.reset();
11671 crypto_config_handle2.reset();
11672
11673 std::unique_ptr<QuicCryptoClientConfigHandle> crypto_config_handle3 =
11674 QuicSessionPoolPeer::GetCryptoConfig(factory_.get(),
11675 kNetworkAnonymizationKey3);
11676 EXPECT_EQ(kUserAgentId, crypto_config_handle3->GetConfig()->user_agent_id());
11677 }
11678
11679 // With different NetworkAnonymizationKeys enabled for HttpServerProperties,
11680 // there should only be one global CryptoCache per NetworkAnonymizationKey.
TEST_P(QuicSessionPoolTest,CryptoConfigCacheWithNetworkAnonymizationKey)11681 TEST_P(QuicSessionPoolTest, CryptoConfigCacheWithNetworkAnonymizationKey) {
11682 const char kUserAgentId1[] = "spoon";
11683 const char kUserAgentId2[] = "fork";
11684 const char kUserAgentId3[] = "another spoon";
11685
11686 base::test::ScopedFeatureList feature_list;
11687 feature_list.InitWithFeatures(
11688 // enabled_features
11689 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
11690 // Need to partition connections by NetworkAnonymizationKey for
11691 // QuicSessionAliasKey to include NetworkAnonymizationKeys.
11692 features::kPartitionConnectionsByNetworkIsolationKey},
11693 // disabled_features
11694 {});
11695
11696 const SchemefulSite kSite1(GURL("https://foo.test/"));
11697 const auto kNetworkAnonymizationKey1 =
11698 NetworkAnonymizationKey::CreateSameSite(kSite1);
11699
11700 const SchemefulSite kSite2(GURL("https://bar.test/"));
11701 const auto kNetworkAnonymizationKey2 =
11702 NetworkAnonymizationKey::CreateSameSite(kSite2);
11703
11704 const SchemefulSite kSite3(GURL("https://baz.test/"));
11705 const auto kNetworkAnonymizationKey3 =
11706 NetworkAnonymizationKey::CreateSameSite(kSite3);
11707
11708 Initialize();
11709
11710 // Create a QuicCryptoClientConfigHandle for kNetworkAnonymizationKey1, and
11711 // set the user agent.
11712 std::unique_ptr<QuicCryptoClientConfigHandle> crypto_config_handle1 =
11713 QuicSessionPoolPeer::GetCryptoConfig(factory_.get(),
11714 kNetworkAnonymizationKey1);
11715 crypto_config_handle1->GetConfig()->set_user_agent_id(kUserAgentId1);
11716 EXPECT_EQ(kUserAgentId1, crypto_config_handle1->GetConfig()->user_agent_id());
11717
11718 // Create another crypto config handle using a different
11719 // NetworkAnonymizationKey while the first one is still alive should return a
11720 // different config.
11721 std::unique_ptr<QuicCryptoClientConfigHandle> crypto_config_handle2 =
11722 QuicSessionPoolPeer::GetCryptoConfig(factory_.get(),
11723 kNetworkAnonymizationKey2);
11724 EXPECT_EQ("", crypto_config_handle2->GetConfig()->user_agent_id());
11725 crypto_config_handle2->GetConfig()->set_user_agent_id(kUserAgentId2);
11726 EXPECT_EQ(kUserAgentId1, crypto_config_handle1->GetConfig()->user_agent_id());
11727 EXPECT_EQ(kUserAgentId2, crypto_config_handle2->GetConfig()->user_agent_id());
11728
11729 // Creating handles with the same NAKs while the old handles are still alive
11730 // should result in getting the same CryptoConfigs.
11731 std::unique_ptr<QuicCryptoClientConfigHandle> crypto_config_handle1_2 =
11732 QuicSessionPoolPeer::GetCryptoConfig(factory_.get(),
11733 kNetworkAnonymizationKey1);
11734 std::unique_ptr<QuicCryptoClientConfigHandle> crypto_config_handle2_2 =
11735 QuicSessionPoolPeer::GetCryptoConfig(factory_.get(),
11736 kNetworkAnonymizationKey2);
11737 EXPECT_EQ(kUserAgentId1,
11738 crypto_config_handle1_2->GetConfig()->user_agent_id());
11739 EXPECT_EQ(kUserAgentId2,
11740 crypto_config_handle2_2->GetConfig()->user_agent_id());
11741
11742 // Destroying all handles and creating a new one with yet another
11743 // NetworkAnonymizationKey return yet another config.
11744 crypto_config_handle1.reset();
11745 crypto_config_handle2.reset();
11746 crypto_config_handle1_2.reset();
11747 crypto_config_handle2_2.reset();
11748
11749 std::unique_ptr<QuicCryptoClientConfigHandle> crypto_config_handle3 =
11750 QuicSessionPoolPeer::GetCryptoConfig(factory_.get(),
11751 kNetworkAnonymizationKey3);
11752 EXPECT_EQ("", crypto_config_handle3->GetConfig()->user_agent_id());
11753 crypto_config_handle3->GetConfig()->set_user_agent_id(kUserAgentId3);
11754 EXPECT_EQ(kUserAgentId3, crypto_config_handle3->GetConfig()->user_agent_id());
11755 crypto_config_handle3.reset();
11756
11757 // The old CryptoConfigs should be recovered when creating handles with the
11758 // same NAKs as before.
11759 crypto_config_handle2 = QuicSessionPoolPeer::GetCryptoConfig(
11760 factory_.get(), kNetworkAnonymizationKey2);
11761 crypto_config_handle1 = QuicSessionPoolPeer::GetCryptoConfig(
11762 factory_.get(), kNetworkAnonymizationKey1);
11763 crypto_config_handle3 = QuicSessionPoolPeer::GetCryptoConfig(
11764 factory_.get(), kNetworkAnonymizationKey3);
11765 EXPECT_EQ(kUserAgentId1, crypto_config_handle1->GetConfig()->user_agent_id());
11766 EXPECT_EQ(kUserAgentId2, crypto_config_handle2->GetConfig()->user_agent_id());
11767 EXPECT_EQ(kUserAgentId3, crypto_config_handle3->GetConfig()->user_agent_id());
11768 }
11769
11770 // Makes Verifies MRU behavior of the crypto config caches. Without
11771 // NetworkAnonymizationKeys enabled, behavior is uninteresting, since there's
11772 // only one cache, so nothing is ever evicted.
TEST_P(QuicSessionPoolTest,CryptoConfigCacheMRUWithNetworkAnonymizationKey)11773 TEST_P(QuicSessionPoolTest, CryptoConfigCacheMRUWithNetworkAnonymizationKey) {
11774 base::test::ScopedFeatureList feature_list;
11775 feature_list.InitWithFeatures(
11776 // enabled_features
11777 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
11778 // Need to partition connections by NetworkAnonymizationKey for
11779 // QuicSessionAliasKey to include NetworkAnonymizationKeys.
11780 features::kPartitionConnectionsByNetworkIsolationKey},
11781 // disabled_features
11782 {});
11783
11784 const int kNumSessionsToMake = kMaxRecentCryptoConfigs + 5;
11785
11786 Initialize();
11787
11788 // Make more entries than the maximum, setting a unique user agent for each,
11789 // and keeping the handles alives.
11790 std::vector<std::unique_ptr<QuicCryptoClientConfigHandle>>
11791 crypto_config_handles;
11792 std::vector<NetworkAnonymizationKey> network_anonymization_keys;
11793 for (int i = 0; i < kNumSessionsToMake; ++i) {
11794 SchemefulSite site(GURL(base::StringPrintf("https://foo%i.test/", i)));
11795 network_anonymization_keys.emplace_back(
11796 NetworkAnonymizationKey::CreateSameSite(site));
11797
11798 std::unique_ptr<QuicCryptoClientConfigHandle> crypto_config_handle =
11799 QuicSessionPoolPeer::GetCryptoConfig(factory_.get(),
11800 network_anonymization_keys[i]);
11801 crypto_config_handle->GetConfig()->set_user_agent_id(
11802 base::NumberToString(i));
11803 crypto_config_handles.emplace_back(std::move(crypto_config_handle));
11804 }
11805
11806 // Since all the handles are still alive, nothing should be evicted yet.
11807 for (int i = 0; i < kNumSessionsToMake; ++i) {
11808 SCOPED_TRACE(i);
11809 EXPECT_EQ(base::NumberToString(i),
11810 crypto_config_handles[i]->GetConfig()->user_agent_id());
11811
11812 // A new handle for the same NAK returns the same crypto config.
11813 std::unique_ptr<QuicCryptoClientConfigHandle> crypto_config_handle =
11814 QuicSessionPoolPeer::GetCryptoConfig(factory_.get(),
11815 network_anonymization_keys[i]);
11816 EXPECT_EQ(base::NumberToString(i),
11817 crypto_config_handle->GetConfig()->user_agent_id());
11818 }
11819
11820 // Destroying the only remaining handle for a NAK results in evicting entries,
11821 // until there are exactly |kMaxRecentCryptoConfigs| handles.
11822 for (int i = 0; i < kNumSessionsToMake; ++i) {
11823 SCOPED_TRACE(i);
11824 EXPECT_EQ(base::NumberToString(i),
11825 crypto_config_handles[i]->GetConfig()->user_agent_id());
11826
11827 crypto_config_handles[i].reset();
11828
11829 // A new handle for the same NAK will return a new config, if the config was
11830 // evicted. Otherwise, it will return the same one.
11831 std::unique_ptr<QuicCryptoClientConfigHandle> crypto_config_handle =
11832 QuicSessionPoolPeer::GetCryptoConfig(factory_.get(),
11833 network_anonymization_keys[i]);
11834 if (kNumSessionsToMake - i > kNumSessionsToMake) {
11835 EXPECT_EQ("", crypto_config_handle->GetConfig()->user_agent_id());
11836 } else {
11837 EXPECT_EQ(base::NumberToString(i),
11838 crypto_config_handle->GetConfig()->user_agent_id());
11839 }
11840 }
11841 }
11842
11843 // Similar to above test, but uses real requests, and doesn't keep Handles
11844 // around, so evictions happen immediately.
TEST_P(QuicSessionPoolTest,CryptoConfigCacheMRUWithRealRequestsAndWithNetworkAnonymizationKey)11845 TEST_P(QuicSessionPoolTest,
11846 CryptoConfigCacheMRUWithRealRequestsAndWithNetworkAnonymizationKey) {
11847 const int kNumSessionsToMake = kMaxRecentCryptoConfigs + 5;
11848
11849 base::test::ScopedFeatureList feature_list;
11850 feature_list.InitWithFeatures(
11851 // enabled_features
11852 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
11853 // Need to partition connections by NetworkAnonymizationKey for
11854 // QuicSessionAliasKey to include NetworkAnonymizationKeys.
11855 features::kPartitionConnectionsByNetworkIsolationKey},
11856 // disabled_features
11857 {});
11858 // Since HttpServerProperties caches the feature value, have to create a new
11859 // one.
11860 http_server_properties_ = std::make_unique<HttpServerProperties>();
11861
11862 std::vector<NetworkAnonymizationKey> network_anonymization_keys;
11863 for (int i = 0; i < kNumSessionsToMake; ++i) {
11864 SchemefulSite site(GURL(base::StringPrintf("https://foo%i.test/", i)));
11865 network_anonymization_keys.emplace_back(
11866 NetworkAnonymizationKey::CreateSameSite(site));
11867 }
11868
11869 const quic::QuicServerId kQuicServerId(
11870 kDefaultServerHostName, kDefaultServerPort, PRIVACY_MODE_DISABLED);
11871
11872 quic_params_->max_server_configs_stored_in_properties = 1;
11873 quic_params_->idle_connection_timeout = base::Seconds(500);
11874 Initialize();
11875 factory_->set_is_quic_known_to_work_on_current_network(true);
11876 crypto_client_stream_factory_.set_handshake_mode(
11877 MockCryptoClientStream::ZERO_RTT);
11878 const quic::QuicConfig* config =
11879 QuicSessionPoolPeer::GetConfig(factory_.get());
11880 EXPECT_EQ(500, config->IdleNetworkTimeout().ToSeconds());
11881 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
11882
11883 for (int i = 0; i < kNumSessionsToMake; ++i) {
11884 SCOPED_TRACE(i);
11885 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
11886
11887 QuicSessionPoolPeer::SetTaskRunner(factory_.get(), runner_.get());
11888
11889 const AlternativeService alternative_service1(
11890 kProtoQUIC, kDefaultServerHostName, kDefaultServerPort);
11891 AlternativeServiceInfoVector alternative_service_info_vector;
11892 base::Time expiration = base::Time::Now() + base::Days(1);
11893 alternative_service_info_vector.push_back(
11894 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11895 alternative_service1, expiration, {version_}));
11896 http_server_properties_->SetAlternativeServices(
11897 url::SchemeHostPort(GURL(kDefaultUrl)), network_anonymization_keys[i],
11898 alternative_service_info_vector);
11899
11900 http_server_properties_->SetMaxServerConfigsStoredInProperties(
11901 kDefaultMaxQuicServerEntries);
11902
11903 std::unique_ptr<QuicServerInfo> quic_server_info =
11904 std::make_unique<PropertiesBasedQuicServerInfo>(
11905 kQuicServerId, network_anonymization_keys[i],
11906 http_server_properties_.get());
11907
11908 // Update quic_server_info's server_config and persist it.
11909 QuicServerInfo::State* state = quic_server_info->mutable_state();
11910 // Minimum SCFG that passes config validation checks.
11911 const char scfg[] = {// SCFG
11912 0x53, 0x43, 0x46, 0x47,
11913 // num entries
11914 0x01, 0x00,
11915 // padding
11916 0x00, 0x00,
11917 // EXPY
11918 0x45, 0x58, 0x50, 0x59,
11919 // EXPY end offset
11920 0x08, 0x00, 0x00, 0x00,
11921 // Value
11922 '1', '2', '3', '4', '5', '6', '7', '8'};
11923
11924 // Create temporary strings because Persist() clears string data in |state|.
11925 string server_config(reinterpret_cast<const char*>(&scfg), sizeof(scfg));
11926 string source_address_token("test_source_address_token");
11927 string cert_sct("test_cert_sct");
11928 string chlo_hash("test_chlo_hash");
11929 string signature("test_signature");
11930 string test_cert("test_cert");
11931 std::vector<string> certs;
11932 certs.push_back(test_cert);
11933 state->server_config = server_config;
11934 state->source_address_token = source_address_token;
11935 state->cert_sct = cert_sct;
11936 state->chlo_hash = chlo_hash;
11937 state->server_config_sig = signature;
11938 state->certs = certs;
11939
11940 quic_server_info->Persist();
11941
11942 // Create a session and verify that the cached state is loaded.
11943 MockQuicData socket_data(version_);
11944 socket_data.AddReadPauseForever();
11945 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
11946 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
11947 // For the close socket message.
11948 socket_data.AddWrite(SYNCHRONOUS, ERR_IO_PENDING);
11949 socket_data.AddSocketDataToFactory(socket_factory_.get());
11950 client_maker_.Reset();
11951
11952 RequestBuilder builder(this);
11953 builder.destination = url::SchemeHostPort(
11954 url::kHttpsScheme, kDefaultServerHostName, kDefaultServerPort);
11955 builder.network_anonymization_key = network_anonymization_keys[i];
11956 int rv = builder.CallRequest();
11957 EXPECT_THAT(callback_.GetResult(rv), IsOk());
11958
11959 // While the session is still alive, there should be
11960 // kMaxRecentCryptoConfigs+1 CryptoConfigCaches alive, since active configs
11961 // don't count towards the limit.
11962 for (int j = 0; j < kNumSessionsToMake; ++j) {
11963 SCOPED_TRACE(j);
11964 EXPECT_EQ(
11965 i - (kMaxRecentCryptoConfigs + 1) < j && j <= i,
11966 !QuicSessionPoolPeer::CryptoConfigCacheIsEmpty(
11967 factory_.get(), kQuicServerId, network_anonymization_keys[j]));
11968 }
11969
11970 // Close the sessions, which should cause its CryptoConfigCache to be moved
11971 // to the MRU cache, potentially evicting the oldest entry..
11972 factory_->CloseAllSessions(ERR_FAILED, quic::QUIC_PEER_GOING_AWAY);
11973
11974 // There should now be at most kMaxRecentCryptoConfigs live
11975 // CryptoConfigCaches
11976 for (int j = 0; j < kNumSessionsToMake; ++j) {
11977 SCOPED_TRACE(j);
11978 EXPECT_EQ(
11979 i - kMaxRecentCryptoConfigs < j && j <= i,
11980 !QuicSessionPoolPeer::CryptoConfigCacheIsEmpty(
11981 factory_.get(), kQuicServerId, network_anonymization_keys[j]));
11982 }
11983 }
11984 }
11985
TEST_P(QuicSessionPoolTest,YieldAfterPackets)11986 TEST_P(QuicSessionPoolTest, YieldAfterPackets) {
11987 Initialize();
11988 factory_->set_is_quic_known_to_work_on_current_network(true);
11989 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
11990 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
11991 QuicSessionPoolPeer::SetYieldAfterPackets(factory_.get(), 0);
11992
11993 MockQuicData socket_data(version_);
11994 socket_data.AddRead(SYNCHRONOUS, ConstructServerConnectionClosePacket(1));
11995 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
11996 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
11997 socket_data.AddSocketDataToFactory(socket_factory_.get());
11998
11999 crypto_client_stream_factory_.set_handshake_mode(
12000 MockCryptoClientStream::ZERO_RTT);
12001 host_resolver_->set_synchronous_mode(true);
12002 host_resolver_->rules()->AddIPLiteralRule(kDefaultServerHostName,
12003 "192.168.0.1", "");
12004
12005 // Set up the TaskObserver to verify QuicChromiumPacketReader::StartReading
12006 // posts a task.
12007 // TODO(rtenneti): Change SpdySessionTestTaskObserver to NetTestTaskObserver??
12008 SpdySessionTestTaskObserver observer("quic_chromium_packet_reader.cc",
12009 "StartReading");
12010
12011 RequestBuilder builder(this);
12012 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
12013 EXPECT_THAT(callback_.WaitForResult(), IsOk());
12014 // Call run_loop so that QuicChromiumPacketReader::OnReadComplete() gets
12015 // called.
12016 base::RunLoop().RunUntilIdle();
12017
12018 // Verify task that the observer's executed_count is 1, which indicates
12019 // QuicChromiumPacketReader::StartReading() has posted only one task and
12020 // yielded the read.
12021 EXPECT_EQ(1u, observer.executed_count());
12022
12023 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
12024 EXPECT_FALSE(stream.get()); // Session is already closed.
12025 socket_data.ExpectAllReadDataConsumed();
12026 socket_data.ExpectAllWriteDataConsumed();
12027 }
12028
TEST_P(QuicSessionPoolTest,YieldAfterDuration)12029 TEST_P(QuicSessionPoolTest, YieldAfterDuration) {
12030 Initialize();
12031 factory_->set_is_quic_known_to_work_on_current_network(true);
12032 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
12033 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
12034 QuicSessionPoolPeer::SetYieldAfterDuration(
12035 factory_.get(), quic::QuicTime::Delta::FromMilliseconds(-1));
12036
12037 MockQuicData socket_data(version_);
12038 socket_data.AddRead(SYNCHRONOUS, ConstructServerConnectionClosePacket(1));
12039 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
12040 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
12041 socket_data.AddSocketDataToFactory(socket_factory_.get());
12042
12043 crypto_client_stream_factory_.set_handshake_mode(
12044 MockCryptoClientStream::ZERO_RTT);
12045 host_resolver_->set_synchronous_mode(true);
12046 host_resolver_->rules()->AddIPLiteralRule(kDefaultServerHostName,
12047 "192.168.0.1", "");
12048
12049 // Set up the TaskObserver to verify QuicChromiumPacketReader::StartReading
12050 // posts a task.
12051 // TODO(rtenneti): Change SpdySessionTestTaskObserver to NetTestTaskObserver??
12052 SpdySessionTestTaskObserver observer("quic_chromium_packet_reader.cc",
12053 "StartReading");
12054
12055 RequestBuilder builder(this);
12056 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
12057 EXPECT_THAT(callback_.WaitForResult(), IsOk());
12058 // Call run_loop so that QuicChromiumPacketReader::OnReadComplete() gets
12059 // called.
12060 base::RunLoop().RunUntilIdle();
12061
12062 // Verify task that the observer's executed_count is 1, which indicates
12063 // QuicChromiumPacketReader::StartReading() has posted only one task and
12064 // yielded the read.
12065 EXPECT_EQ(1u, observer.executed_count());
12066
12067 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
12068 EXPECT_FALSE(stream.get()); // Session is already closed.
12069 socket_data.ExpectAllReadDataConsumed();
12070 socket_data.ExpectAllWriteDataConsumed();
12071 }
12072
12073 // Pool to existing session with matching quic::QuicServerId
12074 // even if destination is different.
TEST_P(QuicSessionPoolTest,PoolByOrigin)12075 TEST_P(QuicSessionPoolTest, PoolByOrigin) {
12076 Initialize();
12077
12078 url::SchemeHostPort destination1(url::kHttpsScheme, "first.example.com", 443);
12079 url::SchemeHostPort destination2(url::kHttpsScheme, "second.example.com",
12080 443);
12081
12082 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
12083 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
12084
12085 MockQuicData socket_data(version_);
12086 socket_data.AddReadPauseForever();
12087 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
12088 socket_data.AddSocketDataToFactory(socket_factory_.get());
12089
12090 RequestBuilder builder1(this);
12091 builder1.destination = destination1;
12092 EXPECT_EQ(ERR_IO_PENDING, builder1.CallRequest());
12093 EXPECT_THAT(callback_.WaitForResult(), IsOk());
12094 std::unique_ptr<HttpStream> stream1 = CreateStream(&builder1.request);
12095 EXPECT_TRUE(stream1.get());
12096 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
12097
12098 // Second request returns synchronously because it pools to existing session.
12099 TestCompletionCallback callback2;
12100 RequestBuilder builder2(this);
12101 builder2.destination = destination2;
12102 builder2.callback = callback2.callback();
12103 EXPECT_EQ(OK, builder2.CallRequest());
12104 std::unique_ptr<HttpStream> stream2 = CreateStream(&builder2.request);
12105 EXPECT_TRUE(stream2.get());
12106
12107 QuicChromiumClientSession::Handle* session1 =
12108 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
12109 QuicChromiumClientSession::Handle* session2 =
12110 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
12111 EXPECT_TRUE(session1->SharesSameSession(*session2));
12112 EXPECT_EQ(quic::QuicServerId(kDefaultServerHostName, kDefaultServerPort,
12113 /*privacy_mode_enabled=*/false),
12114 session1->server_id());
12115
12116 socket_data.ExpectAllReadDataConsumed();
12117 socket_data.ExpectAllWriteDataConsumed();
12118 }
12119
12120 namespace {
12121
12122 enum DestinationType {
12123 // In pooling tests with two requests for different origins to the same
12124 // destination, the destination should be
12125 SAME_AS_FIRST, // the same as the first origin,
12126 SAME_AS_SECOND, // the same as the second origin, or
12127 DIFFERENT, // different from both.
12128 };
12129
12130 // Run QuicSessionPoolWithDestinationTest instances with all value
12131 // combinations of version and destination_type.
12132 struct PoolingTestParams {
12133 quic::ParsedQuicVersion version;
12134 DestinationType destination_type;
12135 };
12136
12137 // Used by ::testing::PrintToStringParamName().
PrintToString(const PoolingTestParams & p)12138 std::string PrintToString(const PoolingTestParams& p) {
12139 const char* destination_string = "";
12140 switch (p.destination_type) {
12141 case SAME_AS_FIRST:
12142 destination_string = "SAME_AS_FIRST";
12143 break;
12144 case SAME_AS_SECOND:
12145 destination_string = "SAME_AS_SECOND";
12146 break;
12147 case DIFFERENT:
12148 destination_string = "DIFFERENT";
12149 break;
12150 }
12151 return base::StrCat(
12152 {ParsedQuicVersionToString(p.version), "_", destination_string});
12153 }
12154
GetPoolingTestParams()12155 std::vector<PoolingTestParams> GetPoolingTestParams() {
12156 std::vector<PoolingTestParams> params;
12157 quic::ParsedQuicVersionVector all_supported_versions =
12158 AllSupportedQuicVersions();
12159 for (const quic::ParsedQuicVersion& version : all_supported_versions) {
12160 params.push_back(PoolingTestParams{version, SAME_AS_FIRST});
12161 params.push_back(PoolingTestParams{version, SAME_AS_SECOND});
12162 params.push_back(PoolingTestParams{version, DIFFERENT});
12163 }
12164 return params;
12165 }
12166
12167 } // namespace
12168
12169 class QuicSessionPoolWithDestinationTest
12170 : public QuicSessionPoolTestBase,
12171 public ::testing::TestWithParam<PoolingTestParams> {
12172 protected:
QuicSessionPoolWithDestinationTest()12173 QuicSessionPoolWithDestinationTest()
12174 : QuicSessionPoolTestBase(GetParam().version),
12175 destination_type_(GetParam().destination_type),
12176 hanging_read_(SYNCHRONOUS, ERR_IO_PENDING, 0) {}
12177
GetDestination()12178 url::SchemeHostPort GetDestination() {
12179 switch (destination_type_) {
12180 case SAME_AS_FIRST:
12181 return origin1_;
12182 case SAME_AS_SECOND:
12183 return origin2_;
12184 case DIFFERENT:
12185 return url::SchemeHostPort(url::kHttpsScheme, kDifferentHostname, 443);
12186 default:
12187 NOTREACHED();
12188 return url::SchemeHostPort();
12189 }
12190 }
12191
AddHangingSocketData()12192 void AddHangingSocketData() {
12193 auto sequenced_socket_data = std::make_unique<SequencedSocketData>(
12194 base::make_span(&hanging_read_, 1u), base::span<MockWrite>());
12195 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
12196 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
12197 }
12198
AllDataConsumed()12199 bool AllDataConsumed() {
12200 for (const auto& socket_data_ptr : sequenced_socket_data_vector_) {
12201 if (!socket_data_ptr->AllReadDataConsumed() ||
12202 !socket_data_ptr->AllWriteDataConsumed()) {
12203 return false;
12204 }
12205 }
12206 return true;
12207 }
12208
12209 DestinationType destination_type_;
12210 url::SchemeHostPort origin1_;
12211 url::SchemeHostPort origin2_;
12212 MockRead hanging_read_;
12213 std::vector<std::unique_ptr<SequencedSocketData>>
12214 sequenced_socket_data_vector_;
12215 };
12216
12217 INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
12218 QuicSessionPoolWithDestinationTest,
12219 ::testing::ValuesIn(GetPoolingTestParams()),
12220 ::testing::PrintToStringParamName());
12221
12222 // A single QUIC request fails because the certificate does not match the origin
12223 // hostname, regardless of whether it matches the alternative service hostname.
TEST_P(QuicSessionPoolWithDestinationTest,InvalidCertificate)12224 TEST_P(QuicSessionPoolWithDestinationTest, InvalidCertificate) {
12225 if (destination_type_ == DIFFERENT) {
12226 return;
12227 }
12228
12229 Initialize();
12230
12231 GURL url("https://mail.example.com/");
12232 origin1_ = url::SchemeHostPort(url);
12233
12234 // Not used for requests, but this provides a test case where the certificate
12235 // is valid for the hostname of the alternative service.
12236 origin2_ = url::SchemeHostPort(url::kHttpsScheme, "mail.example.org", 433);
12237
12238 scoped_refptr<X509Certificate> cert(
12239 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
12240 ASSERT_FALSE(cert->VerifyNameMatch(origin1_.host()));
12241 ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host()));
12242
12243 ProofVerifyDetailsChromium verify_details;
12244 verify_details.cert_verify_result.verified_cert = cert;
12245 verify_details.cert_verify_result.is_issued_by_known_root = true;
12246 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
12247
12248 AddHangingSocketData();
12249
12250 RequestBuilder builder(this);
12251 builder.destination = GetDestination();
12252 builder.url = url;
12253 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
12254 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_QUIC_HANDSHAKE_FAILED));
12255
12256 EXPECT_TRUE(AllDataConsumed());
12257 }
12258
12259 // QuicSessionRequest is pooled based on |destination| if certificate matches.
TEST_P(QuicSessionPoolWithDestinationTest,SharedCertificate)12260 TEST_P(QuicSessionPoolWithDestinationTest, SharedCertificate) {
12261 Initialize();
12262
12263 GURL url1("https://www.example.org/");
12264 GURL url2("https://mail.example.org/");
12265 origin1_ = url::SchemeHostPort(url1);
12266 origin2_ = url::SchemeHostPort(url2);
12267
12268 scoped_refptr<X509Certificate> cert(
12269 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
12270 ASSERT_TRUE(cert->VerifyNameMatch(origin1_.host()));
12271 ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host()));
12272 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
12273
12274 ProofVerifyDetailsChromium verify_details;
12275 verify_details.cert_verify_result.verified_cert = cert;
12276 verify_details.cert_verify_result.is_issued_by_known_root = true;
12277 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
12278
12279 MockQuicData socket_data(version_);
12280 socket_data.AddReadPauseForever();
12281 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
12282 socket_data.AddSocketDataToFactory(socket_factory_.get());
12283
12284 RequestBuilder builder1(this);
12285 builder1.destination = GetDestination();
12286 builder1.url = url1;
12287 EXPECT_EQ(ERR_IO_PENDING, builder1.CallRequest());
12288 EXPECT_THAT(callback_.WaitForResult(), IsOk());
12289
12290 std::unique_ptr<HttpStream> stream1 = CreateStream(&builder1.request);
12291 EXPECT_TRUE(stream1.get());
12292 EXPECT_TRUE(HasActiveSession(origin1_));
12293
12294 // Second request returns synchronously because it pools to existing session.
12295 TestCompletionCallback callback2;
12296 RequestBuilder builder2(this);
12297 builder2.destination = GetDestination();
12298 builder2.url = url2;
12299 builder2.callback = callback2.callback();
12300 EXPECT_EQ(OK, builder2.CallRequest());
12301 std::unique_ptr<HttpStream> stream2 = CreateStream(&builder2.request);
12302 EXPECT_TRUE(stream2.get());
12303
12304 QuicChromiumClientSession::Handle* session1 =
12305 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
12306 QuicChromiumClientSession::Handle* session2 =
12307 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
12308 EXPECT_TRUE(session1->SharesSameSession(*session2));
12309
12310 EXPECT_EQ(quic::QuicServerId(origin1_.host(), origin1_.port(),
12311 /*privacy_mode_enabled=*/false),
12312 session1->server_id());
12313
12314 socket_data.ExpectAllReadDataConsumed();
12315 socket_data.ExpectAllWriteDataConsumed();
12316 }
12317
12318 // QuicSessionRequest is not pooled if PrivacyMode differs.
TEST_P(QuicSessionPoolWithDestinationTest,DifferentPrivacyMode)12319 TEST_P(QuicSessionPoolWithDestinationTest, DifferentPrivacyMode) {
12320 Initialize();
12321
12322 GURL url1("https://www.example.org/");
12323 GURL url2("https://mail.example.org/");
12324 origin1_ = url::SchemeHostPort(url1);
12325 origin2_ = url::SchemeHostPort(url2);
12326
12327 url::SchemeHostPort destination = GetDestination();
12328
12329 scoped_refptr<X509Certificate> cert(
12330 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
12331 ASSERT_TRUE(cert->VerifyNameMatch(origin1_.host()));
12332 ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host()));
12333 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
12334
12335 ProofVerifyDetailsChromium verify_details1;
12336 verify_details1.cert_verify_result.verified_cert = cert;
12337 verify_details1.cert_verify_result.is_issued_by_known_root = true;
12338 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
12339
12340 ProofVerifyDetailsChromium verify_details2;
12341 verify_details2.cert_verify_result.verified_cert = cert;
12342 verify_details2.cert_verify_result.is_issued_by_known_root = true;
12343 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
12344
12345 MockQuicData socket_data1(version_);
12346 socket_data1.AddReadPauseForever();
12347 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
12348 socket_data1.AddSocketDataToFactory(socket_factory_.get());
12349 client_maker_.Reset();
12350 MockQuicData socket_data2(version_);
12351 socket_data2.AddReadPauseForever();
12352 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
12353 socket_data2.AddSocketDataToFactory(socket_factory_.get());
12354
12355 RequestBuilder builder1(this);
12356 builder1.destination = destination;
12357 builder1.privacy_mode = PRIVACY_MODE_DISABLED;
12358 builder1.url = url1;
12359 EXPECT_EQ(ERR_IO_PENDING, builder1.CallRequest());
12360 EXPECT_EQ(OK, callback_.WaitForResult());
12361 std::unique_ptr<HttpStream> stream1 = CreateStream(&builder1.request);
12362 EXPECT_TRUE(stream1.get());
12363 EXPECT_TRUE(HasActiveSession(origin1_));
12364
12365 TestCompletionCallback callback2;
12366 RequestBuilder builder2(this);
12367 builder2.destination = destination;
12368 builder2.privacy_mode = PRIVACY_MODE_ENABLED;
12369 builder2.url = url2;
12370 builder2.callback = callback2.callback();
12371 EXPECT_EQ(ERR_IO_PENDING, builder2.CallRequest());
12372 EXPECT_EQ(OK, callback2.WaitForResult());
12373 std::unique_ptr<HttpStream> stream2 = CreateStream(&builder2.request);
12374 EXPECT_TRUE(stream2.get());
12375
12376 // |request2| does not pool to the first session, because PrivacyMode does not
12377 // match. Instead, another session is opened to the same destination, but
12378 // with a different quic::QuicServerId.
12379 QuicChromiumClientSession::Handle* session1 =
12380 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
12381 QuicChromiumClientSession::Handle* session2 =
12382 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
12383 EXPECT_FALSE(session1->SharesSameSession(*session2));
12384
12385 EXPECT_EQ(quic::QuicServerId(origin1_.host(), origin1_.port(),
12386 /*privacy_mode_enabled=*/false),
12387 session1->server_id());
12388 EXPECT_EQ(quic::QuicServerId(origin2_.host(), origin2_.port(),
12389 /*privacy_mode_enabled=*/true),
12390 session2->server_id());
12391
12392 socket_data1.ExpectAllReadDataConsumed();
12393 socket_data1.ExpectAllWriteDataConsumed();
12394 socket_data2.ExpectAllReadDataConsumed();
12395 socket_data2.ExpectAllWriteDataConsumed();
12396 }
12397
12398 // QuicSessionRequest is not pooled if the secure_dns_policy field differs.
TEST_P(QuicSessionPoolWithDestinationTest,DifferentSecureDnsPolicy)12399 TEST_P(QuicSessionPoolWithDestinationTest, DifferentSecureDnsPolicy) {
12400 Initialize();
12401
12402 GURL url1("https://www.example.org/");
12403 GURL url2("https://mail.example.org/");
12404 origin1_ = url::SchemeHostPort(url1);
12405 origin2_ = url::SchemeHostPort(url2);
12406
12407 url::SchemeHostPort destination = GetDestination();
12408
12409 scoped_refptr<X509Certificate> cert(
12410 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
12411 ASSERT_TRUE(cert->VerifyNameMatch(origin1_.host()));
12412 ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host()));
12413 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
12414
12415 ProofVerifyDetailsChromium verify_details1;
12416 verify_details1.cert_verify_result.verified_cert = cert;
12417 verify_details1.cert_verify_result.is_issued_by_known_root = true;
12418 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
12419
12420 ProofVerifyDetailsChromium verify_details2;
12421 verify_details2.cert_verify_result.verified_cert = cert;
12422 verify_details2.cert_verify_result.is_issued_by_known_root = true;
12423 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
12424
12425 MockQuicData socket_data1(version_);
12426 socket_data1.AddReadPauseForever();
12427 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
12428 socket_data1.AddSocketDataToFactory(socket_factory_.get());
12429 client_maker_.Reset();
12430 MockQuicData socket_data2(version_);
12431 socket_data2.AddReadPauseForever();
12432 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
12433 socket_data2.AddSocketDataToFactory(socket_factory_.get());
12434
12435 RequestBuilder builder1(this);
12436 builder1.destination = destination;
12437 builder1.secure_dns_policy = SecureDnsPolicy::kAllow;
12438 builder1.url = url1;
12439 EXPECT_EQ(ERR_IO_PENDING, builder1.CallRequest());
12440 EXPECT_EQ(OK, callback_.WaitForResult());
12441 std::unique_ptr<HttpStream> stream1 = CreateStream(&builder1.request);
12442 EXPECT_TRUE(stream1.get());
12443 EXPECT_TRUE(HasActiveSession(origin1_));
12444
12445 TestCompletionCallback callback2;
12446 RequestBuilder builder2(this);
12447 builder2.destination = destination;
12448 builder2.secure_dns_policy = SecureDnsPolicy::kDisable;
12449 builder2.url = url2;
12450 builder2.callback = callback2.callback();
12451 EXPECT_EQ(ERR_IO_PENDING, builder2.CallRequest());
12452 EXPECT_EQ(OK, callback2.WaitForResult());
12453 std::unique_ptr<HttpStream> stream2 = CreateStream(&builder2.request);
12454 EXPECT_TRUE(stream2.get());
12455
12456 // |request2| does not pool to the first session, because |secure_dns_policy|
12457 // does not match.
12458 QuicChromiumClientSession::Handle* session1 =
12459 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
12460 QuicChromiumClientSession::Handle* session2 =
12461 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
12462 EXPECT_FALSE(session1->SharesSameSession(*session2));
12463 socket_data1.ExpectAllReadDataConsumed();
12464 socket_data1.ExpectAllWriteDataConsumed();
12465 socket_data2.ExpectAllReadDataConsumed();
12466 socket_data2.ExpectAllWriteDataConsumed();
12467 }
12468
12469 // QuicSessionRequest is not pooled if the ProxyChain field differs.
TEST_P(QuicSessionPoolWithDestinationTest,DifferentProxyChain)12470 TEST_P(QuicSessionPoolWithDestinationTest, DifferentProxyChain) {
12471 Initialize();
12472
12473 GURL url1("https://www.example.org/");
12474 GURL url2("https://mail.example.org/");
12475 GURL proxy1(kProxy1Url);
12476 GURL proxy2(kProxy2Url);
12477 origin1_ = url::SchemeHostPort(url1);
12478 origin2_ = url::SchemeHostPort(url2);
12479 auto proxy1_origin = url::SchemeHostPort(proxy1);
12480 auto proxy2_origin = url::SchemeHostPort(proxy2);
12481
12482 url::SchemeHostPort destination = GetDestination();
12483
12484 scoped_refptr<X509Certificate> cert(
12485 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
12486 ASSERT_TRUE(cert->VerifyNameMatch(origin1_.host()));
12487 ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host()));
12488 ASSERT_TRUE(cert->VerifyNameMatch(proxy1_origin.host()));
12489 ASSERT_TRUE(cert->VerifyNameMatch(proxy2_origin.host()));
12490
12491 ProofVerifyDetailsChromium verify_details1;
12492 verify_details1.cert_verify_result.verified_cert = cert;
12493 verify_details1.cert_verify_result.is_issued_by_known_root = true;
12494 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
12495
12496 ProofVerifyDetailsChromium verify_details2;
12497 verify_details2.cert_verify_result.verified_cert = cert;
12498 verify_details2.cert_verify_result.is_issued_by_known_root = true;
12499 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
12500
12501 client_maker_.set_use_priority_header(false);
12502
12503 QuicTestPacketMaker endpoint_maker1(
12504 version_,
12505 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
12506 context_.clock(), origin1_.host(), quic::Perspective::IS_CLIENT,
12507 /*client_priority_uses_incremental=*/true,
12508 /*use_priority_header=*/true);
12509
12510 const uint64_t stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
12511 MockQuicData socket_data1(version_);
12512 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
12513 socket_data1.AddWrite(
12514 SYNCHRONOUS, ConstructConnectUdpRequestPacket(
12515 2, stream_id, proxy1.host(),
12516 "/.well-known/masque/udp/www.example.org/443/", false));
12517 socket_data1.AddRead(ASYNC, ConstructServerSettingsPacket(3));
12518 socket_data1.AddRead(ASYNC, ConstructOkResponsePacket(4, stream_id, true));
12519 socket_data1.AddReadPauseForever();
12520 socket_data1.AddWrite(ASYNC, client_maker_.MakeAckPacket(3, 3, 4, 3));
12521 socket_data1.AddWrite(ASYNC,
12522 ConstructClientH3DatagramPacket(
12523 4, stream_id, kConnectUdpContextId,
12524 endpoint_maker1.MakeInitialSettingsPacket(1)));
12525 socket_data1.AddSocketDataToFactory(socket_factory_.get());
12526
12527 QuicTestPacketMaker endpoint_maker2(
12528 version_,
12529 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
12530 context_.clock(), origin2_.host(), quic::Perspective::IS_CLIENT,
12531 /*client_priority_uses_incremental=*/true,
12532 /*use_priority_header=*/true);
12533 client_maker_.Reset();
12534 server_maker_.Reset();
12535
12536 MockQuicData socket_data2(version_);
12537 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
12538 socket_data2.AddWrite(
12539 SYNCHRONOUS, ConstructConnectUdpRequestPacket(
12540 2, stream_id, proxy2.host(),
12541 "/.well-known/masque/udp/mail.example.org/443/", false));
12542 socket_data2.AddRead(ASYNC, ConstructServerSettingsPacket(3));
12543 socket_data2.AddRead(ASYNC, ConstructOkResponsePacket(4, stream_id, true));
12544 socket_data2.AddReadPauseForever();
12545 socket_data2.AddWrite(ASYNC, client_maker_.MakeAckPacket(3, 3, 4, 3));
12546 socket_data2.AddWrite(ASYNC,
12547 ConstructClientH3DatagramPacket(
12548 4, stream_id, kConnectUdpContextId,
12549 endpoint_maker2.MakeInitialSettingsPacket(1)));
12550 socket_data2.AddSocketDataToFactory(socket_factory_.get());
12551
12552 auto proxy_chain1 = ProxyChain::ForIpProtection({
12553 ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_QUIC,
12554 proxy1_origin.host(), 443),
12555 });
12556 EXPECT_TRUE(proxy_chain1.IsValid());
12557
12558 auto proxy_chain2 = ProxyChain::ForIpProtection({
12559 ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_QUIC,
12560 proxy2_origin.host(), 443),
12561 });
12562 EXPECT_TRUE(proxy_chain2.IsValid());
12563 EXPECT_NE(proxy_chain1, proxy_chain2);
12564
12565 RequestBuilder builder1(this);
12566 builder1.destination = destination;
12567 builder1.proxy_chain = proxy_chain1;
12568 builder1.http_user_agent_settings = &http_user_agent_settings_;
12569 builder1.url = url1;
12570 EXPECT_EQ(ERR_IO_PENDING, builder1.CallRequest());
12571 ASSERT_EQ(OK, callback_.WaitForResult());
12572 std::unique_ptr<HttpStream> stream1 = CreateStream(&builder1.request);
12573 EXPECT_TRUE(stream1.get());
12574 EXPECT_TRUE(
12575 HasActiveSession(origin1_, NetworkAnonymizationKey(), proxy_chain1));
12576
12577 // There are ACKs still pending at this point, so to avoid confusing logs let
12578 // those finish before proceeding.
12579 RunUntilIdle();
12580
12581 TestCompletionCallback callback2;
12582 RequestBuilder builder2(this);
12583 builder2.destination = destination;
12584 builder2.proxy_chain = proxy_chain2;
12585 builder2.http_user_agent_settings = &http_user_agent_settings_;
12586 builder2.url = url2;
12587 builder2.callback = callback2.callback();
12588 EXPECT_EQ(ERR_IO_PENDING, builder2.CallRequest());
12589 EXPECT_EQ(OK, callback2.WaitForResult());
12590 std::unique_ptr<HttpStream> stream2 = CreateStream(&builder2.request);
12591 EXPECT_TRUE(stream2.get());
12592
12593 // `request2` does not pool to the first session, because `proxy_chain` does
12594 // not match.
12595 QuicChromiumClientSession::Handle* session1 =
12596 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
12597 QuicChromiumClientSession::Handle* session2 =
12598 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
12599 EXPECT_FALSE(session1->SharesSameSession(*session2));
12600
12601 // Ensure the session finishes creating before proceeding.
12602 RunUntilIdle();
12603
12604 socket_data1.ExpectAllReadDataConsumed();
12605 socket_data1.ExpectAllWriteDataConsumed();
12606 socket_data2.ExpectAllReadDataConsumed();
12607 socket_data2.ExpectAllWriteDataConsumed();
12608 }
12609
12610 // QuicSessionRequest is not pooled if the SessionUsage field differs.
TEST_P(QuicSessionPoolWithDestinationTest,DifferentSessionUsage)12611 TEST_P(QuicSessionPoolWithDestinationTest, DifferentSessionUsage) {
12612 Initialize();
12613
12614 GURL url1("https://www.example.org/");
12615 GURL url2("https://mail.example.org/");
12616 origin1_ = url::SchemeHostPort(url1);
12617 origin2_ = url::SchemeHostPort(url2);
12618
12619 url::SchemeHostPort destination = GetDestination();
12620
12621 scoped_refptr<X509Certificate> cert(
12622 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
12623 ASSERT_TRUE(cert->VerifyNameMatch(origin1_.host()));
12624 ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host()));
12625 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
12626
12627 ProofVerifyDetailsChromium verify_details1;
12628 verify_details1.cert_verify_result.verified_cert = cert;
12629 verify_details1.cert_verify_result.is_issued_by_known_root = true;
12630 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
12631
12632 ProofVerifyDetailsChromium verify_details2;
12633 verify_details2.cert_verify_result.verified_cert = cert;
12634 verify_details2.cert_verify_result.is_issued_by_known_root = true;
12635 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
12636
12637 MockQuicData socket_data1(version_);
12638 socket_data1.AddReadPauseForever();
12639 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
12640 socket_data1.AddSocketDataToFactory(socket_factory_.get());
12641 client_maker_.Reset();
12642 MockQuicData socket_data2(version_);
12643 socket_data2.AddReadPauseForever();
12644 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
12645 socket_data2.AddSocketDataToFactory(socket_factory_.get());
12646
12647 RequestBuilder builder1(this);
12648 builder1.destination = destination;
12649 builder1.session_usage = SessionUsage::kDestination;
12650 builder1.url = url1;
12651 EXPECT_EQ(ERR_IO_PENDING, builder1.CallRequest());
12652 EXPECT_EQ(OK, callback_.WaitForResult());
12653 std::unique_ptr<HttpStream> stream1 = CreateStream(&builder1.request);
12654 EXPECT_TRUE(stream1.get());
12655 EXPECT_TRUE(HasActiveSession(origin1_));
12656
12657 TestCompletionCallback callback2;
12658 RequestBuilder builder2(this);
12659 builder2.destination = destination;
12660 builder2.session_usage = SessionUsage::kProxy;
12661 builder2.url = url2;
12662 builder2.callback = callback2.callback();
12663 EXPECT_EQ(ERR_IO_PENDING, builder2.CallRequest());
12664 EXPECT_EQ(OK, callback2.WaitForResult());
12665 std::unique_ptr<HttpStream> stream2 = CreateStream(&builder2.request);
12666 EXPECT_TRUE(stream2.get());
12667
12668 // `request2` does not pool to the first session, because `session_usage`
12669 // does not match.
12670 QuicChromiumClientSession::Handle* session1 =
12671 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
12672 QuicChromiumClientSession::Handle* session2 =
12673 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
12674 EXPECT_FALSE(session1->SharesSameSession(*session2));
12675 socket_data1.ExpectAllReadDataConsumed();
12676 socket_data1.ExpectAllWriteDataConsumed();
12677 socket_data2.ExpectAllReadDataConsumed();
12678 socket_data2.ExpectAllWriteDataConsumed();
12679 }
12680
12681 // QuicSessionRequest is not pooled if certificate does not match its origin.
TEST_P(QuicSessionPoolWithDestinationTest,DisjointCertificate)12682 TEST_P(QuicSessionPoolWithDestinationTest, DisjointCertificate) {
12683 Initialize();
12684
12685 GURL url1("https://news.example.org/");
12686 GURL url2("https://mail.example.com/");
12687 origin1_ = url::SchemeHostPort(url1);
12688 origin2_ = url::SchemeHostPort(url2);
12689
12690 url::SchemeHostPort destination = GetDestination();
12691
12692 scoped_refptr<X509Certificate> cert1(
12693 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
12694 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_.host()));
12695 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_.host()));
12696 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
12697
12698 ProofVerifyDetailsChromium verify_details1;
12699 verify_details1.cert_verify_result.verified_cert = cert1;
12700 verify_details1.cert_verify_result.is_issued_by_known_root = true;
12701 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
12702
12703 scoped_refptr<X509Certificate> cert2(
12704 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
12705 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_.host()));
12706 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
12707
12708 ProofVerifyDetailsChromium verify_details2;
12709 verify_details2.cert_verify_result.verified_cert = cert2;
12710 verify_details2.cert_verify_result.is_issued_by_known_root = true;
12711 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
12712
12713 MockQuicData socket_data1(version_);
12714 socket_data1.AddReadPauseForever();
12715 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
12716 socket_data1.AddSocketDataToFactory(socket_factory_.get());
12717 client_maker_.Reset();
12718 MockQuicData socket_data2(version_);
12719 socket_data2.AddReadPauseForever();
12720 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
12721 socket_data2.AddSocketDataToFactory(socket_factory_.get());
12722
12723 RequestBuilder builder1(this);
12724 builder1.destination = destination;
12725 builder1.url = url1;
12726 EXPECT_EQ(ERR_IO_PENDING, builder1.CallRequest());
12727 EXPECT_THAT(callback_.WaitForResult(), IsOk());
12728 std::unique_ptr<HttpStream> stream1 = CreateStream(&builder1.request);
12729 EXPECT_TRUE(stream1.get());
12730 EXPECT_TRUE(HasActiveSession(origin1_));
12731
12732 TestCompletionCallback callback2;
12733 RequestBuilder builder2(this);
12734 builder2.destination = destination;
12735 builder2.url = url2;
12736 builder2.callback = callback2.callback();
12737 EXPECT_EQ(ERR_IO_PENDING, builder2.CallRequest());
12738 EXPECT_THAT(callback2.WaitForResult(), IsOk());
12739 std::unique_ptr<HttpStream> stream2 = CreateStream(&builder2.request);
12740 EXPECT_TRUE(stream2.get());
12741
12742 // |request2| does not pool to the first session, because the certificate does
12743 // not match. Instead, another session is opened to the same destination, but
12744 // with a different quic::QuicServerId.
12745 QuicChromiumClientSession::Handle* session1 =
12746 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
12747 QuicChromiumClientSession::Handle* session2 =
12748 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
12749 EXPECT_FALSE(session1->SharesSameSession(*session2));
12750
12751 EXPECT_EQ(quic::QuicServerId(origin1_.host(), origin1_.port(),
12752 /*privacy_mode_enabled=*/false),
12753 session1->server_id());
12754 EXPECT_EQ(quic::QuicServerId(origin2_.host(), origin2_.port(),
12755 /*privacy_mode_enabled=*/false),
12756 session2->server_id());
12757
12758 socket_data1.ExpectAllReadDataConsumed();
12759 socket_data1.ExpectAllWriteDataConsumed();
12760 socket_data2.ExpectAllReadDataConsumed();
12761 socket_data2.ExpectAllWriteDataConsumed();
12762 }
12763
12764 // This test verifies that QuicSessionPool::ClearCachedStatesInCryptoConfig
12765 // correctly transform an origin filter to a ServerIdFilter. Whether the
12766 // deletion itself works correctly is tested in QuicCryptoClientConfigTest.
TEST_P(QuicSessionPoolTest,ClearCachedStatesInCryptoConfig)12767 TEST_P(QuicSessionPoolTest, ClearCachedStatesInCryptoConfig) {
12768 Initialize();
12769 // Need to hold onto this through the test, to keep the QuicCryptoClientConfig
12770 // alive.
12771 std::unique_ptr<QuicCryptoClientConfigHandle> crypto_config_handle =
12772 QuicSessionPoolPeer::GetCryptoConfig(factory_.get(),
12773 NetworkAnonymizationKey());
12774
12775 struct TestCase {
12776 TestCase(const std::string& host,
12777 int port,
12778 PrivacyMode privacy_mode,
12779 quic::QuicCryptoClientConfig* crypto_config)
12780 : server_id(host, port, privacy_mode),
12781 state(crypto_config->LookupOrCreate(server_id)) {
12782 std::vector<string> certs(1);
12783 certs[0] = "cert";
12784 state->SetProof(certs, "cert_sct", "chlo_hash", "signature");
12785 state->set_source_address_token("TOKEN");
12786 state->SetProofValid();
12787
12788 EXPECT_FALSE(state->certs().empty());
12789 }
12790
12791 quic::QuicServerId server_id;
12792 raw_ptr<quic::QuicCryptoClientConfig::CachedState> state;
12793 } test_cases[] = {TestCase("www.google.com", 443, PRIVACY_MODE_DISABLED,
12794 crypto_config_handle->GetConfig()),
12795 TestCase("www.example.com", 443, PRIVACY_MODE_DISABLED,
12796 crypto_config_handle->GetConfig()),
12797 TestCase("www.example.com", 4433, PRIVACY_MODE_DISABLED,
12798 crypto_config_handle->GetConfig())};
12799
12800 // Clear cached states for the origin https://www.example.com:4433.
12801 GURL origin("https://www.example.com:4433");
12802 factory_->ClearCachedStatesInCryptoConfig(base::BindRepeating(
12803 static_cast<bool (*)(const GURL&, const GURL&)>(::operator==), origin));
12804 EXPECT_FALSE(test_cases[0].state->certs().empty());
12805 EXPECT_FALSE(test_cases[1].state->certs().empty());
12806 EXPECT_TRUE(test_cases[2].state->certs().empty());
12807
12808 // Clear all cached states.
12809 factory_->ClearCachedStatesInCryptoConfig(
12810 base::RepeatingCallback<bool(const GURL&)>());
12811 EXPECT_TRUE(test_cases[0].state->certs().empty());
12812 EXPECT_TRUE(test_cases[1].state->certs().empty());
12813 EXPECT_TRUE(test_cases[2].state->certs().empty());
12814 }
12815
12816 // Passes connection options and client connection options to QuicSessionPool,
12817 // then checks that its internal quic::QuicConfig is correct.
TEST_P(QuicSessionPoolTest,ConfigConnectionOptions)12818 TEST_P(QuicSessionPoolTest, ConfigConnectionOptions) {
12819 quic_params_->connection_options.push_back(quic::kTIME);
12820 quic_params_->connection_options.push_back(quic::kTBBR);
12821 quic_params_->connection_options.push_back(quic::kREJ);
12822
12823 quic_params_->client_connection_options.push_back(quic::kTBBR);
12824 quic_params_->client_connection_options.push_back(quic::k1RTT);
12825
12826 Initialize();
12827
12828 const quic::QuicConfig* config =
12829 QuicSessionPoolPeer::GetConfig(factory_.get());
12830 EXPECT_EQ(quic_params_->connection_options, config->SendConnectionOptions());
12831 EXPECT_TRUE(config->HasClientRequestedIndependentOption(
12832 quic::kTBBR, quic::Perspective::IS_CLIENT));
12833 EXPECT_TRUE(config->HasClientRequestedIndependentOption(
12834 quic::k1RTT, quic::Perspective::IS_CLIENT));
12835 }
12836
12837 // Verifies that the host resolver uses the request priority passed to
12838 // QuicSessionRequest::Request().
TEST_P(QuicSessionPoolTest,HostResolverUsesRequestPriority)12839 TEST_P(QuicSessionPoolTest, HostResolverUsesRequestPriority) {
12840 Initialize();
12841 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
12842 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
12843
12844 MockQuicData socket_data(version_);
12845 socket_data.AddReadPauseForever();
12846 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
12847 socket_data.AddSocketDataToFactory(socket_factory_.get());
12848
12849 RequestBuilder builder(this);
12850 builder.priority = MAXIMUM_PRIORITY;
12851 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
12852 EXPECT_THAT(callback_.WaitForResult(), IsOk());
12853 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
12854 EXPECT_TRUE(stream.get());
12855
12856 EXPECT_EQ(MAXIMUM_PRIORITY, host_resolver_->last_request_priority());
12857
12858 socket_data.ExpectAllReadDataConsumed();
12859 socket_data.ExpectAllWriteDataConsumed();
12860 }
12861
TEST_P(QuicSessionPoolTest,HostResolverRequestReprioritizedOnSetPriority)12862 TEST_P(QuicSessionPoolTest, HostResolverRequestReprioritizedOnSetPriority) {
12863 Initialize();
12864 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
12865 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
12866
12867 MockQuicData socket_data(version_);
12868 socket_data.AddReadPauseForever();
12869 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
12870 socket_data.AddSocketDataToFactory(socket_factory_.get());
12871
12872 RequestBuilder builder(this);
12873 builder.priority = MAXIMUM_PRIORITY;
12874 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
12875 EXPECT_EQ(MAXIMUM_PRIORITY, host_resolver_->last_request_priority());
12876 EXPECT_EQ(MAXIMUM_PRIORITY, host_resolver_->request_priority(1));
12877
12878 RequestBuilder builder2(this);
12879 builder2.priority = DEFAULT_PRIORITY;
12880 builder2.url = GURL(kServer2Url);
12881 EXPECT_EQ(ERR_IO_PENDING, builder2.CallRequest());
12882 EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_->last_request_priority());
12883 EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_->request_priority(2));
12884
12885 builder.request.SetPriority(LOWEST);
12886 EXPECT_EQ(LOWEST, host_resolver_->request_priority(1));
12887 EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_->request_priority(2));
12888 }
12889
12890 // Verifies that the host resolver uses the disable secure DNS setting and
12891 // NetworkAnonymizationKey passed to QuicSessionRequest::Request().
TEST_P(QuicSessionPoolTest,HostResolverUsesParams)12892 TEST_P(QuicSessionPoolTest, HostResolverUsesParams) {
12893 const SchemefulSite kSite1(GURL("https://foo.test/"));
12894 const SchemefulSite kSite2(GURL("https://bar.test/"));
12895 const auto kNetworkAnonymizationKey =
12896 NetworkAnonymizationKey::CreateSameSite(kSite1);
12897 base::test::ScopedFeatureList feature_list;
12898 feature_list.InitWithFeatures(
12899 // enabled_features
12900 {features::kPartitionConnectionsByNetworkIsolationKey,
12901 features::kSplitHostCacheByNetworkIsolationKey},
12902 // disabled_features
12903 {});
12904
12905 Initialize();
12906 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
12907 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
12908
12909 MockQuicData socket_data(version_);
12910 socket_data.AddReadPauseForever();
12911 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
12912 socket_data.AddSocketDataToFactory(socket_factory_.get());
12913
12914 RequestBuilder builder(this);
12915 builder.network_anonymization_key = kNetworkAnonymizationKey;
12916 builder.secure_dns_policy = SecureDnsPolicy::kDisable;
12917 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
12918 EXPECT_THAT(callback_.WaitForResult(), IsOk());
12919 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
12920 EXPECT_TRUE(stream.get());
12921
12922 EXPECT_EQ(net::SecureDnsPolicy::kDisable,
12923 host_resolver_->last_secure_dns_policy());
12924 ASSERT_TRUE(
12925 host_resolver_->last_request_network_anonymization_key().has_value());
12926 EXPECT_EQ(kNetworkAnonymizationKey,
12927 host_resolver_->last_request_network_anonymization_key().value());
12928
12929 socket_data.ExpectAllReadDataConsumed();
12930 socket_data.ExpectAllWriteDataConsumed();
12931 }
12932
TEST_P(QuicSessionPoolTest,ConfigMaxTimeBeforeCryptoHandshake)12933 TEST_P(QuicSessionPoolTest, ConfigMaxTimeBeforeCryptoHandshake) {
12934 quic_params_->max_time_before_crypto_handshake = base::Seconds(11);
12935 quic_params_->max_idle_time_before_crypto_handshake = base::Seconds(13);
12936 Initialize();
12937
12938 const quic::QuicConfig* config =
12939 QuicSessionPoolPeer::GetConfig(factory_.get());
12940 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(11),
12941 config->max_time_before_crypto_handshake());
12942 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(13),
12943 config->max_idle_time_before_crypto_handshake());
12944 }
12945
12946 // Verify ResultAfterQuicSessionCreationCallback behavior when the crypto
12947 // handshake fails.
TEST_P(QuicSessionPoolTest,ResultAfterQuicSessionCreationCallbackFail)12948 TEST_P(QuicSessionPoolTest, ResultAfterQuicSessionCreationCallbackFail) {
12949 Initialize();
12950 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
12951 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
12952
12953 MockQuicData socket_data(version_);
12954 socket_data.AddRead(SYNCHRONOUS, ERR_FAILED);
12955 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
12956 socket_data.AddSocketDataToFactory(socket_factory_.get());
12957
12958 RequestBuilder builder(this);
12959 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
12960
12961 TestCompletionCallback quic_session_callback;
12962 EXPECT_TRUE(builder.request.WaitForQuicSessionCreation(
12963 quic_session_callback.callback()));
12964
12965 base::RunLoop().RunUntilIdle();
12966 EXPECT_TRUE(quic_session_callback.have_result());
12967 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, quic_session_callback.WaitForResult());
12968
12969 // Calling WaitForQuicSessionCreation() a second time should return
12970 // false since the session has been created.
12971 EXPECT_FALSE(builder.request.WaitForQuicSessionCreation(
12972 quic_session_callback.callback()));
12973
12974 EXPECT_TRUE(callback_.have_result());
12975 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
12976 }
12977
12978 // Verify ResultAfterQuicSessionCreationCallback behavior when the crypto
12979 // handshake succeeds synchronously.
TEST_P(QuicSessionPoolTest,ResultAfterQuicSessionCreationCallbackSuccessSync)12980 TEST_P(QuicSessionPoolTest, ResultAfterQuicSessionCreationCallbackSuccessSync) {
12981 Initialize();
12982 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
12983 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
12984
12985 MockQuicData socket_data(version_);
12986 socket_data.AddRead(SYNCHRONOUS, OK);
12987 socket_data.AddWrite(SYNCHRONOUS, OK);
12988 socket_data.AddSocketDataToFactory(socket_factory_.get());
12989
12990 RequestBuilder builder(this);
12991 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
12992
12993 TestCompletionCallback quic_session_callback;
12994 EXPECT_TRUE(builder.request.WaitForQuicSessionCreation(
12995 quic_session_callback.callback()));
12996
12997 EXPECT_EQ(OK, quic_session_callback.WaitForResult());
12998
12999 // Calling WaitForQuicSessionCreation() a second time should return
13000 // false since the session has been created.
13001 EXPECT_FALSE(builder.request.WaitForQuicSessionCreation(
13002 quic_session_callback.callback()));
13003
13004 EXPECT_TRUE(callback_.have_result());
13005 EXPECT_EQ(OK, callback_.WaitForResult());
13006 }
13007
13008 // Verify ResultAfterQuicSessionCreationCallback behavior when the crypto
13009 // handshake succeeds asynchronously.
TEST_P(QuicSessionPoolTest,ResultAfterQuicSessionCreationCallbackSuccessAsync)13010 TEST_P(QuicSessionPoolTest,
13011 ResultAfterQuicSessionCreationCallbackSuccessAsync) {
13012 Initialize();
13013 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
13014 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
13015
13016 crypto_client_stream_factory_.set_handshake_mode(
13017 MockCryptoClientStream::ZERO_RTT);
13018
13019 MockQuicData socket_data(version_);
13020 socket_data.AddRead(SYNCHRONOUS, OK);
13021 socket_data.AddWrite(SYNCHRONOUS, OK);
13022 socket_data.AddSocketDataToFactory(socket_factory_.get());
13023
13024 RequestBuilder builder(this);
13025 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
13026
13027 TestCompletionCallback quic_session_callback;
13028 EXPECT_TRUE(builder.request.WaitForQuicSessionCreation(
13029 quic_session_callback.callback()));
13030
13031 EXPECT_EQ(ERR_IO_PENDING, quic_session_callback.WaitForResult());
13032
13033 // Send Crypto handshake so connect will call back.
13034 crypto_client_stream_factory_.last_stream()
13035 ->NotifySessionOneRttKeyAvailable();
13036 // Calling WaitForQuicSessionCreation() a second time should return
13037 // false since the session has been created.
13038 EXPECT_FALSE(builder.request.WaitForQuicSessionCreation(
13039 quic_session_callback.callback()));
13040
13041 EXPECT_EQ(OK, callback_.WaitForResult());
13042 }
13043
13044 // Verify ResultAfterHostResolutionCallback behavior when host resolution
13045 // succeeds asynchronously, then crypto handshake fails synchronously.
TEST_P(QuicSessionPoolTest,ResultAfterHostResolutionCallbackAsyncSync)13046 TEST_P(QuicSessionPoolTest, ResultAfterHostResolutionCallbackAsyncSync) {
13047 Initialize();
13048 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
13049 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
13050
13051 host_resolver_->set_ondemand_mode(true);
13052
13053 MockQuicData socket_data(version_);
13054 socket_data.AddRead(SYNCHRONOUS, ERR_FAILED);
13055 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
13056 socket_data.AddSocketDataToFactory(socket_factory_.get());
13057
13058 RequestBuilder builder(this);
13059 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
13060
13061 TestCompletionCallback host_resolution_callback;
13062 EXPECT_TRUE(builder.request.WaitForHostResolution(
13063 host_resolution_callback.callback()));
13064
13065 // |host_resolver_| has not finished host resolution at this point, so
13066 // |host_resolution_callback| should not have a result.
13067 base::RunLoop().RunUntilIdle();
13068 EXPECT_FALSE(host_resolution_callback.have_result());
13069
13070 // Allow |host_resolver_| to finish host resolution.
13071 // Since the request fails immediately after host resolution (getting
13072 // ERR_FAILED from socket reads/writes), |host_resolution_callback| should be
13073 // called with ERR_QUIC_PROTOCOL_ERROR since that's the next result in
13074 // forming the connection.
13075 host_resolver_->ResolveAllPending();
13076 base::RunLoop().RunUntilIdle();
13077 EXPECT_TRUE(host_resolution_callback.have_result());
13078 EXPECT_EQ(ERR_IO_PENDING, host_resolution_callback.WaitForResult());
13079
13080 // Calling WaitForHostResolution() a second time should return
13081 // false since host resolution has finished already.
13082 EXPECT_FALSE(builder.request.WaitForHostResolution(
13083 host_resolution_callback.callback()));
13084
13085 EXPECT_TRUE(callback_.have_result());
13086 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
13087 }
13088
13089 // Verify ResultAfterHostResolutionCallback behavior when host resolution
13090 // succeeds asynchronously, then crypto handshake fails asynchronously.
TEST_P(QuicSessionPoolTest,ResultAfterHostResolutionCallbackAsyncAsync)13091 TEST_P(QuicSessionPoolTest, ResultAfterHostResolutionCallbackAsyncAsync) {
13092 Initialize();
13093 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
13094 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
13095
13096 host_resolver_->set_ondemand_mode(true);
13097 crypto_client_stream_factory_.set_handshake_mode(
13098 MockCryptoClientStream::ZERO_RTT);
13099 factory_->set_is_quic_known_to_work_on_current_network(false);
13100
13101 MockQuicData socket_data(version_);
13102 socket_data.AddReadPause();
13103 socket_data.AddRead(ASYNC, ERR_FAILED);
13104 socket_data.AddWrite(ASYNC, ERR_FAILED);
13105 socket_data.AddSocketDataToFactory(socket_factory_.get());
13106
13107 RequestBuilder builder(this);
13108 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
13109
13110 TestCompletionCallback host_resolution_callback;
13111 EXPECT_TRUE(builder.request.WaitForHostResolution(
13112 host_resolution_callback.callback()));
13113
13114 // |host_resolver_| has not finished host resolution at this point, so
13115 // |host_resolution_callback| should not have a result.
13116 base::RunLoop().RunUntilIdle();
13117 EXPECT_FALSE(host_resolution_callback.have_result());
13118
13119 // Allow |host_resolver_| to finish host resolution. Since crypto handshake
13120 // will hang after host resolution, |host_resolution_callback| should run with
13121 // ERR_IO_PENDING since that's the next result in forming the connection.
13122 host_resolver_->ResolveAllPending();
13123 base::RunLoop().RunUntilIdle();
13124 EXPECT_TRUE(host_resolution_callback.have_result());
13125 EXPECT_EQ(ERR_IO_PENDING, host_resolution_callback.WaitForResult());
13126
13127 // Calling WaitForHostResolution() a second time should return
13128 // false since host resolution has finished already.
13129 EXPECT_FALSE(builder.request.WaitForHostResolution(
13130 host_resolution_callback.callback()));
13131
13132 EXPECT_FALSE(callback_.have_result());
13133 socket_data.Resume();
13134 base::RunLoop().RunUntilIdle();
13135 EXPECT_TRUE(callback_.have_result());
13136 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
13137 }
13138
13139 // Verify ResultAfterHostResolutionCallback behavior when host resolution
13140 // succeeds synchronously, then crypto handshake fails synchronously.
TEST_P(QuicSessionPoolTest,ResultAfterHostResolutionCallbackSyncSync)13141 TEST_P(QuicSessionPoolTest, ResultAfterHostResolutionCallbackSyncSync) {
13142 Initialize();
13143 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
13144 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
13145
13146 host_resolver_->set_synchronous_mode(true);
13147
13148 MockQuicData socket_data(version_);
13149 socket_data.AddRead(SYNCHRONOUS, ERR_FAILED);
13150 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
13151 socket_data.AddSocketDataToFactory(socket_factory_.get());
13152
13153 RequestBuilder builder(this);
13154 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
13155
13156 // WaitForHostResolution() should return false since host
13157 // resolution has finished already.
13158 TestCompletionCallback host_resolution_callback;
13159 EXPECT_FALSE(builder.request.WaitForHostResolution(
13160 host_resolution_callback.callback()));
13161 base::RunLoop().RunUntilIdle();
13162 EXPECT_FALSE(host_resolution_callback.have_result());
13163 EXPECT_TRUE(callback_.have_result());
13164 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
13165 }
13166
13167 // Verify ResultAfterHostResolutionCallback behavior when host resolution
13168 // succeeds synchronously, then crypto handshake fails asynchronously.
TEST_P(QuicSessionPoolTest,ResultAfterHostResolutionCallbackSyncAsync)13169 TEST_P(QuicSessionPoolTest, ResultAfterHostResolutionCallbackSyncAsync) {
13170 Initialize();
13171 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
13172 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
13173
13174 // Host resolution will succeed synchronously, but Request() as a whole
13175 // will fail asynchronously.
13176 host_resolver_->set_synchronous_mode(true);
13177 crypto_client_stream_factory_.set_handshake_mode(
13178 MockCryptoClientStream::ZERO_RTT);
13179 factory_->set_is_quic_known_to_work_on_current_network(false);
13180
13181 MockQuicData socket_data(version_);
13182 socket_data.AddReadPause();
13183 socket_data.AddRead(ASYNC, ERR_FAILED);
13184 socket_data.AddWrite(ASYNC, ERR_FAILED);
13185 socket_data.AddSocketDataToFactory(socket_factory_.get());
13186
13187 RequestBuilder builder(this);
13188 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
13189
13190 // WaitForHostResolution() should return false since host
13191 // resolution has finished already.
13192 TestCompletionCallback host_resolution_callback;
13193 EXPECT_FALSE(builder.request.WaitForHostResolution(
13194 host_resolution_callback.callback()));
13195 base::RunLoop().RunUntilIdle();
13196 EXPECT_FALSE(host_resolution_callback.have_result());
13197
13198 EXPECT_FALSE(callback_.have_result());
13199 socket_data.Resume();
13200 base::RunLoop().RunUntilIdle();
13201 EXPECT_TRUE(callback_.have_result());
13202 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
13203 }
13204
13205 // Verify ResultAfterHostResolutionCallback behavior when host resolution fails
13206 // synchronously.
TEST_P(QuicSessionPoolTest,ResultAfterHostResolutionCallbackFailSync)13207 TEST_P(QuicSessionPoolTest, ResultAfterHostResolutionCallbackFailSync) {
13208 Initialize();
13209 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
13210 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
13211
13212 // Host resolution will fail synchronously.
13213 host_resolver_->rules()->AddSimulatedFailure(kDefaultServerHostName);
13214 host_resolver_->set_synchronous_mode(true);
13215
13216 RequestBuilder builder(this);
13217 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, builder.CallRequest());
13218
13219 // WaitForHostResolution() should return false since host
13220 // resolution has failed already.
13221 TestCompletionCallback host_resolution_callback;
13222 EXPECT_FALSE(builder.request.WaitForHostResolution(
13223 host_resolution_callback.callback()));
13224 base::RunLoop().RunUntilIdle();
13225 EXPECT_FALSE(host_resolution_callback.have_result());
13226 }
13227
13228 // Verify ResultAfterHostResolutionCallback behavior when host resolution fails
13229 // asynchronously.
TEST_P(QuicSessionPoolTest,ResultAfterHostResolutionCallbackFailAsync)13230 TEST_P(QuicSessionPoolTest, ResultAfterHostResolutionCallbackFailAsync) {
13231 Initialize();
13232 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
13233 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
13234
13235 host_resolver_->rules()->AddSimulatedFailure(kDefaultServerHostName);
13236
13237 RequestBuilder builder(this);
13238 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
13239
13240 TestCompletionCallback host_resolution_callback;
13241 EXPECT_TRUE(builder.request.WaitForHostResolution(
13242 host_resolution_callback.callback()));
13243
13244 // Allow |host_resolver_| to fail host resolution. |host_resolution_callback|
13245 // Should run with ERR_NAME_NOT_RESOLVED since that's the error host
13246 // resolution failed with.
13247 base::RunLoop().RunUntilIdle();
13248 EXPECT_TRUE(host_resolution_callback.have_result());
13249 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, host_resolution_callback.WaitForResult());
13250
13251 EXPECT_TRUE(callback_.have_result());
13252 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, callback_.WaitForResult());
13253 }
13254
13255 // Test that QuicSessionRequests with similar and different tags results in
13256 // reused and unique QUIC streams using appropriately tagged sockets.
TEST_P(QuicSessionPoolTest,Tag)13257 TEST_P(QuicSessionPoolTest, Tag) {
13258 socket_factory_ = std::make_unique<MockTaggingClientSocketFactory>();
13259 auto* socket_factory =
13260 static_cast<MockTaggingClientSocketFactory*>(socket_factory_.get());
13261 Initialize();
13262 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
13263 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
13264
13265 // Prepare to establish two QUIC sessions.
13266 MockQuicData socket_data(version_);
13267 socket_data.AddReadPauseForever();
13268 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
13269 socket_data.AddSocketDataToFactory(socket_factory_.get());
13270 client_maker_.Reset();
13271 MockQuicData socket_data2(version_);
13272 socket_data2.AddReadPauseForever();
13273 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
13274 socket_data2.AddSocketDataToFactory(socket_factory_.get());
13275
13276 #if BUILDFLAG(IS_ANDROID)
13277 SocketTag tag1(SocketTag::UNSET_UID, 0x12345678);
13278 SocketTag tag2(getuid(), 0x87654321);
13279 #else
13280 // On non-Android platforms we can only use the default constructor.
13281 SocketTag tag1, tag2;
13282 #endif
13283
13284 // Request a stream with |tag1|.
13285 RequestBuilder builder1(this);
13286 builder1.socket_tag = tag1;
13287 int rv = builder1.CallRequest();
13288 EXPECT_THAT(callback_.GetResult(rv), IsOk());
13289 EXPECT_EQ(socket_factory->GetLastProducedUDPSocket()->tag(), tag1);
13290 EXPECT_TRUE(socket_factory->GetLastProducedUDPSocket()
13291 ->tagged_before_data_transferred());
13292 std::unique_ptr<QuicChromiumClientSession::Handle> stream1 =
13293 builder1.request.ReleaseSessionHandle();
13294 EXPECT_TRUE(stream1);
13295 EXPECT_TRUE(stream1->IsConnected());
13296
13297 // Request a stream with |tag1| and verify underlying session is reused.
13298 RequestBuilder builder2(this);
13299 builder2.socket_tag = tag1;
13300 rv = builder2.CallRequest();
13301 EXPECT_THAT(callback_.GetResult(rv), IsOk());
13302 std::unique_ptr<QuicChromiumClientSession::Handle> stream2 =
13303 builder2.request.ReleaseSessionHandle();
13304 EXPECT_TRUE(stream2);
13305 EXPECT_TRUE(stream2->IsConnected());
13306 EXPECT_TRUE(stream2->SharesSameSession(*stream1));
13307
13308 // Request a stream with |tag2| and verify a new session is created.
13309 RequestBuilder builder3(this);
13310 builder3.socket_tag = tag2;
13311 rv = builder3.CallRequest();
13312 EXPECT_THAT(callback_.GetResult(rv), IsOk());
13313 EXPECT_EQ(socket_factory->GetLastProducedUDPSocket()->tag(), tag2);
13314 EXPECT_TRUE(socket_factory->GetLastProducedUDPSocket()
13315 ->tagged_before_data_transferred());
13316 std::unique_ptr<QuicChromiumClientSession::Handle> stream3 =
13317 builder3.request.ReleaseSessionHandle();
13318 EXPECT_TRUE(stream3);
13319 EXPECT_TRUE(stream3->IsConnected());
13320 #if BUILDFLAG(IS_ANDROID)
13321 EXPECT_FALSE(stream3->SharesSameSession(*stream1));
13322 #else
13323 // Same tag should reuse session.
13324 EXPECT_TRUE(stream3->SharesSameSession(*stream1));
13325 #endif
13326 }
13327
TEST_P(QuicSessionPoolTest,ReadErrorClosesConnection)13328 TEST_P(QuicSessionPoolTest, ReadErrorClosesConnection) {
13329 Initialize();
13330 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
13331 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
13332
13333 MockQuicData socket_data(version_);
13334 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
13335 socket_data.AddReadPause();
13336 socket_data.AddRead(ASYNC, ERR_CONNECTION_REFUSED);
13337 socket_data.AddSocketDataToFactory(socket_factory_.get());
13338
13339 // Create request and QuicHttpStream to trigger creation of the session.
13340 RequestBuilder builder(this);
13341 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
13342 EXPECT_THAT(callback_.WaitForResult(), IsOk());
13343 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
13344 EXPECT_TRUE(stream.get());
13345
13346 // Ensure that the session is alive and active before we read the error.
13347 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
13348 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
13349 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
13350
13351 // Resume the socket data to get the read error delivered.
13352 socket_data.Resume();
13353 // Ensure that the session is no longer active.
13354 EXPECT_FALSE(HasActiveSession(kDefaultDestination));
13355 }
13356
TEST_P(QuicSessionPoolTest,MessageTooBigReadErrorDoesNotCloseConnection)13357 TEST_P(QuicSessionPoolTest, MessageTooBigReadErrorDoesNotCloseConnection) {
13358 Initialize();
13359 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
13360 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
13361
13362 MockQuicData socket_data(version_);
13363 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
13364 socket_data.AddReadPause();
13365 socket_data.AddRead(ASYNC, ERR_MSG_TOO_BIG);
13366 socket_data.AddSocketDataToFactory(socket_factory_.get());
13367
13368 // Create request and QuicHttpStream to trigger creation of the session.
13369 RequestBuilder builder(this);
13370 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
13371 EXPECT_THAT(callback_.WaitForResult(), IsOk());
13372 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
13373 EXPECT_TRUE(stream.get());
13374
13375 // Ensure that the session is alive and active before we read the error.
13376 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
13377 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
13378 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
13379
13380 // Resume the socket data to get the read error delivered.
13381 socket_data.Resume();
13382 // Ensure that the session is still active.
13383 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
13384 }
13385
TEST_P(QuicSessionPoolTest,ZeroLengthReadDoesNotCloseConnection)13386 TEST_P(QuicSessionPoolTest, ZeroLengthReadDoesNotCloseConnection) {
13387 Initialize();
13388 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
13389 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
13390
13391 MockQuicData socket_data(version_);
13392 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
13393 socket_data.AddReadPause();
13394 socket_data.AddRead(ASYNC, 0);
13395 socket_data.AddSocketDataToFactory(socket_factory_.get());
13396
13397 // Create request and QuicHttpStream to trigger creation of the session.
13398 RequestBuilder builder(this);
13399 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
13400 EXPECT_THAT(callback_.WaitForResult(), IsOk());
13401 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
13402 EXPECT_TRUE(stream.get());
13403
13404 // Ensure that the session is alive and active before we read the error.
13405 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
13406 EXPECT_TRUE(QuicSessionPoolPeer::IsLiveSession(factory_.get(), session));
13407 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
13408
13409 // Resume the socket data to get the zero-length read delivered.
13410 socket_data.Resume();
13411 // Ensure that the session is still active.
13412 EXPECT_TRUE(HasActiveSession(kDefaultDestination));
13413 }
13414
TEST_P(QuicSessionPoolTest,DnsAliasesCanBeAccessedFromStream)13415 TEST_P(QuicSessionPoolTest, DnsAliasesCanBeAccessedFromStream) {
13416 std::vector<std::string> dns_aliases(
13417 {"alias1", "alias2", kDefaultServerHostName});
13418 host_resolver_->rules()->AddIPLiteralRuleWithDnsAliases(
13419 kDefaultServerHostName, "192.168.0.1", std::move(dns_aliases));
13420
13421 Initialize();
13422 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
13423 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
13424
13425 MockQuicData socket_data(version_);
13426 socket_data.AddReadPauseForever();
13427 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
13428 socket_data.AddSocketDataToFactory(socket_factory_.get());
13429
13430 RequestBuilder builder(this);
13431 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
13432 EXPECT_THAT(callback_.WaitForResult(), IsOk());
13433 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
13434 EXPECT_TRUE(stream.get());
13435
13436 EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_->last_request_priority());
13437
13438 socket_data.ExpectAllReadDataConsumed();
13439 socket_data.ExpectAllWriteDataConsumed();
13440
13441 EXPECT_THAT(stream->GetDnsAliases(),
13442 testing::ElementsAre("alias1", "alias2", kDefaultServerHostName));
13443 }
13444
TEST_P(QuicSessionPoolTest,NoAdditionalDnsAliases)13445 TEST_P(QuicSessionPoolTest, NoAdditionalDnsAliases) {
13446 std::vector<std::string> dns_aliases;
13447 host_resolver_->rules()->AddIPLiteralRuleWithDnsAliases(
13448 kDefaultServerHostName, "192.168.0.1", std::move(dns_aliases));
13449
13450 Initialize();
13451 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
13452 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
13453
13454 MockQuicData socket_data(version_);
13455 socket_data.AddReadPauseForever();
13456 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
13457 socket_data.AddSocketDataToFactory(socket_factory_.get());
13458
13459 RequestBuilder builder(this);
13460 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
13461 EXPECT_THAT(callback_.WaitForResult(), IsOk());
13462 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
13463 EXPECT_TRUE(stream.get());
13464
13465 EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_->last_request_priority());
13466
13467 socket_data.ExpectAllReadDataConsumed();
13468 socket_data.ExpectAllWriteDataConsumed();
13469
13470 EXPECT_THAT(stream->GetDnsAliases(),
13471 testing::ElementsAre(kDefaultServerHostName));
13472 }
13473
TEST_P(QuicSessionPoolTest,DoNotUseDnsAliases)13474 TEST_P(QuicSessionPoolTest, DoNotUseDnsAliases) {
13475 std::vector<std::string> dns_aliases({"alias1", "alias2"});
13476 host_resolver_->rules()->AddIPLiteralRuleWithDnsAliases(
13477 kDefaultServerHostName, "192.168.0.1", std::move(dns_aliases));
13478
13479 Initialize();
13480 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
13481 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
13482
13483 MockQuicData socket_data(version_);
13484 socket_data.AddReadPauseForever();
13485 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
13486 socket_data.AddSocketDataToFactory(socket_factory_.get());
13487
13488 // By indicating that this is a request to a proxy server, DNS aliasing will
13489 // not be performed.
13490 RequestBuilder builder(this);
13491 builder.session_usage = SessionUsage::kProxy;
13492 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
13493 EXPECT_THAT(callback_.WaitForResult(), IsOk());
13494 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
13495 EXPECT_TRUE(stream.get());
13496
13497 EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_->last_request_priority());
13498
13499 socket_data.ExpectAllReadDataConsumed();
13500 socket_data.ExpectAllWriteDataConsumed();
13501
13502 EXPECT_TRUE(stream->GetDnsAliases().empty());
13503 }
13504
TEST_P(QuicSessionPoolTest,ConnectErrorInCreateWithDnsAliases)13505 TEST_P(QuicSessionPoolTest, ConnectErrorInCreateWithDnsAliases) {
13506 std::vector<std::string> dns_aliases({"alias1", "alias2"});
13507 host_resolver_->rules()->AddIPLiteralRuleWithDnsAliases(
13508 kDefaultServerHostName, "192.168.0.1", std::move(dns_aliases));
13509
13510 Initialize();
13511 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
13512 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
13513
13514 MockQuicData socket_data(version_);
13515 socket_data.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
13516 socket_data.AddSocketDataToFactory(socket_factory_.get());
13517
13518 RequestBuilder builder(this);
13519 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
13520 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_ADDRESS_IN_USE));
13521
13522 socket_data.ExpectAllReadDataConsumed();
13523 socket_data.ExpectAllWriteDataConsumed();
13524 }
13525
TEST_P(QuicSessionPoolTest,RequireDnsHttpsAlpnNoHttpsRecord)13526 TEST_P(QuicSessionPoolTest, RequireDnsHttpsAlpnNoHttpsRecord) {
13527 std::vector<HostResolverEndpointResult> endpoints(1);
13528 endpoints[0].ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
13529 TestRequireDnsHttpsAlpn(std::move(endpoints), /*expect_success=*/false);
13530 }
13531
TEST_P(QuicSessionPoolTest,RequireDnsHttpsAlpnMatch)13532 TEST_P(QuicSessionPoolTest, RequireDnsHttpsAlpnMatch) {
13533 std::vector<HostResolverEndpointResult> endpoints(2);
13534 endpoints[0].ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
13535 endpoints[0].metadata.supported_protocol_alpns = {
13536 quic::AlpnForVersion(version_)};
13537 // Add a final non-protocol endpoint at the end.
13538 endpoints[1].ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
13539 TestRequireDnsHttpsAlpn(std::move(endpoints), /*expect_success=*/true);
13540 }
13541
TEST_P(QuicSessionPoolTest,RequireDnsHttpsAlpnUnknownAlpn)13542 TEST_P(QuicSessionPoolTest, RequireDnsHttpsAlpnUnknownAlpn) {
13543 std::vector<HostResolverEndpointResult> endpoints(2);
13544 endpoints[0].ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
13545 endpoints[0].metadata.supported_protocol_alpns = {"unknown"};
13546 // Add a final non-protocol endpoint at the end.
13547 endpoints[1].ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
13548 TestRequireDnsHttpsAlpn(std::move(endpoints), /*expect_success=*/false);
13549 }
13550
TEST_P(QuicSessionPoolTest,RequireDnsHttpsAlpnUnknownAndSupportedAlpn)13551 TEST_P(QuicSessionPoolTest, RequireDnsHttpsAlpnUnknownAndSupportedAlpn) {
13552 std::vector<HostResolverEndpointResult> endpoints(2);
13553 endpoints[0].ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
13554 endpoints[0].metadata.supported_protocol_alpns = {
13555 "unknown", quic::AlpnForVersion(version_)};
13556 // Add a final non-protocol endpoint at the end.
13557 endpoints[1].ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
13558 TestRequireDnsHttpsAlpn(std::move(endpoints), /*expect_success=*/true);
13559 }
13560
13561 // QUIC has many string representations of versions. Only the ALPN name is
13562 // acceptable in HTTPS/SVCB records.
TEST_P(QuicSessionPoolTest,RequireDnsHttpsNotAlpnName)13563 TEST_P(QuicSessionPoolTest, RequireDnsHttpsNotAlpnName) {
13564 std::vector<HostResolverEndpointResult> endpoints(2);
13565 endpoints[0].ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
13566 endpoints[0].metadata.supported_protocol_alpns = {
13567 quic::ParsedQuicVersionToString(version_)};
13568 // Add a final non-protocol endpoint at the end.
13569 endpoints[1].ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
13570 TestRequireDnsHttpsAlpn(std::move(endpoints), /*expect_success=*/false);
13571 }
13572
13573 // If the only routes come from HTTPS/SVCB records (impossible until
13574 // https://crbug.com/1417033 is implemented), we should still pick up the
13575 // address from the HTTPS record.
TEST_P(QuicSessionPoolTest,RequireDnsHttpsRecordOnly)13576 TEST_P(QuicSessionPoolTest, RequireDnsHttpsRecordOnly) {
13577 std::vector<HostResolverEndpointResult> endpoints(1);
13578 endpoints[0].ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
13579 endpoints[0].metadata.supported_protocol_alpns = {
13580 quic::AlpnForVersion(version_)};
13581 TestRequireDnsHttpsAlpn(std::move(endpoints), /*expect_success=*/true);
13582 }
13583
TestRequireDnsHttpsAlpn(std::vector<HostResolverEndpointResult> endpoints,bool expect_success)13584 void QuicSessionPoolTest::TestRequireDnsHttpsAlpn(
13585 std::vector<HostResolverEndpointResult> endpoints,
13586 bool expect_success) {
13587 quic_params_->supported_versions = {version_};
13588 host_resolver_ = std::make_unique<MockHostResolver>();
13589 host_resolver_->rules()->AddRule(
13590 kDefaultServerHostName,
13591 MockHostResolverBase::RuleResolver::RuleResult(
13592 std::move(endpoints),
13593 /*aliases=*/std::set<std::string>{kDefaultServerHostName}));
13594
13595 Initialize();
13596 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
13597 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
13598
13599 MockQuicData socket_data(version_);
13600 socket_data.AddReadPauseForever();
13601 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
13602 socket_data.AddSocketDataToFactory(socket_factory_.get());
13603
13604 RequestBuilder builder(this);
13605 builder.quic_version = quic::ParsedQuicVersion::Unsupported();
13606 builder.require_dns_https_alpn = true;
13607 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
13608 if (expect_success) {
13609 EXPECT_THAT(callback_.WaitForResult(), IsOk());
13610 } else {
13611 EXPECT_THAT(callback_.WaitForResult(),
13612 IsError(ERR_DNS_NO_MATCHING_SUPPORTED_ALPN));
13613 }
13614 }
13615
13616 namespace {
13617
13618 // Run QuicSessionPoolDnsAliasPoolingTest instances with all value
13619 // combinations of version, H2 stream dependency or not, DNS alias use or not,
13620 // and example DNS aliases. `expected_dns_aliases*` params are dependent on
13621 // `use_dns_aliases`, `dns_aliases1`, and `dns_aliases2`.
13622 struct DnsAliasPoolingTestParams {
13623 quic::ParsedQuicVersion version;
13624 bool use_dns_aliases;
13625 std::set<std::string> dns_aliases1;
13626 std::set<std::string> dns_aliases2;
13627 std::set<std::string> expected_dns_aliases1;
13628 std::set<std::string> expected_dns_aliases2;
13629 };
13630
PrintToString(const std::set<std::string> & set)13631 std::string PrintToString(const std::set<std::string>& set) {
13632 std::string joined;
13633 for (const std::string& str : set) {
13634 if (!joined.empty()) {
13635 joined += "_";
13636 }
13637 joined += str;
13638 }
13639 return joined;
13640 }
13641
13642 // Used by ::testing::PrintToStringParamName().
PrintToString(const DnsAliasPoolingTestParams & p)13643 std::string PrintToString(const DnsAliasPoolingTestParams& p) {
13644 return base::StrCat({ParsedQuicVersionToString(p.version), "_",
13645 (p.use_dns_aliases ? "" : "DoNot"), "UseDnsAliases_1st_",
13646 PrintToString(p.dns_aliases1), "_2nd_",
13647 PrintToString(p.dns_aliases2)});
13648 }
13649
GetDnsAliasPoolingTestParams()13650 std::vector<DnsAliasPoolingTestParams> GetDnsAliasPoolingTestParams() {
13651 std::vector<DnsAliasPoolingTestParams> params;
13652 quic::ParsedQuicVersionVector all_supported_versions =
13653 AllSupportedQuicVersions();
13654 for (const quic::ParsedQuicVersion& version : all_supported_versions) {
13655 params.push_back(DnsAliasPoolingTestParams{version,
13656 false /* use_dns_aliases */,
13657 {} /* dns_aliases1 */,
13658 {} /* dns_aliases2 */,
13659 {} /* expected_dns_aliases1 */,
13660 {} /* expected_dns_aliases2 */});
13661 params.push_back(DnsAliasPoolingTestParams{
13662 version,
13663 true /* use_dns_aliases */,
13664 {} /* dns_aliases1 */,
13665 {} /* dns_aliases2 */,
13666 {QuicSessionPoolTest::
13667 kDefaultServerHostName} /* expected_dns_aliases1 */,
13668 {QuicSessionPoolTest::kServer2HostName} /* expected_dns_aliases2 */});
13669 params.push_back(DnsAliasPoolingTestParams{version,
13670 false /* use_dns_aliases */,
13671 {"alias1", "alias2", "alias3"},
13672 {} /* dns_aliases2 */,
13673 {} /* expected_dns_aliases1 */,
13674 {} /* expected_dns_aliases2 */});
13675 params.push_back(DnsAliasPoolingTestParams{
13676 version,
13677 true /* use_dns_aliases */,
13678 {"alias1", "alias2", "alias3"} /* dns_aliases1 */,
13679 {} /* dns_aliases2 */,
13680 {"alias1", "alias2", "alias3"} /* expected_dns_aliases1 */,
13681 {QuicSessionPoolTest::kServer2HostName} /* expected_dns_aliases2 */});
13682 params.push_back(DnsAliasPoolingTestParams{
13683 version,
13684 false /* use_dns_aliases */,
13685 {"alias1", "alias2", "alias3"} /* dns_aliases1 */,
13686 {"alias3", "alias4", "alias5"} /* dns_aliases2 */,
13687 {} /* expected_dns_aliases1 */,
13688 {} /* expected_dns_aliases2 */});
13689 params.push_back(DnsAliasPoolingTestParams{
13690 version,
13691 true /* use_dns_aliases */,
13692 {"alias1", "alias2", "alias3"} /* dns_aliases1 */,
13693 {"alias3", "alias4", "alias5"} /* dns_aliases2 */,
13694 {"alias1", "alias2", "alias3"} /* expected_dns_aliases1 */,
13695 {"alias3", "alias4", "alias5"} /* expected_dns_aliases2 */});
13696 params.push_back(DnsAliasPoolingTestParams{
13697 version,
13698 false /* use_dns_aliases */,
13699 {} /* dns_aliases1 */,
13700 {"alias3", "alias4", "alias5"} /* dns_aliases2 */,
13701 {} /* expected_dns_aliases1 */,
13702 {} /* expected_dns_aliases2 */});
13703 params.push_back(DnsAliasPoolingTestParams{
13704 version,
13705 true /* use_dns_aliases */,
13706 {} /* dns_aliases1 */,
13707 {"alias3", "alias4", "alias5"} /* dns_aliases2 */,
13708 {QuicSessionPoolTest::
13709 kDefaultServerHostName} /* expected_dns_aliases1 */,
13710 {"alias3", "alias4", "alias5"} /* expected_dns_aliases2 */});
13711 }
13712 return params;
13713 }
13714
13715 } // namespace
13716
13717 class QuicSessionPoolDnsAliasPoolingTest
13718 : public QuicSessionPoolTestBase,
13719 public ::testing::TestWithParam<DnsAliasPoolingTestParams> {
13720 protected:
QuicSessionPoolDnsAliasPoolingTest()13721 QuicSessionPoolDnsAliasPoolingTest()
13722 : QuicSessionPoolTestBase(GetParam().version),
13723 use_dns_aliases_(GetParam().use_dns_aliases),
13724 dns_aliases1_(GetParam().dns_aliases1),
13725 dns_aliases2_(GetParam().dns_aliases2),
13726 expected_dns_aliases1_(GetParam().expected_dns_aliases1),
13727 expected_dns_aliases2_(GetParam().expected_dns_aliases2) {}
13728
13729 const bool use_dns_aliases_;
13730 const std::set<std::string> dns_aliases1_;
13731 const std::set<std::string> dns_aliases2_;
13732 const std::set<std::string> expected_dns_aliases1_;
13733 const std::set<std::string> expected_dns_aliases2_;
13734 };
13735
13736 INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
13737 QuicSessionPoolDnsAliasPoolingTest,
13738 ::testing::ValuesIn(GetDnsAliasPoolingTestParams()),
13739 ::testing::PrintToStringParamName());
13740
TEST_P(QuicSessionPoolDnsAliasPoolingTest,IPPooling)13741 TEST_P(QuicSessionPoolDnsAliasPoolingTest, IPPooling) {
13742 Initialize();
13743
13744 const GURL kUrl1(kDefaultUrl);
13745 const GURL kUrl2(kServer2Url);
13746 const url::SchemeHostPort kOrigin1 = url::SchemeHostPort(kUrl1);
13747 const url::SchemeHostPort kOrigin2 = url::SchemeHostPort(kUrl2);
13748
13749 host_resolver_->rules()->AddIPLiteralRuleWithDnsAliases(
13750 kOrigin1.host(), "192.168.0.1", std::move(dns_aliases1_));
13751 host_resolver_->rules()->AddIPLiteralRuleWithDnsAliases(
13752 kOrigin2.host(), "192.168.0.1", std::move(dns_aliases2_));
13753
13754 scoped_refptr<X509Certificate> cert(
13755 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
13756 ASSERT_TRUE(cert->VerifyNameMatch(kOrigin1.host()));
13757 ASSERT_TRUE(cert->VerifyNameMatch(kOrigin2.host()));
13758
13759 ProofVerifyDetailsChromium verify_details;
13760 verify_details.cert_verify_result.verified_cert = cert;
13761 verify_details.cert_verify_result.is_issued_by_known_root = true;
13762 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
13763
13764 MockQuicData socket_data(version_);
13765 socket_data.AddReadPauseForever();
13766 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
13767 socket_data.AddSocketDataToFactory(socket_factory_.get());
13768
13769 SessionUsage session_usage;
13770 if (use_dns_aliases_) {
13771 session_usage = SessionUsage::kDestination;
13772 } else {
13773 session_usage = SessionUsage::kProxy;
13774 }
13775 RequestBuilder builder1(this);
13776 builder1.destination = kOrigin1;
13777 builder1.session_usage = session_usage;
13778 builder1.url = kUrl1;
13779 EXPECT_EQ(ERR_IO_PENDING, builder1.CallRequest());
13780 EXPECT_THAT(callback_.WaitForResult(), IsOk());
13781
13782 std::unique_ptr<HttpStream> stream1 = CreateStream(&builder1.request);
13783 EXPECT_TRUE(stream1.get());
13784 EXPECT_TRUE(HasActiveSession(kOrigin1, NetworkAnonymizationKey(),
13785 ProxyChain::Direct(), session_usage));
13786
13787 TestCompletionCallback callback2;
13788 RequestBuilder builder2(this);
13789 builder2.destination = kOrigin2;
13790 builder2.session_usage = session_usage;
13791 builder2.url = kUrl2;
13792 builder2.callback = callback2.callback();
13793 EXPECT_EQ(ERR_IO_PENDING, builder2.CallRequest());
13794 EXPECT_THAT(callback2.WaitForResult(), IsOk());
13795
13796 std::unique_ptr<HttpStream> stream2 = CreateStream(&builder2.request);
13797 EXPECT_TRUE(stream2.get());
13798 EXPECT_TRUE(HasActiveSession(kOrigin2, NetworkAnonymizationKey(),
13799 ProxyChain::Direct(), session_usage));
13800
13801 QuicChromiumClientSession::Handle* session1 =
13802 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
13803 QuicChromiumClientSession::Handle* session2 =
13804 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
13805 EXPECT_TRUE(session1->SharesSameSession(*session2));
13806
13807 EXPECT_EQ(quic::QuicServerId(kOrigin1.host(), kOrigin1.port(),
13808 /*privacy_mode_enabled=*/false),
13809 session1->server_id());
13810
13811 socket_data.ExpectAllReadDataConsumed();
13812 socket_data.ExpectAllWriteDataConsumed();
13813
13814 EXPECT_EQ(expected_dns_aliases1_, stream1->GetDnsAliases());
13815 EXPECT_EQ(expected_dns_aliases2_, stream2->GetDnsAliases());
13816 }
13817
13818 // Test that, even if DNS does not provide ECH keys, ECH GREASE is enabled.
TEST_P(QuicSessionPoolTest,EchGrease)13819 TEST_P(QuicSessionPoolTest, EchGrease) {
13820 Initialize();
13821 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
13822 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
13823
13824 MockQuicData socket_data(version_);
13825 socket_data.AddReadPauseForever();
13826 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
13827 socket_data.AddSocketDataToFactory(socket_factory_.get());
13828
13829 RequestBuilder builder(this);
13830 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
13831 EXPECT_THAT(callback_.WaitForResult(), IsOk());
13832
13833 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
13834 ASSERT_TRUE(session);
13835 quic::QuicSSLConfig config = session->GetSSLConfig();
13836 EXPECT_TRUE(config.ech_grease_enabled);
13837 EXPECT_TRUE(config.ech_config_list.empty());
13838 }
13839
13840 // Test that, connections where we discover QUIC from Alt-Svc (as opposed to
13841 // HTTPS-RR), ECH is picked up from DNS.
TEST_P(QuicSessionPoolTest,EchWithQuicFromAltSvc)13842 TEST_P(QuicSessionPoolTest, EchWithQuicFromAltSvc) {
13843 HostResolverEndpointResult endpoint;
13844 endpoint.ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
13845 endpoint.metadata.supported_protocol_alpns = {quic::AlpnForVersion(version_)};
13846 endpoint.metadata.ech_config_list = {1, 2, 3, 4};
13847
13848 host_resolver_ = std::make_unique<MockHostResolver>();
13849 host_resolver_->rules()->AddRule(
13850 kDefaultServerHostName,
13851 MockHostResolverBase::RuleResolver::RuleResult({endpoint}));
13852
13853 Initialize();
13854 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
13855 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
13856
13857 MockQuicData socket_data(version_);
13858 socket_data.AddReadPauseForever();
13859 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
13860 socket_data.AddSocketDataToFactory(socket_factory_.get());
13861
13862 RequestBuilder builder(this);
13863 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
13864 ASSERT_THAT(callback_.WaitForResult(), IsOk());
13865
13866 QuicChromiumClientSession* session = GetActiveSession(kDefaultDestination);
13867 ASSERT_TRUE(session);
13868 quic::QuicSSLConfig config = session->GetSSLConfig();
13869 EXPECT_EQ(std::string(endpoint.metadata.ech_config_list.begin(),
13870 endpoint.metadata.ech_config_list.end()),
13871 config.ech_config_list);
13872 }
13873
13874 // Test that, connections where we discover QUIC from HTTPS-RR (as opposed to
13875 // Alt-Svc), ECH is picked up from DNS.
TEST_P(QuicSessionPoolTest,EchWithQuicFromHttpsRecord)13876 TEST_P(QuicSessionPoolTest, EchWithQuicFromHttpsRecord) {
13877 quic_params_->supported_versions = {version_};
13878 HostResolverEndpointResult endpoint;
13879 endpoint.ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
13880 endpoint.metadata.supported_protocol_alpns = {quic::AlpnForVersion(version_)};
13881 endpoint.metadata.ech_config_list = {1, 2, 3, 4};
13882
13883 host_resolver_ = std::make_unique<MockHostResolver>();
13884 host_resolver_->rules()->AddRule(
13885 kDefaultServerHostName,
13886 MockHostResolverBase::RuleResolver::RuleResult({endpoint}));
13887
13888 Initialize();
13889 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
13890 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
13891
13892 MockQuicData socket_data(version_);
13893 socket_data.AddReadPauseForever();
13894 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
13895 socket_data.AddSocketDataToFactory(socket_factory_.get());
13896
13897 RequestBuilder builder(this);
13898 builder.quic_version = quic::ParsedQuicVersion::Unsupported();
13899 builder.require_dns_https_alpn = true;
13900 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
13901 ASSERT_THAT(callback_.WaitForResult(), IsOk());
13902
13903 QuicChromiumClientSession* session =
13904 GetActiveSession(kDefaultDestination, NetworkAnonymizationKey(),
13905 ProxyChain::Direct(), SessionUsage::kDestination,
13906 /*require_dns_https_alpn=*/true);
13907 ASSERT_TRUE(session);
13908 quic::QuicSSLConfig config = session->GetSSLConfig();
13909 EXPECT_EQ(std::string(endpoint.metadata.ech_config_list.begin(),
13910 endpoint.metadata.ech_config_list.end()),
13911 config.ech_config_list);
13912 }
13913
13914 // Test that, when ECH is disabled, neither ECH nor ECH GREASE are configured.
TEST_P(QuicSessionPoolTest,EchDisabled)13915 TEST_P(QuicSessionPoolTest, EchDisabled) {
13916 quic_params_->supported_versions = {version_};
13917 HostResolverEndpointResult endpoint;
13918 endpoint.ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
13919 endpoint.metadata.supported_protocol_alpns = {quic::AlpnForVersion(version_)};
13920 endpoint.metadata.ech_config_list = {1, 2, 3, 4};
13921
13922 host_resolver_ = std::make_unique<MockHostResolver>();
13923 host_resolver_->rules()->AddRule(
13924 kDefaultServerHostName,
13925 MockHostResolverBase::RuleResolver::RuleResult({endpoint}));
13926
13927 SSLContextConfig ssl_config;
13928 ssl_config.ech_enabled = false;
13929 ssl_config_service_.UpdateSSLConfigAndNotify(ssl_config);
13930
13931 Initialize();
13932 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
13933 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
13934
13935 MockQuicData socket_data(version_);
13936 socket_data.AddReadPauseForever();
13937 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
13938 socket_data.AddSocketDataToFactory(socket_factory_.get());
13939
13940 RequestBuilder builder(this);
13941 builder.quic_version = quic::ParsedQuicVersion::Unsupported();
13942 builder.require_dns_https_alpn = true;
13943 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
13944 ASSERT_THAT(callback_.WaitForResult(), IsOk());
13945
13946 QuicChromiumClientSession* session =
13947 GetActiveSession(kDefaultDestination, NetworkAnonymizationKey(),
13948 ProxyChain::Direct(), SessionUsage::kDestination,
13949 /*require_dns_https_alpn=*/true);
13950 ASSERT_TRUE(session);
13951 quic::QuicSSLConfig config = session->GetSSLConfig();
13952 EXPECT_TRUE(config.ech_config_list.empty());
13953 EXPECT_FALSE(config.ech_grease_enabled);
13954 }
13955
13956 // Test that, when the server supports ECH, the connection should use
13957 // SVCB-reliant behavior.
TEST_P(QuicSessionPoolTest,EchSvcbReliant)13958 TEST_P(QuicSessionPoolTest, EchSvcbReliant) {
13959 // The HTTPS-RR route only advertises HTTP/2 and is therefore incompatible
13960 // with QUIC. The fallback A/AAAA is compatible, but is ineligible in
13961 // ECH-capable clients.
13962 std::vector<HostResolverEndpointResult> endpoints(2);
13963 endpoints[0].ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
13964 endpoints[0].metadata.supported_protocol_alpns = {"h2"};
13965 endpoints[0].metadata.ech_config_list = {1, 2, 3, 4};
13966 endpoints[1].ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
13967
13968 host_resolver_ = std::make_unique<MockHostResolver>();
13969 host_resolver_->rules()->AddRule(
13970 kDefaultServerHostName,
13971 MockHostResolverBase::RuleResolver::RuleResult(std::move(endpoints)));
13972
13973 Initialize();
13974 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
13975 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
13976
13977 MockQuicData socket_data(version_);
13978 socket_data.AddReadPauseForever();
13979 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
13980 socket_data.AddSocketDataToFactory(socket_factory_.get());
13981
13982 RequestBuilder builder(this);
13983 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
13984 EXPECT_THAT(callback_.WaitForResult(),
13985 IsError(ERR_DNS_NO_MATCHING_SUPPORTED_ALPN));
13986 }
13987
13988 // Test that, when ECH is disabled, SVCB-reliant behavior doesn't trigger.
TEST_P(QuicSessionPoolTest,EchDisabledSvcbOptional)13989 TEST_P(QuicSessionPoolTest, EchDisabledSvcbOptional) {
13990 // The HTTPS-RR route only advertises HTTP/2 and is therefore incompatible
13991 // with QUIC. The fallback A/AAAA is compatible, but is ineligible in
13992 // ECH-capable clients.
13993 std::vector<HostResolverEndpointResult> endpoints(2);
13994 endpoints[0].ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
13995 endpoints[0].metadata.supported_protocol_alpns = {"h2"};
13996 endpoints[0].metadata.ech_config_list = {1, 2, 3, 4};
13997 endpoints[1].ip_endpoints = {IPEndPoint(IPAddress::IPv4Localhost(), 0)};
13998
13999 host_resolver_ = std::make_unique<MockHostResolver>();
14000 host_resolver_->rules()->AddRule(
14001 kDefaultServerHostName,
14002 MockHostResolverBase::RuleResolver::RuleResult(std::move(endpoints)));
14003
14004 // But this client is not ECH-capable, so the connection should succeed.
14005 SSLContextConfig ssl_config;
14006 ssl_config.ech_enabled = false;
14007 ssl_config_service_.UpdateSSLConfigAndNotify(ssl_config);
14008
14009 Initialize();
14010 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
14011 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
14012
14013 MockQuicData socket_data(version_);
14014 socket_data.AddReadPauseForever();
14015 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
14016 socket_data.AddSocketDataToFactory(socket_factory_.get());
14017
14018 RequestBuilder builder(this);
14019 EXPECT_EQ(ERR_IO_PENDING, builder.CallRequest());
14020 EXPECT_THAT(callback_.WaitForResult(), IsOk());
14021 }
14022
14023 } // namespace net::test
14024