blob: 63b82c0ad74864fdf50b35ddbf0e23e093a81f2e [file] [log] [blame]
[email protected]8ddf8322012-02-23 18:08:061// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]76a51ac82009-06-28 07:58:582// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/socket/socks_client_socket.h"
6
danakj655b66c2016-04-16 00:51:387#include <memory>
dchengc7eeda422015-12-26 03:56:488#include <utility>
9
Avi Drissman13fc8932015-12-20 04:40:4610#include "base/macros.h"
Paul Jensen0f49dec2017-12-12 23:39:5811#include "build/build_config.h"
[email protected]76a51ac82009-06-28 07:58:5812#include "net/base/address_list.h"
[email protected]76a51ac82009-06-28 07:58:5813#include "net/base/test_completion_callback.h"
14#include "net/base/winsock_init.h"
[email protected]1c7cf3f82014-08-07 21:33:4815#include "net/dns/host_resolver.h"
[email protected]f2cb3cf2013-03-21 01:40:5316#include "net/dns/mock_host_resolver.h"
mikecirone8b85c432016-09-08 19:11:0017#include "net/log/net_log_event_type.h"
mmenke16a7cbdd2015-04-24 23:00:5618#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4619#include "net/log/test_net_log_entry.h"
20#include "net/log/test_net_log_util.h"
[email protected]76a51ac82009-06-28 07:58:5821#include "net/socket/client_socket_factory.h"
[email protected]76a51ac82009-06-28 07:58:5822#include "net/socket/socket_test_util.h"
[email protected]f2cb3cf2013-03-21 01:40:5323#include "net/socket/tcp_client_socket.h"
robpercival214763f2016-07-01 23:27:0124#include "net/test/gtest_util.h"
[email protected]a2b2cfc2017-12-06 09:06:0825#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
robpercival214763f2016-07-01 23:27:0126#include "testing/gmock/include/gmock/gmock.h"
[email protected]76a51ac82009-06-28 07:58:5827#include "testing/gtest/include/gtest/gtest.h"
28#include "testing/platform_test.h"
29
robpercival214763f2016-07-01 23:27:0130using net::test::IsError;
31using net::test::IsOk;
32
[email protected]76a51ac82009-06-28 07:58:5833//-----------------------------------------------------------------------------
34
35namespace net {
36
mikecironef22f9812016-10-04 03:40:1937class NetLog;
38
[email protected]76a51ac82009-06-28 07:58:5839class SOCKSClientSocketTest : public PlatformTest {
40 public:
41 SOCKSClientSocketTest();
42 // Create a SOCKSClientSocket on top of a MockSocket.
danakj655b66c2016-04-16 00:51:3843 std::unique_ptr<SOCKSClientSocket> BuildMockSocket(
44 MockRead reads[],
45 size_t reads_count,
46 MockWrite writes[],
47 size_t writes_count,
[email protected]18ccfdb2013-08-15 00:13:4448 HostResolver* host_resolver,
danakj655b66c2016-04-16 00:51:3849 const std::string& hostname,
50 int port,
[email protected]18ccfdb2013-08-15 00:13:4451 NetLog* net_log);
dcheng67be2b1f2014-10-27 21:47:2952 void SetUp() override;
[email protected]76a51ac82009-06-28 07:58:5853
54 protected:
danakj655b66c2016-04-16 00:51:3855 std::unique_ptr<SOCKSClientSocket> user_sock_;
[email protected]76a51ac82009-06-28 07:58:5856 AddressList address_list_;
[email protected]e3850f282013-08-14 01:43:1857 // Filled in by BuildMockSocket() and owned by its return value
58 // (which |user_sock| is set to).
[email protected]3268023f2011-05-05 00:08:1059 StreamSocket* tcp_sock_;
[email protected]83039bb2011-12-09 18:43:5560 TestCompletionCallback callback_;
danakj655b66c2016-04-16 00:51:3861 std::unique_ptr<MockHostResolver> host_resolver_;
62 std::unique_ptr<SocketDataProvider> data_;
[email protected]76a51ac82009-06-28 07:58:5863};
64
65SOCKSClientSocketTest::SOCKSClientSocketTest()
[email protected]b59ff372009-07-15 22:04:3266 : host_resolver_(new MockHostResolver) {
[email protected]76a51ac82009-06-28 07:58:5867}
68
69// Set up platform before every test case
70void SOCKSClientSocketTest::SetUp() {
71 PlatformTest::SetUp();
[email protected]76a51ac82009-06-28 07:58:5872}
73
danakj655b66c2016-04-16 00:51:3874std::unique_ptr<SOCKSClientSocket> SOCKSClientSocketTest::BuildMockSocket(
[email protected]76a51ac82009-06-28 07:58:5875 MockRead reads[],
[email protected]31a2bfe2010-02-09 08:03:3976 size_t reads_count,
[email protected]76a51ac82009-06-28 07:58:5877 MockWrite writes[],
[email protected]31a2bfe2010-02-09 08:03:3978 size_t writes_count,
[email protected]16a02742010-01-07 22:50:1079 HostResolver* host_resolver,
[email protected]76a51ac82009-06-28 07:58:5880 const std::string& hostname,
[email protected]a2006ece2010-04-23 16:44:0281 int port,
82 NetLog* net_log) {
[email protected]83039bb2011-12-09 18:43:5583 TestCompletionCallback callback;
[email protected]31a2bfe2010-02-09 08:03:3984 data_.reset(new StaticSocketDataProvider(reads, reads_count,
85 writes, writes_count));
[email protected]a2006ece2010-04-23 16:44:0286 tcp_sock_ = new MockTCPClientSocket(address_list_, net_log, data_.get());
[email protected]76a51ac82009-06-28 07:58:5887
[email protected]83039bb2011-12-09 18:43:5588 int rv = tcp_sock_->Connect(callback.callback());
robpercival214763f2016-07-01 23:27:0189 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a51ac82009-06-28 07:58:5890 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0191 EXPECT_THAT(rv, IsOk());
[email protected]76a51ac82009-06-28 07:58:5892 EXPECT_TRUE(tcp_sock_->IsConnected());
93
danakj655b66c2016-04-16 00:51:3894 std::unique_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
[email protected]e3850f282013-08-14 01:43:1895 // |connection| takes ownership of |tcp_sock_|, but keep a
96 // non-owning pointer to it.
danakj655b66c2016-04-16 00:51:3897 connection->SetSocket(std::unique_ptr<StreamSocket>(tcp_sock_));
98 return std::unique_ptr<SOCKSClientSocket>(new SOCKSClientSocket(
dchengc7eeda422015-12-26 03:56:4899 std::move(connection),
100 HostResolver::RequestInfo(HostPortPair(hostname, port)), DEFAULT_PRIORITY,
[email protected]27fb73c2018-01-11 13:27:24101 host_resolver, TRAFFIC_ANNOTATION_FOR_TESTS));
[email protected]76a51ac82009-06-28 07:58:58102}
103
[email protected]16a02742010-01-07 22:50:10104// Implementation of HostResolver that never completes its resolve request.
105// We use this in the test "DisconnectWhileHostResolveInProgress" to make
106// sure that the outstanding resolve request gets cancelled.
[email protected]98e1cd012011-11-08 15:33:09107class HangingHostResolverWithCancel : public HostResolver {
[email protected]16a02742010-01-07 22:50:10108 public:
[email protected]98e1cd012011-11-08 15:33:09109 HangingHostResolverWithCancel() : outstanding_request_(NULL) {}
[email protected]16a02742010-01-07 22:50:10110
dchengb03027d2014-10-21 12:00:20111 int Resolve(const RequestInfo& info,
112 RequestPriority priority,
113 AddressList* addresses,
114 const CompletionCallback& callback,
maksim.sisov31452af2016-07-27 06:38:10115 std::unique_ptr<Request>* out_req,
tfarina42834112016-09-22 13:38:20116 const NetLogWithSource& net_log) override {
[email protected]95a214c2011-08-04 21:50:40117 DCHECK(addresses);
[email protected]aa22b242011-11-16 18:58:29118 DCHECK_EQ(false, callback.is_null());
[email protected]16a02742010-01-07 22:50:10119 EXPECT_FALSE(HasOutstandingRequest());
maksim.sisov31452af2016-07-27 06:38:10120 outstanding_request_ = new RequestImpl(this);
121 out_req->reset(outstanding_request_);
[email protected]16a02742010-01-07 22:50:10122 return ERR_IO_PENDING;
123 }
124
dchengb03027d2014-10-21 12:00:20125 int ResolveFromCache(const RequestInfo& info,
126 AddressList* addresses,
tfarina42834112016-09-22 13:38:20127 const NetLogWithSource& net_log) override {
[email protected]95a214c2011-08-04 21:50:40128 NOTIMPLEMENTED();
129 return ERR_UNEXPECTED;
130 }
131
Miriam Gershenson69333632018-01-05 17:50:24132 int ResolveStaleFromCache(const RequestInfo& info,
133 AddressList* addresses,
134 HostCache::EntryStaleness* stale_info,
135 const NetLogWithSource& net_log) override {
136 NOTIMPLEMENTED();
137 return ERR_UNEXPECTED;
138 }
139
Rob Percivalbc658a22017-12-13 08:24:42140 bool HasCached(base::StringPiece hostname,
141 HostCache::Entry::Source* source_out,
142 HostCache::EntryStaleness* stale_out) const override {
143 NOTIMPLEMENTED();
144 return false;
145 }
146
maksim.sisov31452af2016-07-27 06:38:10147 void RemoveRequest(Request* req) {
[email protected]16a02742010-01-07 22:50:10148 EXPECT_TRUE(HasOutstandingRequest());
149 EXPECT_EQ(outstanding_request_, req);
maksim.sisov31452af2016-07-27 06:38:10150 outstanding_request_ = nullptr;
[email protected]16a02742010-01-07 22:50:10151 }
152
maksim.sisov31452af2016-07-27 06:38:10153 bool HasOutstandingRequest() { return outstanding_request_ != nullptr; }
[email protected]16a02742010-01-07 22:50:10154
155 private:
maksim.sisov31452af2016-07-27 06:38:10156 class RequestImpl : public HostResolver::Request {
157 public:
158 RequestImpl(HangingHostResolverWithCancel* resolver)
159 : resolver_(resolver) {}
160 ~RequestImpl() override {
161 DCHECK(resolver_);
162 resolver_->RemoveRequest(this);
163 }
164
165 void ChangeRequestPriority(RequestPriority priority) override {}
166
167 private:
168 HangingHostResolverWithCancel* resolver_;
169 };
170
171 Request* outstanding_request_;
[email protected]16a02742010-01-07 22:50:10172
[email protected]98e1cd012011-11-08 15:33:09173 DISALLOW_COPY_AND_ASSIGN(HangingHostResolverWithCancel);
[email protected]16a02742010-01-07 22:50:10174};
175
[email protected]76a51ac82009-06-28 07:58:58176// Tests a complete handshake and the disconnection.
177TEST_F(SOCKSClientSocketTest, CompleteHandshake) {
178 const std::string payload_write = "random data";
179 const std::string payload_read = "moar random data";
180
181 MockWrite data_writes[] = {
Matt Menked1eb6d42018-01-17 04:54:06182 MockWrite(ASYNC, kSOCKS4OkRequestLocalHostPort80,
183 kSOCKS4OkRequestLocalHostPort80Length),
184 MockWrite(ASYNC, payload_write.data(), payload_write.size())};
[email protected]76a51ac82009-06-28 07:58:58185 MockRead data_reads[] = {
Matt Menked1eb6d42018-01-17 04:54:06186 MockRead(ASYNC, kSOCKS4OkReply, kSOCKS4OkReplyLength),
187 MockRead(ASYNC, payload_read.data(), payload_read.size())};
vishal.b62985ca92015-04-17 08:45:51188 TestNetLog log;
[email protected]76a51ac82009-06-28 07:58:58189
[email protected]18ccfdb2013-08-15 00:13:44190 user_sock_ = BuildMockSocket(data_reads, arraysize(data_reads),
191 data_writes, arraysize(data_writes),
192 host_resolver_.get(),
193 "localhost", 80,
194 &log);
[email protected]76a51ac82009-06-28 07:58:58195
196 // At this state the TCP connection is completed but not the SOCKS handshake.
197 EXPECT_TRUE(tcp_sock_->IsConnected());
198 EXPECT_FALSE(user_sock_->IsConnected());
199
[email protected]83039bb2011-12-09 18:43:55200 int rv = user_sock_->Connect(callback_.callback());
robpercival214763f2016-07-01 23:27:01201 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a51ac82009-06-28 07:58:58202
mmenke43758e62015-05-04 21:09:46203 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40204 log.GetEntries(&entries);
205 EXPECT_TRUE(
mikecirone8b85c432016-09-08 19:11:00206 LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKS_CONNECT));
[email protected]b2fcd0e2010-12-01 15:19:40207 EXPECT_FALSE(user_sock_->IsConnected());
208
209 rv = callback_.WaitForResult();
robpercival214763f2016-07-01 23:27:01210 EXPECT_THAT(rv, IsOk());
[email protected]76a51ac82009-06-28 07:58:58211 EXPECT_TRUE(user_sock_->IsConnected());
[email protected]b2fcd0e2010-12-01 15:19:40212 log.GetEntries(&entries);
mikecirone8b85c432016-09-08 19:11:00213 EXPECT_TRUE(LogContainsEndEvent(entries, -1, NetLogEventType::SOCKS_CONNECT));
[email protected]76a51ac82009-06-28 07:58:58214
[email protected]ad8e04a2010-11-01 04:16:27215 scoped_refptr<IOBuffer> buffer(new IOBuffer(payload_write.size()));
[email protected]76a51ac82009-06-28 07:58:58216 memcpy(buffer->data(), payload_write.data(), payload_write.size());
[email protected]a2b2cfc2017-12-06 09:06:08217 rv = user_sock_->Write(buffer.get(), payload_write.size(),
218 callback_.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
robpercival214763f2016-07-01 23:27:01219 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a51ac82009-06-28 07:58:58220 rv = callback_.WaitForResult();
221 EXPECT_EQ(static_cast<int>(payload_write.size()), rv);
222
223 buffer = new IOBuffer(payload_read.size());
[email protected]90499482013-06-01 00:39:50224 rv =
225 user_sock_->Read(buffer.get(), payload_read.size(), callback_.callback());
robpercival214763f2016-07-01 23:27:01226 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a51ac82009-06-28 07:58:58227 rv = callback_.WaitForResult();
228 EXPECT_EQ(static_cast<int>(payload_read.size()), rv);
229 EXPECT_EQ(payload_read, std::string(buffer->data(), payload_read.size()));
230
231 user_sock_->Disconnect();
232 EXPECT_FALSE(tcp_sock_->IsConnected());
233 EXPECT_FALSE(user_sock_->IsConnected());
234}
235
236// List of responses from the socks server and the errors they should
237// throw up are tested here.
238TEST_F(SOCKSClientSocketTest, HandshakeFailures) {
239 const struct {
240 const char fail_reply[8];
241 Error fail_code;
242 } tests[] = {
243 // Failure of the server response code
244 {
245 { 0x01, 0x5A, 0x00, 0x00, 0, 0, 0, 0 },
[email protected]d5a309592010-02-05 02:22:52246 ERR_SOCKS_CONNECTION_FAILED,
[email protected]76a51ac82009-06-28 07:58:58247 },
248 // Failure of the null byte
249 {
250 { 0x00, 0x5B, 0x00, 0x00, 0, 0, 0, 0 },
[email protected]d5a309592010-02-05 02:22:52251 ERR_SOCKS_CONNECTION_FAILED,
[email protected]76a51ac82009-06-28 07:58:58252 },
253 };
254
255 //---------------------------------------
256
viettrungluue4a8b882014-10-16 06:17:38257 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]76a51ac82009-06-28 07:58:58258 MockWrite data_writes[] = {
Matt Menked1eb6d42018-01-17 04:54:06259 MockWrite(SYNCHRONOUS, kSOCKS4OkRequestLocalHostPort80,
260 kSOCKS4OkRequestLocalHostPort80Length)};
[email protected]76a51ac82009-06-28 07:58:58261 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:06262 MockRead(SYNCHRONOUS, tests[i].fail_reply,
263 arraysize(tests[i].fail_reply)) };
vishal.b62985ca92015-04-17 08:45:51264 TestNetLog log;
[email protected]76a51ac82009-06-28 07:58:58265
[email protected]18ccfdb2013-08-15 00:13:44266 user_sock_ = BuildMockSocket(data_reads, arraysize(data_reads),
267 data_writes, arraysize(data_writes),
268 host_resolver_.get(),
269 "localhost", 80,
270 &log);
[email protected]76a51ac82009-06-28 07:58:58271
[email protected]83039bb2011-12-09 18:43:55272 int rv = user_sock_->Connect(callback_.callback());
robpercival214763f2016-07-01 23:27:01273 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b2fcd0e2010-12-01 15:19:40274
mmenke43758e62015-05-04 21:09:46275 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40276 log.GetEntries(&entries);
mikecirone8b85c432016-09-08 19:11:00277 EXPECT_TRUE(
278 LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKS_CONNECT));
[email protected]b2fcd0e2010-12-01 15:19:40279
[email protected]76a51ac82009-06-28 07:58:58280 rv = callback_.WaitForResult();
281 EXPECT_EQ(tests[i].fail_code, rv);
282 EXPECT_FALSE(user_sock_->IsConnected());
283 EXPECT_TRUE(tcp_sock_->IsConnected());
[email protected]b2fcd0e2010-12-01 15:19:40284 log.GetEntries(&entries);
mikecirone8b85c432016-09-08 19:11:00285 EXPECT_TRUE(
286 LogContainsEndEvent(entries, -1, NetLogEventType::SOCKS_CONNECT));
[email protected]76a51ac82009-06-28 07:58:58287 }
288}
289
290// Tests scenario when the server sends the handshake response in
291// more than one packet.
292TEST_F(SOCKSClientSocketTest, PartialServerReads) {
293 const char kSOCKSPartialReply1[] = { 0x00 };
294 const char kSOCKSPartialReply2[] = { 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
295
Matt Menked1eb6d42018-01-17 04:54:06296 MockWrite data_writes[] = {MockWrite(ASYNC, kSOCKS4OkRequestLocalHostPort80,
297 kSOCKS4OkRequestLocalHostPort80Length)};
[email protected]76a51ac82009-06-28 07:58:58298 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:06299 MockRead(ASYNC, kSOCKSPartialReply1, arraysize(kSOCKSPartialReply1)),
300 MockRead(ASYNC, kSOCKSPartialReply2, arraysize(kSOCKSPartialReply2)) };
vishal.b62985ca92015-04-17 08:45:51301 TestNetLog log;
[email protected]76a51ac82009-06-28 07:58:58302
[email protected]18ccfdb2013-08-15 00:13:44303 user_sock_ = BuildMockSocket(data_reads, arraysize(data_reads),
304 data_writes, arraysize(data_writes),
305 host_resolver_.get(),
306 "localhost", 80,
307 &log);
[email protected]76a51ac82009-06-28 07:58:58308
[email protected]83039bb2011-12-09 18:43:55309 int rv = user_sock_->Connect(callback_.callback());
robpercival214763f2016-07-01 23:27:01310 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
mmenke43758e62015-05-04 21:09:46311 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40312 log.GetEntries(&entries);
mikecirone8b85c432016-09-08 19:11:00313 EXPECT_TRUE(
314 LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKS_CONNECT));
[email protected]b2fcd0e2010-12-01 15:19:40315
[email protected]76a51ac82009-06-28 07:58:58316 rv = callback_.WaitForResult();
robpercival214763f2016-07-01 23:27:01317 EXPECT_THAT(rv, IsOk());
[email protected]76a51ac82009-06-28 07:58:58318 EXPECT_TRUE(user_sock_->IsConnected());
[email protected]b2fcd0e2010-12-01 15:19:40319 log.GetEntries(&entries);
mikecirone8b85c432016-09-08 19:11:00320 EXPECT_TRUE(LogContainsEndEvent(entries, -1, NetLogEventType::SOCKS_CONNECT));
[email protected]76a51ac82009-06-28 07:58:58321}
322
323// Tests scenario when the client sends the handshake request in
324// more than one packet.
325TEST_F(SOCKSClientSocketTest, PartialClientWrites) {
326 const char kSOCKSPartialRequest1[] = { 0x04, 0x01 };
327 const char kSOCKSPartialRequest2[] = { 0x00, 0x50, 127, 0, 0, 1, 0 };
328
329 MockWrite data_writes[] = {
Peter Kastingbe940e92014-11-20 23:14:08330 MockWrite(ASYNC, kSOCKSPartialRequest1, arraysize(kSOCKSPartialRequest1)),
[email protected]76a51ac82009-06-28 07:58:58331 // simulate some empty writes
[email protected]8ddf8322012-02-23 18:08:06332 MockWrite(ASYNC, 0),
333 MockWrite(ASYNC, 0),
Peter Kastingbe940e92014-11-20 23:14:08334 MockWrite(ASYNC, kSOCKSPartialRequest2, arraysize(kSOCKSPartialRequest2)),
335 };
[email protected]76a51ac82009-06-28 07:58:58336 MockRead data_reads[] = {
Matt Menked1eb6d42018-01-17 04:54:06337 MockRead(ASYNC, kSOCKS4OkReply, kSOCKS4OkReplyLength)};
vishal.b62985ca92015-04-17 08:45:51338 TestNetLog log;
[email protected]76a51ac82009-06-28 07:58:58339
[email protected]18ccfdb2013-08-15 00:13:44340 user_sock_ = BuildMockSocket(data_reads, arraysize(data_reads),
341 data_writes, arraysize(data_writes),
342 host_resolver_.get(),
343 "localhost", 80,
344 &log);
[email protected]76a51ac82009-06-28 07:58:58345
[email protected]83039bb2011-12-09 18:43:55346 int rv = user_sock_->Connect(callback_.callback());
robpercival214763f2016-07-01 23:27:01347 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
mmenke43758e62015-05-04 21:09:46348 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40349 log.GetEntries(&entries);
mikecirone8b85c432016-09-08 19:11:00350 EXPECT_TRUE(
351 LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKS_CONNECT));
[email protected]b2fcd0e2010-12-01 15:19:40352
[email protected]76a51ac82009-06-28 07:58:58353 rv = callback_.WaitForResult();
robpercival214763f2016-07-01 23:27:01354 EXPECT_THAT(rv, IsOk());
[email protected]76a51ac82009-06-28 07:58:58355 EXPECT_TRUE(user_sock_->IsConnected());
[email protected]b2fcd0e2010-12-01 15:19:40356 log.GetEntries(&entries);
mikecirone8b85c432016-09-08 19:11:00357 EXPECT_TRUE(LogContainsEndEvent(entries, -1, NetLogEventType::SOCKS_CONNECT));
[email protected]76a51ac82009-06-28 07:58:58358}
359
360// Tests the case when the server sends a smaller sized handshake data
361// and closes the connection.
362TEST_F(SOCKSClientSocketTest, FailedSocketRead) {
Matt Menked1eb6d42018-01-17 04:54:06363 MockWrite data_writes[] = {MockWrite(ASYNC, kSOCKS4OkRequestLocalHostPort80,
364 kSOCKS4OkRequestLocalHostPort80Length)};
[email protected]76a51ac82009-06-28 07:58:58365 MockRead data_reads[] = {
Matt Menked1eb6d42018-01-17 04:54:06366 MockRead(ASYNC, kSOCKS4OkReply, kSOCKS4OkReplyLength - 2),
[email protected]76a51ac82009-06-28 07:58:58367 // close connection unexpectedly
Matt Menked1eb6d42018-01-17 04:54:06368 MockRead(SYNCHRONOUS, 0)};
vishal.b62985ca92015-04-17 08:45:51369 TestNetLog log;
[email protected]76a51ac82009-06-28 07:58:58370
[email protected]18ccfdb2013-08-15 00:13:44371 user_sock_ = BuildMockSocket(data_reads, arraysize(data_reads),
372 data_writes, arraysize(data_writes),
373 host_resolver_.get(),
374 "localhost", 80,
375 &log);
[email protected]76a51ac82009-06-28 07:58:58376
[email protected]83039bb2011-12-09 18:43:55377 int rv = user_sock_->Connect(callback_.callback());
robpercival214763f2016-07-01 23:27:01378 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
mmenke43758e62015-05-04 21:09:46379 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40380 log.GetEntries(&entries);
mikecirone8b85c432016-09-08 19:11:00381 EXPECT_TRUE(
382 LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKS_CONNECT));
[email protected]b2fcd0e2010-12-01 15:19:40383
[email protected]76a51ac82009-06-28 07:58:58384 rv = callback_.WaitForResult();
robpercival214763f2016-07-01 23:27:01385 EXPECT_THAT(rv, IsError(ERR_CONNECTION_CLOSED));
[email protected]76a51ac82009-06-28 07:58:58386 EXPECT_FALSE(user_sock_->IsConnected());
[email protected]b2fcd0e2010-12-01 15:19:40387 log.GetEntries(&entries);
mikecirone8b85c432016-09-08 19:11:00388 EXPECT_TRUE(LogContainsEndEvent(entries, -1, NetLogEventType::SOCKS_CONNECT));
[email protected]76a51ac82009-06-28 07:58:58389}
390
[email protected]034d3892011-03-29 04:07:21391// Tries to connect to an unknown hostname. Should fail rather than
392// falling back to SOCKS4a.
393TEST_F(SOCKSClientSocketTest, FailedDNS) {
[email protected]76a51ac82009-06-28 07:58:58394 const char hostname[] = "unresolved.ipv4.address";
395
[email protected]b59ff372009-07-15 22:04:32396 host_resolver_->rules()->AddSimulatedFailure(hostname);
[email protected]76a51ac82009-06-28 07:58:58397
vishal.b62985ca92015-04-17 08:45:51398 TestNetLog log;
[email protected]76a51ac82009-06-28 07:58:58399
[email protected]18ccfdb2013-08-15 00:13:44400 user_sock_ = BuildMockSocket(NULL, 0,
401 NULL, 0,
402 host_resolver_.get(),
403 hostname, 80,
404 &log);
[email protected]76a51ac82009-06-28 07:58:58405
[email protected]83039bb2011-12-09 18:43:55406 int rv = user_sock_->Connect(callback_.callback());
robpercival214763f2016-07-01 23:27:01407 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
mmenke43758e62015-05-04 21:09:46408 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40409 log.GetEntries(&entries);
mikecirone8b85c432016-09-08 19:11:00410 EXPECT_TRUE(
411 LogContainsBeginEvent(entries, 0, NetLogEventType::SOCKS_CONNECT));
[email protected]b2fcd0e2010-12-01 15:19:40412
[email protected]76a51ac82009-06-28 07:58:58413 rv = callback_.WaitForResult();
robpercival214763f2016-07-01 23:27:01414 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]034d3892011-03-29 04:07:21415 EXPECT_FALSE(user_sock_->IsConnected());
[email protected]b2fcd0e2010-12-01 15:19:40416 log.GetEntries(&entries);
mikecirone8b85c432016-09-08 19:11:00417 EXPECT_TRUE(LogContainsEndEvent(entries, -1, NetLogEventType::SOCKS_CONNECT));
[email protected]76a51ac82009-06-28 07:58:58418}
419
[email protected]16a02742010-01-07 22:50:10420// Calls Disconnect() while a host resolve is in progress. The outstanding host
421// resolve should be cancelled.
422TEST_F(SOCKSClientSocketTest, DisconnectWhileHostResolveInProgress) {
danakj655b66c2016-04-16 00:51:38423 std::unique_ptr<HangingHostResolverWithCancel> hanging_resolver(
424 new HangingHostResolverWithCancel());
[email protected]16a02742010-01-07 22:50:10425
426 // Doesn't matter what the socket data is, we will never use it -- garbage.
[email protected]8ddf8322012-02-23 18:08:06427 MockWrite data_writes[] = { MockWrite(SYNCHRONOUS, "", 0) };
428 MockRead data_reads[] = { MockRead(SYNCHRONOUS, "", 0) };
[email protected]16a02742010-01-07 22:50:10429
[email protected]18ccfdb2013-08-15 00:13:44430 user_sock_ = BuildMockSocket(data_reads, arraysize(data_reads),
431 data_writes, arraysize(data_writes),
432 hanging_resolver.get(),
433 "foo", 80,
434 NULL);
[email protected]16a02742010-01-07 22:50:10435
436 // Start connecting (will get stuck waiting for the host to resolve).
[email protected]83039bb2011-12-09 18:43:55437 int rv = user_sock_->Connect(callback_.callback());
robpercival214763f2016-07-01 23:27:01438 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]16a02742010-01-07 22:50:10439
440 EXPECT_FALSE(user_sock_->IsConnected());
441 EXPECT_FALSE(user_sock_->IsConnectedAndIdle());
442
443 // The host resolver should have received the resolve request.
444 EXPECT_TRUE(hanging_resolver->HasOutstandingRequest());
445
446 // Disconnect the SOCKS socket -- this should cancel the outstanding resolve.
447 user_sock_->Disconnect();
448
449 EXPECT_FALSE(hanging_resolver->HasOutstandingRequest());
450
451 EXPECT_FALSE(user_sock_->IsConnected());
452 EXPECT_FALSE(user_sock_->IsConnectedAndIdle());
453}
454
[email protected]1c7cf3f82014-08-07 21:33:48455// Tries to connect to an IPv6 IP. Should fail, as SOCKS4 does not support
456// IPv6.
457TEST_F(SOCKSClientSocketTest, NoIPv6) {
458 const char kHostName[] = "::1";
459
460 user_sock_ = BuildMockSocket(NULL, 0,
461 NULL, 0,
462 host_resolver_.get(),
463 kHostName, 80,
464 NULL);
465
466 EXPECT_EQ(ERR_NAME_NOT_RESOLVED,
467 callback_.GetResult(user_sock_->Connect(callback_.callback())));
468}
469
470// Same as above, but with a real resolver, to protect against regressions.
471TEST_F(SOCKSClientSocketTest, NoIPv6RealResolver) {
472 const char kHostName[] = "::1";
473
danakj655b66c2016-04-16 00:51:38474 std::unique_ptr<HostResolver> host_resolver(
[email protected]1c7cf3f82014-08-07 21:33:48475 HostResolver::CreateSystemResolver(HostResolver::Options(), NULL));
476
477 user_sock_ = BuildMockSocket(NULL, 0,
478 NULL, 0,
479 host_resolver.get(),
480 kHostName, 80,
481 NULL);
482
483 EXPECT_EQ(ERR_NAME_NOT_RESOLVED,
484 callback_.GetResult(user_sock_->Connect(callback_.callback())));
485}
486
Paul Jensen0f49dec2017-12-12 23:39:58487TEST_F(SOCKSClientSocketTest, Tag) {
488 StaticSocketDataProvider data;
489 TestNetLog log;
490 MockTaggingStreamSocket* tagging_sock =
491 new MockTaggingStreamSocket(std::unique_ptr<StreamSocket>(
492 new MockTCPClientSocket(address_list_, &log, &data)));
493
494 std::unique_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
495 // |connection| takes ownership of |tagging_sock|, but keep a
496 // non-owning pointer to it.
497 connection->SetSocket(std::unique_ptr<StreamSocket>(tagging_sock));
498 MockHostResolver host_resolver;
499 SOCKSClientSocket socket(
500 std::move(connection),
501 HostResolver::RequestInfo(HostPortPair("localhost", 80)),
[email protected]27fb73c2018-01-11 13:27:24502 DEFAULT_PRIORITY, &host_resolver, TRAFFIC_ANNOTATION_FOR_TESTS);
Paul Jensen0f49dec2017-12-12 23:39:58503
504 EXPECT_EQ(tagging_sock->tag(), SocketTag());
505#if defined(OS_ANDROID)
506 SocketTag tag(0x12345678, 0x87654321);
507 socket.ApplySocketTag(tag);
508 EXPECT_EQ(tagging_sock->tag(), tag);
509#endif // OS_ANDROID
510}
511
[email protected]76a51ac82009-06-28 07:58:58512} // namespace net