1 // Copyright 2014 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/socket/websocket_transport_client_socket_pool.h"
6
7 #include <algorithm>
8 #include <memory>
9 #include <optional>
10 #include <utility>
11 #include <vector>
12
13 #include "base/functional/bind.h"
14 #include "base/functional/callback.h"
15 #include "base/functional/callback_helpers.h"
16 #include "base/location.h"
17 #include "base/run_loop.h"
18 #include "base/strings/stringprintf.h"
19 #include "base/task/single_thread_task_runner.h"
20 #include "base/test/scoped_feature_list.h"
21 #include "base/time/time.h"
22 #include "net/base/features.h"
23 #include "net/base/ip_endpoint.h"
24 #include "net/base/load_timing_info.h"
25 #include "net/base/load_timing_info_test_util.h"
26 #include "net/base/net_errors.h"
27 #include "net/base/privacy_mode.h"
28 #include "net/base/proxy_chain.h"
29 #include "net/base/proxy_server.h"
30 #include "net/base/schemeful_site.h"
31 #include "net/base/test_completion_callback.h"
32 #include "net/dns/mock_host_resolver.h"
33 #include "net/dns/public/secure_dns_policy.h"
34 #include "net/log/net_log.h"
35 #include "net/socket/client_socket_handle.h"
36 #include "net/socket/connect_job.h"
37 #include "net/socket/connect_job_test_util.h"
38 #include "net/socket/socket_tag.h"
39 #include "net/socket/socket_test_util.h"
40 #include "net/socket/ssl_client_socket.h"
41 #include "net/socket/stream_socket.h"
42 #include "net/socket/transport_client_socket_pool_test_util.h"
43 #include "net/socket/transport_connect_job.h"
44 #include "net/socket/websocket_endpoint_lock_manager.h"
45 #include "net/test/gtest_util.h"
46 #include "net/test/test_with_task_environment.h"
47 #include "testing/gmock/include/gmock/gmock.h"
48 #include "testing/gtest/include/gtest/gtest.h"
49 #include "url/gurl.h"
50 #include "url/scheme_host_port.h"
51 #include "url/url_constants.h"
52
53 using net::test::IsError;
54 using net::test::IsOk;
55
56 namespace net {
57
58 namespace {
59
60 const int kMaxSockets = 32;
61 const int kMaxSocketsPerGroup = 6;
62 const RequestPriority kDefaultPriority = LOW;
63
ParseIP(const std::string & ip)64 IPAddress ParseIP(const std::string& ip) {
65 IPAddress address;
66 CHECK(address.AssignFromIPLiteral(ip));
67 return address;
68 }
69
70 // RunLoop doesn't support this natively but it is easy to emulate.
RunLoopForTimePeriod(base::TimeDelta period)71 void RunLoopForTimePeriod(base::TimeDelta period) {
72 base::RunLoop run_loop;
73 base::OnceClosure quit_closure(run_loop.QuitClosure());
74 base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
75 FROM_HERE, std::move(quit_closure), period);
76 run_loop.Run();
77 }
78
79 class WebSocketTransportClientSocketPoolTest : public TestWithTaskEnvironment {
80 protected:
WebSocketTransportClientSocketPoolTest()81 WebSocketTransportClientSocketPoolTest()
82 : group_id_(url::SchemeHostPort(url::kHttpScheme, "www.google.com", 80),
83 PrivacyMode::PRIVACY_MODE_DISABLED,
84 NetworkAnonymizationKey(),
85 SecureDnsPolicy::kAllow,
86 /*disable_cert_network_fetches=*/false),
87 params_(ClientSocketPool::SocketParams::CreateForHttpForTesting()),
88 host_resolver_(std::make_unique<
89 MockHostResolver>(/*default_result=*/
90 MockHostResolverBase::RuleResolver::
91 GetLocalhostResult())),
92 client_socket_factory_(NetLog::Get()),
93 common_connect_job_params_(
94 &client_socket_factory_,
95 host_resolver_.get(),
96 /*http_auth_cache=*/nullptr,
97 /*http_auth_handler_factory=*/nullptr,
98 /*spdy_session_pool=*/nullptr,
99 /*quic_supported_versions=*/nullptr,
100 /*quic_session_pool=*/nullptr,
101 /*proxy_delegate=*/nullptr,
102 /*http_user_agent_settings=*/nullptr,
103 /*ssl_client_context=*/nullptr,
104 /*socket_performance_watcher_factory=*/nullptr,
105 /*network_quality_estimator=*/nullptr,
106 /*net_log=*/nullptr,
107 &websocket_endpoint_lock_manager_,
108 /*http_server_properties=*/nullptr,
109 /*alpn_protos=*/nullptr,
110 /*application_settings=*/nullptr,
111 /*ignore_certificate_errors=*/nullptr,
112 /*early_data_enabled=*/nullptr),
113 pool_(kMaxSockets,
114 kMaxSocketsPerGroup,
115 ProxyChain::Direct(),
116 &common_connect_job_params_) {
117 websocket_endpoint_lock_manager_.SetUnlockDelayForTesting(
118 base::TimeDelta());
119 }
120
121 WebSocketTransportClientSocketPoolTest(
122 const WebSocketTransportClientSocketPoolTest&) = delete;
123 WebSocketTransportClientSocketPoolTest& operator=(
124 const WebSocketTransportClientSocketPoolTest&) = delete;
125
~WebSocketTransportClientSocketPoolTest()126 ~WebSocketTransportClientSocketPoolTest() override {
127 RunUntilIdle();
128 // ReleaseAllConnections() calls RunUntilIdle() after releasing each
129 // connection.
130 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
131 EXPECT_TRUE(websocket_endpoint_lock_manager_.IsEmpty());
132 }
133
RunUntilIdle()134 static void RunUntilIdle() { base::RunLoop().RunUntilIdle(); }
135
StartRequest(RequestPriority priority)136 int StartRequest(RequestPriority priority) {
137 return test_base_.StartRequestUsingPool(
138 &pool_, group_id_, priority, ClientSocketPool::RespectLimits::ENABLED,
139 params_);
140 }
141
GetOrderOfRequest(size_t index)142 int GetOrderOfRequest(size_t index) {
143 return test_base_.GetOrderOfRequest(index);
144 }
145
ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive)146 bool ReleaseOneConnection(ClientSocketPoolTest::KeepAlive keep_alive) {
147 return test_base_.ReleaseOneConnection(keep_alive);
148 }
149
ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive)150 void ReleaseAllConnections(ClientSocketPoolTest::KeepAlive keep_alive) {
151 test_base_.ReleaseAllConnections(keep_alive);
152 }
153
request(int i)154 TestSocketRequest* request(int i) { return test_base_.request(i); }
155
requests()156 std::vector<std::unique_ptr<TestSocketRequest>>* requests() {
157 return test_base_.requests();
158 }
completion_count() const159 size_t completion_count() const { return test_base_.completion_count(); }
160
161 // |group_id_| and |params_| correspond to the same socket parameters.
162 const ClientSocketPool::GroupId group_id_;
163 scoped_refptr<ClientSocketPool::SocketParams> params_;
164 std::unique_ptr<MockHostResolver> host_resolver_;
165 MockTransportClientSocketFactory client_socket_factory_;
166 WebSocketEndpointLockManager websocket_endpoint_lock_manager_;
167 const CommonConnectJobParams common_connect_job_params_;
168 WebSocketTransportClientSocketPool pool_;
169 ClientSocketPoolTest test_base_;
170 };
171
TEST_F(WebSocketTransportClientSocketPoolTest,Basic)172 TEST_F(WebSocketTransportClientSocketPoolTest, Basic) {
173 TestCompletionCallback callback;
174 ClientSocketHandle handle;
175 int rv =
176 handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
177 LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
178 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
179 &pool_, NetLogWithSource());
180 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
181 EXPECT_FALSE(handle.is_initialized());
182 EXPECT_FALSE(handle.socket());
183
184 EXPECT_THAT(callback.WaitForResult(), IsOk());
185 EXPECT_TRUE(handle.is_initialized());
186 EXPECT_TRUE(handle.socket());
187 TestLoadTimingInfoConnectedNotReused(handle);
188 }
189
190 // Make sure that the ConnectJob passes on its priority to its HostResolver
191 // request on Init.
TEST_F(WebSocketTransportClientSocketPoolTest,SetResolvePriorityOnInit)192 TEST_F(WebSocketTransportClientSocketPoolTest, SetResolvePriorityOnInit) {
193 for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; ++i) {
194 RequestPriority priority = static_cast<RequestPriority>(i);
195 TestCompletionCallback callback;
196 ClientSocketHandle handle;
197 EXPECT_EQ(
198 ERR_IO_PENDING,
199 handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
200 priority, SocketTag(),
201 ClientSocketPool::RespectLimits::ENABLED,
202 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
203 &pool_, NetLogWithSource()));
204 EXPECT_EQ(priority, host_resolver_->last_request_priority());
205 }
206 }
207
TEST_F(WebSocketTransportClientSocketPoolTest,InitHostResolutionFailure)208 TEST_F(WebSocketTransportClientSocketPoolTest, InitHostResolutionFailure) {
209 url::SchemeHostPort endpoint(url::kHttpScheme, "unresolvable.host.name", 80);
210 host_resolver_->rules()->AddSimulatedTimeoutFailure(endpoint.host());
211 TestCompletionCallback callback;
212 ClientSocketHandle handle;
213 EXPECT_EQ(
214 ERR_IO_PENDING,
215 handle.Init(ClientSocketPool::GroupId(
216 std::move(endpoint), PRIVACY_MODE_DISABLED,
217 NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
218 /*disable_cert_network_fetches=*/false),
219 ClientSocketPool::SocketParams::CreateForHttpForTesting(),
220 std::nullopt /* proxy_annotation_tag */, kDefaultPriority,
221 SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
222 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
223 &pool_, NetLogWithSource()));
224 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
225 EXPECT_THAT(handle.resolve_error_info().error, IsError(ERR_DNS_TIMED_OUT));
226 EXPECT_THAT(handle.connection_attempts(),
227 testing::ElementsAre(
228 ConnectionAttempt(IPEndPoint(), ERR_NAME_NOT_RESOLVED)));
229 }
230
TEST_F(WebSocketTransportClientSocketPoolTest,InitConnectionFailure)231 TEST_F(WebSocketTransportClientSocketPoolTest, InitConnectionFailure) {
232 client_socket_factory_.set_default_client_socket_type(
233 MockTransportClientSocketFactory::Type::kFailing);
234 TestCompletionCallback callback;
235 ClientSocketHandle handle;
236 EXPECT_EQ(
237 ERR_IO_PENDING,
238 handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
239 kDefaultPriority, SocketTag(),
240 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
241 ClientSocketPool::ProxyAuthCallback(), &pool_,
242 NetLogWithSource()));
243 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
244 EXPECT_THAT(
245 handle.connection_attempts(),
246 testing::ElementsAre(ConnectionAttempt(
247 IPEndPoint(IPAddress::IPv4Localhost(), 80), ERR_CONNECTION_FAILED)));
248
249 // Make the host resolutions complete synchronously this time.
250 host_resolver_->set_synchronous_mode(true);
251 EXPECT_EQ(
252 ERR_CONNECTION_FAILED,
253 handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
254 kDefaultPriority, SocketTag(),
255 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
256 ClientSocketPool::ProxyAuthCallback(), &pool_,
257 NetLogWithSource()));
258 EXPECT_THAT(
259 handle.connection_attempts(),
260 testing::ElementsAre(ConnectionAttempt(
261 IPEndPoint(IPAddress::IPv4Localhost(), 80), ERR_CONNECTION_FAILED)));
262 }
263
TEST_F(WebSocketTransportClientSocketPoolTest,PendingRequestsFinishFifo)264 TEST_F(WebSocketTransportClientSocketPoolTest, PendingRequestsFinishFifo) {
265 // First request finishes asynchronously.
266 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
267 EXPECT_THAT(request(0)->WaitForResult(), IsOk());
268
269 // Make all subsequent host resolutions complete synchronously.
270 host_resolver_->set_synchronous_mode(true);
271
272 // Rest of them wait for the first socket to be released.
273 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
274 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
275 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
276 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
277 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
278
279 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
280
281 EXPECT_EQ(6, client_socket_factory_.allocation_count());
282
283 // One initial asynchronous request and then 5 pending requests.
284 EXPECT_EQ(6U, completion_count());
285
286 // The requests finish in FIFO order.
287 EXPECT_EQ(1, GetOrderOfRequest(1));
288 EXPECT_EQ(2, GetOrderOfRequest(2));
289 EXPECT_EQ(3, GetOrderOfRequest(3));
290 EXPECT_EQ(4, GetOrderOfRequest(4));
291 EXPECT_EQ(5, GetOrderOfRequest(5));
292 EXPECT_EQ(6, GetOrderOfRequest(6));
293
294 // Make sure we test order of all requests made.
295 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(7));
296 }
297
TEST_F(WebSocketTransportClientSocketPoolTest,PendingRequests_NoKeepAlive)298 TEST_F(WebSocketTransportClientSocketPoolTest, PendingRequests_NoKeepAlive) {
299 // First request finishes asynchronously.
300 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
301 EXPECT_THAT(request(0)->WaitForResult(), IsOk());
302
303 // Make all subsequent host resolutions complete synchronously.
304 host_resolver_->set_synchronous_mode(true);
305
306 // Rest of them wait for the first socket to be released.
307 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
308 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
309 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
310 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
311 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
312
313 ReleaseAllConnections(ClientSocketPoolTest::NO_KEEP_ALIVE);
314
315 // The pending requests should finish successfully.
316 EXPECT_THAT(request(1)->WaitForResult(), IsOk());
317 EXPECT_THAT(request(2)->WaitForResult(), IsOk());
318 EXPECT_THAT(request(3)->WaitForResult(), IsOk());
319 EXPECT_THAT(request(4)->WaitForResult(), IsOk());
320 EXPECT_THAT(request(5)->WaitForResult(), IsOk());
321
322 EXPECT_EQ(static_cast<int>(requests()->size()),
323 client_socket_factory_.allocation_count());
324
325 // First asynchronous request, and then last 5 pending requests.
326 EXPECT_EQ(6U, completion_count());
327 }
328
329 // This test will start up a RequestSocket() and then immediately Cancel() it.
330 // The pending host resolution will eventually complete, and destroy the
331 // ClientSocketPool which will crash if the group was not cleared properly.
TEST_F(WebSocketTransportClientSocketPoolTest,CancelRequestClearGroup)332 TEST_F(WebSocketTransportClientSocketPoolTest, CancelRequestClearGroup) {
333 TestCompletionCallback callback;
334 ClientSocketHandle handle;
335 EXPECT_EQ(
336 ERR_IO_PENDING,
337 handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
338 kDefaultPriority, SocketTag(),
339 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
340 ClientSocketPool::ProxyAuthCallback(), &pool_,
341 NetLogWithSource()));
342 handle.Reset();
343 }
344
TEST_F(WebSocketTransportClientSocketPoolTest,TwoRequestsCancelOne)345 TEST_F(WebSocketTransportClientSocketPoolTest, TwoRequestsCancelOne) {
346 ClientSocketHandle handle;
347 TestCompletionCallback callback;
348 ClientSocketHandle handle2;
349 TestCompletionCallback callback2;
350
351 EXPECT_EQ(
352 ERR_IO_PENDING,
353 handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
354 kDefaultPriority, SocketTag(),
355 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
356 ClientSocketPool::ProxyAuthCallback(), &pool_,
357 NetLogWithSource()));
358 EXPECT_EQ(
359 ERR_IO_PENDING,
360 handle2.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
361 kDefaultPriority, SocketTag(),
362 ClientSocketPool::RespectLimits::ENABLED,
363 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
364 &pool_, NetLogWithSource()));
365
366 handle.Reset();
367
368 EXPECT_THAT(callback2.WaitForResult(), IsOk());
369 handle2.Reset();
370 }
371
TEST_F(WebSocketTransportClientSocketPoolTest,ConnectCancelConnect)372 TEST_F(WebSocketTransportClientSocketPoolTest, ConnectCancelConnect) {
373 client_socket_factory_.set_default_client_socket_type(
374 MockTransportClientSocketFactory::Type::kPending);
375 ClientSocketHandle handle;
376 TestCompletionCallback callback;
377 EXPECT_EQ(
378 ERR_IO_PENDING,
379 handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
380 kDefaultPriority, SocketTag(),
381 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
382 ClientSocketPool::ProxyAuthCallback(), &pool_,
383 NetLogWithSource()));
384
385 handle.Reset();
386
387 TestCompletionCallback callback2;
388 EXPECT_EQ(
389 ERR_IO_PENDING,
390 handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
391 kDefaultPriority, SocketTag(),
392 ClientSocketPool::RespectLimits::ENABLED,
393 callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
394 &pool_, NetLogWithSource()));
395
396 host_resolver_->set_synchronous_mode(true);
397 // At this point, handle has two ConnectingSockets out for it. Due to the
398 // setting the mock resolver into synchronous mode, the host resolution for
399 // both will return in the same loop of the MessageLoop. The client socket
400 // is a pending socket, so the Connect() will asynchronously complete on the
401 // next loop of the MessageLoop. That means that the first
402 // ConnectingSocket will enter OnIOComplete, and then the second one will.
403 // If the first one is not cancelled, it will advance the load state, and
404 // then the second one will crash.
405
406 EXPECT_THAT(callback2.WaitForResult(), IsOk());
407 EXPECT_FALSE(callback.have_result());
408
409 handle.Reset();
410 }
411
TEST_F(WebSocketTransportClientSocketPoolTest,CancelRequest)412 TEST_F(WebSocketTransportClientSocketPoolTest, CancelRequest) {
413 // First request finishes asynchronously.
414 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
415 EXPECT_THAT(request(0)->WaitForResult(), IsOk());
416
417 // Make all subsequent host resolutions complete synchronously.
418 host_resolver_->set_synchronous_mode(true);
419
420 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
421 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
422 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
423 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
424 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
425
426 // Cancel a request.
427 const size_t index_to_cancel = 2;
428 EXPECT_FALSE(request(index_to_cancel)->handle()->is_initialized());
429 request(index_to_cancel)->handle()->Reset();
430
431 ReleaseAllConnections(ClientSocketPoolTest::KEEP_ALIVE);
432
433 EXPECT_EQ(5, client_socket_factory_.allocation_count());
434
435 EXPECT_EQ(1, GetOrderOfRequest(1));
436 EXPECT_EQ(2, GetOrderOfRequest(2));
437 EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound,
438 GetOrderOfRequest(3)); // Canceled request.
439 EXPECT_EQ(3, GetOrderOfRequest(4));
440 EXPECT_EQ(4, GetOrderOfRequest(5));
441 EXPECT_EQ(5, GetOrderOfRequest(6));
442
443 // Make sure we test order of all requests made.
444 EXPECT_EQ(ClientSocketPoolTest::kIndexOutOfBounds, GetOrderOfRequest(7));
445 }
446
447 // Function to be used as a callback on socket request completion. It first
448 // disconnects the successfully connected socket from the first request, and
449 // then reuses the ClientSocketHandle to request another socket. The second
450 // request is expected to succeed asynchronously.
451 //
452 // |nested_callback| is called with the result of the second socket request.
RequestSocketOnComplete(const ClientSocketPool::GroupId & group_id,ClientSocketHandle * handle,WebSocketTransportClientSocketPool * pool,TestCompletionCallback * nested_callback,int first_request_result)453 void RequestSocketOnComplete(const ClientSocketPool::GroupId& group_id,
454 ClientSocketHandle* handle,
455 WebSocketTransportClientSocketPool* pool,
456 TestCompletionCallback* nested_callback,
457 int first_request_result) {
458 EXPECT_THAT(first_request_result, IsOk());
459
460 // Don't allow reuse of the socket. Disconnect it and then release it.
461 handle->socket()->Disconnect();
462 handle->Reset();
463
464 int rv = handle->Init(
465 group_id, ClientSocketPool::SocketParams::CreateForHttpForTesting(),
466 std::nullopt /* proxy_annotation_tag */, LOWEST, SocketTag(),
467 ClientSocketPool::RespectLimits::ENABLED, nested_callback->callback(),
468 ClientSocketPool::ProxyAuthCallback(), pool, NetLogWithSource());
469 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
470 if (ERR_IO_PENDING != rv) {
471 nested_callback->callback().Run(rv);
472 }
473 }
474
475 // Tests the case where a second socket is requested in a completion callback,
476 // and the second socket connects asynchronously. Reuses the same
477 // ClientSocketHandle for the second socket, after disconnecting the first.
TEST_F(WebSocketTransportClientSocketPoolTest,RequestTwice)478 TEST_F(WebSocketTransportClientSocketPoolTest, RequestTwice) {
479 ClientSocketHandle handle;
480 TestCompletionCallback second_result_callback;
481 int rv = handle.Init(
482 group_id_, ClientSocketPool::SocketParams::CreateForHttpForTesting(),
483 std::nullopt /* proxy_annotation_tag */, LOWEST, SocketTag(),
484 ClientSocketPool::RespectLimits::ENABLED,
485 base::BindOnce(&RequestSocketOnComplete, group_id_, &handle, &pool_,
486 &second_result_callback),
487 ClientSocketPool::ProxyAuthCallback(), &pool_, NetLogWithSource());
488 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
489 EXPECT_THAT(second_result_callback.WaitForResult(), IsOk());
490
491 handle.Reset();
492 }
493
494 // Make sure that pending requests get serviced after active requests get
495 // cancelled.
TEST_F(WebSocketTransportClientSocketPoolTest,CancelActiveRequestWithPendingRequests)496 TEST_F(WebSocketTransportClientSocketPoolTest,
497 CancelActiveRequestWithPendingRequests) {
498 client_socket_factory_.set_default_client_socket_type(
499 MockTransportClientSocketFactory::Type::kPending);
500
501 // Queue up all the requests
502 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
503 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
504 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
505 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
506 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
507 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
508 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
509 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
510 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
511
512 // Now, kMaxSocketsPerGroup requests should be active. Let's cancel them.
513 ASSERT_LE(kMaxSocketsPerGroup, static_cast<int>(requests()->size()));
514 for (int i = 0; i < kMaxSocketsPerGroup; i++) {
515 request(i)->handle()->Reset();
516 }
517
518 // Let's wait for the rest to complete now.
519 for (size_t i = kMaxSocketsPerGroup; i < requests()->size(); ++i) {
520 EXPECT_THAT(request(i)->WaitForResult(), IsOk());
521 request(i)->handle()->Reset();
522 }
523
524 EXPECT_EQ(requests()->size() - kMaxSocketsPerGroup, completion_count());
525 }
526
527 // Make sure that pending requests get serviced after active requests fail.
TEST_F(WebSocketTransportClientSocketPoolTest,FailingActiveRequestWithPendingRequests)528 TEST_F(WebSocketTransportClientSocketPoolTest,
529 FailingActiveRequestWithPendingRequests) {
530 client_socket_factory_.set_default_client_socket_type(
531 MockTransportClientSocketFactory::Type::kPendingFailing);
532
533 const int kNumRequests = 2 * kMaxSocketsPerGroup + 1;
534 ASSERT_LE(kNumRequests, kMaxSockets); // Otherwise the test will hang.
535
536 // Queue up all the requests
537 for (int i = 0; i < kNumRequests; i++) {
538 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
539 }
540
541 for (int i = 0; i < kNumRequests; i++) {
542 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_CONNECTION_FAILED));
543 }
544 }
545
546 // The lock on the endpoint is released when a ClientSocketHandle is reset.
TEST_F(WebSocketTransportClientSocketPoolTest,LockReleasedOnHandleReset)547 TEST_F(WebSocketTransportClientSocketPoolTest, LockReleasedOnHandleReset) {
548 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
549 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
550 EXPECT_THAT(request(0)->WaitForResult(), IsOk());
551 EXPECT_FALSE(request(1)->handle()->is_initialized());
552 request(0)->handle()->Reset();
553 RunUntilIdle();
554 EXPECT_TRUE(request(1)->handle()->is_initialized());
555 }
556
557 // The lock on the endpoint is released when a ClientSocketHandle is deleted.
TEST_F(WebSocketTransportClientSocketPoolTest,LockReleasedOnHandleDelete)558 TEST_F(WebSocketTransportClientSocketPoolTest, LockReleasedOnHandleDelete) {
559 TestCompletionCallback callback;
560 auto handle = std::make_unique<ClientSocketHandle>();
561 int rv =
562 handle->Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
563 LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
564 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
565 &pool_, NetLogWithSource());
566 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
567
568 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
569 EXPECT_THAT(callback.WaitForResult(), IsOk());
570 EXPECT_FALSE(request(0)->handle()->is_initialized());
571 handle.reset();
572 RunUntilIdle();
573 EXPECT_TRUE(request(0)->handle()->is_initialized());
574 }
575
576 // A new connection is performed when the lock on the previous connection is
577 // explicitly released.
TEST_F(WebSocketTransportClientSocketPoolTest,ConnectionProceedsOnExplicitRelease)578 TEST_F(WebSocketTransportClientSocketPoolTest,
579 ConnectionProceedsOnExplicitRelease) {
580 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
581 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
582 EXPECT_THAT(request(0)->WaitForResult(), IsOk());
583 EXPECT_FALSE(request(1)->handle()->is_initialized());
584 WebSocketTransportClientSocketPool::UnlockEndpoint(
585 request(0)->handle(), &websocket_endpoint_lock_manager_);
586 RunUntilIdle();
587 EXPECT_TRUE(request(1)->handle()->is_initialized());
588 }
589
590 // A connection which is cancelled before completion does not block subsequent
591 // connections.
TEST_F(WebSocketTransportClientSocketPoolTest,CancelDuringConnectionReleasesLock)592 TEST_F(WebSocketTransportClientSocketPoolTest,
593 CancelDuringConnectionReleasesLock) {
594 MockTransportClientSocketFactory::Rule rules[] = {
595 MockTransportClientSocketFactory::Rule(
596 MockTransportClientSocketFactory::Type::kStalled),
597 MockTransportClientSocketFactory::Rule(
598 MockTransportClientSocketFactory::Type::kPending)};
599
600 client_socket_factory_.SetRules(rules);
601
602 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
603 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
604 RunUntilIdle();
605 pool_.CancelRequest(group_id_, request(0)->handle(),
606 false /* cancel_connect_job */);
607 EXPECT_THAT(request(1)->WaitForResult(), IsOk());
608 }
609
610 // Test the case of the IPv6 address stalling, and falling back to the IPv4
611 // socket which finishes first.
TEST_F(WebSocketTransportClientSocketPoolTest,IPv6FallbackSocketIPv4FinishesFirst)612 TEST_F(WebSocketTransportClientSocketPoolTest,
613 IPv6FallbackSocketIPv4FinishesFirst) {
614 MockTransportClientSocketFactory::Rule rules[] = {
615 // This is the IPv6 socket.
616 MockTransportClientSocketFactory::Rule(
617 MockTransportClientSocketFactory::Type::kStalled),
618 // This is the IPv4 socket.
619 MockTransportClientSocketFactory::Rule(
620 MockTransportClientSocketFactory::Type::kPending)};
621
622 client_socket_factory_.SetRules(rules);
623
624 // Resolve an AddressList with an IPv6 address first and then an IPv4 address.
625 host_resolver_->rules()->AddIPLiteralRule("*", "2:abcd::3:4:ff,2.2.2.2",
626 std::string());
627
628 TestCompletionCallback callback;
629 ClientSocketHandle handle;
630 int rv =
631 handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
632 LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
633 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
634 &pool_, NetLogWithSource());
635 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
636 EXPECT_FALSE(handle.is_initialized());
637 EXPECT_FALSE(handle.socket());
638
639 EXPECT_THAT(callback.WaitForResult(), IsOk());
640 EXPECT_TRUE(handle.is_initialized());
641 EXPECT_TRUE(handle.socket());
642 IPEndPoint endpoint;
643 handle.socket()->GetLocalAddress(&endpoint);
644 EXPECT_TRUE(endpoint.address().IsIPv4());
645 EXPECT_EQ(2, client_socket_factory_.allocation_count());
646 }
647
648 // Test the case of the IPv6 address being slow, thus falling back to trying to
649 // connect to the IPv4 address, but having the connect to the IPv6 address
650 // finish first.
TEST_F(WebSocketTransportClientSocketPoolTest,IPv6FallbackSocketIPv6FinishesFirst)651 TEST_F(WebSocketTransportClientSocketPoolTest,
652 IPv6FallbackSocketIPv6FinishesFirst) {
653 MockTransportClientSocketFactory::Rule rules[] = {
654 // This is the IPv6 socket.
655 MockTransportClientSocketFactory::Rule(
656 MockTransportClientSocketFactory::Type::kDelayed),
657 // This is the IPv4 socket.
658 MockTransportClientSocketFactory::Rule(
659 MockTransportClientSocketFactory::Type::kStalled)};
660
661 client_socket_factory_.SetRules(rules);
662 client_socket_factory_.set_delay(TransportConnectJob::kIPv6FallbackTime +
663 base::Milliseconds(50));
664
665 // Resolve an AddressList with an IPv6 address first and then an IPv4 address.
666 host_resolver_->rules()->AddIPLiteralRule("*", "2:abcd::3:4:ff,2.2.2.2",
667 std::string());
668
669 TestCompletionCallback callback;
670 ClientSocketHandle handle;
671 int rv =
672 handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
673 LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
674 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
675 &pool_, NetLogWithSource());
676 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
677 EXPECT_FALSE(handle.is_initialized());
678 EXPECT_FALSE(handle.socket());
679
680 EXPECT_THAT(callback.WaitForResult(), IsOk());
681 EXPECT_TRUE(handle.is_initialized());
682 EXPECT_TRUE(handle.socket());
683 IPEndPoint endpoint;
684 handle.socket()->GetLocalAddress(&endpoint);
685 EXPECT_TRUE(endpoint.address().IsIPv6());
686 EXPECT_EQ(2, client_socket_factory_.allocation_count());
687 }
688
TEST_F(WebSocketTransportClientSocketPoolTest,IPv6NoIPv4AddressesToFallbackTo)689 TEST_F(WebSocketTransportClientSocketPoolTest,
690 IPv6NoIPv4AddressesToFallbackTo) {
691 client_socket_factory_.set_default_client_socket_type(
692 MockTransportClientSocketFactory::Type::kDelayed);
693
694 // Resolve an AddressList with only IPv6 addresses.
695 host_resolver_->rules()->AddIPLiteralRule(
696 "*", "2:abcd::3:4:ff,3:abcd::3:4:ff", std::string());
697
698 TestCompletionCallback callback;
699 ClientSocketHandle handle;
700 int rv =
701 handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
702 LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
703 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
704 &pool_, NetLogWithSource());
705 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
706 EXPECT_FALSE(handle.is_initialized());
707 EXPECT_FALSE(handle.socket());
708
709 EXPECT_THAT(callback.WaitForResult(), IsOk());
710 EXPECT_TRUE(handle.is_initialized());
711 EXPECT_TRUE(handle.socket());
712 IPEndPoint endpoint;
713 handle.socket()->GetLocalAddress(&endpoint);
714 EXPECT_TRUE(endpoint.address().IsIPv6());
715 EXPECT_EQ(1, client_socket_factory_.allocation_count());
716 }
717
TEST_F(WebSocketTransportClientSocketPoolTest,IPv4HasNoFallback)718 TEST_F(WebSocketTransportClientSocketPoolTest, IPv4HasNoFallback) {
719 client_socket_factory_.set_default_client_socket_type(
720 MockTransportClientSocketFactory::Type::kDelayed);
721
722 // Resolve an AddressList with only IPv4 addresses.
723 host_resolver_->rules()->AddIPLiteralRule("*", "1.1.1.1", std::string());
724
725 TestCompletionCallback callback;
726 ClientSocketHandle handle;
727 int rv =
728 handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
729 LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
730 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
731 &pool_, NetLogWithSource());
732 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
733 EXPECT_FALSE(handle.is_initialized());
734 EXPECT_FALSE(handle.socket());
735
736 EXPECT_THAT(callback.WaitForResult(), IsOk());
737 EXPECT_TRUE(handle.is_initialized());
738 EXPECT_TRUE(handle.socket());
739 IPEndPoint endpoint;
740 handle.socket()->GetLocalAddress(&endpoint);
741 EXPECT_TRUE(endpoint.address().IsIPv4());
742 EXPECT_EQ(1, client_socket_factory_.allocation_count());
743 }
744
745 // If all IPv6 addresses fail to connect synchronously, then IPv4 connections
746 // proceeed immediately.
TEST_F(WebSocketTransportClientSocketPoolTest,IPv6InstantFail)747 TEST_F(WebSocketTransportClientSocketPoolTest, IPv6InstantFail) {
748 MockTransportClientSocketFactory::Rule rules[] = {
749 // First IPv6 socket.
750 MockTransportClientSocketFactory::Rule(
751 MockTransportClientSocketFactory::Type::kFailing),
752 // Second IPv6 socket.
753 MockTransportClientSocketFactory::Rule(
754 MockTransportClientSocketFactory::Type::kFailing),
755 // This is the IPv4 socket.
756 MockTransportClientSocketFactory::Rule(
757 MockTransportClientSocketFactory::Type::kSynchronous)};
758
759 client_socket_factory_.SetRules(rules);
760
761 // Resolve an AddressList with two IPv6 addresses and then an IPv4 address.
762 host_resolver_->rules()->AddIPLiteralRule(
763 "*", "2:abcd::3:4:ff,2:abcd::3:5:ff,2.2.2.2", std::string());
764 host_resolver_->set_synchronous_mode(true);
765 TestCompletionCallback callback;
766 ClientSocketHandle handle;
767 int rv =
768 handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
769 LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
770 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
771 &pool_, NetLogWithSource());
772 EXPECT_THAT(rv, IsOk());
773 ASSERT_TRUE(handle.socket());
774
775 IPEndPoint endpoint;
776 handle.socket()->GetPeerAddress(&endpoint);
777 EXPECT_EQ("2.2.2.2", endpoint.ToStringWithoutPort());
778 }
779
780 // If all IPv6 addresses fail before the IPv4 fallback timeout, then the IPv4
781 // connections proceed immediately.
TEST_F(WebSocketTransportClientSocketPoolTest,IPv6RapidFail)782 TEST_F(WebSocketTransportClientSocketPoolTest, IPv6RapidFail) {
783 MockTransportClientSocketFactory::Rule rules[] = {
784 // First IPv6 socket.
785 MockTransportClientSocketFactory::Rule(
786 MockTransportClientSocketFactory::Type::kPendingFailing),
787 // Second IPv6 socket.
788 MockTransportClientSocketFactory::Rule(
789 MockTransportClientSocketFactory::Type::kPendingFailing),
790 // This is the IPv4 socket.
791 MockTransportClientSocketFactory::Rule(
792 MockTransportClientSocketFactory::Type::kSynchronous)};
793
794 client_socket_factory_.SetRules(rules);
795
796 // Resolve an AddressList with two IPv6 addresses and then an IPv4 address.
797 host_resolver_->rules()->AddIPLiteralRule(
798 "*", "2:abcd::3:4:ff,2:abcd::3:5:ff,2.2.2.2", std::string());
799
800 TestCompletionCallback callback;
801 ClientSocketHandle handle;
802 int rv =
803 handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
804 LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
805 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
806 &pool_, NetLogWithSource());
807 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
808 EXPECT_FALSE(handle.socket());
809
810 base::TimeTicks start(base::TimeTicks::Now());
811 EXPECT_THAT(callback.WaitForResult(), IsOk());
812 EXPECT_LT(base::TimeTicks::Now() - start,
813 TransportConnectJob::kIPv6FallbackTime);
814 ASSERT_TRUE(handle.socket());
815
816 IPEndPoint endpoint;
817 handle.socket()->GetPeerAddress(&endpoint);
818 EXPECT_EQ("2.2.2.2", endpoint.ToStringWithoutPort());
819 }
820
821 // If two sockets connect successfully, the one which connected first wins (this
822 // can only happen if the sockets are different types, since sockets of the same
823 // type do not race).
TEST_F(WebSocketTransportClientSocketPoolTest,FirstSuccessWins)824 TEST_F(WebSocketTransportClientSocketPoolTest, FirstSuccessWins) {
825 client_socket_factory_.set_default_client_socket_type(
826 MockTransportClientSocketFactory::Type::kTriggerable);
827
828 // Resolve an AddressList with an IPv6 addresses and an IPv4 address.
829 host_resolver_->rules()->AddIPLiteralRule("*", "2:abcd::3:4:ff,2.2.2.2",
830 std::string());
831
832 TestCompletionCallback callback;
833 ClientSocketHandle handle;
834 int rv =
835 handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
836 LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
837 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
838 &pool_, NetLogWithSource());
839 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
840 ASSERT_FALSE(handle.socket());
841
842 base::OnceClosure ipv6_connect_trigger =
843 client_socket_factory_.WaitForTriggerableSocketCreation();
844 base::OnceClosure ipv4_connect_trigger =
845 client_socket_factory_.WaitForTriggerableSocketCreation();
846
847 std::move(ipv4_connect_trigger).Run();
848 std::move(ipv6_connect_trigger).Run();
849
850 EXPECT_THAT(callback.WaitForResult(), IsOk());
851 ASSERT_TRUE(handle.socket());
852
853 IPEndPoint endpoint;
854 handle.socket()->GetPeerAddress(&endpoint);
855 EXPECT_EQ("2.2.2.2", endpoint.ToStringWithoutPort());
856 }
857
858 // We should not report failure until all connections have failed.
TEST_F(WebSocketTransportClientSocketPoolTest,LastFailureWins)859 TEST_F(WebSocketTransportClientSocketPoolTest, LastFailureWins) {
860 client_socket_factory_.set_default_client_socket_type(
861 MockTransportClientSocketFactory::Type::kDelayedFailing);
862 base::TimeDelta delay = TransportConnectJob::kIPv6FallbackTime / 3;
863 client_socket_factory_.set_delay(delay);
864
865 // Resolve an AddressList with 4 IPv6 addresses and 2 IPv4 addresses.
866 host_resolver_->rules()->AddIPLiteralRule("*",
867 "1:abcd::3:4:ff,2:abcd::3:4:ff,"
868 "3:abcd::3:4:ff,4:abcd::3:4:ff,"
869 "1.1.1.1,2.2.2.2",
870 std::string());
871
872 // Expected order of events:
873 // After 100ms: Connect to 1:abcd::3:4:ff times out
874 // After 200ms: Connect to 2:abcd::3:4:ff times out
875 // After 300ms: Connect to 3:abcd::3:4:ff times out, IPv4 fallback starts
876 // After 400ms: Connect to 4:abcd::3:4:ff and 1.1.1.1 time out
877 // After 500ms: Connect to 2.2.2.2 times out
878
879 TestCompletionCallback callback;
880 ClientSocketHandle handle;
881 base::TimeTicks start(base::TimeTicks::Now());
882 int rv =
883 handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
884 LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
885 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
886 &pool_, NetLogWithSource());
887 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
888
889 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED));
890
891 EXPECT_GE(base::TimeTicks::Now() - start, delay * 5);
892
893 // The order is slightly timing-dependent, so don't assert on the order.
894 EXPECT_THAT(handle.connection_attempts(),
895 testing::UnorderedElementsAre(
896 ConnectionAttempt(IPEndPoint(ParseIP("1:abcd::3:4:ff"), 80),
897 ERR_CONNECTION_FAILED),
898 ConnectionAttempt(IPEndPoint(ParseIP("2:abcd::3:4:ff"), 80),
899 ERR_CONNECTION_FAILED),
900 ConnectionAttempt(IPEndPoint(ParseIP("3:abcd::3:4:ff"), 80),
901 ERR_CONNECTION_FAILED),
902 ConnectionAttempt(IPEndPoint(ParseIP("4:abcd::3:4:ff"), 80),
903 ERR_CONNECTION_FAILED),
904 ConnectionAttempt(IPEndPoint(ParseIP("1.1.1.1"), 80),
905 ERR_CONNECTION_FAILED),
906 ConnectionAttempt(IPEndPoint(ParseIP("2.2.2.2"), 80),
907 ERR_CONNECTION_FAILED)));
908 }
909
910 // Test that, if an address fails due to `ERR_NETWORK_IO_SUSPENDED`, we do not
911 // try subsequent addresses.
TEST_F(WebSocketTransportClientSocketPoolTest,Suspend)912 TEST_F(WebSocketTransportClientSocketPoolTest, Suspend) {
913 // Resolve an AddressList with 4 IPv6 addresses and 2 IPv4 addresses.
914 host_resolver_->rules()->AddIPLiteralRule("*",
915 "1:abcd::3:4:ff,2:abcd::3:4:ff,"
916 "3:abcd::3:4:ff,4:abcd::3:4:ff,"
917 "1.1.1.1,2.2.2.2",
918 std::string());
919
920 // The first connection attempt will fail, after which no more will be
921 // attempted.
922 MockTransportClientSocketFactory::Rule rule(
923 MockTransportClientSocketFactory::Type::kFailing,
924 std::vector{IPEndPoint(ParseIP("1:abcd::3:4:ff"), 80)},
925 ERR_NETWORK_IO_SUSPENDED);
926 client_socket_factory_.SetRules(base::make_span(&rule, 1u));
927
928 TestCompletionCallback callback;
929 ClientSocketHandle handle;
930 int rv =
931 handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
932 LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
933 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
934 &pool_, NetLogWithSource());
935 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NETWORK_IO_SUSPENDED));
936 EXPECT_THAT(handle.connection_attempts(),
937 testing::ElementsAre(
938 ConnectionAttempt(IPEndPoint(ParseIP("1:abcd::3:4:ff"), 80),
939 ERR_NETWORK_IO_SUSPENDED)));
940 }
941
942 // Same as above, but with a asynchronous failure.
TEST_F(WebSocketTransportClientSocketPoolTest,SuspendAsync)943 TEST_F(WebSocketTransportClientSocketPoolTest, SuspendAsync) {
944 // Resolve an AddressList with 4 IPv6 addresses and 2 IPv4 addresses.
945 host_resolver_->rules()->AddIPLiteralRule("*",
946 "1:abcd::3:4:ff,2:abcd::3:4:ff,"
947 "3:abcd::3:4:ff,4:abcd::3:4:ff,"
948 "1.1.1.1,2.2.2.2",
949 std::string());
950
951 // The first connection attempt will fail, after which no more will be
952 // attempted.
953 MockTransportClientSocketFactory::Rule rule(
954 MockTransportClientSocketFactory::Type::kPendingFailing,
955 std::vector{IPEndPoint(ParseIP("1:abcd::3:4:ff"), 80)},
956 ERR_NETWORK_IO_SUSPENDED);
957 client_socket_factory_.SetRules(base::make_span(&rule, 1u));
958
959 TestCompletionCallback callback;
960 ClientSocketHandle handle;
961 int rv =
962 handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
963 LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
964 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
965 &pool_, NetLogWithSource());
966 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NETWORK_IO_SUSPENDED));
967 EXPECT_THAT(handle.connection_attempts(),
968 testing::ElementsAre(
969 ConnectionAttempt(IPEndPoint(ParseIP("1:abcd::3:4:ff"), 80),
970 ERR_NETWORK_IO_SUSPENDED)));
971 }
972
973 // Global timeout for all connects applies. This test is disabled by default
974 // because it takes 4 minutes. Run with --gtest_also_run_disabled_tests if you
975 // want to run it.
TEST_F(WebSocketTransportClientSocketPoolTest,DISABLED_OverallTimeoutApplies)976 TEST_F(WebSocketTransportClientSocketPoolTest, DISABLED_OverallTimeoutApplies) {
977 const base::TimeDelta connect_job_timeout =
978 TransportConnectJob::ConnectionTimeout();
979
980 client_socket_factory_.set_default_client_socket_type(
981 MockTransportClientSocketFactory::Type::kDelayedFailing);
982 client_socket_factory_.set_delay(base::Seconds(1) + connect_job_timeout / 6);
983
984 // Resolve an AddressList with 6 IPv6 addresses and 6 IPv4 addresses.
985 host_resolver_->rules()->AddIPLiteralRule("*",
986 "1:abcd::3:4:ff,2:abcd::3:4:ff,"
987 "3:abcd::3:4:ff,4:abcd::3:4:ff,"
988 "5:abcd::3:4:ff,6:abcd::3:4:ff,"
989 "1.1.1.1,2.2.2.2,3.3.3.3,"
990 "4.4.4.4,5.5.5.5,6.6.6.6",
991 std::string());
992
993 TestCompletionCallback callback;
994 ClientSocketHandle handle;
995
996 int rv =
997 handle.Init(group_id_, params_, std::nullopt /* proxy_annotation_tag */,
998 LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
999 callback.callback(), ClientSocketPool::ProxyAuthCallback(),
1000 &pool_, NetLogWithSource());
1001 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1002
1003 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_TIMED_OUT));
1004 }
1005
TEST_F(WebSocketTransportClientSocketPoolTest,MaxSocketsEnforced)1006 TEST_F(WebSocketTransportClientSocketPoolTest, MaxSocketsEnforced) {
1007 host_resolver_->set_synchronous_mode(true);
1008 for (int i = 0; i < kMaxSockets; ++i) {
1009 ASSERT_THAT(StartRequest(kDefaultPriority), IsOk());
1010 WebSocketTransportClientSocketPool::UnlockEndpoint(
1011 request(i)->handle(), &websocket_endpoint_lock_manager_);
1012 RunUntilIdle();
1013 }
1014 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
1015 }
1016
TEST_F(WebSocketTransportClientSocketPoolTest,MaxSocketsEnforcedWhenPending)1017 TEST_F(WebSocketTransportClientSocketPoolTest, MaxSocketsEnforcedWhenPending) {
1018 for (int i = 0; i < kMaxSockets + 1; ++i) {
1019 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
1020 }
1021 // Now there are 32 sockets waiting to connect, and one stalled.
1022 for (int i = 0; i < kMaxSockets; ++i) {
1023 RunUntilIdle();
1024 EXPECT_TRUE(request(i)->handle()->is_initialized());
1025 EXPECT_TRUE(request(i)->handle()->socket());
1026 WebSocketTransportClientSocketPool::UnlockEndpoint(
1027 request(i)->handle(), &websocket_endpoint_lock_manager_);
1028 }
1029 // Now there are 32 sockets connected, and one stalled.
1030 RunUntilIdle();
1031 EXPECT_FALSE(request(kMaxSockets)->handle()->is_initialized());
1032 EXPECT_FALSE(request(kMaxSockets)->handle()->socket());
1033 }
1034
TEST_F(WebSocketTransportClientSocketPoolTest,StalledSocketReleased)1035 TEST_F(WebSocketTransportClientSocketPoolTest, StalledSocketReleased) {
1036 host_resolver_->set_synchronous_mode(true);
1037 for (int i = 0; i < kMaxSockets; ++i) {
1038 ASSERT_THAT(StartRequest(kDefaultPriority), IsOk());
1039 WebSocketTransportClientSocketPool::UnlockEndpoint(
1040 request(i)->handle(), &websocket_endpoint_lock_manager_);
1041 RunUntilIdle();
1042 }
1043
1044 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
1045 ReleaseOneConnection(ClientSocketPoolTest::NO_KEEP_ALIVE);
1046 EXPECT_TRUE(request(kMaxSockets)->handle()->is_initialized());
1047 EXPECT_TRUE(request(kMaxSockets)->handle()->socket());
1048 }
1049
TEST_F(WebSocketTransportClientSocketPoolTest,IsStalledTrueWhenStalled)1050 TEST_F(WebSocketTransportClientSocketPoolTest, IsStalledTrueWhenStalled) {
1051 for (int i = 0; i < kMaxSockets + 1; ++i) {
1052 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
1053 }
1054 EXPECT_THAT(request(0)->WaitForResult(), IsOk());
1055 EXPECT_TRUE(pool_.IsStalled());
1056 }
1057
TEST_F(WebSocketTransportClientSocketPoolTest,CancellingPendingSocketUnstallsStalledSocket)1058 TEST_F(WebSocketTransportClientSocketPoolTest,
1059 CancellingPendingSocketUnstallsStalledSocket) {
1060 for (int i = 0; i < kMaxSockets + 1; ++i) {
1061 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
1062 }
1063 EXPECT_THAT(request(0)->WaitForResult(), IsOk());
1064 request(1)->handle()->Reset();
1065 RunUntilIdle();
1066 EXPECT_FALSE(pool_.IsStalled());
1067 }
1068
TEST_F(WebSocketTransportClientSocketPoolTest,LoadStateOfStalledSocketIsWaitingForAvailableSocket)1069 TEST_F(WebSocketTransportClientSocketPoolTest,
1070 LoadStateOfStalledSocketIsWaitingForAvailableSocket) {
1071 for (int i = 0; i < kMaxSockets + 1; ++i) {
1072 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
1073 }
1074 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET,
1075 pool_.GetLoadState(group_id_, request(kMaxSockets)->handle()));
1076 }
1077
TEST_F(WebSocketTransportClientSocketPoolTest,CancellingStalledSocketUnstallsPool)1078 TEST_F(WebSocketTransportClientSocketPoolTest,
1079 CancellingStalledSocketUnstallsPool) {
1080 for (int i = 0; i < kMaxSockets + 1; ++i) {
1081 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
1082 }
1083 request(kMaxSockets)->handle()->Reset();
1084 RunUntilIdle();
1085 EXPECT_FALSE(pool_.IsStalled());
1086 }
1087
TEST_F(WebSocketTransportClientSocketPoolTest,FlushWithErrorFlushesPendingConnections)1088 TEST_F(WebSocketTransportClientSocketPoolTest,
1089 FlushWithErrorFlushesPendingConnections) {
1090 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
1091 pool_.FlushWithError(ERR_FAILED, "Very good reason");
1092 EXPECT_THAT(request(0)->WaitForResult(), IsError(ERR_FAILED));
1093 }
1094
TEST_F(WebSocketTransportClientSocketPoolTest,FlushWithErrorFlushesStalledConnections)1095 TEST_F(WebSocketTransportClientSocketPoolTest,
1096 FlushWithErrorFlushesStalledConnections) {
1097 for (int i = 0; i < kMaxSockets + 1; ++i) {
1098 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
1099 }
1100 pool_.FlushWithError(ERR_FAILED, "Very good reason");
1101 EXPECT_THAT(request(kMaxSockets)->WaitForResult(), IsError(ERR_FAILED));
1102 }
1103
TEST_F(WebSocketTransportClientSocketPoolTest,AfterFlushWithErrorCanMakeNewConnections)1104 TEST_F(WebSocketTransportClientSocketPoolTest,
1105 AfterFlushWithErrorCanMakeNewConnections) {
1106 for (int i = 0; i < kMaxSockets + 1; ++i) {
1107 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
1108 }
1109 pool_.FlushWithError(ERR_FAILED, "Very good reason");
1110 host_resolver_->set_synchronous_mode(true);
1111 EXPECT_THAT(StartRequest(kDefaultPriority), IsOk());
1112 }
1113
1114 // Deleting pending connections can release the lock on the endpoint, which can
1115 // in principle lead to other pending connections succeeding. However, when we
1116 // call FlushWithError(), everything should fail.
TEST_F(WebSocketTransportClientSocketPoolTest,FlushWithErrorDoesNotCauseSuccessfulConnections)1117 TEST_F(WebSocketTransportClientSocketPoolTest,
1118 FlushWithErrorDoesNotCauseSuccessfulConnections) {
1119 host_resolver_->set_synchronous_mode(true);
1120 MockTransportClientSocketFactory::Rule first_rule[] = {
1121 // First socket
1122 MockTransportClientSocketFactory::Rule(
1123 MockTransportClientSocketFactory::Type::kPending),
1124 };
1125 client_socket_factory_.SetRules(first_rule);
1126 // The rest of the sockets will connect synchronously.
1127 client_socket_factory_.set_default_client_socket_type(
1128 MockTransportClientSocketFactory::Type::kSynchronous);
1129 for (int i = 0; i < kMaxSockets; ++i) {
1130 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
1131 }
1132 // Now we have one socket in STATE_TRANSPORT_CONNECT and the rest in
1133 // STATE_OBTAIN_LOCK. If any of the sockets in STATE_OBTAIN_LOCK is given the
1134 // lock, they will synchronously connect.
1135 pool_.FlushWithError(ERR_FAILED, "Very good reason");
1136 for (int i = 0; i < kMaxSockets; ++i) {
1137 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_FAILED));
1138 }
1139 }
1140
1141 // This is a regression test for the first attempted fix for
1142 // FlushWithErrorDoesNotCauseSuccessfulConnections. Because a ConnectJob can
1143 // have both IPv4 and IPv6 subjobs, it can be both connecting and waiting for
1144 // the lock at the same time.
TEST_F(WebSocketTransportClientSocketPoolTest,FlushWithErrorDoesNotCauseSuccessfulConnectionsMultipleAddressTypes)1145 TEST_F(WebSocketTransportClientSocketPoolTest,
1146 FlushWithErrorDoesNotCauseSuccessfulConnectionsMultipleAddressTypes) {
1147 host_resolver_->set_synchronous_mode(true);
1148 // The first |kMaxSockets| sockets to connect will be IPv6. Then we will have
1149 // one IPv4.
1150 std::vector<MockTransportClientSocketFactory::Rule> rules(
1151 kMaxSockets + 1, MockTransportClientSocketFactory::Rule(
1152 MockTransportClientSocketFactory::Type::kStalled));
1153 client_socket_factory_.SetRules(rules);
1154 // The rest of the sockets will connect synchronously.
1155 client_socket_factory_.set_default_client_socket_type(
1156 MockTransportClientSocketFactory::Type::kSynchronous);
1157 for (int i = 0; i < kMaxSockets; ++i) {
1158 host_resolver_->rules()->ClearRules();
1159 // Each connect job has a different IPv6 address but the same IPv4 address.
1160 // So the IPv6 connections happen in parallel but the IPv4 ones are
1161 // serialised.
1162 host_resolver_->rules()->AddIPLiteralRule(
1163 "*",
1164 base::StringPrintf("%x:abcd::3:4:ff,"
1165 "1.1.1.1",
1166 i + 1),
1167 std::string());
1168 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
1169 }
1170 // Now we have |kMaxSockets| IPv6 sockets stalled in connect. No IPv4 sockets
1171 // are started yet.
1172 RunLoopForTimePeriod(TransportConnectJob::kIPv6FallbackTime);
1173 // Now we have |kMaxSockets| IPv6 sockets and one IPv4 socket stalled in
1174 // connect, and |kMaxSockets - 1| IPv4 sockets waiting for the endpoint lock.
1175 pool_.FlushWithError(ERR_FAILED, "Very good reason");
1176 for (int i = 0; i < kMaxSockets; ++i) {
1177 EXPECT_THAT(request(i)->WaitForResult(), IsError(ERR_FAILED));
1178 }
1179 }
1180
1181 // Sockets that have had ownership transferred to a ClientSocketHandle should
1182 // not be affected by FlushWithError.
TEST_F(WebSocketTransportClientSocketPoolTest,FlushWithErrorDoesNotAffectHandedOutSockets)1183 TEST_F(WebSocketTransportClientSocketPoolTest,
1184 FlushWithErrorDoesNotAffectHandedOutSockets) {
1185 host_resolver_->set_synchronous_mode(true);
1186 MockTransportClientSocketFactory::Rule rules[] = {
1187 MockTransportClientSocketFactory::Rule(
1188 MockTransportClientSocketFactory::Type::kSynchronous),
1189 MockTransportClientSocketFactory::Rule(
1190 MockTransportClientSocketFactory::Type::kStalled)};
1191 client_socket_factory_.SetRules(rules);
1192 EXPECT_THAT(StartRequest(kDefaultPriority), IsOk());
1193 // Socket has been "handed out".
1194 EXPECT_TRUE(request(0)->handle()->socket());
1195
1196 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
1197 // Now we have one socket handed out, and one pending.
1198 pool_.FlushWithError(ERR_FAILED, "Very good reason");
1199 EXPECT_THAT(request(1)->WaitForResult(), IsError(ERR_FAILED));
1200 // Socket owned by ClientSocketHandle is unaffected:
1201 EXPECT_TRUE(request(0)->handle()->socket());
1202 // Return it to the pool (which deletes it).
1203 request(0)->handle()->Reset();
1204 }
1205
1206 // Sockets should not be leaked if CancelRequest() is called in between
1207 // SetSocket() being called on the ClientSocketHandle and InvokeUserCallback().
TEST_F(WebSocketTransportClientSocketPoolTest,CancelRequestReclaimsSockets)1208 TEST_F(WebSocketTransportClientSocketPoolTest, CancelRequestReclaimsSockets) {
1209 host_resolver_->set_synchronous_mode(true);
1210 MockTransportClientSocketFactory::Rule rules[] = {
1211 MockTransportClientSocketFactory::Rule(
1212 MockTransportClientSocketFactory::Type::kTriggerable),
1213 MockTransportClientSocketFactory::Rule(
1214 MockTransportClientSocketFactory::Type::kSynchronous)};
1215
1216 client_socket_factory_.SetRules(rules);
1217
1218 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
1219
1220 base::OnceClosure connect_trigger =
1221 client_socket_factory_.WaitForTriggerableSocketCreation();
1222
1223 std::move(connect_trigger).Run(); // Calls InvokeUserCallbackLater()
1224
1225 request(0)->handle()->Reset(); // calls CancelRequest()
1226
1227 RunUntilIdle();
1228 // We should now be able to create a new connection without blocking on the
1229 // endpoint lock.
1230 EXPECT_THAT(StartRequest(kDefaultPriority), IsOk());
1231 }
1232
1233 // A handshake completing and then the WebSocket closing should only release one
1234 // Endpoint, not two.
TEST_F(WebSocketTransportClientSocketPoolTest,EndpointLockIsOnlyReleasedOnce)1235 TEST_F(WebSocketTransportClientSocketPoolTest, EndpointLockIsOnlyReleasedOnce) {
1236 host_resolver_->set_synchronous_mode(true);
1237 ASSERT_THAT(StartRequest(kDefaultPriority), IsOk());
1238 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
1239 EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING));
1240 // First socket completes handshake.
1241 WebSocketTransportClientSocketPool::UnlockEndpoint(
1242 request(0)->handle(), &websocket_endpoint_lock_manager_);
1243 RunUntilIdle();
1244 // First socket is closed.
1245 request(0)->handle()->Reset();
1246 // Second socket should have been released.
1247 EXPECT_THAT(request(1)->WaitForResult(), IsOk());
1248 // Third socket should still be waiting for endpoint.
1249 ASSERT_FALSE(request(2)->handle()->is_initialized());
1250 EXPECT_EQ(LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET,
1251 request(2)->handle()->GetLoadState());
1252 }
1253
1254 // Make sure that WebSocket requests use the correct NetworkAnonymizationKey.
TEST_F(WebSocketTransportClientSocketPoolTest,NetworkAnonymizationKey)1255 TEST_F(WebSocketTransportClientSocketPoolTest, NetworkAnonymizationKey) {
1256 const SchemefulSite kSite(GURL("https://foo.test/"));
1257 const auto kNetworkAnonymizationKey =
1258 NetworkAnonymizationKey::CreateSameSite(kSite);
1259
1260 base::test::ScopedFeatureList scoped_feature_list;
1261 scoped_feature_list.InitWithFeatures(
1262 // enabled_features
1263 {features::kPartitionConnectionsByNetworkIsolationKey,
1264 features::kSplitHostCacheByNetworkIsolationKey},
1265 // disabled_features
1266 {});
1267
1268 host_resolver_->set_ondemand_mode(true);
1269
1270 TestCompletionCallback callback;
1271 ClientSocketHandle handle;
1272 ClientSocketPool::GroupId group_id(
1273 url::SchemeHostPort(url::kHttpScheme, "www.google.com", 80),
1274 PrivacyMode::PRIVACY_MODE_DISABLED, kNetworkAnonymizationKey,
1275 SecureDnsPolicy::kAllow, /*disable_cert_network_fetches=*/false);
1276 EXPECT_THAT(
1277 handle.Init(group_id, params_, std::nullopt /* proxy_annotation_tag */,
1278 kDefaultPriority, SocketTag(),
1279 ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
1280 ClientSocketPool::ProxyAuthCallback(), &pool_,
1281 NetLogWithSource()),
1282 IsError(ERR_IO_PENDING));
1283
1284 ASSERT_EQ(1u, host_resolver_->last_id());
1285 EXPECT_EQ(kNetworkAnonymizationKey,
1286 host_resolver_->request_network_anonymization_key(1));
1287 }
1288
TEST_F(WebSocketTransportClientSocketPoolTest,TransportConnectJobWithDnsAliases)1289 TEST_F(WebSocketTransportClientSocketPoolTest,
1290 TransportConnectJobWithDnsAliases) {
1291 host_resolver_->set_synchronous_mode(true);
1292 client_socket_factory_.set_default_client_socket_type(
1293 MockTransportClientSocketFactory::Type::kSynchronous);
1294
1295 // Resolve an AddressList with DNS aliases.
1296 std::string kHostName("host");
1297 std::vector<std::string> aliases({"alias1", "alias2", kHostName});
1298 host_resolver_->rules()->AddIPLiteralRuleWithDnsAliases(kHostName, "2.2.2.2",
1299 std::move(aliases));
1300
1301 TestConnectJobDelegate test_delegate;
1302 scoped_refptr<TransportSocketParams> params =
1303 base::MakeRefCounted<TransportSocketParams>(
1304 HostPortPair(kHostName, 80), NetworkAnonymizationKey(),
1305 SecureDnsPolicy::kAllow, OnHostResolutionCallback(),
1306 /*supported_alpns=*/base::flat_set<std::string>());
1307
1308 TransportConnectJob transport_connect_job(
1309 DEFAULT_PRIORITY, SocketTag(), &common_connect_job_params_, params,
1310 &test_delegate, nullptr /* net_log */);
1311
1312 test_delegate.StartJobExpectingResult(&transport_connect_job, OK,
1313 true /* expect_sync_result */);
1314
1315 // Verify that the elements of the alias list are those from the
1316 // parameter vector.
1317 EXPECT_THAT(test_delegate.socket()->GetDnsAliases(),
1318 testing::ElementsAre("alias1", "alias2", kHostName));
1319 }
1320
TEST_F(WebSocketTransportClientSocketPoolTest,TransportConnectJobWithNoAdditionalDnsAliases)1321 TEST_F(WebSocketTransportClientSocketPoolTest,
1322 TransportConnectJobWithNoAdditionalDnsAliases) {
1323 host_resolver_->set_synchronous_mode(true);
1324 client_socket_factory_.set_default_client_socket_type(
1325 MockTransportClientSocketFactory::Type::kSynchronous);
1326
1327 // Resolve an AddressList without additional DNS aliases. (The parameter
1328 // is an empty vector.)
1329 std::string kHostName("host");
1330 std::vector<std::string> aliases;
1331 host_resolver_->rules()->AddIPLiteralRuleWithDnsAliases(kHostName, "2.2.2.2",
1332 std::move(aliases));
1333
1334 TestConnectJobDelegate test_delegate;
1335 scoped_refptr<TransportSocketParams> params =
1336 base::MakeRefCounted<TransportSocketParams>(
1337 HostPortPair(kHostName, 80), NetworkAnonymizationKey(),
1338 SecureDnsPolicy::kAllow, OnHostResolutionCallback(),
1339 /*supported_alpns=*/base::flat_set<std::string>());
1340
1341 TransportConnectJob transport_connect_job(
1342 DEFAULT_PRIORITY, SocketTag(), &common_connect_job_params_, params,
1343 &test_delegate, nullptr /* net_log */);
1344
1345 test_delegate.StartJobExpectingResult(&transport_connect_job, OK,
1346 true /* expect_sync_result */);
1347
1348 // Verify that the alias list only contains kHostName.
1349 EXPECT_THAT(test_delegate.socket()->GetDnsAliases(),
1350 testing::ElementsAre(kHostName));
1351 }
1352
TEST_F(WebSocketTransportClientSocketPoolTest,LoadState)1353 TEST_F(WebSocketTransportClientSocketPoolTest, LoadState) {
1354 host_resolver_->rules()->AddRule("v6-only.test", "1:abcd::3:4:ff");
1355 host_resolver_->rules()->AddRule("v6-and-v4.test", "1:abcd::3:4:ff,2.2.2.2");
1356 host_resolver_->set_ondemand_mode(true);
1357
1358 client_socket_factory_.set_default_client_socket_type(
1359 MockTransportClientSocketFactory::Type::kDelayedFailing);
1360
1361 auto params_v6_only = base::MakeRefCounted<TransportSocketParams>(
1362 HostPortPair("v6-only.test", 80), NetworkAnonymizationKey(),
1363 SecureDnsPolicy::kAllow, OnHostResolutionCallback(),
1364 /*supported_alpns=*/base::flat_set<std::string>());
1365 auto params_v6_and_v4 = base::MakeRefCounted<TransportSocketParams>(
1366 HostPortPair("v6-and-v4.test", 80), NetworkAnonymizationKey(),
1367 SecureDnsPolicy::kAllow, OnHostResolutionCallback(),
1368 /*supported_alpns=*/base::flat_set<std::string>());
1369
1370 // v6-only.test will first block on DNS.
1371 TestConnectJobDelegate test_delegate_v6_only;
1372 TransportConnectJob connect_job_v6_only(
1373 DEFAULT_PRIORITY, SocketTag(), &common_connect_job_params_,
1374 params_v6_only, &test_delegate_v6_only, /*net_log=*/nullptr);
1375 EXPECT_THAT(connect_job_v6_only.Connect(), test::IsError(ERR_IO_PENDING));
1376 EXPECT_THAT(connect_job_v6_only.GetLoadState(), LOAD_STATE_RESOLVING_HOST);
1377
1378 // When DNS is resolved, it should block on making a connection.
1379 host_resolver_->ResolveOnlyRequestNow();
1380 base::RunLoop().RunUntilIdle();
1381 EXPECT_THAT(connect_job_v6_only.GetLoadState(), LOAD_STATE_CONNECTING);
1382
1383 // v6-and-v4.test will also first block on DNS.
1384 TestConnectJobDelegate test_delegate_v6_and_v4;
1385 TransportConnectJob connect_job_v6_and_v4(
1386 DEFAULT_PRIORITY, SocketTag(), &common_connect_job_params_,
1387 params_v6_and_v4, &test_delegate_v6_and_v4, /*net_log=*/nullptr);
1388 EXPECT_THAT(connect_job_v6_and_v4.Connect(), test::IsError(ERR_IO_PENDING));
1389 EXPECT_THAT(connect_job_v6_and_v4.GetLoadState(), LOAD_STATE_RESOLVING_HOST);
1390
1391 // When DNS is resolved, it should attempt to connect to the IPv6 address, but
1392 // `connect_job_v6_only` holds the lock.
1393 host_resolver_->ResolveOnlyRequestNow();
1394 RunUntilIdle();
1395 EXPECT_THAT(connect_job_v6_and_v4.GetLoadState(),
1396 LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET);
1397
1398 // After the IPv6 fallback timeout, it should attempt to connect to the IPv4
1399 // address. This lock is available, so `GetLoadState` should report it is now
1400 // actively connecting.
1401 RunLoopForTimePeriod(TransportConnectJob::kIPv6FallbackTime +
1402 base::Milliseconds(50));
1403 EXPECT_THAT(connect_job_v6_and_v4.GetLoadState(), LOAD_STATE_CONNECTING);
1404 }
1405
1406 } // namespace
1407
1408 } // namespace net
1409