| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "base/memory/scoped_ptr.h" | 7 #include "base/memory/scoped_ptr.h" |
| 8 #include "net/base/address_list.h" | 8 #include "net/base/address_list.h" |
| 9 #include "net/base/net_log.h" | 9 #include "net/base/net_log.h" |
| 10 #include "net/base/net_log_unittest.h" | 10 #include "net/base/net_log_unittest.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/dns/mock_host_resolver.h" | 13 #include "net/dns/mock_host_resolver.h" |
| 14 #include "net/socket/client_socket_factory.h" | 14 #include "net/socket/client_socket_factory.h" |
| 15 #include "net/socket/socket_test_util.h" | 15 #include "net/socket/socket_test_util.h" |
| 16 #include "net/socket/tcp_client_socket.h" | 16 #include "net/socket/tcp_client_socket.h" |
| 17 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
| 18 #include "testing/platform_test.h" | 18 #include "testing/platform_test.h" |
| 19 | 19 |
| 20 //----------------------------------------------------------------------------- | 20 //----------------------------------------------------------------------------- |
| 21 | 21 |
| 22 namespace net { | 22 namespace net { |
| 23 | 23 |
| 24 const char kSOCKSOkRequest[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 }; | 24 const char kSOCKSOkRequest[] = {0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0}; |
| 25 const char kSOCKSOkReply[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 }; | 25 const char kSOCKSOkReply[] = {0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0}; |
| 26 | 26 |
| 27 class SOCKSClientSocketTest : public PlatformTest { | 27 class SOCKSClientSocketTest : public PlatformTest { |
| 28 public: | 28 public: |
| 29 SOCKSClientSocketTest(); | 29 SOCKSClientSocketTest(); |
| 30 // Create a SOCKSClientSocket on top of a MockSocket. | 30 // Create a SOCKSClientSocket on top of a MockSocket. |
| 31 scoped_ptr<SOCKSClientSocket> BuildMockSocket( | 31 scoped_ptr<SOCKSClientSocket> BuildMockSocket(MockRead reads[], |
| 32 MockRead reads[], size_t reads_count, | 32 size_t reads_count, |
| 33 MockWrite writes[], size_t writes_count, | 33 MockWrite writes[], |
| 34 HostResolver* host_resolver, | 34 size_t writes_count, |
| 35 const std::string& hostname, int port, | 35 HostResolver* host_resolver, |
| 36 NetLog* net_log); | 36 const std::string& hostname, |
| 37 int port, |
| 38 NetLog* net_log); |
| 37 virtual void SetUp(); | 39 virtual void SetUp(); |
| 38 | 40 |
| 39 protected: | 41 protected: |
| 40 scoped_ptr<SOCKSClientSocket> user_sock_; | 42 scoped_ptr<SOCKSClientSocket> user_sock_; |
| 41 AddressList address_list_; | 43 AddressList address_list_; |
| 42 // Filled in by BuildMockSocket() and owned by its return value | 44 // Filled in by BuildMockSocket() and owned by its return value |
| 43 // (which |user_sock| is set to). | 45 // (which |user_sock| is set to). |
| 44 StreamSocket* tcp_sock_; | 46 StreamSocket* tcp_sock_; |
| 45 TestCompletionCallback callback_; | 47 TestCompletionCallback callback_; |
| 46 scoped_ptr<MockHostResolver> host_resolver_; | 48 scoped_ptr<MockHostResolver> host_resolver_; |
| 47 scoped_ptr<SocketDataProvider> data_; | 49 scoped_ptr<SocketDataProvider> data_; |
| 48 }; | 50 }; |
| 49 | 51 |
| 50 SOCKSClientSocketTest::SOCKSClientSocketTest() | 52 SOCKSClientSocketTest::SOCKSClientSocketTest() |
| 51 : host_resolver_(new MockHostResolver) { | 53 : host_resolver_(new MockHostResolver) { |
| 52 } | 54 } |
| 53 | 55 |
| 54 // Set up platform before every test case | 56 // Set up platform before every test case |
| 55 void SOCKSClientSocketTest::SetUp() { | 57 void SOCKSClientSocketTest::SetUp() { |
| 56 PlatformTest::SetUp(); | 58 PlatformTest::SetUp(); |
| 57 } | 59 } |
| 58 | 60 |
| 59 scoped_ptr<SOCKSClientSocket> SOCKSClientSocketTest::BuildMockSocket( | 61 scoped_ptr<SOCKSClientSocket> SOCKSClientSocketTest::BuildMockSocket( |
| 60 MockRead reads[], | 62 MockRead reads[], |
| 61 size_t reads_count, | 63 size_t reads_count, |
| 62 MockWrite writes[], | 64 MockWrite writes[], |
| 63 size_t writes_count, | 65 size_t writes_count, |
| 64 HostResolver* host_resolver, | 66 HostResolver* host_resolver, |
| 65 const std::string& hostname, | 67 const std::string& hostname, |
| 66 int port, | 68 int port, |
| 67 NetLog* net_log) { | 69 NetLog* net_log) { |
| 68 | |
| 69 TestCompletionCallback callback; | 70 TestCompletionCallback callback; |
| 70 data_.reset(new StaticSocketDataProvider(reads, reads_count, | 71 data_.reset( |
| 71 writes, writes_count)); | 72 new StaticSocketDataProvider(reads, reads_count, writes, writes_count)); |
| 72 tcp_sock_ = new MockTCPClientSocket(address_list_, net_log, data_.get()); | 73 tcp_sock_ = new MockTCPClientSocket(address_list_, net_log, data_.get()); |
| 73 | 74 |
| 74 int rv = tcp_sock_->Connect(callback.callback()); | 75 int rv = tcp_sock_->Connect(callback.callback()); |
| 75 EXPECT_EQ(ERR_IO_PENDING, rv); | 76 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 76 rv = callback.WaitForResult(); | 77 rv = callback.WaitForResult(); |
| 77 EXPECT_EQ(OK, rv); | 78 EXPECT_EQ(OK, rv); |
| 78 EXPECT_TRUE(tcp_sock_->IsConnected()); | 79 EXPECT_TRUE(tcp_sock_->IsConnected()); |
| 79 | 80 |
| 80 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle); | 81 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle); |
| 81 // |connection| takes ownership of |tcp_sock_|, but keep a | 82 // |connection| takes ownership of |tcp_sock_|, but keep a |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 NOTIMPLEMENTED(); | 116 NOTIMPLEMENTED(); |
| 116 return ERR_UNEXPECTED; | 117 return ERR_UNEXPECTED; |
| 117 } | 118 } |
| 118 | 119 |
| 119 virtual void CancelRequest(RequestHandle req) OVERRIDE { | 120 virtual void CancelRequest(RequestHandle req) OVERRIDE { |
| 120 EXPECT_TRUE(HasOutstandingRequest()); | 121 EXPECT_TRUE(HasOutstandingRequest()); |
| 121 EXPECT_EQ(outstanding_request_, req); | 122 EXPECT_EQ(outstanding_request_, req); |
| 122 outstanding_request_ = NULL; | 123 outstanding_request_ = NULL; |
| 123 } | 124 } |
| 124 | 125 |
| 125 bool HasOutstandingRequest() { | 126 bool HasOutstandingRequest() { return outstanding_request_ != NULL; } |
| 126 return outstanding_request_ != NULL; | |
| 127 } | |
| 128 | 127 |
| 129 private: | 128 private: |
| 130 RequestHandle outstanding_request_; | 129 RequestHandle outstanding_request_; |
| 131 | 130 |
| 132 DISALLOW_COPY_AND_ASSIGN(HangingHostResolverWithCancel); | 131 DISALLOW_COPY_AND_ASSIGN(HangingHostResolverWithCancel); |
| 133 }; | 132 }; |
| 134 | 133 |
| 135 // Tests a complete handshake and the disconnection. | 134 // Tests a complete handshake and the disconnection. |
| 136 TEST_F(SOCKSClientSocketTest, CompleteHandshake) { | 135 TEST_F(SOCKSClientSocketTest, CompleteHandshake) { |
| 137 const std::string payload_write = "random data"; | 136 const std::string payload_write = "random data"; |
| 138 const std::string payload_read = "moar random data"; | 137 const std::string payload_read = "moar random data"; |
| 139 | 138 |
| 140 MockWrite data_writes[] = { | 139 MockWrite data_writes[] = { |
| 141 MockWrite(ASYNC, kSOCKSOkRequest, arraysize(kSOCKSOkRequest)), | 140 MockWrite(ASYNC, kSOCKSOkRequest, arraysize(kSOCKSOkRequest)), |
| 142 MockWrite(ASYNC, payload_write.data(), payload_write.size()) }; | 141 MockWrite(ASYNC, payload_write.data(), payload_write.size())}; |
| 143 MockRead data_reads[] = { | 142 MockRead data_reads[] = { |
| 144 MockRead(ASYNC, kSOCKSOkReply, arraysize(kSOCKSOkReply)), | 143 MockRead(ASYNC, kSOCKSOkReply, arraysize(kSOCKSOkReply)), |
| 145 MockRead(ASYNC, payload_read.data(), payload_read.size()) }; | 144 MockRead(ASYNC, payload_read.data(), payload_read.size())}; |
| 146 CapturingNetLog log; | 145 CapturingNetLog log; |
| 147 | 146 |
| 148 user_sock_ = BuildMockSocket(data_reads, arraysize(data_reads), | 147 user_sock_ = BuildMockSocket(data_reads, |
| 149 data_writes, arraysize(data_writes), | 148 arraysize(data_reads), |
| 149 data_writes, |
| 150 arraysize(data_writes), |
| 150 host_resolver_.get(), | 151 host_resolver_.get(), |
| 151 "localhost", 80, | 152 "localhost", |
| 153 80, |
| 152 &log); | 154 &log); |
| 153 | 155 |
| 154 // At this state the TCP connection is completed but not the SOCKS handshake. | 156 // At this state the TCP connection is completed but not the SOCKS handshake. |
| 155 EXPECT_TRUE(tcp_sock_->IsConnected()); | 157 EXPECT_TRUE(tcp_sock_->IsConnected()); |
| 156 EXPECT_FALSE(user_sock_->IsConnected()); | 158 EXPECT_FALSE(user_sock_->IsConnected()); |
| 157 | 159 |
| 158 int rv = user_sock_->Connect(callback_.callback()); | 160 int rv = user_sock_->Connect(callback_.callback()); |
| 159 EXPECT_EQ(ERR_IO_PENDING, rv); | 161 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 160 | 162 |
| 161 CapturingNetLog::CapturedEntryList entries; | 163 CapturingNetLog::CapturedEntryList entries; |
| 162 log.GetEntries(&entries); | 164 log.GetEntries(&entries); |
| 163 EXPECT_TRUE( | 165 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLog::TYPE_SOCKS_CONNECT)); |
| 164 LogContainsBeginEvent(entries, 0, NetLog::TYPE_SOCKS_CONNECT)); | |
| 165 EXPECT_FALSE(user_sock_->IsConnected()); | 166 EXPECT_FALSE(user_sock_->IsConnected()); |
| 166 | 167 |
| 167 rv = callback_.WaitForResult(); | 168 rv = callback_.WaitForResult(); |
| 168 EXPECT_EQ(OK, rv); | 169 EXPECT_EQ(OK, rv); |
| 169 EXPECT_TRUE(user_sock_->IsConnected()); | 170 EXPECT_TRUE(user_sock_->IsConnected()); |
| 170 log.GetEntries(&entries); | 171 log.GetEntries(&entries); |
| 171 EXPECT_TRUE(LogContainsEndEvent( | 172 EXPECT_TRUE(LogContainsEndEvent(entries, -1, NetLog::TYPE_SOCKS_CONNECT)); |
| 172 entries, -1, NetLog::TYPE_SOCKS_CONNECT)); | |
| 173 | 173 |
| 174 scoped_refptr<IOBuffer> buffer(new IOBuffer(payload_write.size())); | 174 scoped_refptr<IOBuffer> buffer(new IOBuffer(payload_write.size())); |
| 175 memcpy(buffer->data(), payload_write.data(), payload_write.size()); | 175 memcpy(buffer->data(), payload_write.data(), payload_write.size()); |
| 176 rv = user_sock_->Write( | 176 rv = user_sock_->Write( |
| 177 buffer.get(), payload_write.size(), callback_.callback()); | 177 buffer.get(), payload_write.size(), callback_.callback()); |
| 178 EXPECT_EQ(ERR_IO_PENDING, rv); | 178 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 179 rv = callback_.WaitForResult(); | 179 rv = callback_.WaitForResult(); |
| 180 EXPECT_EQ(static_cast<int>(payload_write.size()), rv); | 180 EXPECT_EQ(static_cast<int>(payload_write.size()), rv); |
| 181 | 181 |
| 182 buffer = new IOBuffer(payload_read.size()); | 182 buffer = new IOBuffer(payload_read.size()); |
| 183 rv = | 183 rv = |
| 184 user_sock_->Read(buffer.get(), payload_read.size(), callback_.callback()); | 184 user_sock_->Read(buffer.get(), payload_read.size(), callback_.callback()); |
| 185 EXPECT_EQ(ERR_IO_PENDING, rv); | 185 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 186 rv = callback_.WaitForResult(); | 186 rv = callback_.WaitForResult(); |
| 187 EXPECT_EQ(static_cast<int>(payload_read.size()), rv); | 187 EXPECT_EQ(static_cast<int>(payload_read.size()), rv); |
| 188 EXPECT_EQ(payload_read, std::string(buffer->data(), payload_read.size())); | 188 EXPECT_EQ(payload_read, std::string(buffer->data(), payload_read.size())); |
| 189 | 189 |
| 190 user_sock_->Disconnect(); | 190 user_sock_->Disconnect(); |
| 191 EXPECT_FALSE(tcp_sock_->IsConnected()); | 191 EXPECT_FALSE(tcp_sock_->IsConnected()); |
| 192 EXPECT_FALSE(user_sock_->IsConnected()); | 192 EXPECT_FALSE(user_sock_->IsConnected()); |
| 193 } | 193 } |
| 194 | 194 |
| 195 // List of responses from the socks server and the errors they should | 195 // List of responses from the socks server and the errors they should |
| 196 // throw up are tested here. | 196 // throw up are tested here. |
| 197 TEST_F(SOCKSClientSocketTest, HandshakeFailures) { | 197 TEST_F(SOCKSClientSocketTest, HandshakeFailures) { |
| 198 const struct { | 198 const struct { |
| 199 const char fail_reply[8]; | 199 const char fail_reply[8]; |
| 200 Error fail_code; | 200 Error fail_code; |
| 201 } tests[] = { | 201 } tests[] = { |
| 202 // Failure of the server response code | 202 // Failure of the server response code |
| 203 { | 203 { |
| 204 { 0x01, 0x5A, 0x00, 0x00, 0, 0, 0, 0 }, | 204 {0x01, 0x5A, 0x00, 0x00, 0, 0, 0, 0}, ERR_SOCKS_CONNECTION_FAILED, |
| 205 ERR_SOCKS_CONNECTION_FAILED, | 205 }, |
| 206 }, | 206 // Failure of the null byte |
| 207 // Failure of the null byte | 207 { |
| 208 { | 208 {0x00, 0x5B, 0x00, 0x00, 0, 0, 0, 0}, ERR_SOCKS_CONNECTION_FAILED, |
| 209 { 0x00, 0x5B, 0x00, 0x00, 0, 0, 0, 0 }, | 209 }, |
| 210 ERR_SOCKS_CONNECTION_FAILED, | 210 }; |
| 211 }, | |
| 212 }; | |
| 213 | 211 |
| 214 //--------------------------------------- | 212 //--------------------------------------- |
| 215 | 213 |
| 216 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | 214 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { |
| 217 MockWrite data_writes[] = { | 215 MockWrite data_writes[] = { |
| 218 MockWrite(SYNCHRONOUS, kSOCKSOkRequest, arraysize(kSOCKSOkRequest)) }; | 216 MockWrite(SYNCHRONOUS, kSOCKSOkRequest, arraysize(kSOCKSOkRequest))}; |
| 219 MockRead data_reads[] = { | 217 MockRead data_reads[] = {MockRead( |
| 220 MockRead(SYNCHRONOUS, tests[i].fail_reply, | 218 SYNCHRONOUS, tests[i].fail_reply, arraysize(tests[i].fail_reply))}; |
| 221 arraysize(tests[i].fail_reply)) }; | |
| 222 CapturingNetLog log; | 219 CapturingNetLog log; |
| 223 | 220 |
| 224 user_sock_ = BuildMockSocket(data_reads, arraysize(data_reads), | 221 user_sock_ = BuildMockSocket(data_reads, |
| 225 data_writes, arraysize(data_writes), | 222 arraysize(data_reads), |
| 223 data_writes, |
| 224 arraysize(data_writes), |
| 226 host_resolver_.get(), | 225 host_resolver_.get(), |
| 227 "localhost", 80, | 226 "localhost", |
| 227 80, |
| 228 &log); | 228 &log); |
| 229 | 229 |
| 230 int rv = user_sock_->Connect(callback_.callback()); | 230 int rv = user_sock_->Connect(callback_.callback()); |
| 231 EXPECT_EQ(ERR_IO_PENDING, rv); | 231 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 232 | 232 |
| 233 CapturingNetLog::CapturedEntryList entries; | 233 CapturingNetLog::CapturedEntryList entries; |
| 234 log.GetEntries(&entries); | 234 log.GetEntries(&entries); |
| 235 EXPECT_TRUE(LogContainsBeginEvent( | 235 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLog::TYPE_SOCKS_CONNECT)); |
| 236 entries, 0, NetLog::TYPE_SOCKS_CONNECT)); | |
| 237 | 236 |
| 238 rv = callback_.WaitForResult(); | 237 rv = callback_.WaitForResult(); |
| 239 EXPECT_EQ(tests[i].fail_code, rv); | 238 EXPECT_EQ(tests[i].fail_code, rv); |
| 240 EXPECT_FALSE(user_sock_->IsConnected()); | 239 EXPECT_FALSE(user_sock_->IsConnected()); |
| 241 EXPECT_TRUE(tcp_sock_->IsConnected()); | 240 EXPECT_TRUE(tcp_sock_->IsConnected()); |
| 242 log.GetEntries(&entries); | 241 log.GetEntries(&entries); |
| 243 EXPECT_TRUE(LogContainsEndEvent( | 242 EXPECT_TRUE(LogContainsEndEvent(entries, -1, NetLog::TYPE_SOCKS_CONNECT)); |
| 244 entries, -1, NetLog::TYPE_SOCKS_CONNECT)); | |
| 245 } | 243 } |
| 246 } | 244 } |
| 247 | 245 |
| 248 // Tests scenario when the server sends the handshake response in | 246 // Tests scenario when the server sends the handshake response in |
| 249 // more than one packet. | 247 // more than one packet. |
| 250 TEST_F(SOCKSClientSocketTest, PartialServerReads) { | 248 TEST_F(SOCKSClientSocketTest, PartialServerReads) { |
| 251 const char kSOCKSPartialReply1[] = { 0x00 }; | 249 const char kSOCKSPartialReply1[] = {0x00}; |
| 252 const char kSOCKSPartialReply2[] = { 0x5A, 0x00, 0x00, 0, 0, 0, 0 }; | 250 const char kSOCKSPartialReply2[] = {0x5A, 0x00, 0x00, 0, 0, 0, 0}; |
| 253 | 251 |
| 254 MockWrite data_writes[] = { | 252 MockWrite data_writes[] = { |
| 255 MockWrite(ASYNC, kSOCKSOkRequest, arraysize(kSOCKSOkRequest)) }; | 253 MockWrite(ASYNC, kSOCKSOkRequest, arraysize(kSOCKSOkRequest))}; |
| 256 MockRead data_reads[] = { | 254 MockRead data_reads[] = { |
| 257 MockRead(ASYNC, kSOCKSPartialReply1, arraysize(kSOCKSPartialReply1)), | 255 MockRead(ASYNC, kSOCKSPartialReply1, arraysize(kSOCKSPartialReply1)), |
| 258 MockRead(ASYNC, kSOCKSPartialReply2, arraysize(kSOCKSPartialReply2)) }; | 256 MockRead(ASYNC, kSOCKSPartialReply2, arraysize(kSOCKSPartialReply2))}; |
| 259 CapturingNetLog log; | 257 CapturingNetLog log; |
| 260 | 258 |
| 261 user_sock_ = BuildMockSocket(data_reads, arraysize(data_reads), | 259 user_sock_ = BuildMockSocket(data_reads, |
| 262 data_writes, arraysize(data_writes), | 260 arraysize(data_reads), |
| 261 data_writes, |
| 262 arraysize(data_writes), |
| 263 host_resolver_.get(), | 263 host_resolver_.get(), |
| 264 "localhost", 80, | 264 "localhost", |
| 265 80, |
| 265 &log); | 266 &log); |
| 266 | 267 |
| 267 int rv = user_sock_->Connect(callback_.callback()); | 268 int rv = user_sock_->Connect(callback_.callback()); |
| 268 EXPECT_EQ(ERR_IO_PENDING, rv); | 269 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 269 CapturingNetLog::CapturedEntryList entries; | 270 CapturingNetLog::CapturedEntryList entries; |
| 270 log.GetEntries(&entries); | 271 log.GetEntries(&entries); |
| 271 EXPECT_TRUE(LogContainsBeginEvent( | 272 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLog::TYPE_SOCKS_CONNECT)); |
| 272 entries, 0, NetLog::TYPE_SOCKS_CONNECT)); | |
| 273 | 273 |
| 274 rv = callback_.WaitForResult(); | 274 rv = callback_.WaitForResult(); |
| 275 EXPECT_EQ(OK, rv); | 275 EXPECT_EQ(OK, rv); |
| 276 EXPECT_TRUE(user_sock_->IsConnected()); | 276 EXPECT_TRUE(user_sock_->IsConnected()); |
| 277 log.GetEntries(&entries); | 277 log.GetEntries(&entries); |
| 278 EXPECT_TRUE(LogContainsEndEvent( | 278 EXPECT_TRUE(LogContainsEndEvent(entries, -1, NetLog::TYPE_SOCKS_CONNECT)); |
| 279 entries, -1, NetLog::TYPE_SOCKS_CONNECT)); | |
| 280 } | 279 } |
| 281 | 280 |
| 282 // Tests scenario when the client sends the handshake request in | 281 // Tests scenario when the client sends the handshake request in |
| 283 // more than one packet. | 282 // more than one packet. |
| 284 TEST_F(SOCKSClientSocketTest, PartialClientWrites) { | 283 TEST_F(SOCKSClientSocketTest, PartialClientWrites) { |
| 285 const char kSOCKSPartialRequest1[] = { 0x04, 0x01 }; | 284 const char kSOCKSPartialRequest1[] = {0x04, 0x01}; |
| 286 const char kSOCKSPartialRequest2[] = { 0x00, 0x50, 127, 0, 0, 1, 0 }; | 285 const char kSOCKSPartialRequest2[] = {0x00, 0x50, 127, 0, 0, 1, 0}; |
| 287 | 286 |
| 288 MockWrite data_writes[] = { | 287 MockWrite data_writes[] = { |
| 289 MockWrite(ASYNC, arraysize(kSOCKSPartialRequest1)), | 288 MockWrite(ASYNC, arraysize(kSOCKSPartialRequest1)), |
| 290 // simulate some empty writes | 289 // simulate some empty writes |
| 291 MockWrite(ASYNC, 0), | 290 MockWrite(ASYNC, 0), MockWrite(ASYNC, 0), |
| 292 MockWrite(ASYNC, 0), | 291 MockWrite( |
| 293 MockWrite(ASYNC, kSOCKSPartialRequest2, | 292 ASYNC, kSOCKSPartialRequest2, arraysize(kSOCKSPartialRequest2))}; |
| 294 arraysize(kSOCKSPartialRequest2)) }; | |
| 295 MockRead data_reads[] = { | 293 MockRead data_reads[] = { |
| 296 MockRead(ASYNC, kSOCKSOkReply, arraysize(kSOCKSOkReply)) }; | 294 MockRead(ASYNC, kSOCKSOkReply, arraysize(kSOCKSOkReply))}; |
| 297 CapturingNetLog log; | 295 CapturingNetLog log; |
| 298 | 296 |
| 299 user_sock_ = BuildMockSocket(data_reads, arraysize(data_reads), | 297 user_sock_ = BuildMockSocket(data_reads, |
| 300 data_writes, arraysize(data_writes), | 298 arraysize(data_reads), |
| 299 data_writes, |
| 300 arraysize(data_writes), |
| 301 host_resolver_.get(), | 301 host_resolver_.get(), |
| 302 "localhost", 80, | 302 "localhost", |
| 303 80, |
| 303 &log); | 304 &log); |
| 304 | 305 |
| 305 int rv = user_sock_->Connect(callback_.callback()); | 306 int rv = user_sock_->Connect(callback_.callback()); |
| 306 EXPECT_EQ(ERR_IO_PENDING, rv); | 307 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 307 CapturingNetLog::CapturedEntryList entries; | 308 CapturingNetLog::CapturedEntryList entries; |
| 308 log.GetEntries(&entries); | 309 log.GetEntries(&entries); |
| 309 EXPECT_TRUE(LogContainsBeginEvent( | 310 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLog::TYPE_SOCKS_CONNECT)); |
| 310 entries, 0, NetLog::TYPE_SOCKS_CONNECT)); | |
| 311 | 311 |
| 312 rv = callback_.WaitForResult(); | 312 rv = callback_.WaitForResult(); |
| 313 EXPECT_EQ(OK, rv); | 313 EXPECT_EQ(OK, rv); |
| 314 EXPECT_TRUE(user_sock_->IsConnected()); | 314 EXPECT_TRUE(user_sock_->IsConnected()); |
| 315 log.GetEntries(&entries); | 315 log.GetEntries(&entries); |
| 316 EXPECT_TRUE(LogContainsEndEvent( | 316 EXPECT_TRUE(LogContainsEndEvent(entries, -1, NetLog::TYPE_SOCKS_CONNECT)); |
| 317 entries, -1, NetLog::TYPE_SOCKS_CONNECT)); | |
| 318 } | 317 } |
| 319 | 318 |
| 320 // Tests the case when the server sends a smaller sized handshake data | 319 // Tests the case when the server sends a smaller sized handshake data |
| 321 // and closes the connection. | 320 // and closes the connection. |
| 322 TEST_F(SOCKSClientSocketTest, FailedSocketRead) { | 321 TEST_F(SOCKSClientSocketTest, FailedSocketRead) { |
| 323 MockWrite data_writes[] = { | 322 MockWrite data_writes[] = { |
| 324 MockWrite(ASYNC, kSOCKSOkRequest, arraysize(kSOCKSOkRequest)) }; | 323 MockWrite(ASYNC, kSOCKSOkRequest, arraysize(kSOCKSOkRequest))}; |
| 325 MockRead data_reads[] = { | 324 MockRead data_reads[] = { |
| 326 MockRead(ASYNC, kSOCKSOkReply, arraysize(kSOCKSOkReply) - 2), | 325 MockRead(ASYNC, kSOCKSOkReply, arraysize(kSOCKSOkReply) - 2), |
| 327 // close connection unexpectedly | 326 // close connection unexpectedly |
| 328 MockRead(SYNCHRONOUS, 0) }; | 327 MockRead(SYNCHRONOUS, 0)}; |
| 329 CapturingNetLog log; | 328 CapturingNetLog log; |
| 330 | 329 |
| 331 user_sock_ = BuildMockSocket(data_reads, arraysize(data_reads), | 330 user_sock_ = BuildMockSocket(data_reads, |
| 332 data_writes, arraysize(data_writes), | 331 arraysize(data_reads), |
| 332 data_writes, |
| 333 arraysize(data_writes), |
| 333 host_resolver_.get(), | 334 host_resolver_.get(), |
| 334 "localhost", 80, | 335 "localhost", |
| 336 80, |
| 335 &log); | 337 &log); |
| 336 | 338 |
| 337 int rv = user_sock_->Connect(callback_.callback()); | 339 int rv = user_sock_->Connect(callback_.callback()); |
| 338 EXPECT_EQ(ERR_IO_PENDING, rv); | 340 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 339 CapturingNetLog::CapturedEntryList entries; | 341 CapturingNetLog::CapturedEntryList entries; |
| 340 log.GetEntries(&entries); | 342 log.GetEntries(&entries); |
| 341 EXPECT_TRUE(LogContainsBeginEvent( | 343 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLog::TYPE_SOCKS_CONNECT)); |
| 342 entries, 0, NetLog::TYPE_SOCKS_CONNECT)); | |
| 343 | 344 |
| 344 rv = callback_.WaitForResult(); | 345 rv = callback_.WaitForResult(); |
| 345 EXPECT_EQ(ERR_CONNECTION_CLOSED, rv); | 346 EXPECT_EQ(ERR_CONNECTION_CLOSED, rv); |
| 346 EXPECT_FALSE(user_sock_->IsConnected()); | 347 EXPECT_FALSE(user_sock_->IsConnected()); |
| 347 log.GetEntries(&entries); | 348 log.GetEntries(&entries); |
| 348 EXPECT_TRUE(LogContainsEndEvent( | 349 EXPECT_TRUE(LogContainsEndEvent(entries, -1, NetLog::TYPE_SOCKS_CONNECT)); |
| 349 entries, -1, NetLog::TYPE_SOCKS_CONNECT)); | |
| 350 } | 350 } |
| 351 | 351 |
| 352 // Tries to connect to an unknown hostname. Should fail rather than | 352 // Tries to connect to an unknown hostname. Should fail rather than |
| 353 // falling back to SOCKS4a. | 353 // falling back to SOCKS4a. |
| 354 TEST_F(SOCKSClientSocketTest, FailedDNS) { | 354 TEST_F(SOCKSClientSocketTest, FailedDNS) { |
| 355 const char hostname[] = "unresolved.ipv4.address"; | 355 const char hostname[] = "unresolved.ipv4.address"; |
| 356 | 356 |
| 357 host_resolver_->rules()->AddSimulatedFailure(hostname); | 357 host_resolver_->rules()->AddSimulatedFailure(hostname); |
| 358 | 358 |
| 359 CapturingNetLog log; | 359 CapturingNetLog log; |
| 360 | 360 |
| 361 user_sock_ = BuildMockSocket(NULL, 0, | 361 user_sock_ = BuildMockSocket( |
| 362 NULL, 0, | 362 NULL, 0, NULL, 0, host_resolver_.get(), hostname, 80, &log); |
| 363 host_resolver_.get(), | |
| 364 hostname, 80, | |
| 365 &log); | |
| 366 | 363 |
| 367 int rv = user_sock_->Connect(callback_.callback()); | 364 int rv = user_sock_->Connect(callback_.callback()); |
| 368 EXPECT_EQ(ERR_IO_PENDING, rv); | 365 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 369 CapturingNetLog::CapturedEntryList entries; | 366 CapturingNetLog::CapturedEntryList entries; |
| 370 log.GetEntries(&entries); | 367 log.GetEntries(&entries); |
| 371 EXPECT_TRUE(LogContainsBeginEvent( | 368 EXPECT_TRUE(LogContainsBeginEvent(entries, 0, NetLog::TYPE_SOCKS_CONNECT)); |
| 372 entries, 0, NetLog::TYPE_SOCKS_CONNECT)); | |
| 373 | 369 |
| 374 rv = callback_.WaitForResult(); | 370 rv = callback_.WaitForResult(); |
| 375 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv); | 371 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv); |
| 376 EXPECT_FALSE(user_sock_->IsConnected()); | 372 EXPECT_FALSE(user_sock_->IsConnected()); |
| 377 log.GetEntries(&entries); | 373 log.GetEntries(&entries); |
| 378 EXPECT_TRUE(LogContainsEndEvent( | 374 EXPECT_TRUE(LogContainsEndEvent(entries, -1, NetLog::TYPE_SOCKS_CONNECT)); |
| 379 entries, -1, NetLog::TYPE_SOCKS_CONNECT)); | |
| 380 } | 375 } |
| 381 | 376 |
| 382 // Calls Disconnect() while a host resolve is in progress. The outstanding host | 377 // Calls Disconnect() while a host resolve is in progress. The outstanding host |
| 383 // resolve should be cancelled. | 378 // resolve should be cancelled. |
| 384 TEST_F(SOCKSClientSocketTest, DisconnectWhileHostResolveInProgress) { | 379 TEST_F(SOCKSClientSocketTest, DisconnectWhileHostResolveInProgress) { |
| 385 scoped_ptr<HangingHostResolverWithCancel> hanging_resolver( | 380 scoped_ptr<HangingHostResolverWithCancel> hanging_resolver( |
| 386 new HangingHostResolverWithCancel()); | 381 new HangingHostResolverWithCancel()); |
| 387 | 382 |
| 388 // Doesn't matter what the socket data is, we will never use it -- garbage. | 383 // Doesn't matter what the socket data is, we will never use it -- garbage. |
| 389 MockWrite data_writes[] = { MockWrite(SYNCHRONOUS, "", 0) }; | 384 MockWrite data_writes[] = {MockWrite(SYNCHRONOUS, "", 0)}; |
| 390 MockRead data_reads[] = { MockRead(SYNCHRONOUS, "", 0) }; | 385 MockRead data_reads[] = {MockRead(SYNCHRONOUS, "", 0)}; |
| 391 | 386 |
| 392 user_sock_ = BuildMockSocket(data_reads, arraysize(data_reads), | 387 user_sock_ = BuildMockSocket(data_reads, |
| 393 data_writes, arraysize(data_writes), | 388 arraysize(data_reads), |
| 389 data_writes, |
| 390 arraysize(data_writes), |
| 394 hanging_resolver.get(), | 391 hanging_resolver.get(), |
| 395 "foo", 80, | 392 "foo", |
| 393 80, |
| 396 NULL); | 394 NULL); |
| 397 | 395 |
| 398 // Start connecting (will get stuck waiting for the host to resolve). | 396 // Start connecting (will get stuck waiting for the host to resolve). |
| 399 int rv = user_sock_->Connect(callback_.callback()); | 397 int rv = user_sock_->Connect(callback_.callback()); |
| 400 EXPECT_EQ(ERR_IO_PENDING, rv); | 398 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 401 | 399 |
| 402 EXPECT_FALSE(user_sock_->IsConnected()); | 400 EXPECT_FALSE(user_sock_->IsConnected()); |
| 403 EXPECT_FALSE(user_sock_->IsConnectedAndIdle()); | 401 EXPECT_FALSE(user_sock_->IsConnectedAndIdle()); |
| 404 | 402 |
| 405 // The host resolver should have received the resolve request. | 403 // The host resolver should have received the resolve request. |
| 406 EXPECT_TRUE(hanging_resolver->HasOutstandingRequest()); | 404 EXPECT_TRUE(hanging_resolver->HasOutstandingRequest()); |
| 407 | 405 |
| 408 // Disconnect the SOCKS socket -- this should cancel the outstanding resolve. | 406 // Disconnect the SOCKS socket -- this should cancel the outstanding resolve. |
| 409 user_sock_->Disconnect(); | 407 user_sock_->Disconnect(); |
| 410 | 408 |
| 411 EXPECT_FALSE(hanging_resolver->HasOutstandingRequest()); | 409 EXPECT_FALSE(hanging_resolver->HasOutstandingRequest()); |
| 412 | 410 |
| 413 EXPECT_FALSE(user_sock_->IsConnected()); | 411 EXPECT_FALSE(user_sock_->IsConnected()); |
| 414 EXPECT_FALSE(user_sock_->IsConnectedAndIdle()); | 412 EXPECT_FALSE(user_sock_->IsConnectedAndIdle()); |
| 415 } | 413 } |
| 416 | 414 |
| 417 } // namespace net | 415 } // namespace net |
| OLD | NEW |