| OLD | NEW |
| 1 // Copyright (c) 2010 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/socks_client_socket.h" | 5 #include "net/socket/socks_client_socket.h" |
| 6 | 6 |
| 7 #include "net/base/address_list.h" | 7 #include "net/base/address_list.h" |
| 8 #include "net/base/net_log.h" | 8 #include "net/base/net_log.h" |
| 9 #include "net/base/net_log_unittest.h" | 9 #include "net/base/net_log_unittest.h" |
| 10 #include "net/base/mock_host_resolver.h" | 10 #include "net/base/mock_host_resolver.h" |
| 11 #include "net/base/test_completion_callback.h" | 11 #include "net/base/test_completion_callback.h" |
| 12 #include "net/base/winsock_init.h" | 12 #include "net/base/winsock_init.h" |
| 13 #include "net/socket/client_socket_factory.h" | 13 #include "net/socket/client_socket_factory.h" |
| 14 #include "net/socket/tcp_client_socket.h" | 14 #include "net/socket/tcp_client_socket.h" |
| 15 #include "net/socket/socket_test_util.h" | 15 #include "net/socket/socket_test_util.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 17 #include "testing/platform_test.h" | 17 #include "testing/platform_test.h" |
| 18 | 18 |
| 19 //----------------------------------------------------------------------------- | 19 //----------------------------------------------------------------------------- |
| 20 | 20 |
| 21 namespace net { | 21 namespace net { |
| 22 | 22 |
| 23 const char kSOCKSOkRequest[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 }; | 23 const char kSOCKSOkRequest[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 }; |
| 24 const char kSOCKS4aInitialRequest[] = | |
| 25 { 0x04, 0x01, 0x00, 0x50, 0, 0, 0, 127, 0 }; | |
| 26 const char kSOCKSOkReply[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 }; | 24 const char kSOCKSOkReply[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 }; |
| 27 | 25 |
| 28 class SOCKSClientSocketTest : public PlatformTest { | 26 class SOCKSClientSocketTest : public PlatformTest { |
| 29 public: | 27 public: |
| 30 SOCKSClientSocketTest(); | 28 SOCKSClientSocketTest(); |
| 31 // Create a SOCKSClientSocket on top of a MockSocket. | 29 // Create a SOCKSClientSocket on top of a MockSocket. |
| 32 SOCKSClientSocket* BuildMockSocket(MockRead reads[], size_t reads_count, | 30 SOCKSClientSocket* BuildMockSocket(MockRead reads[], size_t reads_count, |
| 33 MockWrite writes[], size_t writes_count, | 31 MockWrite writes[], size_t writes_count, |
| 34 HostResolver* host_resolver, | 32 HostResolver* host_resolver, |
| 35 const std::string& hostname, int port, | 33 const std::string& hostname, int port, |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 | 143 |
| 146 net::CapturingNetLog::EntryList entries; | 144 net::CapturingNetLog::EntryList entries; |
| 147 log.GetEntries(&entries); | 145 log.GetEntries(&entries); |
| 148 EXPECT_TRUE( | 146 EXPECT_TRUE( |
| 149 LogContainsBeginEvent(entries, 0, NetLog::TYPE_SOCKS_CONNECT)); | 147 LogContainsBeginEvent(entries, 0, NetLog::TYPE_SOCKS_CONNECT)); |
| 150 EXPECT_FALSE(user_sock_->IsConnected()); | 148 EXPECT_FALSE(user_sock_->IsConnected()); |
| 151 | 149 |
| 152 rv = callback_.WaitForResult(); | 150 rv = callback_.WaitForResult(); |
| 153 EXPECT_EQ(OK, rv); | 151 EXPECT_EQ(OK, rv); |
| 154 EXPECT_TRUE(user_sock_->IsConnected()); | 152 EXPECT_TRUE(user_sock_->IsConnected()); |
| 155 EXPECT_EQ(SOCKSClientSocket::kSOCKS4, user_sock_->socks_version_); | |
| 156 log.GetEntries(&entries); | 153 log.GetEntries(&entries); |
| 157 EXPECT_TRUE(LogContainsEndEvent( | 154 EXPECT_TRUE(LogContainsEndEvent( |
| 158 entries, -1, NetLog::TYPE_SOCKS_CONNECT)); | 155 entries, -1, NetLog::TYPE_SOCKS_CONNECT)); |
| 159 | 156 |
| 160 scoped_refptr<IOBuffer> buffer(new IOBuffer(payload_write.size())); | 157 scoped_refptr<IOBuffer> buffer(new IOBuffer(payload_write.size())); |
| 161 memcpy(buffer->data(), payload_write.data(), payload_write.size()); | 158 memcpy(buffer->data(), payload_write.data(), payload_write.size()); |
| 162 rv = user_sock_->Write(buffer, payload_write.size(), &callback_); | 159 rv = user_sock_->Write(buffer, payload_write.size(), &callback_); |
| 163 EXPECT_EQ(ERR_IO_PENDING, rv); | 160 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 164 rv = callback_.WaitForResult(); | 161 rv = callback_.WaitForResult(); |
| 165 EXPECT_EQ(static_cast<int>(payload_write.size()), rv); | 162 EXPECT_EQ(static_cast<int>(payload_write.size()), rv); |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 325 entries, 0, NetLog::TYPE_SOCKS_CONNECT)); | 322 entries, 0, NetLog::TYPE_SOCKS_CONNECT)); |
| 326 | 323 |
| 327 rv = callback_.WaitForResult(); | 324 rv = callback_.WaitForResult(); |
| 328 EXPECT_EQ(ERR_CONNECTION_CLOSED, rv); | 325 EXPECT_EQ(ERR_CONNECTION_CLOSED, rv); |
| 329 EXPECT_FALSE(user_sock_->IsConnected()); | 326 EXPECT_FALSE(user_sock_->IsConnected()); |
| 330 log.GetEntries(&entries); | 327 log.GetEntries(&entries); |
| 331 EXPECT_TRUE(LogContainsEndEvent( | 328 EXPECT_TRUE(LogContainsEndEvent( |
| 332 entries, -1, NetLog::TYPE_SOCKS_CONNECT)); | 329 entries, -1, NetLog::TYPE_SOCKS_CONNECT)); |
| 333 } | 330 } |
| 334 | 331 |
| 335 // Tries to connect to an unknown DNS and on failure should revert to SOCKS4A. | 332 // Tries to connect to an unknown hostname. Should fail rather than |
| 336 TEST_F(SOCKSClientSocketTest, SOCKS4AFailedDNS) { | 333 // falling back to SOCKS4a. |
| 334 TEST_F(SOCKSClientSocketTest, FailedDNS) { |
| 337 const char hostname[] = "unresolved.ipv4.address"; | 335 const char hostname[] = "unresolved.ipv4.address"; |
| 338 | 336 |
| 339 host_resolver_->rules()->AddSimulatedFailure(hostname); | 337 host_resolver_->rules()->AddSimulatedFailure(hostname); |
| 340 | 338 |
| 341 std::string request(kSOCKS4aInitialRequest, | |
| 342 arraysize(kSOCKS4aInitialRequest)); | |
| 343 request.append(hostname, arraysize(hostname)); | |
| 344 | |
| 345 MockWrite data_writes[] = { | |
| 346 MockWrite(false, request.data(), request.size()) }; | |
| 347 MockRead data_reads[] = { | |
| 348 MockRead(false, kSOCKSOkReply, arraysize(kSOCKSOkReply)) }; | |
| 349 CapturingNetLog log(CapturingNetLog::kUnbounded); | 339 CapturingNetLog log(CapturingNetLog::kUnbounded); |
| 350 | 340 |
| 351 user_sock_.reset(BuildMockSocket(data_reads, arraysize(data_reads), | 341 user_sock_.reset(BuildMockSocket(NULL, 0, |
| 352 data_writes, arraysize(data_writes), | 342 NULL, 0, |
| 353 host_resolver_.get(), | 343 host_resolver_.get(), |
| 354 hostname, 80, | 344 hostname, 80, |
| 355 &log)); | 345 &log)); |
| 356 | 346 |
| 357 int rv = user_sock_->Connect(&callback_); | 347 int rv = user_sock_->Connect(&callback_); |
| 358 EXPECT_EQ(ERR_IO_PENDING, rv); | 348 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 359 net::CapturingNetLog::EntryList entries; | 349 net::CapturingNetLog::EntryList entries; |
| 360 log.GetEntries(&entries); | 350 log.GetEntries(&entries); |
| 361 EXPECT_TRUE(LogContainsBeginEvent( | 351 EXPECT_TRUE(LogContainsBeginEvent( |
| 362 entries, 0, NetLog::TYPE_SOCKS_CONNECT)); | 352 entries, 0, NetLog::TYPE_SOCKS_CONNECT)); |
| 363 | 353 |
| 364 rv = callback_.WaitForResult(); | 354 rv = callback_.WaitForResult(); |
| 365 EXPECT_EQ(OK, rv); | 355 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv); |
| 366 EXPECT_TRUE(user_sock_->IsConnected()); | 356 EXPECT_FALSE(user_sock_->IsConnected()); |
| 367 EXPECT_EQ(SOCKSClientSocket::kSOCKS4a, user_sock_->socks_version_); | |
| 368 log.GetEntries(&entries); | |
| 369 EXPECT_TRUE(LogContainsEndEvent( | |
| 370 entries, -1, NetLog::TYPE_SOCKS_CONNECT)); | |
| 371 } | |
| 372 | |
| 373 // Tries to connect to a domain that resolves to IPv6. | |
| 374 // Should revert to SOCKS4a. | |
| 375 TEST_F(SOCKSClientSocketTest, SOCKS4AIfDomainInIPv6) { | |
| 376 const char hostname[] = "an.ipv6.address"; | |
| 377 | |
| 378 host_resolver_->rules()->AddIPLiteralRule(hostname, | |
| 379 "2001:db8:8714:3a90::12", ""); | |
| 380 | |
| 381 std::string request(kSOCKS4aInitialRequest, | |
| 382 arraysize(kSOCKS4aInitialRequest)); | |
| 383 request.append(hostname, arraysize(hostname)); | |
| 384 | |
| 385 MockWrite data_writes[] = { | |
| 386 MockWrite(false, request.data(), request.size()) }; | |
| 387 MockRead data_reads[] = { | |
| 388 MockRead(false, kSOCKSOkReply, arraysize(kSOCKSOkReply)) }; | |
| 389 CapturingNetLog log(CapturingNetLog::kUnbounded); | |
| 390 | |
| 391 user_sock_.reset(BuildMockSocket(data_reads, arraysize(data_reads), | |
| 392 data_writes, arraysize(data_writes), | |
| 393 host_resolver_.get(), | |
| 394 hostname, 80, | |
| 395 &log)); | |
| 396 | |
| 397 int rv = user_sock_->Connect(&callback_); | |
| 398 EXPECT_EQ(ERR_IO_PENDING, rv); | |
| 399 net::CapturingNetLog::EntryList entries; | |
| 400 log.GetEntries(&entries); | |
| 401 EXPECT_TRUE(LogContainsBeginEvent( | |
| 402 entries, 0, NetLog::TYPE_SOCKS_CONNECT)); | |
| 403 | |
| 404 rv = callback_.WaitForResult(); | |
| 405 EXPECT_EQ(OK, rv); | |
| 406 EXPECT_TRUE(user_sock_->IsConnected()); | |
| 407 EXPECT_EQ(SOCKSClientSocket::kSOCKS4a, user_sock_->socks_version_); | |
| 408 log.GetEntries(&entries); | 357 log.GetEntries(&entries); |
| 409 EXPECT_TRUE(LogContainsEndEvent( | 358 EXPECT_TRUE(LogContainsEndEvent( |
| 410 entries, -1, NetLog::TYPE_SOCKS_CONNECT)); | 359 entries, -1, NetLog::TYPE_SOCKS_CONNECT)); |
| 411 } | 360 } |
| 412 | 361 |
| 413 // Calls Disconnect() while a host resolve is in progress. The outstanding host | 362 // Calls Disconnect() while a host resolve is in progress. The outstanding host |
| 414 // resolve should be cancelled. | 363 // resolve should be cancelled. |
| 415 TEST_F(SOCKSClientSocketTest, DisconnectWhileHostResolveInProgress) { | 364 TEST_F(SOCKSClientSocketTest, DisconnectWhileHostResolveInProgress) { |
| 416 scoped_ptr<HangingHostResolver> hanging_resolver(new HangingHostResolver()); | 365 scoped_ptr<HangingHostResolver> hanging_resolver(new HangingHostResolver()); |
| 417 | 366 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 438 // Disconnect the SOCKS socket -- this should cancel the outstanding resolve. | 387 // Disconnect the SOCKS socket -- this should cancel the outstanding resolve. |
| 439 user_sock_->Disconnect(); | 388 user_sock_->Disconnect(); |
| 440 | 389 |
| 441 EXPECT_FALSE(hanging_resolver->HasOutstandingRequest()); | 390 EXPECT_FALSE(hanging_resolver->HasOutstandingRequest()); |
| 442 | 391 |
| 443 EXPECT_FALSE(user_sock_->IsConnected()); | 392 EXPECT_FALSE(user_sock_->IsConnected()); |
| 444 EXPECT_FALSE(user_sock_->IsConnectedAndIdle()); | 393 EXPECT_FALSE(user_sock_->IsConnectedAndIdle()); |
| 445 } | 394 } |
| 446 | 395 |
| 447 } // namespace net | 396 } // namespace net |
| OLD | NEW |