| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/tcp_client_socket_pool.h" | 5 #include "net/socket/tcp_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 namespace { | 28 namespace { |
| 25 | 29 |
| 26 const int kMaxSockets = 32; | 30 const int kMaxSockets = 32; |
| 27 const int kMaxSocketsPerGroup = 6; | 31 const int kMaxSocketsPerGroup = 6; |
| 28 const net::RequestPriority kDefaultPriority = LOW; | 32 const net::RequestPriority kDefaultPriority = LOW; |
| 29 | 33 |
| 34 void SetIPv4Address(IPEndPoint* address) { |
| 35 IPAddressNumber number; |
| 36 CHECK(ParseIPLiteralToNumber("1.1.1.1", &number)); |
| 37 *address = IPEndPoint(number, 80); |
| 38 } |
| 39 |
| 40 void SetIPv6Address(IPEndPoint* address) { |
| 41 IPAddressNumber number; |
| 42 CHECK(ParseIPLiteralToNumber("1:abcd::3:4:ff", &number)); |
| 43 *address = IPEndPoint(number, 80); |
| 44 } |
| 45 |
| 30 class MockClientSocket : public ClientSocket { | 46 class MockClientSocket : public ClientSocket { |
| 31 public: | 47 public: |
| 32 MockClientSocket() : connected_(false) {} | 48 MockClientSocket(const AddressList& addrlist) |
| 49 : connected_(false), |
| 50 addrlist_(addrlist) {} |
| 33 | 51 |
| 34 // ClientSocket methods: | 52 // ClientSocket methods: |
| 35 virtual int Connect(CompletionCallback* callback) { | 53 virtual int Connect(CompletionCallback* callback) { |
| 36 connected_ = true; | 54 connected_ = true; |
| 37 return OK; | 55 return OK; |
| 38 } | 56 } |
| 39 virtual void Disconnect() { | 57 virtual void Disconnect() { |
| 40 connected_ = false; | 58 connected_ = false; |
| 41 } | 59 } |
| 42 virtual bool IsConnected() const { | 60 virtual bool IsConnected() const { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 64 } | 82 } |
| 65 virtual int Write(IOBuffer* buf, int buf_len, | 83 virtual int Write(IOBuffer* buf, int buf_len, |
| 66 CompletionCallback* callback) { | 84 CompletionCallback* callback) { |
| 67 return ERR_FAILED; | 85 return ERR_FAILED; |
| 68 } | 86 } |
| 69 virtual bool SetReceiveBufferSize(int32 size) { return true; } | 87 virtual bool SetReceiveBufferSize(int32 size) { return true; } |
| 70 virtual bool SetSendBufferSize(int32 size) { return true; } | 88 virtual bool SetSendBufferSize(int32 size) { return true; } |
| 71 | 89 |
| 72 private: | 90 private: |
| 73 bool connected_; | 91 bool connected_; |
| 92 const AddressList addrlist_; |
| 74 BoundNetLog net_log_; | 93 BoundNetLog net_log_; |
| 75 }; | 94 }; |
| 76 | 95 |
| 77 class MockFailingClientSocket : public ClientSocket { | 96 class MockFailingClientSocket : public ClientSocket { |
| 78 public: | 97 public: |
| 79 MockFailingClientSocket() {} | 98 MockFailingClientSocket(const AddressList& addrlist) : addrlist_(addrlist) {} |
| 80 | 99 |
| 81 // ClientSocket methods: | 100 // ClientSocket methods: |
| 82 virtual int Connect(CompletionCallback* callback) { | 101 virtual int Connect(CompletionCallback* callback) { |
| 83 return ERR_CONNECTION_FAILED; | 102 return ERR_CONNECTION_FAILED; |
| 84 } | 103 } |
| 85 | 104 |
| 86 virtual void Disconnect() {} | 105 virtual void Disconnect() {} |
| 87 | 106 |
| 88 virtual bool IsConnected() const { | 107 virtual bool IsConnected() const { |
| 89 return false; | 108 return false; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 110 } | 129 } |
| 111 | 130 |
| 112 virtual int Write(IOBuffer* buf, int buf_len, | 131 virtual int Write(IOBuffer* buf, int buf_len, |
| 113 CompletionCallback* callback) { | 132 CompletionCallback* callback) { |
| 114 return ERR_FAILED; | 133 return ERR_FAILED; |
| 115 } | 134 } |
| 116 virtual bool SetReceiveBufferSize(int32 size) { return true; } | 135 virtual bool SetReceiveBufferSize(int32 size) { return true; } |
| 117 virtual bool SetSendBufferSize(int32 size) { return true; } | 136 virtual bool SetSendBufferSize(int32 size) { return true; } |
| 118 | 137 |
| 119 private: | 138 private: |
| 139 const AddressList addrlist_; |
| 120 BoundNetLog net_log_; | 140 BoundNetLog net_log_; |
| 121 }; | 141 }; |
| 122 | 142 |
| 123 class MockPendingClientSocket : public ClientSocket { | 143 class MockPendingClientSocket : public ClientSocket { |
| 124 public: | 144 public: |
| 125 // |should_connect| indicates whether the socket should successfully complete | 145 // |should_connect| indicates whether the socket should successfully complete |
| 126 // or fail. | 146 // or fail. |
| 127 // |should_stall| indicates that this socket should never connect. | 147 // |should_stall| indicates that this socket should never connect. |
| 128 // |delay_ms| is the delay, in milliseconds, before simulating a connect. | 148 // |delay_ms| is the delay, in milliseconds, before simulating a connect. |
| 129 MockPendingClientSocket(bool should_connect, bool should_stall, int delay_ms) | 149 MockPendingClientSocket( |
| 150 const AddressList& addrlist, |
| 151 bool should_connect, |
| 152 bool should_stall, |
| 153 int delay_ms) |
| 130 : method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 154 : method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 131 should_connect_(should_connect), | 155 should_connect_(should_connect), |
| 132 should_stall_(should_stall), | 156 should_stall_(should_stall), |
| 133 delay_ms_(delay_ms), | 157 delay_ms_(delay_ms), |
| 134 is_connected_(false) {} | 158 is_connected_(false), |
| 159 addrlist_(addrlist) {} |
| 135 | 160 |
| 136 // ClientSocket methods: | 161 // ClientSocket methods: |
| 137 virtual int Connect(CompletionCallback* callback) { | 162 virtual int Connect(CompletionCallback* callback) { |
| 138 MessageLoop::current()->PostDelayedTask( | 163 MessageLoop::current()->PostDelayedTask( |
| 139 FROM_HERE, | 164 FROM_HERE, |
| 140 method_factory_.NewRunnableMethod( | 165 method_factory_.NewRunnableMethod( |
| 141 &MockPendingClientSocket::DoCallback, callback), delay_ms_); | 166 &MockPendingClientSocket::DoCallback, callback), delay_ms_); |
| 142 return ERR_IO_PENDING; | 167 return ERR_IO_PENDING; |
| 143 } | 168 } |
| 144 | 169 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 is_connected_ = false; | 212 is_connected_ = false; |
| 188 callback->Run(ERR_CONNECTION_FAILED); | 213 callback->Run(ERR_CONNECTION_FAILED); |
| 189 } | 214 } |
| 190 } | 215 } |
| 191 | 216 |
| 192 ScopedRunnableMethodFactory<MockPendingClientSocket> method_factory_; | 217 ScopedRunnableMethodFactory<MockPendingClientSocket> method_factory_; |
| 193 bool should_connect_; | 218 bool should_connect_; |
| 194 bool should_stall_; | 219 bool should_stall_; |
| 195 int delay_ms_; | 220 int delay_ms_; |
| 196 bool is_connected_; | 221 bool is_connected_; |
| 222 const AddressList addrlist_; |
| 197 BoundNetLog net_log_; | 223 BoundNetLog net_log_; |
| 198 }; | 224 }; |
| 199 | 225 |
| 200 class MockClientSocketFactory : public ClientSocketFactory { | 226 class MockClientSocketFactory : public ClientSocketFactory { |
| 201 public: | 227 public: |
| 202 enum ClientSocketType { | 228 enum ClientSocketType { |
| 203 MOCK_CLIENT_SOCKET, | 229 MOCK_CLIENT_SOCKET, |
| 204 MOCK_FAILING_CLIENT_SOCKET, | 230 MOCK_FAILING_CLIENT_SOCKET, |
| 205 MOCK_PENDING_CLIENT_SOCKET, | 231 MOCK_PENDING_CLIENT_SOCKET, |
| 206 MOCK_PENDING_FAILING_CLIENT_SOCKET, | 232 MOCK_PENDING_FAILING_CLIENT_SOCKET, |
| 207 // A delayed socket will pause before connecting through the message loop. | 233 // A delayed socket will pause before connecting through the message loop. |
| 208 MOCK_DELAYED_CLIENT_SOCKET, | 234 MOCK_DELAYED_CLIENT_SOCKET, |
| 209 // A stalled socket that never connects at all. | 235 // A stalled socket that never connects at all. |
| 210 MOCK_STALLED_CLIENT_SOCKET, | 236 MOCK_STALLED_CLIENT_SOCKET, |
| 211 }; | 237 }; |
| 212 | 238 |
| 213 MockClientSocketFactory() | 239 MockClientSocketFactory() |
| 214 : allocation_count_(0), client_socket_type_(MOCK_CLIENT_SOCKET), | 240 : allocation_count_(0), client_socket_type_(MOCK_CLIENT_SOCKET), |
| 215 client_socket_types_(NULL), client_socket_index_(0), | 241 client_socket_types_(NULL), client_socket_index_(0), |
| 216 client_socket_index_max_(0) {} | 242 client_socket_index_max_(0), |
| 243 delay_ms_(ClientSocketPool::kMaxConnectRetryIntervalMs) {} |
| 217 | 244 |
| 218 virtual ClientSocket* CreateTCPClientSocket( | 245 virtual ClientSocket* CreateTCPClientSocket( |
| 219 const AddressList& addresses, | 246 const AddressList& addresses, |
| 220 NetLog* /* net_log */, | 247 NetLog* /* net_log */, |
| 221 const NetLog::Source& /* source */) { | 248 const NetLog::Source& /* source */) { |
| 222 allocation_count_++; | 249 allocation_count_++; |
| 223 | 250 |
| 224 ClientSocketType type = client_socket_type_; | 251 ClientSocketType type = client_socket_type_; |
| 225 if (client_socket_types_ && | 252 if (client_socket_types_ && |
| 226 client_socket_index_ < client_socket_index_max_) { | 253 client_socket_index_ < client_socket_index_max_) { |
| 227 type = client_socket_types_[client_socket_index_++]; | 254 type = client_socket_types_[client_socket_index_++]; |
| 228 } | 255 } |
| 229 | 256 |
| 230 switch (type) { | 257 switch (type) { |
| 231 case MOCK_CLIENT_SOCKET: | 258 case MOCK_CLIENT_SOCKET: |
| 232 return new MockClientSocket(); | 259 return new MockClientSocket(addresses); |
| 233 case MOCK_FAILING_CLIENT_SOCKET: | 260 case MOCK_FAILING_CLIENT_SOCKET: |
| 234 return new MockFailingClientSocket(); | 261 return new MockFailingClientSocket(addresses); |
| 235 case MOCK_PENDING_CLIENT_SOCKET: | 262 case MOCK_PENDING_CLIENT_SOCKET: |
| 236 return new MockPendingClientSocket(true, false, 0); | 263 return new MockPendingClientSocket(addresses, true, false, 0); |
| 237 case MOCK_PENDING_FAILING_CLIENT_SOCKET: | 264 case MOCK_PENDING_FAILING_CLIENT_SOCKET: |
| 238 return new MockPendingClientSocket(false, false, 0); | 265 return new MockPendingClientSocket(addresses, false, false, 0); |
| 239 case MOCK_DELAYED_CLIENT_SOCKET: | 266 case MOCK_DELAYED_CLIENT_SOCKET: |
| 240 return new MockPendingClientSocket(true, false, | 267 return new MockPendingClientSocket(addresses, true, false, delay_ms_); |
| 241 ClientSocketPool::kMaxConnectRetryIntervalMs); | |
| 242 case MOCK_STALLED_CLIENT_SOCKET: | 268 case MOCK_STALLED_CLIENT_SOCKET: |
| 243 return new MockPendingClientSocket(true, true, 0); | 269 return new MockPendingClientSocket(addresses, true, true, 0); |
| 244 default: | 270 default: |
| 245 NOTREACHED(); | 271 NOTREACHED(); |
| 246 return new MockClientSocket(); | 272 return new MockClientSocket(addresses); |
| 247 } | 273 } |
| 248 } | 274 } |
| 249 | 275 |
| 250 virtual SSLClientSocket* CreateSSLClientSocket( | 276 virtual SSLClientSocket* CreateSSLClientSocket( |
| 251 ClientSocketHandle* transport_socket, | 277 ClientSocketHandle* transport_socket, |
| 252 const HostPortPair& host_and_port, | 278 const HostPortPair& host_and_port, |
| 253 const SSLConfig& ssl_config, | 279 const SSLConfig& ssl_config, |
| 254 SSLHostInfo* ssl_host_info, | 280 SSLHostInfo* ssl_host_info, |
| 255 CertVerifier* cert_verifier, | 281 CertVerifier* cert_verifier, |
| 256 DnsCertProvenanceChecker* dns_cert_checker) { | 282 DnsCertProvenanceChecker* dns_cert_checker) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 271 } | 297 } |
| 272 | 298 |
| 273 // Set a list of ClientSocketTypes to be used. | 299 // Set a list of ClientSocketTypes to be used. |
| 274 void set_client_socket_types(ClientSocketType* type_list, int num_types) { | 300 void set_client_socket_types(ClientSocketType* type_list, int num_types) { |
| 275 DCHECK_GT(num_types, 0); | 301 DCHECK_GT(num_types, 0); |
| 276 client_socket_types_ = type_list; | 302 client_socket_types_ = type_list; |
| 277 client_socket_index_ = 0; | 303 client_socket_index_ = 0; |
| 278 client_socket_index_max_ = num_types; | 304 client_socket_index_max_ = num_types; |
| 279 } | 305 } |
| 280 | 306 |
| 307 void set_delay_ms(int delay_ms) { delay_ms_ = delay_ms; } |
| 308 |
| 281 private: | 309 private: |
| 282 int allocation_count_; | 310 int allocation_count_; |
| 283 ClientSocketType client_socket_type_; | 311 ClientSocketType client_socket_type_; |
| 284 ClientSocketType* client_socket_types_; | 312 ClientSocketType* client_socket_types_; |
| 285 int client_socket_index_; | 313 int client_socket_index_; |
| 286 int client_socket_index_max_; | 314 int client_socket_index_max_; |
| 315 int delay_ms_; |
| 287 }; | 316 }; |
| 288 | 317 |
| 289 class TCPClientSocketPoolTest : public testing::Test { | 318 class TCPClientSocketPoolTest : public testing::Test { |
| 290 protected: | 319 protected: |
| 291 TCPClientSocketPoolTest() | 320 TCPClientSocketPoolTest() |
| 292 : params_(new TCPSocketParams(HostPortPair("www.google.com", 80), | 321 : params_(new TCPSocketParams(HostPortPair("www.google.com", 80), |
| 293 kDefaultPriority, GURL(), false)), | 322 kDefaultPriority, GURL(), false)), |
| 294 low_params_(new TCPSocketParams(HostPortPair("www.google.com", 80), | 323 low_params_(new TCPSocketParams(HostPortPair("www.google.com", 80), |
| 295 LOW, GURL(), false)), | 324 LOW, GURL(), false)), |
| 296 histograms_(new ClientSocketPoolHistograms("TCPUnitTest")), | 325 histograms_(new ClientSocketPoolHistograms("TCPUnitTest")), |
| (...skipping 30 matching lines...) Expand all Loading... |
| 327 | 356 |
| 328 scoped_refptr<TCPSocketParams> params_; | 357 scoped_refptr<TCPSocketParams> params_; |
| 329 scoped_refptr<TCPSocketParams> low_params_; | 358 scoped_refptr<TCPSocketParams> low_params_; |
| 330 scoped_ptr<ClientSocketPoolHistograms> histograms_; | 359 scoped_ptr<ClientSocketPoolHistograms> histograms_; |
| 331 scoped_ptr<MockHostResolver> host_resolver_; | 360 scoped_ptr<MockHostResolver> host_resolver_; |
| 332 MockClientSocketFactory client_socket_factory_; | 361 MockClientSocketFactory client_socket_factory_; |
| 333 TCPClientSocketPool pool_; | 362 TCPClientSocketPool pool_; |
| 334 ClientSocketPoolTest test_base_; | 363 ClientSocketPoolTest test_base_; |
| 335 }; | 364 }; |
| 336 | 365 |
| 366 TEST(TCPConnectJobTest, MakeAddrListStartWithIPv4) { |
| 367 IPAddressNumber ip_number; |
| 368 ASSERT_TRUE(ParseIPLiteralToNumber("192.168.1.1", &ip_number)); |
| 369 AddressList addrlist_v4_1(ip_number, 80, false); |
| 370 ASSERT_TRUE(ParseIPLiteralToNumber("192.168.1.2", &ip_number)); |
| 371 AddressList addrlist_v4_2(ip_number, 80, false); |
| 372 ASSERT_TRUE(ParseIPLiteralToNumber("2001:4860:b006::64", &ip_number)); |
| 373 AddressList addrlist_v6_1(ip_number, 80, false); |
| 374 ASSERT_TRUE(ParseIPLiteralToNumber("2001:4860:b006::66", &ip_number)); |
| 375 AddressList addrlist_v6_2(ip_number, 80, false); |
| 376 |
| 377 AddressList addrlist; |
| 378 const struct addrinfo* ai; |
| 379 |
| 380 // Test 1: IPv4 only. Expect no change. |
| 381 addrlist.Copy(addrlist_v4_1.head(), true); |
| 382 addrlist.Append(addrlist_v4_2.head()); |
| 383 TCPConnectJob::MakeAddrListStartWithIPv4(&addrlist); |
| 384 ai = addrlist.head(); |
| 385 EXPECT_EQ(AF_INET, ai->ai_family); |
| 386 ai = ai->ai_next; |
| 387 EXPECT_EQ(AF_INET, ai->ai_family); |
| 388 EXPECT_TRUE(ai->ai_next == NULL); |
| 389 |
| 390 // Test 2: IPv6 only. Expect no change. |
| 391 addrlist.Copy(addrlist_v6_1.head(), true); |
| 392 addrlist.Append(addrlist_v6_2.head()); |
| 393 TCPConnectJob::MakeAddrListStartWithIPv4(&addrlist); |
| 394 ai = addrlist.head(); |
| 395 EXPECT_EQ(AF_INET6, ai->ai_family); |
| 396 ai = ai->ai_next; |
| 397 EXPECT_EQ(AF_INET6, ai->ai_family); |
| 398 EXPECT_TRUE(ai->ai_next == NULL); |
| 399 |
| 400 // Test 3: IPv4 then IPv6. Expect no change. |
| 401 addrlist.Copy(addrlist_v4_1.head(), true); |
| 402 addrlist.Append(addrlist_v4_2.head()); |
| 403 addrlist.Append(addrlist_v6_1.head()); |
| 404 addrlist.Append(addrlist_v6_2.head()); |
| 405 TCPConnectJob::MakeAddrListStartWithIPv4(&addrlist); |
| 406 ai = addrlist.head(); |
| 407 EXPECT_EQ(AF_INET, ai->ai_family); |
| 408 ai = ai->ai_next; |
| 409 EXPECT_EQ(AF_INET, ai->ai_family); |
| 410 ai = ai->ai_next; |
| 411 EXPECT_EQ(AF_INET6, ai->ai_family); |
| 412 ai = ai->ai_next; |
| 413 EXPECT_EQ(AF_INET6, ai->ai_family); |
| 414 EXPECT_TRUE(ai->ai_next == NULL); |
| 415 |
| 416 // Test 4: IPv6, IPv4, IPv6, IPv4. Expect first IPv6 moved to the end. |
| 417 addrlist.Copy(addrlist_v6_1.head(), true); |
| 418 addrlist.Append(addrlist_v4_1.head()); |
| 419 addrlist.Append(addrlist_v6_2.head()); |
| 420 addrlist.Append(addrlist_v4_2.head()); |
| 421 TCPConnectJob::MakeAddrListStartWithIPv4(&addrlist); |
| 422 ai = addrlist.head(); |
| 423 EXPECT_EQ(AF_INET, ai->ai_family); |
| 424 ai = ai->ai_next; |
| 425 EXPECT_EQ(AF_INET6, ai->ai_family); |
| 426 ai = ai->ai_next; |
| 427 EXPECT_EQ(AF_INET, ai->ai_family); |
| 428 ai = ai->ai_next; |
| 429 EXPECT_EQ(AF_INET6, ai->ai_family); |
| 430 EXPECT_TRUE(ai->ai_next == NULL); |
| 431 |
| 432 // Test 5: IPv6, IPv6, IPv4, IPv4. Expect first two IPv6's moved to the end. |
| 433 addrlist.Copy(addrlist_v6_1.head(), true); |
| 434 addrlist.Append(addrlist_v6_2.head()); |
| 435 addrlist.Append(addrlist_v4_1.head()); |
| 436 addrlist.Append(addrlist_v4_2.head()); |
| 437 TCPConnectJob::MakeAddrListStartWithIPv4(&addrlist); |
| 438 ai = addrlist.head(); |
| 439 EXPECT_EQ(AF_INET, ai->ai_family); |
| 440 ai = ai->ai_next; |
| 441 EXPECT_EQ(AF_INET, ai->ai_family); |
| 442 ai = ai->ai_next; |
| 443 EXPECT_EQ(AF_INET6, ai->ai_family); |
| 444 ai = ai->ai_next; |
| 445 EXPECT_EQ(AF_INET6, ai->ai_family); |
| 446 EXPECT_TRUE(ai->ai_next == NULL); |
| 447 } |
| 448 |
| 337 TEST_F(TCPClientSocketPoolTest, Basic) { | 449 TEST_F(TCPClientSocketPoolTest, Basic) { |
| 338 TestCompletionCallback callback; | 450 TestCompletionCallback callback; |
| 339 ClientSocketHandle handle; | 451 ClientSocketHandle handle; |
| 340 int rv = handle.Init("a", low_params_, LOW, &callback, &pool_, BoundNetLog()); | 452 int rv = handle.Init("a", low_params_, LOW, &callback, &pool_, BoundNetLog()); |
| 341 EXPECT_EQ(ERR_IO_PENDING, rv); | 453 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 342 EXPECT_FALSE(handle.is_initialized()); | 454 EXPECT_FALSE(handle.is_initialized()); |
| 343 EXPECT_FALSE(handle.socket()); | 455 EXPECT_FALSE(handle.socket()); |
| 344 | 456 |
| 345 EXPECT_EQ(OK, callback.WaitForResult()); | 457 EXPECT_EQ(OK, callback.WaitForResult()); |
| 346 EXPECT_TRUE(handle.is_initialized()); | 458 EXPECT_TRUE(handle.is_initialized()); |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 757 BoundNetLog()); | 869 BoundNetLog()); |
| 758 EXPECT_EQ(ERR_IO_PENDING, rv); | 870 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 759 EXPECT_FALSE(handle.is_initialized()); | 871 EXPECT_FALSE(handle.is_initialized()); |
| 760 EXPECT_FALSE(handle.socket()); | 872 EXPECT_FALSE(handle.socket()); |
| 761 | 873 |
| 762 // Create the first socket, set the timer. | 874 // Create the first socket, set the timer. |
| 763 MessageLoop::current()->RunAllPending(); | 875 MessageLoop::current()->RunAllPending(); |
| 764 | 876 |
| 765 // Wait for the backup socket timer to fire. | 877 // Wait for the backup socket timer to fire. |
| 766 base::PlatformThread::Sleep( | 878 base::PlatformThread::Sleep( |
| 767 ClientSocketPool::kMaxConnectRetryIntervalMs * 2); | 879 ClientSocketPool::kMaxConnectRetryIntervalMs + 50); |
| 768 | 880 |
| 769 // Let the appropriate socket connect. | 881 // Let the appropriate socket connect. |
| 770 MessageLoop::current()->RunAllPending(); | 882 MessageLoop::current()->RunAllPending(); |
| 771 | 883 |
| 772 EXPECT_EQ(OK, callback.WaitForResult()); | 884 EXPECT_EQ(OK, callback.WaitForResult()); |
| 773 EXPECT_TRUE(handle.is_initialized()); | 885 EXPECT_TRUE(handle.is_initialized()); |
| 774 EXPECT_TRUE(handle.socket()); | 886 EXPECT_TRUE(handle.socket()); |
| 775 | 887 |
| 776 // One socket is stalled, the other is active. | 888 // One socket is stalled, the other is active. |
| 777 EXPECT_EQ(0, pool_.IdleSocketCount()); | 889 EXPECT_EQ(0, pool_.IdleSocketCount()); |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 905 | 1017 |
| 906 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult()); | 1018 EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult()); |
| 907 EXPECT_FALSE(handle.is_initialized()); | 1019 EXPECT_FALSE(handle.is_initialized()); |
| 908 EXPECT_FALSE(handle.socket()); | 1020 EXPECT_FALSE(handle.socket()); |
| 909 handle.Reset(); | 1021 handle.Reset(); |
| 910 | 1022 |
| 911 // Reset for the next case. | 1023 // Reset for the next case. |
| 912 host_resolver_->set_synchronous_mode(false); | 1024 host_resolver_->set_synchronous_mode(false); |
| 913 } | 1025 } |
| 914 | 1026 |
| 1027 // Test the case of the IPv6 address stalling, and falling back to the IPv4 |
| 1028 // socket which finishes first. |
| 1029 TEST_F(TCPClientSocketPoolTest, IPv6FallbackSocketIPv4FinishesFirst) { |
| 1030 TCPClientSocketPool pool(1, |
| 1031 1, |
| 1032 histograms_.get(), |
| 1033 host_resolver_.get(), |
| 1034 &client_socket_factory_, |
| 1035 NULL); |
| 1036 |
| 1037 MockClientSocketFactory::ClientSocketType case_types[] = { |
| 1038 // This is the IPv6 socket. |
| 1039 MockClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET, |
| 1040 // This is the IPv4 socket. |
| 1041 MockClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET |
| 1042 }; |
| 1043 |
| 1044 client_socket_factory_.set_client_socket_types(case_types, 2); |
| 1045 |
| 1046 // Resolve an AddressList with a IPv6 address first and then a IPv4 address. |
| 1047 host_resolver_->rules()->AddIPLiteralRule( |
| 1048 "*", "2:abcd::3:4:ff,2.2.2.2", ""); |
| 1049 |
| 1050 TestCompletionCallback callback; |
| 1051 ClientSocketHandle handle; |
| 1052 int rv = handle.Init("a", low_params_, LOW, &callback, &pool, BoundNetLog()); |
| 1053 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1054 EXPECT_FALSE(handle.is_initialized()); |
| 1055 EXPECT_FALSE(handle.socket()); |
| 1056 |
| 1057 EXPECT_EQ(OK, callback.WaitForResult()); |
| 1058 EXPECT_TRUE(handle.is_initialized()); |
| 1059 EXPECT_TRUE(handle.socket()); |
| 1060 EXPECT_EQ(2, client_socket_factory_.allocation_count()); |
| 1061 } |
| 1062 |
| 1063 // Test the case of the IPv6 address being slow, thus falling back to trying to |
| 1064 // connect to the IPv4 address, but having the connect to the IPv6 address |
| 1065 // finish first. |
| 1066 TEST_F(TCPClientSocketPoolTest, IPv6FallbackSocketIPv6FinishesFirst) { |
| 1067 TCPClientSocketPool pool(1, |
| 1068 1, |
| 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_DELAYED_CLIENT_SOCKET, |
| 1077 // This is the IPv4 socket. |
| 1078 MockClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET |
| 1079 }; |
| 1080 |
| 1081 client_socket_factory_.set_client_socket_types(case_types, 2); |
| 1082 client_socket_factory_.set_delay_ms( |
| 1083 TCPConnectJob::kIPv6FallbackTimerInMs + 50); |
| 1084 |
| 1085 // Resolve an AddressList with a IPv6 address first and then a IPv4 address. |
| 1086 host_resolver_->rules()->AddIPLiteralRule( |
| 1087 "*", "2:abcd::3:4:ff,2.2.2.2", ""); |
| 1088 |
| 1089 TestCompletionCallback callback; |
| 1090 ClientSocketHandle handle; |
| 1091 int rv = handle.Init("a", low_params_, LOW, &callback, &pool, BoundNetLog()); |
| 1092 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1093 EXPECT_FALSE(handle.is_initialized()); |
| 1094 EXPECT_FALSE(handle.socket()); |
| 1095 |
| 1096 EXPECT_EQ(OK, callback.WaitForResult()); |
| 1097 EXPECT_TRUE(handle.is_initialized()); |
| 1098 EXPECT_TRUE(handle.socket()); |
| 1099 EXPECT_EQ(2, client_socket_factory_.allocation_count()); |
| 1100 } |
| 1101 |
| 1102 TEST_F(TCPClientSocketPoolTest, IPv6NoIPv4AddressesToFallbackTo) { |
| 1103 TCPClientSocketPool pool(1, |
| 1104 1, |
| 1105 histograms_.get(), |
| 1106 host_resolver_.get(), |
| 1107 &client_socket_factory_, |
| 1108 NULL); |
| 1109 |
| 1110 client_socket_factory_.set_client_socket_type( |
| 1111 MockClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET); |
| 1112 |
| 1113 // Resolve an AddressList with only IPv6 addresses. |
| 1114 host_resolver_->rules()->AddIPLiteralRule( |
| 1115 "*", "2:abcd::3:4:ff,3:abcd::3:4:ff", ""); |
| 1116 |
| 1117 TestCompletionCallback callback; |
| 1118 ClientSocketHandle handle; |
| 1119 int rv = handle.Init("a", low_params_, LOW, &callback, &pool, BoundNetLog()); |
| 1120 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1121 EXPECT_FALSE(handle.is_initialized()); |
| 1122 EXPECT_FALSE(handle.socket()); |
| 1123 |
| 1124 EXPECT_EQ(OK, callback.WaitForResult()); |
| 1125 EXPECT_TRUE(handle.is_initialized()); |
| 1126 EXPECT_TRUE(handle.socket()); |
| 1127 EXPECT_EQ(1, client_socket_factory_.allocation_count()); |
| 1128 } |
| 1129 |
| 1130 TEST_F(TCPClientSocketPoolTest, IPv4HasNoFallback) { |
| 1131 TCPClientSocketPool pool(1, |
| 1132 1, |
| 1133 histograms_.get(), |
| 1134 host_resolver_.get(), |
| 1135 &client_socket_factory_, |
| 1136 NULL); |
| 1137 |
| 1138 client_socket_factory_.set_client_socket_type( |
| 1139 MockClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET); |
| 1140 |
| 1141 // Resolve an AddressList with only IPv4 addresses. |
| 1142 host_resolver_->rules()->AddIPLiteralRule( |
| 1143 "*", "1.1.1.1", ""); |
| 1144 |
| 1145 TestCompletionCallback callback; |
| 1146 ClientSocketHandle handle; |
| 1147 int rv = handle.Init("a", low_params_, LOW, &callback, &pool, BoundNetLog()); |
| 1148 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 1149 EXPECT_FALSE(handle.is_initialized()); |
| 1150 EXPECT_FALSE(handle.socket()); |
| 1151 |
| 1152 EXPECT_EQ(OK, callback.WaitForResult()); |
| 1153 EXPECT_TRUE(handle.is_initialized()); |
| 1154 EXPECT_TRUE(handle.socket()); |
| 1155 EXPECT_EQ(1, client_socket_factory_.allocation_count()); |
| 1156 } |
| 1157 |
| 915 } // namespace | 1158 } // namespace |
| 916 | 1159 |
| 917 } // namespace net | 1160 } // namespace net |
| OLD | NEW |