OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/socket/transport_client_socket_pool.h" | 5 #include "net/socket/transport_client_socket_pool.h" |
6 | 6 |
7 #include "base/callback.h" | 7 #include "base/callback.h" |
8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
| 9 #include "base/logging.h" |
9 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
10 #include "base/threading/platform_thread.h" | 11 #include "base/threading/platform_thread.h" |
| 12 #include "net/base/ip_endpoint.h" |
11 #include "net/base/mock_host_resolver.h" | 13 #include "net/base/mock_host_resolver.h" |
12 #include "net/base/net_errors.h" | 14 #include "net/base/net_errors.h" |
| 15 #include "net/base/net_util.h" |
| 16 #include "net/base/sys_addrinfo.h" |
13 #include "net/base/test_completion_callback.h" | 17 #include "net/base/test_completion_callback.h" |
14 #include "net/socket/client_socket.h" | 18 #include "net/socket/client_socket.h" |
15 #include "net/socket/client_socket_factory.h" | 19 #include "net/socket/client_socket_factory.h" |
16 #include "net/socket/client_socket_handle.h" | 20 #include "net/socket/client_socket_handle.h" |
17 #include "net/socket/client_socket_pool_histograms.h" | 21 #include "net/socket/client_socket_pool_histograms.h" |
18 #include "net/socket/socket_test_util.h" | 22 #include "net/socket/socket_test_util.h" |
19 #include "net/socket/ssl_host_info.h" | 23 #include "net/socket/ssl_host_info.h" |
20 #include "testing/gtest/include/gtest/gtest.h" | 24 #include "testing/gtest/include/gtest/gtest.h" |
21 | 25 |
22 namespace net { | 26 namespace net { |
23 | 27 |
24 using internal::ClientSocketPoolBaseHelper; | 28 using internal::ClientSocketPoolBaseHelper; |
25 | 29 |
26 namespace { | 30 namespace { |
27 | 31 |
28 const int kMaxSockets = 32; | 32 const int kMaxSockets = 32; |
29 const int kMaxSocketsPerGroup = 6; | 33 const int kMaxSocketsPerGroup = 6; |
30 const net::RequestPriority kDefaultPriority = LOW; | 34 const net::RequestPriority kDefaultPriority = LOW; |
31 | 35 |
| 36 void SetIPv4Address(IPEndPoint* address) { |
| 37 IPAddressNumber number; |
| 38 CHECK(ParseIPLiteralToNumber("1.1.1.1", &number)); |
| 39 *address = IPEndPoint(number, 80); |
| 40 } |
| 41 |
| 42 void SetIPv6Address(IPEndPoint* address) { |
| 43 IPAddressNumber number; |
| 44 CHECK(ParseIPLiteralToNumber("1:abcd::3:4:ff", &number)); |
| 45 *address = IPEndPoint(number, 80); |
| 46 } |
| 47 |
32 class MockClientSocket : public ClientSocket { | 48 class MockClientSocket : public ClientSocket { |
33 public: | 49 public: |
34 MockClientSocket() : connected_(false) {} | 50 MockClientSocket(const AddressList& addrlist) |
| 51 : connected_(false), |
| 52 addrlist_(addrlist) {} |
35 | 53 |
36 // ClientSocket methods: | 54 // ClientSocket methods: |
37 virtual int Connect(CompletionCallback* callback) { | 55 virtual int Connect(CompletionCallback* callback) { |
38 connected_ = true; | 56 connected_ = true; |
39 return OK; | 57 return OK; |
40 } | 58 } |
41 virtual void Disconnect() { | 59 virtual void Disconnect() { |
42 connected_ = false; | 60 connected_ = false; |
43 } | 61 } |
44 virtual bool IsConnected() const { | 62 virtual bool IsConnected() const { |
45 return connected_; | 63 return connected_; |
46 } | 64 } |
47 virtual bool IsConnectedAndIdle() const { | 65 virtual bool IsConnectedAndIdle() const { |
48 return connected_; | 66 return connected_; |
49 } | 67 } |
50 virtual int GetPeerAddress(AddressList* address) const { | 68 virtual int GetPeerAddress(AddressList* address) const { |
51 return ERR_UNEXPECTED; | 69 return ERR_UNEXPECTED; |
52 } | 70 } |
53 virtual int GetLocalAddress(IPEndPoint* address) const { | 71 virtual int GetLocalAddress(IPEndPoint* address) const { |
54 return ERR_UNEXPECTED; | 72 if (!connected_) |
| 73 return ERR_SOCKET_NOT_CONNECTED; |
| 74 if (addrlist_.head()->ai_family == AF_INET) |
| 75 SetIPv4Address(address); |
| 76 else |
| 77 SetIPv6Address(address); |
| 78 return OK; |
55 } | 79 } |
56 virtual const BoundNetLog& NetLog() const { | 80 virtual const BoundNetLog& NetLog() const { |
57 return net_log_; | 81 return net_log_; |
58 } | 82 } |
59 | 83 |
60 virtual void SetSubresourceSpeculation() {} | 84 virtual void SetSubresourceSpeculation() {} |
61 virtual void SetOmniboxSpeculation() {} | 85 virtual void SetOmniboxSpeculation() {} |
62 virtual bool WasEverUsed() const { return false; } | 86 virtual bool WasEverUsed() const { return false; } |
63 virtual bool UsingTCPFastOpen() const { return false; } | 87 virtual bool UsingTCPFastOpen() const { return false; } |
64 | 88 |
65 // Socket methods: | 89 // Socket methods: |
66 virtual int Read(IOBuffer* buf, int buf_len, | 90 virtual int Read(IOBuffer* buf, int buf_len, |
67 CompletionCallback* callback) { | 91 CompletionCallback* callback) { |
68 return ERR_FAILED; | 92 return ERR_FAILED; |
69 } | 93 } |
70 virtual int Write(IOBuffer* buf, int buf_len, | 94 virtual int Write(IOBuffer* buf, int buf_len, |
71 CompletionCallback* callback) { | 95 CompletionCallback* callback) { |
72 return ERR_FAILED; | 96 return ERR_FAILED; |
73 } | 97 } |
74 virtual bool SetReceiveBufferSize(int32 size) { return true; } | 98 virtual bool SetReceiveBufferSize(int32 size) { return true; } |
75 virtual bool SetSendBufferSize(int32 size) { return true; } | 99 virtual bool SetSendBufferSize(int32 size) { return true; } |
76 | 100 |
77 private: | 101 private: |
78 bool connected_; | 102 bool connected_; |
| 103 const AddressList addrlist_; |
79 BoundNetLog net_log_; | 104 BoundNetLog net_log_; |
80 }; | 105 }; |
81 | 106 |
82 class MockFailingClientSocket : public ClientSocket { | 107 class MockFailingClientSocket : public ClientSocket { |
83 public: | 108 public: |
84 MockFailingClientSocket() {} | 109 MockFailingClientSocket(const AddressList& addrlist) : addrlist_(addrlist) {} |
85 | 110 |
86 // ClientSocket methods: | 111 // ClientSocket methods: |
87 virtual int Connect(CompletionCallback* callback) { | 112 virtual int Connect(CompletionCallback* callback) { |
88 return ERR_CONNECTION_FAILED; | 113 return ERR_CONNECTION_FAILED; |
89 } | 114 } |
90 | 115 |
91 virtual void Disconnect() {} | 116 virtual void Disconnect() {} |
92 | 117 |
93 virtual bool IsConnected() const { | 118 virtual bool IsConnected() const { |
94 return false; | 119 return false; |
(...skipping 23 matching lines...) Expand all Loading... |
118 } | 143 } |
119 | 144 |
120 virtual int Write(IOBuffer* buf, int buf_len, | 145 virtual int Write(IOBuffer* buf, int buf_len, |
121 CompletionCallback* callback) { | 146 CompletionCallback* callback) { |
122 return ERR_FAILED; | 147 return ERR_FAILED; |
123 } | 148 } |
124 virtual bool SetReceiveBufferSize(int32 size) { return true; } | 149 virtual bool SetReceiveBufferSize(int32 size) { return true; } |
125 virtual bool SetSendBufferSize(int32 size) { return true; } | 150 virtual bool SetSendBufferSize(int32 size) { return true; } |
126 | 151 |
127 private: | 152 private: |
| 153 const AddressList addrlist_; |
128 BoundNetLog net_log_; | 154 BoundNetLog net_log_; |
129 }; | 155 }; |
130 | 156 |
131 class MockPendingClientSocket : public ClientSocket { | 157 class MockPendingClientSocket : public ClientSocket { |
132 public: | 158 public: |
133 // |should_connect| indicates whether the socket should successfully complete | 159 // |should_connect| indicates whether the socket should successfully complete |
134 // or fail. | 160 // or fail. |
135 // |should_stall| indicates that this socket should never connect. | 161 // |should_stall| indicates that this socket should never connect. |
136 // |delay_ms| is the delay, in milliseconds, before simulating a connect. | 162 // |delay_ms| is the delay, in milliseconds, before simulating a connect. |
137 MockPendingClientSocket(bool should_connect, bool should_stall, int delay_ms) | 163 MockPendingClientSocket( |
| 164 const AddressList& addrlist, |
| 165 bool should_connect, |
| 166 bool should_stall, |
| 167 int delay_ms) |
138 : method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 168 : method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
139 should_connect_(should_connect), | 169 should_connect_(should_connect), |
140 should_stall_(should_stall), | 170 should_stall_(should_stall), |
141 delay_ms_(delay_ms), | 171 delay_ms_(delay_ms), |
142 is_connected_(false) {} | 172 is_connected_(false), |
| 173 addrlist_(addrlist) {} |
143 | 174 |
144 // ClientSocket methods: | 175 // ClientSocket methods: |
145 virtual int Connect(CompletionCallback* callback) { | 176 virtual int Connect(CompletionCallback* callback) { |
146 MessageLoop::current()->PostDelayedTask( | 177 MessageLoop::current()->PostDelayedTask( |
147 FROM_HERE, | 178 FROM_HERE, |
148 method_factory_.NewRunnableMethod( | 179 method_factory_.NewRunnableMethod( |
149 &MockPendingClientSocket::DoCallback, callback), delay_ms_); | 180 &MockPendingClientSocket::DoCallback, callback), delay_ms_); |
150 return ERR_IO_PENDING; | 181 return ERR_IO_PENDING; |
151 } | 182 } |
152 | 183 |
153 virtual void Disconnect() {} | 184 virtual void Disconnect() {} |
154 | 185 |
155 virtual bool IsConnected() const { | 186 virtual bool IsConnected() const { |
156 return is_connected_; | 187 return is_connected_; |
157 } | 188 } |
158 virtual bool IsConnectedAndIdle() const { | 189 virtual bool IsConnectedAndIdle() const { |
159 return is_connected_; | 190 return is_connected_; |
160 } | 191 } |
161 virtual int GetPeerAddress(AddressList* address) const { | 192 virtual int GetPeerAddress(AddressList* address) const { |
162 return ERR_UNEXPECTED; | 193 return ERR_UNEXPECTED; |
163 } | 194 } |
164 virtual int GetLocalAddress(IPEndPoint* address) const { | 195 virtual int GetLocalAddress(IPEndPoint* address) const { |
165 return ERR_UNEXPECTED; | 196 if (!is_connected_) |
| 197 return ERR_SOCKET_NOT_CONNECTED; |
| 198 if (addrlist_.head()->ai_family == AF_INET) |
| 199 SetIPv4Address(address); |
| 200 else |
| 201 SetIPv6Address(address); |
| 202 return OK; |
166 } | 203 } |
167 virtual const BoundNetLog& NetLog() const { | 204 virtual const BoundNetLog& NetLog() const { |
168 return net_log_; | 205 return net_log_; |
169 } | 206 } |
170 | 207 |
171 virtual void SetSubresourceSpeculation() {} | 208 virtual void SetSubresourceSpeculation() {} |
172 virtual void SetOmniboxSpeculation() {} | 209 virtual void SetOmniboxSpeculation() {} |
173 virtual bool WasEverUsed() const { return false; } | 210 virtual bool WasEverUsed() const { return false; } |
174 virtual bool UsingTCPFastOpen() const { return false; } | 211 virtual bool UsingTCPFastOpen() const { return false; } |
175 | 212 |
(...skipping 22 matching lines...) Expand all Loading... |
198 is_connected_ = false; | 235 is_connected_ = false; |
199 callback->Run(ERR_CONNECTION_FAILED); | 236 callback->Run(ERR_CONNECTION_FAILED); |
200 } | 237 } |
201 } | 238 } |
202 | 239 |
203 ScopedRunnableMethodFactory<MockPendingClientSocket> method_factory_; | 240 ScopedRunnableMethodFactory<MockPendingClientSocket> method_factory_; |
204 bool should_connect_; | 241 bool should_connect_; |
205 bool should_stall_; | 242 bool should_stall_; |
206 int delay_ms_; | 243 int delay_ms_; |
207 bool is_connected_; | 244 bool is_connected_; |
| 245 const AddressList addrlist_; |
208 BoundNetLog net_log_; | 246 BoundNetLog net_log_; |
209 }; | 247 }; |
210 | 248 |
211 class MockClientSocketFactory : public ClientSocketFactory { | 249 class MockClientSocketFactory : public ClientSocketFactory { |
212 public: | 250 public: |
213 enum ClientSocketType { | 251 enum ClientSocketType { |
214 MOCK_CLIENT_SOCKET, | 252 MOCK_CLIENT_SOCKET, |
215 MOCK_FAILING_CLIENT_SOCKET, | 253 MOCK_FAILING_CLIENT_SOCKET, |
216 MOCK_PENDING_CLIENT_SOCKET, | 254 MOCK_PENDING_CLIENT_SOCKET, |
217 MOCK_PENDING_FAILING_CLIENT_SOCKET, | 255 MOCK_PENDING_FAILING_CLIENT_SOCKET, |
218 // A delayed socket will pause before connecting through the message loop. | 256 // A delayed socket will pause before connecting through the message loop. |
219 MOCK_DELAYED_CLIENT_SOCKET, | 257 MOCK_DELAYED_CLIENT_SOCKET, |
220 // A stalled socket that never connects at all. | 258 // A stalled socket that never connects at all. |
221 MOCK_STALLED_CLIENT_SOCKET, | 259 MOCK_STALLED_CLIENT_SOCKET, |
222 }; | 260 }; |
223 | 261 |
224 MockClientSocketFactory() | 262 MockClientSocketFactory() |
225 : allocation_count_(0), client_socket_type_(MOCK_CLIENT_SOCKET), | 263 : allocation_count_(0), client_socket_type_(MOCK_CLIENT_SOCKET), |
226 client_socket_types_(NULL), client_socket_index_(0), | 264 client_socket_types_(NULL), client_socket_index_(0), |
227 client_socket_index_max_(0) {} | 265 client_socket_index_max_(0), |
| 266 delay_ms_(ClientSocketPool::kMaxConnectRetryIntervalMs) {} |
228 | 267 |
229 virtual ClientSocket* CreateTransportClientSocket( | 268 virtual ClientSocket* CreateTransportClientSocket( |
230 const AddressList& addresses, | 269 const AddressList& addresses, |
231 NetLog* /* net_log */, | 270 NetLog* /* net_log */, |
232 const NetLog::Source& /* source */) { | 271 const NetLog::Source& /* source */) { |
233 allocation_count_++; | 272 allocation_count_++; |
234 | 273 |
235 ClientSocketType type = client_socket_type_; | 274 ClientSocketType type = client_socket_type_; |
236 if (client_socket_types_ && | 275 if (client_socket_types_ && |
237 client_socket_index_ < client_socket_index_max_) { | 276 client_socket_index_ < client_socket_index_max_) { |
238 type = client_socket_types_[client_socket_index_++]; | 277 type = client_socket_types_[client_socket_index_++]; |
239 } | 278 } |
240 | 279 |
241 switch (type) { | 280 switch (type) { |
242 case MOCK_CLIENT_SOCKET: | 281 case MOCK_CLIENT_SOCKET: |
243 return new MockClientSocket(); | 282 return new MockClientSocket(addresses); |
244 case MOCK_FAILING_CLIENT_SOCKET: | 283 case MOCK_FAILING_CLIENT_SOCKET: |
245 return new MockFailingClientSocket(); | 284 return new MockFailingClientSocket(addresses); |
246 case MOCK_PENDING_CLIENT_SOCKET: | 285 case MOCK_PENDING_CLIENT_SOCKET: |
247 return new MockPendingClientSocket(true, false, 0); | 286 return new MockPendingClientSocket(addresses, true, false, 0); |
248 case MOCK_PENDING_FAILING_CLIENT_SOCKET: | 287 case MOCK_PENDING_FAILING_CLIENT_SOCKET: |
249 return new MockPendingClientSocket(false, false, 0); | 288 return new MockPendingClientSocket(addresses, false, false, 0); |
250 case MOCK_DELAYED_CLIENT_SOCKET: | 289 case MOCK_DELAYED_CLIENT_SOCKET: |
251 return new MockPendingClientSocket(true, false, | 290 return new MockPendingClientSocket(addresses, true, false, delay_ms_); |
252 ClientSocketPool::kMaxConnectRetryIntervalMs); | |
253 case MOCK_STALLED_CLIENT_SOCKET: | 291 case MOCK_STALLED_CLIENT_SOCKET: |
254 return new MockPendingClientSocket(true, true, 0); | 292 return new MockPendingClientSocket(addresses, true, true, 0); |
255 default: | 293 default: |
256 NOTREACHED(); | 294 NOTREACHED(); |
257 return new MockClientSocket(); | 295 return new MockClientSocket(addresses); |
258 } | 296 } |
259 } | 297 } |
260 | 298 |
261 virtual SSLClientSocket* CreateSSLClientSocket( | 299 virtual SSLClientSocket* CreateSSLClientSocket( |
262 ClientSocketHandle* transport_socket, | 300 ClientSocketHandle* transport_socket, |
263 const HostPortPair& host_and_port, | 301 const HostPortPair& host_and_port, |
264 const SSLConfig& ssl_config, | 302 const SSLConfig& ssl_config, |
265 SSLHostInfo* ssl_host_info, | 303 SSLHostInfo* ssl_host_info, |
266 CertVerifier* cert_verifier, | 304 CertVerifier* cert_verifier, |
267 DnsCertProvenanceChecker* dns_cert_checker) { | 305 DnsCertProvenanceChecker* dns_cert_checker) { |
(...skipping 14 matching lines...) Expand all Loading... |
282 } | 320 } |
283 | 321 |
284 // Set a list of ClientSocketTypes to be used. | 322 // Set a list of ClientSocketTypes to be used. |
285 void set_client_socket_types(ClientSocketType* type_list, int num_types) { | 323 void set_client_socket_types(ClientSocketType* type_list, int num_types) { |
286 DCHECK_GT(num_types, 0); | 324 DCHECK_GT(num_types, 0); |
287 client_socket_types_ = type_list; | 325 client_socket_types_ = type_list; |
288 client_socket_index_ = 0; | 326 client_socket_index_ = 0; |
289 client_socket_index_max_ = num_types; | 327 client_socket_index_max_ = num_types; |
290 } | 328 } |
291 | 329 |
| 330 void set_delay_ms(int delay_ms) { delay_ms_ = delay_ms; } |
| 331 |
292 private: | 332 private: |
293 int allocation_count_; | 333 int allocation_count_; |
294 ClientSocketType client_socket_type_; | 334 ClientSocketType client_socket_type_; |
295 ClientSocketType* client_socket_types_; | 335 ClientSocketType* client_socket_types_; |
296 int client_socket_index_; | 336 int client_socket_index_; |
297 int client_socket_index_max_; | 337 int client_socket_index_max_; |
| 338 int delay_ms_; |
298 }; | 339 }; |
299 | 340 |
300 class TransportClientSocketPoolTest : public testing::Test { | 341 class TransportClientSocketPoolTest : public testing::Test { |
301 protected: | 342 protected: |
302 TransportClientSocketPoolTest() | 343 TransportClientSocketPoolTest() |
303 : connect_backup_jobs_enabled_( | 344 : connect_backup_jobs_enabled_( |
304 ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true)), | 345 ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true)), |
305 params_( | 346 params_( |
306 new TransportSocketParams(HostPortPair("www.google.com", 80), | 347 new TransportSocketParams(HostPortPair("www.google.com", 80), |
307 kDefaultPriority, GURL(), false, false)), | 348 kDefaultPriority, GURL(), false, false)), |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 bool connect_backup_jobs_enabled_; | 389 bool connect_backup_jobs_enabled_; |
349 scoped_refptr<TransportSocketParams> params_; | 390 scoped_refptr<TransportSocketParams> params_; |
350 scoped_refptr<TransportSocketParams> low_params_; | 391 scoped_refptr<TransportSocketParams> low_params_; |
351 scoped_ptr<ClientSocketPoolHistograms> histograms_; | 392 scoped_ptr<ClientSocketPoolHistograms> histograms_; |
352 scoped_ptr<MockHostResolver> host_resolver_; | 393 scoped_ptr<MockHostResolver> host_resolver_; |
353 MockClientSocketFactory client_socket_factory_; | 394 MockClientSocketFactory client_socket_factory_; |
354 TransportClientSocketPool pool_; | 395 TransportClientSocketPool pool_; |
355 ClientSocketPoolTest test_base_; | 396 ClientSocketPoolTest test_base_; |
356 }; | 397 }; |
357 | 398 |
| 399 TEST(TransportConnectJobTest, MakeAddrListStartWithIPv4) { |
| 400 IPAddressNumber ip_number; |
| 401 ASSERT_TRUE(ParseIPLiteralToNumber("192.168.1.1", &ip_number)); |
| 402 AddressList addrlist_v4_1(ip_number, 80, false); |
| 403 ASSERT_TRUE(ParseIPLiteralToNumber("192.168.1.2", &ip_number)); |
| 404 AddressList addrlist_v4_2(ip_number, 80, false); |
| 405 ASSERT_TRUE(ParseIPLiteralToNumber("2001:4860:b006::64", &ip_number)); |
| 406 AddressList addrlist_v6_1(ip_number, 80, false); |
| 407 ASSERT_TRUE(ParseIPLiteralToNumber("2001:4860:b006::66", &ip_number)); |
| 408 AddressList addrlist_v6_2(ip_number, 80, false); |
| 409 |
| 410 AddressList addrlist; |
| 411 const struct addrinfo* ai; |
| 412 |
| 413 // Test 1: IPv4 only. Expect no change. |
| 414 addrlist.Copy(addrlist_v4_1.head(), true); |
| 415 addrlist.Append(addrlist_v4_2.head()); |
| 416 TransportConnectJob::MakeAddrListStartWithIPv4(&addrlist); |
| 417 ai = addrlist.head(); |
| 418 EXPECT_EQ(AF_INET, ai->ai_family); |
| 419 ai = ai->ai_next; |
| 420 EXPECT_EQ(AF_INET, ai->ai_family); |
| 421 EXPECT_TRUE(ai->ai_next == NULL); |
| 422 |
| 423 // Test 2: IPv6 only. Expect no change. |
| 424 addrlist.Copy(addrlist_v6_1.head(), true); |
| 425 addrlist.Append(addrlist_v6_2.head()); |
| 426 TransportConnectJob::MakeAddrListStartWithIPv4(&addrlist); |
| 427 ai = addrlist.head(); |
| 428 EXPECT_EQ(AF_INET6, ai->ai_family); |
| 429 ai = ai->ai_next; |
| 430 EXPECT_EQ(AF_INET6, ai->ai_family); |
| 431 EXPECT_TRUE(ai->ai_next == NULL); |
| 432 |
| 433 // Test 3: IPv4 then IPv6. Expect no change. |
| 434 addrlist.Copy(addrlist_v4_1.head(), true); |
| 435 addrlist.Append(addrlist_v4_2.head()); |
| 436 addrlist.Append(addrlist_v6_1.head()); |
| 437 addrlist.Append(addrlist_v6_2.head()); |
| 438 TransportConnectJob::MakeAddrListStartWithIPv4(&addrlist); |
| 439 ai = addrlist.head(); |
| 440 EXPECT_EQ(AF_INET, ai->ai_family); |
| 441 ai = ai->ai_next; |
| 442 EXPECT_EQ(AF_INET, ai->ai_family); |
| 443 ai = ai->ai_next; |
| 444 EXPECT_EQ(AF_INET6, ai->ai_family); |
| 445 ai = ai->ai_next; |
| 446 EXPECT_EQ(AF_INET6, ai->ai_family); |
| 447 EXPECT_TRUE(ai->ai_next == NULL); |
| 448 |
| 449 // Test 4: IPv6, IPv4, IPv6, IPv4. Expect first IPv6 moved to the end. |
| 450 addrlist.Copy(addrlist_v6_1.head(), true); |
| 451 addrlist.Append(addrlist_v4_1.head()); |
| 452 addrlist.Append(addrlist_v6_2.head()); |
| 453 addrlist.Append(addrlist_v4_2.head()); |
| 454 TransportConnectJob::MakeAddrListStartWithIPv4(&addrlist); |
| 455 ai = addrlist.head(); |
| 456 EXPECT_EQ(AF_INET, ai->ai_family); |
| 457 ai = ai->ai_next; |
| 458 EXPECT_EQ(AF_INET6, ai->ai_family); |
| 459 ai = ai->ai_next; |
| 460 EXPECT_EQ(AF_INET, ai->ai_family); |
| 461 ai = ai->ai_next; |
| 462 EXPECT_EQ(AF_INET6, ai->ai_family); |
| 463 EXPECT_TRUE(ai->ai_next == NULL); |
| 464 |
| 465 // Test 5: IPv6, IPv6, IPv4, IPv4. Expect first two IPv6's moved to the end. |
| 466 addrlist.Copy(addrlist_v6_1.head(), true); |
| 467 addrlist.Append(addrlist_v6_2.head()); |
| 468 addrlist.Append(addrlist_v4_1.head()); |
| 469 addrlist.Append(addrlist_v4_2.head()); |
| 470 TransportConnectJob::MakeAddrListStartWithIPv4(&addrlist); |
| 471 ai = addrlist.head(); |
| 472 EXPECT_EQ(AF_INET, ai->ai_family); |
| 473 ai = ai->ai_next; |
| 474 EXPECT_EQ(AF_INET, ai->ai_family); |
| 475 ai = ai->ai_next; |
| 476 EXPECT_EQ(AF_INET6, ai->ai_family); |
| 477 ai = ai->ai_next; |
| 478 EXPECT_EQ(AF_INET6, ai->ai_family); |
| 479 EXPECT_TRUE(ai->ai_next == NULL); |
| 480 } |
| 481 |
358 TEST_F(TransportClientSocketPoolTest, Basic) { | 482 TEST_F(TransportClientSocketPoolTest, Basic) { |
359 TestCompletionCallback callback; | 483 TestCompletionCallback callback; |
360 ClientSocketHandle handle; | 484 ClientSocketHandle handle; |
361 int rv = handle.Init("a", low_params_, LOW, &callback, &pool_, BoundNetLog()); | 485 int rv = handle.Init("a", low_params_, LOW, &callback, &pool_, BoundNetLog()); |
362 EXPECT_EQ(ERR_IO_PENDING, rv); | 486 EXPECT_EQ(ERR_IO_PENDING, rv); |
363 EXPECT_FALSE(handle.is_initialized()); | 487 EXPECT_FALSE(handle.is_initialized()); |
364 EXPECT_FALSE(handle.socket()); | 488 EXPECT_FALSE(handle.socket()); |
365 | 489 |
366 EXPECT_EQ(OK, callback.WaitForResult()); | 490 EXPECT_EQ(OK, callback.WaitForResult()); |
367 EXPECT_TRUE(handle.is_initialized()); | 491 EXPECT_TRUE(handle.is_initialized()); |
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
780 BoundNetLog()); | 904 BoundNetLog()); |
781 EXPECT_EQ(ERR_IO_PENDING, rv); | 905 EXPECT_EQ(ERR_IO_PENDING, rv); |
782 EXPECT_FALSE(handle.is_initialized()); | 906 EXPECT_FALSE(handle.is_initialized()); |
783 EXPECT_FALSE(handle.socket()); | 907 EXPECT_FALSE(handle.socket()); |
784 | 908 |
785 // Create the first socket, set the timer. | 909 // Create the first socket, set the timer. |
786 MessageLoop::current()->RunAllPending(); | 910 MessageLoop::current()->RunAllPending(); |
787 | 911 |
788 // Wait for the backup socket timer to fire. | 912 // Wait for the backup socket timer to fire. |
789 base::PlatformThread::Sleep( | 913 base::PlatformThread::Sleep( |
790 ClientSocketPool::kMaxConnectRetryIntervalMs * 2); | 914 ClientSocketPool::kMaxConnectRetryIntervalMs + 50); |
791 | 915 |
792 // Let the appropriate socket connect. | 916 // Let the appropriate socket connect. |
793 MessageLoop::current()->RunAllPending(); | 917 MessageLoop::current()->RunAllPending(); |
794 | 918 |
795 EXPECT_EQ(OK, callback.WaitForResult()); | 919 EXPECT_EQ(OK, callback.WaitForResult()); |
796 EXPECT_TRUE(handle.is_initialized()); | 920 EXPECT_TRUE(handle.is_initialized()); |
797 EXPECT_TRUE(handle.socket()); | 921 EXPECT_TRUE(handle.socket()); |
798 | 922 |
799 // One socket is stalled, the other is active. | 923 // One socket is stalled, the other is active. |
800 EXPECT_EQ(0, pool_.IdleSocketCount()); | 924 EXPECT_EQ(0, pool_.IdleSocketCount()); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
928 | 1052 |
929 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult()); | 1053 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult()); |
930 EXPECT_FALSE(handle.is_initialized()); | 1054 EXPECT_FALSE(handle.is_initialized()); |
931 EXPECT_FALSE(handle.socket()); | 1055 EXPECT_FALSE(handle.socket()); |
932 handle.Reset(); | 1056 handle.Reset(); |
933 | 1057 |
934 // Reset for the next case. | 1058 // Reset for the next case. |
935 host_resolver_->set_synchronous_mode(false); | 1059 host_resolver_->set_synchronous_mode(false); |
936 } | 1060 } |
937 | 1061 |
| 1062 // Test the case of the IPv6 address stalling, and falling back to the IPv4 |
| 1063 // socket which finishes first. |
| 1064 TEST_F(TransportClientSocketPoolTest, IPv6FallbackSocketIPv4FinishesFirst) { |
| 1065 // Create a pool without backup jobs. |
| 1066 ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(false); |
| 1067 TransportClientSocketPool pool(kMaxSockets, |
| 1068 kMaxSocketsPerGroup, |
| 1069 histograms_.get(), |
| 1070 host_resolver_.get(), |
| 1071 &client_socket_factory_, |
| 1072 NULL); |
| 1073 |
| 1074 MockClientSocketFactory::ClientSocketType case_types[] = { |
| 1075 // This is the IPv6 socket. |
| 1076 MockClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET, |
| 1077 // This is the IPv4 socket. |
| 1078 MockClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET |
| 1079 }; |
| 1080 |
| 1081 client_socket_factory_.set_client_socket_types(case_types, 2); |
| 1082 |
| 1083 // Resolve an AddressList with a IPv6 address first and then a IPv4 address. |
| 1084 host_resolver_->rules()->AddIPLiteralRule( |
| 1085 "*", "2:abcd::3:4:ff,2.2.2.2", ""); |
| 1086 |
| 1087 TestCompletionCallback callback; |
| 1088 ClientSocketHandle handle; |
| 1089 int rv = handle.Init("a", low_params_, LOW, &callback, &pool, BoundNetLog()); |
| 1090 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1091 EXPECT_FALSE(handle.is_initialized()); |
| 1092 EXPECT_FALSE(handle.socket()); |
| 1093 |
| 1094 EXPECT_EQ(OK, callback.WaitForResult()); |
| 1095 EXPECT_TRUE(handle.is_initialized()); |
| 1096 EXPECT_TRUE(handle.socket()); |
| 1097 IPEndPoint endpoint; |
| 1098 handle.socket()->GetLocalAddress(&endpoint); |
| 1099 EXPECT_EQ(kIPv4AddressSize, endpoint.address().size()); |
| 1100 EXPECT_EQ(2, client_socket_factory_.allocation_count()); |
| 1101 } |
| 1102 |
| 1103 // Test the case of the IPv6 address being slow, thus falling back to trying to |
| 1104 // connect to the IPv4 address, but having the connect to the IPv6 address |
| 1105 // finish first. |
| 1106 TEST_F(TransportClientSocketPoolTest, IPv6FallbackSocketIPv6FinishesFirst) { |
| 1107 // Create a pool without backup jobs. |
| 1108 ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(false); |
| 1109 TransportClientSocketPool pool(kMaxSockets, |
| 1110 kMaxSocketsPerGroup, |
| 1111 histograms_.get(), |
| 1112 host_resolver_.get(), |
| 1113 &client_socket_factory_, |
| 1114 NULL); |
| 1115 |
| 1116 MockClientSocketFactory::ClientSocketType case_types[] = { |
| 1117 // This is the IPv6 socket. |
| 1118 MockClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET, |
| 1119 // This is the IPv4 socket. |
| 1120 MockClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET |
| 1121 }; |
| 1122 |
| 1123 client_socket_factory_.set_client_socket_types(case_types, 2); |
| 1124 client_socket_factory_.set_delay_ms( |
| 1125 TransportConnectJob::kIPv6FallbackTimerInMs + 50); |
| 1126 |
| 1127 // Resolve an AddressList with a IPv6 address first and then a IPv4 address. |
| 1128 host_resolver_->rules()->AddIPLiteralRule( |
| 1129 "*", "2:abcd::3:4:ff,2.2.2.2", ""); |
| 1130 |
| 1131 TestCompletionCallback callback; |
| 1132 ClientSocketHandle handle; |
| 1133 int rv = handle.Init("a", low_params_, LOW, &callback, &pool, BoundNetLog()); |
| 1134 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1135 EXPECT_FALSE(handle.is_initialized()); |
| 1136 EXPECT_FALSE(handle.socket()); |
| 1137 |
| 1138 EXPECT_EQ(OK, callback.WaitForResult()); |
| 1139 EXPECT_TRUE(handle.is_initialized()); |
| 1140 EXPECT_TRUE(handle.socket()); |
| 1141 IPEndPoint endpoint; |
| 1142 handle.socket()->GetLocalAddress(&endpoint); |
| 1143 EXPECT_EQ(kIPv6AddressSize, endpoint.address().size()); |
| 1144 EXPECT_EQ(2, client_socket_factory_.allocation_count()); |
| 1145 } |
| 1146 |
| 1147 TEST_F(TransportClientSocketPoolTest, IPv6NoIPv4AddressesToFallbackTo) { |
| 1148 // Create a pool without backup jobs. |
| 1149 ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(false); |
| 1150 TransportClientSocketPool pool(kMaxSockets, |
| 1151 kMaxSocketsPerGroup, |
| 1152 histograms_.get(), |
| 1153 host_resolver_.get(), |
| 1154 &client_socket_factory_, |
| 1155 NULL); |
| 1156 |
| 1157 client_socket_factory_.set_client_socket_type( |
| 1158 MockClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET); |
| 1159 |
| 1160 // Resolve an AddressList with only IPv6 addresses. |
| 1161 host_resolver_->rules()->AddIPLiteralRule( |
| 1162 "*", "2:abcd::3:4:ff,3:abcd::3:4:ff", ""); |
| 1163 |
| 1164 TestCompletionCallback callback; |
| 1165 ClientSocketHandle handle; |
| 1166 int rv = handle.Init("a", low_params_, LOW, &callback, &pool, BoundNetLog()); |
| 1167 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1168 EXPECT_FALSE(handle.is_initialized()); |
| 1169 EXPECT_FALSE(handle.socket()); |
| 1170 |
| 1171 EXPECT_EQ(OK, callback.WaitForResult()); |
| 1172 EXPECT_TRUE(handle.is_initialized()); |
| 1173 EXPECT_TRUE(handle.socket()); |
| 1174 IPEndPoint endpoint; |
| 1175 handle.socket()->GetLocalAddress(&endpoint); |
| 1176 EXPECT_EQ(kIPv6AddressSize, endpoint.address().size()); |
| 1177 EXPECT_EQ(1, client_socket_factory_.allocation_count()); |
| 1178 } |
| 1179 |
| 1180 TEST_F(TransportClientSocketPoolTest, IPv4HasNoFallback) { |
| 1181 // Create a pool without backup jobs. |
| 1182 ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(false); |
| 1183 TransportClientSocketPool pool(kMaxSockets, |
| 1184 kMaxSocketsPerGroup, |
| 1185 histograms_.get(), |
| 1186 host_resolver_.get(), |
| 1187 &client_socket_factory_, |
| 1188 NULL); |
| 1189 |
| 1190 client_socket_factory_.set_client_socket_type( |
| 1191 MockClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET); |
| 1192 |
| 1193 // Resolve an AddressList with only IPv4 addresses. |
| 1194 host_resolver_->rules()->AddIPLiteralRule( |
| 1195 "*", "1.1.1.1", ""); |
| 1196 |
| 1197 TestCompletionCallback callback; |
| 1198 ClientSocketHandle handle; |
| 1199 int rv = handle.Init("a", low_params_, LOW, &callback, &pool, BoundNetLog()); |
| 1200 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1201 EXPECT_FALSE(handle.is_initialized()); |
| 1202 EXPECT_FALSE(handle.socket()); |
| 1203 |
| 1204 EXPECT_EQ(OK, callback.WaitForResult()); |
| 1205 EXPECT_TRUE(handle.is_initialized()); |
| 1206 EXPECT_TRUE(handle.socket()); |
| 1207 IPEndPoint endpoint; |
| 1208 handle.socket()->GetLocalAddress(&endpoint); |
| 1209 EXPECT_EQ(kIPv4AddressSize, endpoint.address().size()); |
| 1210 EXPECT_EQ(1, client_socket_factory_.allocation_count()); |
| 1211 } |
| 1212 |
938 } // namespace | 1213 } // namespace |
939 | 1214 |
940 } // namespace net | 1215 } // namespace net |
OLD | NEW |