| 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 |