| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 25 { 0x04, 0x01, 0x00, 0x50, 0, 0, 0, 127, 0 }; | 25 { 0x04, 0x01, 0x00, 0x50, 0, 0, 0, 127, 0 }; |
| 26 const char kSOCKSOkReply[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 }; | 26 const char kSOCKSOkReply[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 }; |
| 27 | 27 |
| 28 class SOCKSClientSocketTest : public PlatformTest { | 28 class SOCKSClientSocketTest : public PlatformTest { |
| 29 public: | 29 public: |
| 30 SOCKSClientSocketTest(); | 30 SOCKSClientSocketTest(); |
| 31 // Create a SOCKSClientSocket on top of a MockSocket. | 31 // Create a SOCKSClientSocket on top of a MockSocket. |
| 32 SOCKSClientSocket* BuildMockSocket(MockRead reads[], size_t reads_count, | 32 SOCKSClientSocket* BuildMockSocket(MockRead reads[], size_t reads_count, |
| 33 MockWrite writes[], size_t writes_count, | 33 MockWrite writes[], size_t writes_count, |
| 34 HostResolver* host_resolver, | 34 HostResolver* host_resolver, |
| 35 const std::string& hostname, int port); | 35 const std::string& hostname, int port, |
| 36 NetLog* net_log); |
| 36 virtual void SetUp(); | 37 virtual void SetUp(); |
| 37 | 38 |
| 38 protected: | 39 protected: |
| 39 scoped_ptr<SOCKSClientSocket> user_sock_; | 40 scoped_ptr<SOCKSClientSocket> user_sock_; |
| 40 AddressList address_list_; | 41 AddressList address_list_; |
| 41 ClientSocket* tcp_sock_; | 42 ClientSocket* tcp_sock_; |
| 42 TestCompletionCallback callback_; | 43 TestCompletionCallback callback_; |
| 43 scoped_refptr<MockHostResolver> host_resolver_; | 44 scoped_refptr<MockHostResolver> host_resolver_; |
| 44 scoped_ptr<SocketDataProvider> data_; | 45 scoped_ptr<SocketDataProvider> data_; |
| 45 | 46 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 56 PlatformTest::SetUp(); | 57 PlatformTest::SetUp(); |
| 57 } | 58 } |
| 58 | 59 |
| 59 SOCKSClientSocket* SOCKSClientSocketTest::BuildMockSocket( | 60 SOCKSClientSocket* SOCKSClientSocketTest::BuildMockSocket( |
| 60 MockRead reads[], | 61 MockRead reads[], |
| 61 size_t reads_count, | 62 size_t reads_count, |
| 62 MockWrite writes[], | 63 MockWrite writes[], |
| 63 size_t writes_count, | 64 size_t writes_count, |
| 64 HostResolver* host_resolver, | 65 HostResolver* host_resolver, |
| 65 const std::string& hostname, | 66 const std::string& hostname, |
| 66 int port) { | 67 int port, |
| 68 NetLog* net_log) { |
| 67 | 69 |
| 68 TestCompletionCallback callback; | 70 TestCompletionCallback callback; |
| 69 data_.reset(new StaticSocketDataProvider(reads, reads_count, | 71 data_.reset(new StaticSocketDataProvider(reads, reads_count, |
| 70 writes, writes_count)); | 72 writes, writes_count)); |
| 71 tcp_sock_ = new MockTCPClientSocket(address_list_, data_.get()); | 73 tcp_sock_ = new MockTCPClientSocket(address_list_, net_log, data_.get()); |
| 72 | 74 |
| 73 int rv = tcp_sock_->Connect(&callback, NULL); | 75 int rv = tcp_sock_->Connect(&callback); |
| 74 EXPECT_EQ(ERR_IO_PENDING, rv); | 76 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 75 rv = callback.WaitForResult(); | 77 rv = callback.WaitForResult(); |
| 76 EXPECT_EQ(OK, rv); | 78 EXPECT_EQ(OK, rv); |
| 77 EXPECT_TRUE(tcp_sock_->IsConnected()); | 79 EXPECT_TRUE(tcp_sock_->IsConnected()); |
| 78 | 80 |
| 79 return new SOCKSClientSocket(tcp_sock_, | 81 return new SOCKSClientSocket(tcp_sock_, |
| 80 HostResolver::RequestInfo(hostname, port), | 82 HostResolver::RequestInfo(hostname, port), |
| 81 host_resolver); | 83 host_resolver); |
| 82 } | 84 } |
| 83 | 85 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 TEST_F(SOCKSClientSocketTest, CompleteHandshake) { | 124 TEST_F(SOCKSClientSocketTest, CompleteHandshake) { |
| 123 const std::string payload_write = "random data"; | 125 const std::string payload_write = "random data"; |
| 124 const std::string payload_read = "moar random data"; | 126 const std::string payload_read = "moar random data"; |
| 125 | 127 |
| 126 MockWrite data_writes[] = { | 128 MockWrite data_writes[] = { |
| 127 MockWrite(true, kSOCKSOkRequest, arraysize(kSOCKSOkRequest)), | 129 MockWrite(true, kSOCKSOkRequest, arraysize(kSOCKSOkRequest)), |
| 128 MockWrite(true, payload_write.data(), payload_write.size()) }; | 130 MockWrite(true, payload_write.data(), payload_write.size()) }; |
| 129 MockRead data_reads[] = { | 131 MockRead data_reads[] = { |
| 130 MockRead(true, kSOCKSOkReply, arraysize(kSOCKSOkReply)), | 132 MockRead(true, kSOCKSOkReply, arraysize(kSOCKSOkReply)), |
| 131 MockRead(true, payload_read.data(), payload_read.size()) }; | 133 MockRead(true, payload_read.data(), payload_read.size()) }; |
| 134 CapturingNetLog log(CapturingNetLog::kUnbounded); |
| 132 | 135 |
| 133 user_sock_.reset(BuildMockSocket(data_reads, arraysize(data_reads), | 136 user_sock_.reset(BuildMockSocket(data_reads, arraysize(data_reads), |
| 134 data_writes, arraysize(data_writes), | 137 data_writes, arraysize(data_writes), |
| 135 host_resolver_, "localhost", 80)); | 138 host_resolver_, "localhost", 80, &log)); |
| 136 | 139 |
| 137 // At this state the TCP connection is completed but not the SOCKS handshake. | 140 // At this state the TCP connection is completed but not the SOCKS handshake. |
| 138 EXPECT_TRUE(tcp_sock_->IsConnected()); | 141 EXPECT_TRUE(tcp_sock_->IsConnected()); |
| 139 EXPECT_FALSE(user_sock_->IsConnected()); | 142 EXPECT_FALSE(user_sock_->IsConnected()); |
| 140 | 143 |
| 141 CapturingBoundNetLog log(CapturingNetLog::kUnbounded); | 144 int rv = user_sock_->Connect(&callback_); |
| 142 int rv = user_sock_->Connect(&callback_, log.bound()); | |
| 143 EXPECT_EQ(ERR_IO_PENDING, rv); | 145 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 144 EXPECT_TRUE( | 146 EXPECT_TRUE( |
| 145 LogContainsBeginEvent(log.entries(), 0, NetLog::TYPE_SOCKS_CONNECT)); | 147 LogContainsBeginEvent(log.entries(), 0, NetLog::TYPE_SOCKS_CONNECT)); |
| 146 EXPECT_FALSE(user_sock_->IsConnected()); | 148 EXPECT_FALSE(user_sock_->IsConnected()); |
| 147 rv = callback_.WaitForResult(); | 149 rv = callback_.WaitForResult(); |
| 148 | 150 |
| 149 EXPECT_EQ(OK, rv); | 151 EXPECT_EQ(OK, rv); |
| 150 EXPECT_TRUE(user_sock_->IsConnected()); | 152 EXPECT_TRUE(user_sock_->IsConnected()); |
| 151 EXPECT_EQ(SOCKSClientSocket::kSOCKS4, user_sock_->socks_version_); | 153 EXPECT_EQ(SOCKSClientSocket::kSOCKS4, user_sock_->socks_version_); |
| 152 EXPECT_TRUE(LogContainsEndEvent( | 154 EXPECT_TRUE(LogContainsEndEvent( |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 }, | 192 }, |
| 191 }; | 193 }; |
| 192 | 194 |
| 193 //--------------------------------------- | 195 //--------------------------------------- |
| 194 | 196 |
| 195 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | 197 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { |
| 196 MockWrite data_writes[] = { | 198 MockWrite data_writes[] = { |
| 197 MockWrite(false, kSOCKSOkRequest, arraysize(kSOCKSOkRequest)) }; | 199 MockWrite(false, kSOCKSOkRequest, arraysize(kSOCKSOkRequest)) }; |
| 198 MockRead data_reads[] = { | 200 MockRead data_reads[] = { |
| 199 MockRead(false, tests[i].fail_reply, arraysize(tests[i].fail_reply)) }; | 201 MockRead(false, tests[i].fail_reply, arraysize(tests[i].fail_reply)) }; |
| 202 CapturingNetLog log(CapturingNetLog::kUnbounded); |
| 200 | 203 |
| 201 user_sock_.reset(BuildMockSocket(data_reads, arraysize(data_reads), | 204 user_sock_.reset(BuildMockSocket(data_reads, arraysize(data_reads), |
| 202 data_writes, arraysize(data_writes), | 205 data_writes, arraysize(data_writes), |
| 203 host_resolver_, "localhost", 80)); | 206 host_resolver_, "localhost", 80, &log)); |
| 204 CapturingBoundNetLog log(CapturingNetLog::kUnbounded); | |
| 205 | 207 |
| 206 int rv = user_sock_->Connect(&callback_, log.bound()); | 208 int rv = user_sock_->Connect(&callback_); |
| 207 EXPECT_EQ(ERR_IO_PENDING, rv); | 209 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 208 EXPECT_TRUE(LogContainsBeginEvent( | 210 EXPECT_TRUE(LogContainsBeginEvent( |
| 209 log.entries(), 0, NetLog::TYPE_SOCKS_CONNECT)); | 211 log.entries(), 0, NetLog::TYPE_SOCKS_CONNECT)); |
| 210 rv = callback_.WaitForResult(); | 212 rv = callback_.WaitForResult(); |
| 211 EXPECT_EQ(tests[i].fail_code, rv); | 213 EXPECT_EQ(tests[i].fail_code, rv); |
| 212 EXPECT_FALSE(user_sock_->IsConnected()); | 214 EXPECT_FALSE(user_sock_->IsConnected()); |
| 213 EXPECT_TRUE(tcp_sock_->IsConnected()); | 215 EXPECT_TRUE(tcp_sock_->IsConnected()); |
| 214 EXPECT_TRUE(LogContainsEndEvent( | 216 EXPECT_TRUE(LogContainsEndEvent( |
| 215 log.entries(), -1, NetLog::TYPE_SOCKS_CONNECT)); | 217 log.entries(), -1, NetLog::TYPE_SOCKS_CONNECT)); |
| 216 } | 218 } |
| 217 } | 219 } |
| 218 | 220 |
| 219 // Tests scenario when the server sends the handshake response in | 221 // Tests scenario when the server sends the handshake response in |
| 220 // more than one packet. | 222 // more than one packet. |
| 221 TEST_F(SOCKSClientSocketTest, PartialServerReads) { | 223 TEST_F(SOCKSClientSocketTest, PartialServerReads) { |
| 222 const char kSOCKSPartialReply1[] = { 0x00 }; | 224 const char kSOCKSPartialReply1[] = { 0x00 }; |
| 223 const char kSOCKSPartialReply2[] = { 0x5A, 0x00, 0x00, 0, 0, 0, 0 }; | 225 const char kSOCKSPartialReply2[] = { 0x5A, 0x00, 0x00, 0, 0, 0, 0 }; |
| 224 | 226 |
| 225 MockWrite data_writes[] = { | 227 MockWrite data_writes[] = { |
| 226 MockWrite(true, kSOCKSOkRequest, arraysize(kSOCKSOkRequest)) }; | 228 MockWrite(true, kSOCKSOkRequest, arraysize(kSOCKSOkRequest)) }; |
| 227 MockRead data_reads[] = { | 229 MockRead data_reads[] = { |
| 228 MockRead(true, kSOCKSPartialReply1, arraysize(kSOCKSPartialReply1)), | 230 MockRead(true, kSOCKSPartialReply1, arraysize(kSOCKSPartialReply1)), |
| 229 MockRead(true, kSOCKSPartialReply2, arraysize(kSOCKSPartialReply2)) }; | 231 MockRead(true, kSOCKSPartialReply2, arraysize(kSOCKSPartialReply2)) }; |
| 232 CapturingNetLog log(CapturingNetLog::kUnbounded); |
| 230 | 233 |
| 231 user_sock_.reset(BuildMockSocket(data_reads, arraysize(data_reads), | 234 user_sock_.reset(BuildMockSocket(data_reads, arraysize(data_reads), |
| 232 data_writes, arraysize(data_writes), | 235 data_writes, arraysize(data_writes), |
| 233 host_resolver_, "localhost", 80)); | 236 host_resolver_, "localhost", 80, &log)); |
| 234 CapturingBoundNetLog log(CapturingNetLog::kUnbounded); | |
| 235 | 237 |
| 236 | 238 int rv = user_sock_->Connect(&callback_); |
| 237 int rv = user_sock_->Connect(&callback_, log.bound()); | |
| 238 EXPECT_EQ(ERR_IO_PENDING, rv); | 239 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 239 EXPECT_TRUE(LogContainsBeginEvent( | 240 EXPECT_TRUE(LogContainsBeginEvent( |
| 240 log.entries(), 0, NetLog::TYPE_SOCKS_CONNECT)); | 241 log.entries(), 0, NetLog::TYPE_SOCKS_CONNECT)); |
| 241 rv = callback_.WaitForResult(); | 242 rv = callback_.WaitForResult(); |
| 242 EXPECT_EQ(OK, rv); | 243 EXPECT_EQ(OK, rv); |
| 243 EXPECT_TRUE(user_sock_->IsConnected()); | 244 EXPECT_TRUE(user_sock_->IsConnected()); |
| 244 EXPECT_TRUE(LogContainsEndEvent( | 245 EXPECT_TRUE(LogContainsEndEvent( |
| 245 log.entries(), -1, NetLog::TYPE_SOCKS_CONNECT)); | 246 log.entries(), -1, NetLog::TYPE_SOCKS_CONNECT)); |
| 246 } | 247 } |
| 247 | 248 |
| 248 // Tests scenario when the client sends the handshake request in | 249 // Tests scenario when the client sends the handshake request in |
| 249 // more than one packet. | 250 // more than one packet. |
| 250 TEST_F(SOCKSClientSocketTest, PartialClientWrites) { | 251 TEST_F(SOCKSClientSocketTest, PartialClientWrites) { |
| 251 const char kSOCKSPartialRequest1[] = { 0x04, 0x01 }; | 252 const char kSOCKSPartialRequest1[] = { 0x04, 0x01 }; |
| 252 const char kSOCKSPartialRequest2[] = { 0x00, 0x50, 127, 0, 0, 1, 0 }; | 253 const char kSOCKSPartialRequest2[] = { 0x00, 0x50, 127, 0, 0, 1, 0 }; |
| 253 | 254 |
| 254 MockWrite data_writes[] = { | 255 MockWrite data_writes[] = { |
| 255 MockWrite(true, arraysize(kSOCKSPartialRequest1)), | 256 MockWrite(true, arraysize(kSOCKSPartialRequest1)), |
| 256 // simulate some empty writes | 257 // simulate some empty writes |
| 257 MockWrite(true, 0), | 258 MockWrite(true, 0), |
| 258 MockWrite(true, 0), | 259 MockWrite(true, 0), |
| 259 MockWrite(true, kSOCKSPartialRequest2, | 260 MockWrite(true, kSOCKSPartialRequest2, |
| 260 arraysize(kSOCKSPartialRequest2)) }; | 261 arraysize(kSOCKSPartialRequest2)) }; |
| 261 MockRead data_reads[] = { | 262 MockRead data_reads[] = { |
| 262 MockRead(true, kSOCKSOkReply, arraysize(kSOCKSOkReply)) }; | 263 MockRead(true, kSOCKSOkReply, arraysize(kSOCKSOkReply)) }; |
| 264 CapturingNetLog log(CapturingNetLog::kUnbounded); |
| 263 | 265 |
| 264 user_sock_.reset(BuildMockSocket(data_reads, arraysize(data_reads), | 266 user_sock_.reset(BuildMockSocket(data_reads, arraysize(data_reads), |
| 265 data_writes, arraysize(data_writes), | 267 data_writes, arraysize(data_writes), |
| 266 host_resolver_, "localhost", 80)); | 268 host_resolver_, "localhost", 80, &log)); |
| 267 CapturingBoundNetLog log(CapturingNetLog::kUnbounded); | |
| 268 | 269 |
| 269 int rv = user_sock_->Connect(&callback_, log.bound()); | 270 int rv = user_sock_->Connect(&callback_); |
| 270 EXPECT_EQ(ERR_IO_PENDING, rv); | 271 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 271 EXPECT_TRUE(LogContainsBeginEvent( | 272 EXPECT_TRUE(LogContainsBeginEvent( |
| 272 log.entries(), 0, NetLog::TYPE_SOCKS_CONNECT)); | 273 log.entries(), 0, NetLog::TYPE_SOCKS_CONNECT)); |
| 273 rv = callback_.WaitForResult(); | 274 rv = callback_.WaitForResult(); |
| 274 EXPECT_EQ(OK, rv); | 275 EXPECT_EQ(OK, rv); |
| 275 EXPECT_TRUE(user_sock_->IsConnected()); | 276 EXPECT_TRUE(user_sock_->IsConnected()); |
| 276 EXPECT_TRUE(LogContainsEndEvent( | 277 EXPECT_TRUE(LogContainsEndEvent( |
| 277 log.entries(), -1, NetLog::TYPE_SOCKS_CONNECT)); | 278 log.entries(), -1, NetLog::TYPE_SOCKS_CONNECT)); |
| 278 } | 279 } |
| 279 | 280 |
| 280 // Tests the case when the server sends a smaller sized handshake data | 281 // Tests the case when the server sends a smaller sized handshake data |
| 281 // and closes the connection. | 282 // and closes the connection. |
| 282 TEST_F(SOCKSClientSocketTest, FailedSocketRead) { | 283 TEST_F(SOCKSClientSocketTest, FailedSocketRead) { |
| 283 MockWrite data_writes[] = { | 284 MockWrite data_writes[] = { |
| 284 MockWrite(true, kSOCKSOkRequest, arraysize(kSOCKSOkRequest)) }; | 285 MockWrite(true, kSOCKSOkRequest, arraysize(kSOCKSOkRequest)) }; |
| 285 MockRead data_reads[] = { | 286 MockRead data_reads[] = { |
| 286 MockRead(true, kSOCKSOkReply, arraysize(kSOCKSOkReply) - 2), | 287 MockRead(true, kSOCKSOkReply, arraysize(kSOCKSOkReply) - 2), |
| 287 // close connection unexpectedly | 288 // close connection unexpectedly |
| 288 MockRead(false, 0) }; | 289 MockRead(false, 0) }; |
| 290 CapturingNetLog log(CapturingNetLog::kUnbounded); |
| 289 | 291 |
| 290 user_sock_.reset(BuildMockSocket(data_reads, arraysize(data_reads), | 292 user_sock_.reset(BuildMockSocket(data_reads, arraysize(data_reads), |
| 291 data_writes, arraysize(data_writes), | 293 data_writes, arraysize(data_writes), |
| 292 host_resolver_, "localhost", 80)); | 294 host_resolver_, "localhost", 80, &log)); |
| 293 CapturingBoundNetLog log(CapturingNetLog::kUnbounded); | |
| 294 | 295 |
| 295 | 296 int rv = user_sock_->Connect(&callback_); |
| 296 int rv = user_sock_->Connect(&callback_, log.bound()); | |
| 297 EXPECT_EQ(ERR_IO_PENDING, rv); | 297 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 298 EXPECT_TRUE(LogContainsBeginEvent( | 298 EXPECT_TRUE(LogContainsBeginEvent( |
| 299 log.entries(), 0, NetLog::TYPE_SOCKS_CONNECT)); | 299 log.entries(), 0, NetLog::TYPE_SOCKS_CONNECT)); |
| 300 rv = callback_.WaitForResult(); | 300 rv = callback_.WaitForResult(); |
| 301 EXPECT_EQ(ERR_CONNECTION_CLOSED, rv); | 301 EXPECT_EQ(ERR_CONNECTION_CLOSED, rv); |
| 302 EXPECT_FALSE(user_sock_->IsConnected()); | 302 EXPECT_FALSE(user_sock_->IsConnected()); |
| 303 EXPECT_TRUE(LogContainsEndEvent( | 303 EXPECT_TRUE(LogContainsEndEvent( |
| 304 log.entries(), -1, NetLog::TYPE_SOCKS_CONNECT)); | 304 log.entries(), -1, NetLog::TYPE_SOCKS_CONNECT)); |
| 305 } | 305 } |
| 306 | 306 |
| 307 // Tries to connect to an unknown DNS and on failure should revert to SOCKS4A. | 307 // Tries to connect to an unknown DNS and on failure should revert to SOCKS4A. |
| 308 TEST_F(SOCKSClientSocketTest, SOCKS4AFailedDNS) { | 308 TEST_F(SOCKSClientSocketTest, SOCKS4AFailedDNS) { |
| 309 const char hostname[] = "unresolved.ipv4.address"; | 309 const char hostname[] = "unresolved.ipv4.address"; |
| 310 | 310 |
| 311 host_resolver_->rules()->AddSimulatedFailure(hostname); | 311 host_resolver_->rules()->AddSimulatedFailure(hostname); |
| 312 | 312 |
| 313 std::string request(kSOCKS4aInitialRequest, | 313 std::string request(kSOCKS4aInitialRequest, |
| 314 arraysize(kSOCKS4aInitialRequest)); | 314 arraysize(kSOCKS4aInitialRequest)); |
| 315 request.append(hostname, arraysize(hostname)); | 315 request.append(hostname, arraysize(hostname)); |
| 316 | 316 |
| 317 MockWrite data_writes[] = { | 317 MockWrite data_writes[] = { |
| 318 MockWrite(false, request.data(), request.size()) }; | 318 MockWrite(false, request.data(), request.size()) }; |
| 319 MockRead data_reads[] = { | 319 MockRead data_reads[] = { |
| 320 MockRead(false, kSOCKSOkReply, arraysize(kSOCKSOkReply)) }; | 320 MockRead(false, kSOCKSOkReply, arraysize(kSOCKSOkReply)) }; |
| 321 CapturingNetLog log(CapturingNetLog::kUnbounded); |
| 321 | 322 |
| 322 user_sock_.reset(BuildMockSocket(data_reads, arraysize(data_reads), | 323 user_sock_.reset(BuildMockSocket(data_reads, arraysize(data_reads), |
| 323 data_writes, arraysize(data_writes), | 324 data_writes, arraysize(data_writes), |
| 324 host_resolver_, hostname, 80)); | 325 host_resolver_, hostname, 80, &log)); |
| 325 CapturingBoundNetLog log(CapturingNetLog::kUnbounded); | |
| 326 | 326 |
| 327 int rv = user_sock_->Connect(&callback_, log.bound()); | 327 int rv = user_sock_->Connect(&callback_); |
| 328 EXPECT_EQ(ERR_IO_PENDING, rv); | 328 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 329 EXPECT_TRUE(LogContainsBeginEvent( | 329 EXPECT_TRUE(LogContainsBeginEvent( |
| 330 log.entries(), 0, NetLog::TYPE_SOCKS_CONNECT)); | 330 log.entries(), 0, NetLog::TYPE_SOCKS_CONNECT)); |
| 331 rv = callback_.WaitForResult(); | 331 rv = callback_.WaitForResult(); |
| 332 EXPECT_EQ(OK, rv); | 332 EXPECT_EQ(OK, rv); |
| 333 EXPECT_TRUE(user_sock_->IsConnected()); | 333 EXPECT_TRUE(user_sock_->IsConnected()); |
| 334 EXPECT_EQ(SOCKSClientSocket::kSOCKS4a, user_sock_->socks_version_); | 334 EXPECT_EQ(SOCKSClientSocket::kSOCKS4a, user_sock_->socks_version_); |
| 335 EXPECT_TRUE(LogContainsEndEvent( | 335 EXPECT_TRUE(LogContainsEndEvent( |
| 336 log.entries(), -1, NetLog::TYPE_SOCKS_CONNECT)); | 336 log.entries(), -1, NetLog::TYPE_SOCKS_CONNECT)); |
| 337 } | 337 } |
| 338 | 338 |
| 339 // Tries to connect to a domain that resolves to IPv6. | 339 // Tries to connect to a domain that resolves to IPv6. |
| 340 // Should revert to SOCKS4a. | 340 // Should revert to SOCKS4a. |
| 341 TEST_F(SOCKSClientSocketTest, SOCKS4AIfDomainInIPv6) { | 341 TEST_F(SOCKSClientSocketTest, SOCKS4AIfDomainInIPv6) { |
| 342 const char hostname[] = "an.ipv6.address"; | 342 const char hostname[] = "an.ipv6.address"; |
| 343 | 343 |
| 344 host_resolver_->rules()->AddIPv6Rule(hostname, "2001:db8:8714:3a90::12"); | 344 host_resolver_->rules()->AddIPv6Rule(hostname, "2001:db8:8714:3a90::12"); |
| 345 | 345 |
| 346 std::string request(kSOCKS4aInitialRequest, | 346 std::string request(kSOCKS4aInitialRequest, |
| 347 arraysize(kSOCKS4aInitialRequest)); | 347 arraysize(kSOCKS4aInitialRequest)); |
| 348 request.append(hostname, arraysize(hostname)); | 348 request.append(hostname, arraysize(hostname)); |
| 349 | 349 |
| 350 MockWrite data_writes[] = { | 350 MockWrite data_writes[] = { |
| 351 MockWrite(false, request.data(), request.size()) }; | 351 MockWrite(false, request.data(), request.size()) }; |
| 352 MockRead data_reads[] = { | 352 MockRead data_reads[] = { |
| 353 MockRead(false, kSOCKSOkReply, arraysize(kSOCKSOkReply)) }; | 353 MockRead(false, kSOCKSOkReply, arraysize(kSOCKSOkReply)) }; |
| 354 CapturingNetLog log(CapturingNetLog::kUnbounded); |
| 354 | 355 |
| 355 user_sock_.reset(BuildMockSocket(data_reads, arraysize(data_reads), | 356 user_sock_.reset(BuildMockSocket(data_reads, arraysize(data_reads), |
| 356 data_writes, arraysize(data_writes), | 357 data_writes, arraysize(data_writes), |
| 357 host_resolver_, hostname, 80)); | 358 host_resolver_, hostname, 80, &log)); |
| 358 CapturingBoundNetLog log(CapturingNetLog::kUnbounded); | |
| 359 | 359 |
| 360 int rv = user_sock_->Connect(&callback_, log.bound()); | 360 int rv = user_sock_->Connect(&callback_); |
| 361 EXPECT_EQ(ERR_IO_PENDING, rv); | 361 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 362 EXPECT_TRUE(LogContainsBeginEvent( | 362 EXPECT_TRUE(LogContainsBeginEvent( |
| 363 log.entries(), 0, NetLog::TYPE_SOCKS_CONNECT)); | 363 log.entries(), 0, NetLog::TYPE_SOCKS_CONNECT)); |
| 364 rv = callback_.WaitForResult(); | 364 rv = callback_.WaitForResult(); |
| 365 EXPECT_EQ(OK, rv); | 365 EXPECT_EQ(OK, rv); |
| 366 EXPECT_TRUE(user_sock_->IsConnected()); | 366 EXPECT_TRUE(user_sock_->IsConnected()); |
| 367 EXPECT_EQ(SOCKSClientSocket::kSOCKS4a, user_sock_->socks_version_); | 367 EXPECT_EQ(SOCKSClientSocket::kSOCKS4a, user_sock_->socks_version_); |
| 368 EXPECT_TRUE(LogContainsEndEvent( | 368 EXPECT_TRUE(LogContainsEndEvent( |
| 369 log.entries(), -1, NetLog::TYPE_SOCKS_CONNECT)); | 369 log.entries(), -1, NetLog::TYPE_SOCKS_CONNECT)); |
| 370 } | 370 } |
| 371 | 371 |
| 372 // Calls Disconnect() while a host resolve is in progress. The outstanding host | 372 // Calls Disconnect() while a host resolve is in progress. The outstanding host |
| 373 // resolve should be cancelled. | 373 // resolve should be cancelled. |
| 374 TEST_F(SOCKSClientSocketTest, DisconnectWhileHostResolveInProgress) { | 374 TEST_F(SOCKSClientSocketTest, DisconnectWhileHostResolveInProgress) { |
| 375 scoped_refptr<HangingHostResolver> hanging_resolver = | 375 scoped_refptr<HangingHostResolver> hanging_resolver = |
| 376 new HangingHostResolver(); | 376 new HangingHostResolver(); |
| 377 | 377 |
| 378 // Doesn't matter what the socket data is, we will never use it -- garbage. | 378 // Doesn't matter what the socket data is, we will never use it -- garbage. |
| 379 MockWrite data_writes[] = { MockWrite(false, "", 0) }; | 379 MockWrite data_writes[] = { MockWrite(false, "", 0) }; |
| 380 MockRead data_reads[] = { MockRead(false, "", 0) }; | 380 MockRead data_reads[] = { MockRead(false, "", 0) }; |
| 381 | 381 |
| 382 user_sock_.reset(BuildMockSocket(data_reads, arraysize(data_reads), | 382 user_sock_.reset(BuildMockSocket(data_reads, arraysize(data_reads), |
| 383 data_writes, arraysize(data_writes), | 383 data_writes, arraysize(data_writes), |
| 384 hanging_resolver, "foo", 80)); | 384 hanging_resolver, "foo", 80, NULL)); |
| 385 | 385 |
| 386 // Start connecting (will get stuck waiting for the host to resolve). | 386 // Start connecting (will get stuck waiting for the host to resolve). |
| 387 int rv = user_sock_->Connect(&callback_, NULL); | 387 int rv = user_sock_->Connect(&callback_); |
| 388 EXPECT_EQ(ERR_IO_PENDING, rv); | 388 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 389 | 389 |
| 390 EXPECT_FALSE(user_sock_->IsConnected()); | 390 EXPECT_FALSE(user_sock_->IsConnected()); |
| 391 EXPECT_FALSE(user_sock_->IsConnectedAndIdle()); | 391 EXPECT_FALSE(user_sock_->IsConnectedAndIdle()); |
| 392 | 392 |
| 393 // The host resolver should have received the resolve request. | 393 // The host resolver should have received the resolve request. |
| 394 EXPECT_TRUE(hanging_resolver->HasOutstandingRequest()); | 394 EXPECT_TRUE(hanging_resolver->HasOutstandingRequest()); |
| 395 | 395 |
| 396 // Disconnect the SOCKS socket -- this should cancel the outstanding resolve. | 396 // Disconnect the SOCKS socket -- this should cancel the outstanding resolve. |
| 397 user_sock_->Disconnect(); | 397 user_sock_->Disconnect(); |
| 398 | 398 |
| 399 EXPECT_FALSE(hanging_resolver->HasOutstandingRequest()); | 399 EXPECT_FALSE(hanging_resolver->HasOutstandingRequest()); |
| 400 | 400 |
| 401 EXPECT_FALSE(user_sock_->IsConnected()); | 401 EXPECT_FALSE(user_sock_->IsConnected()); |
| 402 EXPECT_FALSE(user_sock_->IsConnectedAndIdle()); | 402 EXPECT_FALSE(user_sock_->IsConnectedAndIdle()); |
| 403 } | 403 } |
| 404 | 404 |
| 405 } // namespace net | 405 } // namespace net |
| OLD | NEW |