141be673e93ed225b45479557b20ff19b3082bae8Richard Smith// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2859b6227694033dd6eaf3991a2b80877a406c382Richard Smith// Use of this source code is governed by a BSD-style license that can be 384ef8990b8f6b0f9ab57f8e2b7372dad5575364fRichard Smith// found in the LICENSE file. 403544fccd1782418c1bf2528111683e18f43b913Richard Smith 503544fccd1782418c1bf2528111683e18f43b913Richard Smith#include "net/socket/socks5_client_socket.h" 603544fccd1782418c1bf2528111683e18f43b913Richard Smith 703544fccd1782418c1bf2528111683e18f43b913Richard Smith#include <algorithm> 803544fccd1782418c1bf2528111683e18f43b913Richard Smith#include <iterator> 903544fccd1782418c1bf2528111683e18f43b913Richard Smith#include <map> 1003544fccd1782418c1bf2528111683e18f43b913Richard Smith 11193649c2a3ff0616777de934a2bf47eaeb4f1076Richard Smith#include "base/sys_byteorder.h" 12193649c2a3ff0616777de934a2bf47eaeb4f1076Richard Smith#include "net/base/address_list.h" 1303544fccd1782418c1bf2528111683e18f43b913Richard Smith#include "net/base/net_log.h" 1403544fccd1782418c1bf2528111683e18f43b913Richard Smith#include "net/base/net_log_unittest.h" 15d390de9c6312684c5e5b333f434199e193c7467aRichard Smith#include "net/base/test_completion_callback.h" 1684ef8990b8f6b0f9ab57f8e2b7372dad5575364fRichard Smith#include "net/base/winsock_init.h" 1784ef8990b8f6b0f9ab57f8e2b7372dad5575364fRichard Smith#include "net/dns/mock_host_resolver.h" 1884ef8990b8f6b0f9ab57f8e2b7372dad5575364fRichard Smith#include "net/socket/client_socket_factory.h" 1984ef8990b8f6b0f9ab57f8e2b7372dad5575364fRichard Smith#include "net/socket/socket_test_util.h" 2084ef8990b8f6b0f9ab57f8e2b7372dad5575364fRichard Smith#include "net/socket/tcp_client_socket.h" 2184ef8990b8f6b0f9ab57f8e2b7372dad5575364fRichard Smith#include "testing/gtest/include/gtest/gtest.h" 2284ef8990b8f6b0f9ab57f8e2b7372dad5575364fRichard Smith#include "testing/platform_test.h" 2384ef8990b8f6b0f9ab57f8e2b7372dad5575364fRichard Smith 2441be673e93ed225b45479557b20ff19b3082bae8Richard Smith//----------------------------------------------------------------------------- 25f64231e9f47234826fbcdc3b4fe0370ef6c9961dMichael Han 26651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesnamespace net { 27661a99690bc133bbaa029da925481d4a860dec90Richard Smith 28661a99690bc133bbaa029da925481d4a860dec90Richard Smithnamespace { 29661a99690bc133bbaa029da925481d4a860dec90Richard Smith 30661a99690bc133bbaa029da925481d4a860dec90Richard Smith// Base class to test SOCKS5ClientSocket 31661a99690bc133bbaa029da925481d4a860dec90Richard Smithclass SOCKS5ClientSocketTest : public PlatformTest { 32661a99690bc133bbaa029da925481d4a860dec90Richard Smith public: 33661a99690bc133bbaa029da925481d4a860dec90Richard Smith SOCKS5ClientSocketTest(); 34661a99690bc133bbaa029da925481d4a860dec90Richard Smith // Create a SOCKSClientSocket on top of a MockSocket. 35661a99690bc133bbaa029da925481d4a860dec90Richard Smith scoped_ptr<SOCKS5ClientSocket> BuildMockSocket(MockRead reads[], 36661a99690bc133bbaa029da925481d4a860dec90Richard Smith size_t reads_count, 37661a99690bc133bbaa029da925481d4a860dec90Richard Smith MockWrite writes[], 38661a99690bc133bbaa029da925481d4a860dec90Richard Smith size_t writes_count, 39661a99690bc133bbaa029da925481d4a860dec90Richard Smith const std::string& hostname, 40661a99690bc133bbaa029da925481d4a860dec90Richard Smith int port, 41661a99690bc133bbaa029da925481d4a860dec90Richard Smith NetLog* net_log); 42661a99690bc133bbaa029da925481d4a860dec90Richard Smith 437fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith virtual void SetUp(); 447fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith 457fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith protected: 467fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith const uint16 kNwPort; 477fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith CapturingNetLog net_log_; 487fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith scoped_ptr<SOCKS5ClientSocket> user_sock_; 49b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smith AddressList address_list_; 507fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith // Filled in by BuildMockSocket() and owned by its return value 517fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith // (which |user_sock| is set to). 5203544fccd1782418c1bf2528111683e18f43b913Richard Smith StreamSocket* tcp_sock_; 5303544fccd1782418c1bf2528111683e18f43b913Richard Smith TestCompletionCallback callback_; 5403544fccd1782418c1bf2528111683e18f43b913Richard Smith scoped_ptr<MockHostResolver> host_resolver_; 5503544fccd1782418c1bf2528111683e18f43b913Richard Smith scoped_ptr<SocketDataProvider> data_; 5603544fccd1782418c1bf2528111683e18f43b913Richard Smith 5703544fccd1782418c1bf2528111683e18f43b913Richard Smith private: 5803544fccd1782418c1bf2528111683e18f43b913Richard Smith DISALLOW_COPY_AND_ASSIGN(SOCKS5ClientSocketTest); 5903544fccd1782418c1bf2528111683e18f43b913Richard Smith}; 603e280b58db5e7dc2bab736fa65af2b8157916726Sebastian Redl 613e280b58db5e7dc2bab736fa65af2b8157916726Sebastian RedlSOCKS5ClientSocketTest::SOCKS5ClientSocketTest() 6256a04287a1c713870d1e03206cce785e985cc866Sebastian Redl : kNwPort(base::HostToNet16(80)), 6356a04287a1c713870d1e03206cce785e985cc866Sebastian Redl host_resolver_(new MockHostResolver) { 646dc00f6e98a00bd1c332927c3e04918d7e8b0d4fSebastian Redl} 656dc00f6e98a00bd1c332927c3e04918d7e8b0d4fSebastian Redl 666b13022faef260c8f49d04310f4a2c0a57f9103bRichard Smith// Set up platform before every test case 67dbe01bb024ce9407954275a5e3c7e1a7113ca9faRichard Smithvoid SOCKS5ClientSocketTest::SetUp() { 68dbe01bb024ce9407954275a5e3c7e1a7113ca9faRichard Smith PlatformTest::SetUp(); 6903544fccd1782418c1bf2528111683e18f43b913Richard Smith 7003544fccd1782418c1bf2528111683e18f43b913Richard Smith // Resolve the "localhost" AddressList used by the TCP connection to connect. 7103544fccd1782418c1bf2528111683e18f43b913Richard Smith HostResolver::RequestInfo info(HostPortPair("www.socks-proxy.com", 1080)); 7203544fccd1782418c1bf2528111683e18f43b913Richard Smith TestCompletionCallback callback; 7303544fccd1782418c1bf2528111683e18f43b913Richard Smith int rv = host_resolver_->Resolve(info, 7403544fccd1782418c1bf2528111683e18f43b913Richard Smith DEFAULT_PRIORITY, 7503544fccd1782418c1bf2528111683e18f43b913Richard Smith &address_list_, 766242a45ca50586ed3f363d4ac7422e07092e4d96Richard Smith callback.callback(), 776b13022faef260c8f49d04310f4a2c0a57f9103bRichard Smith NULL, 787fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith BoundNetLog()); 79ca8937111cccdbf7d17c349487a332d6c7c97f91Sebastian Redl ASSERT_EQ(ERR_IO_PENDING, rv); 80ca8937111cccdbf7d17c349487a332d6c7c97f91Sebastian Redl rv = callback.WaitForResult(); 81ca8937111cccdbf7d17c349487a332d6c7c97f91Sebastian Redl ASSERT_EQ(OK, rv); 82ca8937111cccdbf7d17c349487a332d6c7c97f91Sebastian Redl} 837fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith 845cc2c6eb67b6e5361bbe96f79b519fd62ec666d6Richard Smithscoped_ptr<SOCKS5ClientSocket> SOCKS5ClientSocketTest::BuildMockSocket( 857fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith MockRead reads[], 867fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith size_t reads_count, 877fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith MockWrite writes[], 887fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith size_t writes_count, 897fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith const std::string& hostname, 907fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith int port, 917fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith NetLog* net_log) { 927fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith TestCompletionCallback callback; 937fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith data_.reset(new StaticSocketDataProvider(reads, reads_count, 947fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith writes, writes_count)); 957fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith tcp_sock_ = new MockTCPClientSocket(address_list_, net_log, data_.get()); 967fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith 977fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith int rv = tcp_sock_->Connect(callback.callback()); 987fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith EXPECT_EQ(ERR_IO_PENDING, rv); 997fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith rv = callback.WaitForResult(); 1007fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith EXPECT_EQ(OK, rv); 1017fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith EXPECT_TRUE(tcp_sock_->IsConnected()); 1027fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith 1037fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle); 1047fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith // |connection| takes ownership of |tcp_sock_|, but keep a 1057fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith // non-owning pointer to it. 1067fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith connection->SetSocket(scoped_ptr<StreamSocket>(tcp_sock_)); 1077fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith return scoped_ptr<SOCKS5ClientSocket>(new SOCKS5ClientSocket( 108193649c2a3ff0616777de934a2bf47eaeb4f1076Richard Smith connection.Pass(), 109193649c2a3ff0616777de934a2bf47eaeb4f1076Richard Smith HostResolver::RequestInfo(HostPortPair(hostname, port)))); 110193649c2a3ff0616777de934a2bf47eaeb4f1076Richard Smith} 111193649c2a3ff0616777de934a2bf47eaeb4f1076Richard Smith 11225cf8abf30189323199b1424848b105940267c1bRichard Smith// Tests a complete SOCKS5 handshake and the disconnection. 113193649c2a3ff0616777de934a2bf47eaeb4f1076Richard SmithTEST_F(SOCKS5ClientSocketTest, CompleteHandshake) { 11425cf8abf30189323199b1424848b105940267c1bRichard Smith const std::string payload_write = "random data"; 1157fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith const std::string payload_read = "moar random data"; 1167fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith 1177fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith const char kOkRequest[] = { 1187fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith 0x05, // Version 1197fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith 0x01, // Command (CONNECT) 1207fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith 0x00, // Reserved. 1217fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith 0x03, // Address type (DOMAINNAME). 1227fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith 0x09, // Length of domain (9) 1237fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith // Domain string: 1247fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith 'l', 'o', 'c', 'a', 'l', 'h', 'o', 's', 't', 1257fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith 0x00, 0x50, // 16-bit port (80) 1267fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith }; 1277fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith 1287fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith MockWrite data_writes[] = { 1297fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength), 1307fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith MockWrite(ASYNC, kOkRequest, arraysize(kOkRequest)), 1317fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith MockWrite(ASYNC, payload_write.data(), payload_write.size()) }; 1327fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith MockRead data_reads[] = { 133ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength), 1347fe6208c3fa91f835813bb78236ef5c2bbf81053Richard Smith MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength), 1350aa86c0463a881be85fd34e04c7de3379997621dRichard Smith MockRead(ASYNC, payload_read.data(), payload_read.size()) }; 1360aa86c0463a881be85fd34e04c7de3379997621dRichard Smith 1370aa86c0463a881be85fd34e04c7de3379997621dRichard Smith user_sock_ = BuildMockSocket(data_reads, arraysize(data_reads), 138841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith data_writes, arraysize(data_writes), 139841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith "localhost", 80, &net_log_); 140841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith 141841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith // At this state the TCP connection is completed but not the SOCKS handshake. 142841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith EXPECT_TRUE(tcp_sock_->IsConnected()); 143841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith EXPECT_FALSE(user_sock_->IsConnected()); 14439304fad1c8a7b7e64121e9ae544b18e460b682cRichard Smith 145841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith int rv = user_sock_->Connect(callback_.callback()); 146841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith EXPECT_EQ(ERR_IO_PENDING, rv); 147841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith EXPECT_FALSE(user_sock_->IsConnected()); 148841804baff6ea8ba1904a2ba81265aae1479e882Richard Smith 149ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith CapturingNetLog::CapturedEntryList net_log_entries; 150ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith net_log_.GetEntries(&net_log_entries); 151ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith EXPECT_TRUE(LogContainsBeginEvent(net_log_entries, 0, 152ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith NetLog::TYPE_SOCKS5_CONNECT)); 153ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith 154cbec59a267d8d6c402c6b0206e36dca091fc9ae4Richard Smith rv = callback_.WaitForResult(); 155ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith 156ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith EXPECT_EQ(OK, rv); 157ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith EXPECT_TRUE(user_sock_->IsConnected()); 158ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith 159ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith net_log_.GetEntries(&net_log_entries); 160ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith EXPECT_TRUE(LogContainsEndEvent(net_log_entries, -1, 161ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith NetLog::TYPE_SOCKS5_CONNECT)); 162ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith 163ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith scoped_refptr<IOBuffer> buffer(new IOBuffer(payload_write.size())); 164ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith memcpy(buffer->data(), payload_write.data(), payload_write.size()); 165ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith rv = user_sock_->Write( 166ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith buffer.get(), payload_write.size(), callback_.callback()); 167ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith EXPECT_EQ(ERR_IO_PENDING, rv); 168ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith rv = callback_.WaitForResult(); 169ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith EXPECT_EQ(static_cast<int>(payload_write.size()), rv); 170ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith 171ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith buffer = new IOBuffer(payload_read.size()); 172ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith rv = 173ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith user_sock_->Read(buffer.get(), payload_read.size(), callback_.callback()); 174ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith EXPECT_EQ(ERR_IO_PENDING, rv); 175ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith rv = callback_.WaitForResult(); 176ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith EXPECT_EQ(static_cast<int>(payload_read.size()), rv); 177ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith EXPECT_EQ(payload_read, std::string(buffer->data(), payload_read.size())); 178ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith 179ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith user_sock_->Disconnect(); 180ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith EXPECT_FALSE(tcp_sock_->IsConnected()); 181ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith EXPECT_FALSE(user_sock_->IsConnected()); 182ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith} 183ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith 184ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith// Test that you can call Connect() again after having called Disconnect(). 185ebaf0e6ab743394dda086a01b457838cb6e589a8Richard SmithTEST_F(SOCKS5ClientSocketTest, ConnectAndDisconnectTwice) { 186ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith const std::string hostname = "my-host-name"; 187ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith const char kSOCKS5DomainRequest[] = { 188ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith 0x05, // VER 189ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith 0x01, // CMD 190ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith 0x00, // RSV 191ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith 0x03, // ATYPE 192ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith }; 193ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith 194ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith std::string request(kSOCKS5DomainRequest, arraysize(kSOCKS5DomainRequest)); 195ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith request.push_back(hostname.size()); 196ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith request.append(hostname); 197ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith request.append(reinterpret_cast<const char*>(&kNwPort), sizeof(kNwPort)); 198ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith 199ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith for (int i = 0; i < 2; ++i) { 200ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith MockWrite data_writes[] = { 201ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith MockWrite(SYNCHRONOUS, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength), 202ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith MockWrite(SYNCHRONOUS, request.data(), request.size()) 203ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith }; 204ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith MockRead data_reads[] = { 205ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith MockRead(SYNCHRONOUS, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength), 206ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith MockRead(SYNCHRONOUS, kSOCKS5OkResponse, kSOCKS5OkResponseLength) 207ebaf0e6ab743394dda086a01b457838cb6e589a8Richard Smith }; 2086b13022faef260c8f49d04310f4a2c0a57f9103bRichard Smith 2096b13022faef260c8f49d04310f4a2c0a57f9103bRichard Smith user_sock_ = BuildMockSocket(data_reads, arraysize(data_reads), 2106b13022faef260c8f49d04310f4a2c0a57f9103bRichard Smith data_writes, arraysize(data_writes), 2116b13022faef260c8f49d04310f4a2c0a57f9103bRichard Smith hostname, 80, NULL); 2126b13022faef260c8f49d04310f4a2c0a57f9103bRichard Smith 2136b13022faef260c8f49d04310f4a2c0a57f9103bRichard Smith int rv = user_sock_->Connect(callback_.callback()); 2146b13022faef260c8f49d04310f4a2c0a57f9103bRichard Smith EXPECT_EQ(OK, rv); 2156b13022faef260c8f49d04310f4a2c0a57f9103bRichard Smith EXPECT_TRUE(user_sock_->IsConnected()); 2166b13022faef260c8f49d04310f4a2c0a57f9103bRichard Smith 2176b13022faef260c8f49d04310f4a2c0a57f9103bRichard Smith user_sock_->Disconnect(); 21877faa365cb2322cfc8edf58a4f5d68f2370cc39aRichard Smith EXPECT_FALSE(user_sock_->IsConnected()); 21977faa365cb2322cfc8edf58a4f5d68f2370cc39aRichard Smith } 22077faa365cb2322cfc8edf58a4f5d68f2370cc39aRichard Smith} 22177faa365cb2322cfc8edf58a4f5d68f2370cc39aRichard Smith 222651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// Test that we fail trying to connect to a hosname longer than 255 bytes. 22377faa365cb2322cfc8edf58a4f5d68f2370cc39aRichard SmithTEST_F(SOCKS5ClientSocketTest, LargeHostNameFails) { 22477faa365cb2322cfc8edf58a4f5d68f2370cc39aRichard Smith // Create a string of length 256, where each character is 'x'. 22577faa365cb2322cfc8edf58a4f5d68f2370cc39aRichard Smith std::string large_host_name; 226651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::fill_n(std::back_inserter(large_host_name), 256, 'x'); 22783da2e711902c4c54f5601c9000d646dfff06aeaRichard Smith 22883da2e711902c4c54f5601c9000d646dfff06aeaRichard Smith // Create a SOCKS socket, with mock transport socket. 22983da2e711902c4c54f5601c9000d646dfff06aeaRichard Smith MockWrite data_writes[] = {MockWrite()}; 23083da2e711902c4c54f5601c9000d646dfff06aeaRichard Smith MockRead data_reads[] = {MockRead()}; 23183da2e711902c4c54f5601c9000d646dfff06aeaRichard Smith user_sock_ = BuildMockSocket(data_reads, arraysize(data_reads), 23283da2e711902c4c54f5601c9000d646dfff06aeaRichard Smith data_writes, arraysize(data_writes), 23383da2e711902c4c54f5601c9000d646dfff06aeaRichard Smith large_host_name, 80, NULL); 23483da2e711902c4c54f5601c9000d646dfff06aeaRichard Smith 23583da2e711902c4c54f5601c9000d646dfff06aeaRichard Smith // Try to connect -- should fail (without having read/written anything to 23683da2e711902c4c54f5601c9000d646dfff06aeaRichard Smith // the transport socket first) because the hostname is too long. 23783da2e711902c4c54f5601c9000d646dfff06aeaRichard Smith TestCompletionCallback callback; 23883da2e711902c4c54f5601c9000d646dfff06aeaRichard Smith int rv = user_sock_->Connect(callback.callback()); 23983da2e711902c4c54f5601c9000d646dfff06aeaRichard Smith EXPECT_EQ(ERR_SOCKS_CONNECTION_FAILED, rv); 24083da2e711902c4c54f5601c9000d646dfff06aeaRichard Smith} 24183da2e711902c4c54f5601c9000d646dfff06aeaRichard Smith 24283da2e711902c4c54f5601c9000d646dfff06aeaRichard SmithTEST_F(SOCKS5ClientSocketTest, PartialReadWrites) { 2436c4c36c4ed1007143f5b8655eb68b313a7e12e76Richard Smith const std::string hostname = "www.google.com"; 2446c4c36c4ed1007143f5b8655eb68b313a7e12e76Richard Smith 24583da2e711902c4c54f5601c9000d646dfff06aeaRichard Smith const char kOkRequest[] = { 24683da2e711902c4c54f5601c9000d646dfff06aeaRichard Smith 0x05, // Version 24783da2e711902c4c54f5601c9000d646dfff06aeaRichard Smith 0x01, // Command (CONNECT) 24883da2e711902c4c54f5601c9000d646dfff06aeaRichard Smith 0x00, // Reserved. 24983da2e711902c4c54f5601c9000d646dfff06aeaRichard Smith 0x03, // Address type (DOMAINNAME). 25083da2e711902c4c54f5601c9000d646dfff06aeaRichard Smith 0x0E, // Length of domain (14) 25183da2e711902c4c54f5601c9000d646dfff06aeaRichard Smith // Domain string: 252e7d7c39be90bf654a8da0f53f6682d965426d081Richard Smith 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm', 253e7d7c39be90bf654a8da0f53f6682d965426d081Richard Smith 0x00, 0x50, // 16-bit port (80) 254e7d7c39be90bf654a8da0f53f6682d965426d081Richard Smith }; 255ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith 256e7d7c39be90bf654a8da0f53f6682d965426d081Richard Smith // Test for partial greet request write 257e7d7c39be90bf654a8da0f53f6682d965426d081Richard Smith { 258ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith const char partial1[] = { 0x05, 0x01 }; 259e7d7c39be90bf654a8da0f53f6682d965426d081Richard Smith const char partial2[] = { 0x00 }; 260e7d7c39be90bf654a8da0f53f6682d965426d081Richard Smith MockWrite data_writes[] = { 261ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith MockWrite(ASYNC, arraysize(partial1)), 262e7d7c39be90bf654a8da0f53f6682d965426d081Richard Smith MockWrite(ASYNC, partial2, arraysize(partial2)), 263e7d7c39be90bf654a8da0f53f6682d965426d081Richard Smith MockWrite(ASYNC, kOkRequest, arraysize(kOkRequest)) }; 264e7d7c39be90bf654a8da0f53f6682d965426d081Richard Smith MockRead data_reads[] = { 265e7d7c39be90bf654a8da0f53f6682d965426d081Richard Smith MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength), 266e7d7c39be90bf654a8da0f53f6682d965426d081Richard Smith MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength) }; 267e7d7c39be90bf654a8da0f53f6682d965426d081Richard Smith user_sock_ = BuildMockSocket(data_reads, arraysize(data_reads), 268e7d7c39be90bf654a8da0f53f6682d965426d081Richard Smith data_writes, arraysize(data_writes), 269e7d7c39be90bf654a8da0f53f6682d965426d081Richard Smith hostname, 80, &net_log_); 270e7d7c39be90bf654a8da0f53f6682d965426d081Richard Smith int rv = user_sock_->Connect(callback_.callback()); 271e7d7c39be90bf654a8da0f53f6682d965426d081Richard Smith EXPECT_EQ(ERR_IO_PENDING, rv); 272e7d7c39be90bf654a8da0f53f6682d965426d081Richard Smith 273e7d7c39be90bf654a8da0f53f6682d965426d081Richard Smith CapturingNetLog::CapturedEntryList net_log_entries; 274e7d7c39be90bf654a8da0f53f6682d965426d081Richard Smith net_log_.GetEntries(&net_log_entries); 275b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smith EXPECT_TRUE(LogContainsBeginEvent(net_log_entries, 0, 276b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smith NetLog::TYPE_SOCKS5_CONNECT)); 277b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smith 278b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smith rv = callback_.WaitForResult(); 279b9c64d84ea3edd5e2fffb0a2e85ca1308be4f429Richard Smith EXPECT_EQ(OK, rv); 280e7d7c39be90bf654a8da0f53f6682d965426d081Richard Smith EXPECT_TRUE(user_sock_->IsConnected()); 28195aafb2453e1fecec8dcfd9e125cd78277f45859Richard Smith 28295aafb2453e1fecec8dcfd9e125cd78277f45859Richard Smith net_log_.GetEntries(&net_log_entries); 28395aafb2453e1fecec8dcfd9e125cd78277f45859Richard Smith EXPECT_TRUE(LogContainsEndEvent(net_log_entries, -1, 28495aafb2453e1fecec8dcfd9e125cd78277f45859Richard Smith NetLog::TYPE_SOCKS5_CONNECT)); 28595aafb2453e1fecec8dcfd9e125cd78277f45859Richard Smith } 28695aafb2453e1fecec8dcfd9e125cd78277f45859Richard Smith 2870e9e9814a7f8313c0c02b6afea71f0e4c411873eRichard Smith // Test for partial greet response read 2880e9e9814a7f8313c0c02b6afea71f0e4c411873eRichard Smith { 2890e9e9814a7f8313c0c02b6afea71f0e4c411873eRichard Smith const char partial1[] = { 0x05 }; 2900e9e9814a7f8313c0c02b6afea71f0e4c411873eRichard Smith const char partial2[] = { 0x00 }; 2910e9e9814a7f8313c0c02b6afea71f0e4c411873eRichard Smith MockWrite data_writes[] = { 2920e9e9814a7f8313c0c02b6afea71f0e4c411873eRichard Smith MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength), 2930e9e9814a7f8313c0c02b6afea71f0e4c411873eRichard Smith MockWrite(ASYNC, kOkRequest, arraysize(kOkRequest)) }; 2940e9e9814a7f8313c0c02b6afea71f0e4c411873eRichard Smith MockRead data_reads[] = { 2950e9e9814a7f8313c0c02b6afea71f0e4c411873eRichard Smith MockRead(ASYNC, partial1, arraysize(partial1)), 2960e9e9814a7f8313c0c02b6afea71f0e4c411873eRichard Smith MockRead(ASYNC, partial2, arraysize(partial2)), 2970e9e9814a7f8313c0c02b6afea71f0e4c411873eRichard Smith MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength) }; 2980e9e9814a7f8313c0c02b6afea71f0e4c411873eRichard Smith user_sock_ = BuildMockSocket(data_reads, arraysize(data_reads), 2990e9e9814a7f8313c0c02b6afea71f0e4c411873eRichard Smith data_writes, arraysize(data_writes), 3000e9e9814a7f8313c0c02b6afea71f0e4c411873eRichard Smith hostname, 80, &net_log_); 3010e9e9814a7f8313c0c02b6afea71f0e4c411873eRichard Smith int rv = user_sock_->Connect(callback_.callback()); 3020e9e9814a7f8313c0c02b6afea71f0e4c411873eRichard Smith EXPECT_EQ(ERR_IO_PENDING, rv); 3030e9e9814a7f8313c0c02b6afea71f0e4c411873eRichard Smith 304d390de9c6312684c5e5b333f434199e193c7467aRichard Smith CapturingNetLog::CapturedEntryList net_log_entries; 305d390de9c6312684c5e5b333f434199e193c7467aRichard Smith net_log_.GetEntries(&net_log_entries); 306d390de9c6312684c5e5b333f434199e193c7467aRichard Smith EXPECT_TRUE(LogContainsBeginEvent(net_log_entries, 0, 307d390de9c6312684c5e5b333f434199e193c7467aRichard Smith NetLog::TYPE_SOCKS5_CONNECT)); 308d390de9c6312684c5e5b333f434199e193c7467aRichard Smith rv = callback_.WaitForResult(); 309d390de9c6312684c5e5b333f434199e193c7467aRichard Smith EXPECT_EQ(OK, rv); 310d390de9c6312684c5e5b333f434199e193c7467aRichard Smith EXPECT_TRUE(user_sock_->IsConnected()); 311d390de9c6312684c5e5b333f434199e193c7467aRichard Smith net_log_.GetEntries(&net_log_entries); 312d390de9c6312684c5e5b333f434199e193c7467aRichard Smith EXPECT_TRUE(LogContainsEndEvent(net_log_entries, -1, 31326b75c07317a3b50a8a00a1623e3ef38af1d8349Richard Smith NetLog::TYPE_SOCKS5_CONNECT)); 31426b75c07317a3b50a8a00a1623e3ef38af1d8349Richard Smith } 31526b75c07317a3b50a8a00a1623e3ef38af1d8349Richard Smith 31626b75c07317a3b50a8a00a1623e3ef38af1d8349Richard Smith // Test for partial handshake request write. 31726b75c07317a3b50a8a00a1623e3ef38af1d8349Richard Smith { 31826b75c07317a3b50a8a00a1623e3ef38af1d8349Richard Smith const int kSplitPoint = 3; // Break handshake write into two parts. 31926b75c07317a3b50a8a00a1623e3ef38af1d8349Richard Smith MockWrite data_writes[] = { 320b4051e7047a0085f0679257386ff183aed3e5162Richard Smith MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength), 321b4051e7047a0085f0679257386ff183aed3e5162Richard Smith MockWrite(ASYNC, kOkRequest, kSplitPoint), 322b4051e7047a0085f0679257386ff183aed3e5162Richard Smith MockWrite(ASYNC, kOkRequest + kSplitPoint, 323b4051e7047a0085f0679257386ff183aed3e5162Richard Smith arraysize(kOkRequest) - kSplitPoint) 324b4051e7047a0085f0679257386ff183aed3e5162Richard Smith }; 325b4051e7047a0085f0679257386ff183aed3e5162Richard Smith MockRead data_reads[] = { 326b4051e7047a0085f0679257386ff183aed3e5162Richard Smith MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength), 327b4051e7047a0085f0679257386ff183aed3e5162Richard Smith MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength) }; 32886e6fdcf1a04edc4c24f53f9dbacf7e1b52f306dRichard Smith user_sock_ = BuildMockSocket(data_reads, arraysize(data_reads), 32986e6fdcf1a04edc4c24f53f9dbacf7e1b52f306dRichard Smith data_writes, arraysize(data_writes), 33086e6fdcf1a04edc4c24f53f9dbacf7e1b52f306dRichard Smith hostname, 80, &net_log_); 33186e6fdcf1a04edc4c24f53f9dbacf7e1b52f306dRichard Smith int rv = user_sock_->Connect(callback_.callback()); 33286e6fdcf1a04edc4c24f53f9dbacf7e1b52f306dRichard Smith EXPECT_EQ(ERR_IO_PENDING, rv); 33386e6fdcf1a04edc4c24f53f9dbacf7e1b52f306dRichard Smith CapturingNetLog::CapturedEntryList net_log_entries; 33486e6fdcf1a04edc4c24f53f9dbacf7e1b52f306dRichard Smith net_log_.GetEntries(&net_log_entries); 33586e6fdcf1a04edc4c24f53f9dbacf7e1b52f306dRichard Smith EXPECT_TRUE(LogContainsBeginEvent(net_log_entries, 0, 3362cd7f41f4eb2b02568664132253f8e1d9cf381ddBenjamin Kramer NetLog::TYPE_SOCKS5_CONNECT)); 3372cd7f41f4eb2b02568664132253f8e1d9cf381ddBenjamin Kramer rv = callback_.WaitForResult(); 3382cd7f41f4eb2b02568664132253f8e1d9cf381ddBenjamin Kramer EXPECT_EQ(OK, rv); 339ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith EXPECT_TRUE(user_sock_->IsConnected()); 340ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith net_log_.GetEntries(&net_log_entries); 3412cd7f41f4eb2b02568664132253f8e1d9cf381ddBenjamin Kramer EXPECT_TRUE(LogContainsEndEvent(net_log_entries, -1, 3422cd7f41f4eb2b02568664132253f8e1d9cf381ddBenjamin Kramer NetLog::TYPE_SOCKS5_CONNECT)); 3432cd7f41f4eb2b02568664132253f8e1d9cf381ddBenjamin Kramer } 3442cd7f41f4eb2b02568664132253f8e1d9cf381ddBenjamin Kramer 3452cd7f41f4eb2b02568664132253f8e1d9cf381ddBenjamin Kramer // Test for partial handshake response read 3462cd7f41f4eb2b02568664132253f8e1d9cf381ddBenjamin Kramer { 347e5e8f4d2db48ec21f537fd6452276c1fe26bc726Benjamin Kramer const int kSplitPoint = 6; // Break the handshake read into two parts. 348e5e8f4d2db48ec21f537fd6452276c1fe26bc726Benjamin Kramer MockWrite data_writes[] = { 349e5e8f4d2db48ec21f537fd6452276c1fe26bc726Benjamin Kramer MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength), 350ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith MockWrite(ASYNC, kOkRequest, arraysize(kOkRequest)) 351ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith }; 352e5e8f4d2db48ec21f537fd6452276c1fe26bc726Benjamin Kramer MockRead data_reads[] = { 353e5e8f4d2db48ec21f537fd6452276c1fe26bc726Benjamin Kramer MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength), 354e5e8f4d2db48ec21f537fd6452276c1fe26bc726Benjamin Kramer MockRead(ASYNC, kSOCKS5OkResponse, kSplitPoint), 355ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith MockRead(ASYNC, kSOCKS5OkResponse + kSplitPoint, 356e5e8f4d2db48ec21f537fd6452276c1fe26bc726Benjamin Kramer kSOCKS5OkResponseLength - kSplitPoint) 357e5e8f4d2db48ec21f537fd6452276c1fe26bc726Benjamin Kramer }; 358e5e8f4d2db48ec21f537fd6452276c1fe26bc726Benjamin Kramer 359e5e8f4d2db48ec21f537fd6452276c1fe26bc726Benjamin Kramer user_sock_ = BuildMockSocket(data_reads, arraysize(data_reads), 360e5e8f4d2db48ec21f537fd6452276c1fe26bc726Benjamin Kramer data_writes, arraysize(data_writes), 361e5e8f4d2db48ec21f537fd6452276c1fe26bc726Benjamin Kramer hostname, 80, &net_log_); 362e5e8f4d2db48ec21f537fd6452276c1fe26bc726Benjamin Kramer int rv = user_sock_->Connect(callback_.callback()); 363ccc4f283cf0e892e19a097a2aa4ec4491682b15fDouglas Gregor EXPECT_EQ(ERR_IO_PENDING, rv); 364ccc4f283cf0e892e19a097a2aa4ec4491682b15fDouglas Gregor CapturingNetLog::CapturedEntryList net_log_entries; 365ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith net_log_.GetEntries(&net_log_entries); 366ccc4f283cf0e892e19a097a2aa4ec4491682b15fDouglas Gregor EXPECT_TRUE(LogContainsBeginEvent(net_log_entries, 0, 367ac71351acdefc9de0c770c1d717e621ac9e684bfRichard Smith NetLog::TYPE_SOCKS5_CONNECT)); 368ccc4f283cf0e892e19a097a2aa4ec4491682b15fDouglas Gregor rv = callback_.WaitForResult(); 369ccc4f283cf0e892e19a097a2aa4ec4491682b15fDouglas Gregor EXPECT_EQ(OK, rv); 370ccc4f283cf0e892e19a097a2aa4ec4491682b15fDouglas Gregor EXPECT_TRUE(user_sock_->IsConnected()); 371ccc4f283cf0e892e19a097a2aa4ec4491682b15fDouglas Gregor net_log_.GetEntries(&net_log_entries); 372ccc4f283cf0e892e19a097a2aa4ec4491682b15fDouglas Gregor EXPECT_TRUE(LogContainsEndEvent(net_log_entries, -1, 373ccc4f283cf0e892e19a097a2aa4ec4491682b15fDouglas Gregor NetLog::TYPE_SOCKS5_CONNECT)); 374ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo } 375ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo} 376ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo 377ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo} // namespace 378ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo 379ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo} // namespace net 380ef4579cda09b73e3d4d98af48201da25adc29326Larisse Voufo