| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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/load_log.h" | 8 #include "net/base/load_log.h" |
| 9 #include "net/base/load_log_unittest.h" | 9 #include "net/base/load_log_unittest.h" |
| 10 #include "net/base/mock_host_resolver.h" | 10 #include "net/base/mock_host_resolver.h" |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 MockRead data_reads[] = { | 86 MockRead data_reads[] = { |
| 87 MockRead(true, kSOCKSOkReply, arraysize(kSOCKSOkReply)), | 87 MockRead(true, kSOCKSOkReply, arraysize(kSOCKSOkReply)), |
| 88 MockRead(true, payload_read.data(), payload_read.size()) }; | 88 MockRead(true, payload_read.data(), payload_read.size()) }; |
| 89 | 89 |
| 90 user_sock_.reset(BuildMockSocket(data_reads, data_writes, "localhost", 80)); | 90 user_sock_.reset(BuildMockSocket(data_reads, data_writes, "localhost", 80)); |
| 91 | 91 |
| 92 // At this state the TCP connection is completed but not the SOCKS handshake. | 92 // At this state the TCP connection is completed but not the SOCKS handshake. |
| 93 EXPECT_TRUE(tcp_sock_->IsConnected()); | 93 EXPECT_TRUE(tcp_sock_->IsConnected()); |
| 94 EXPECT_FALSE(user_sock_->IsConnected()); | 94 EXPECT_FALSE(user_sock_->IsConnected()); |
| 95 | 95 |
| 96 scoped_refptr<LoadLog> log(new LoadLog); | 96 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded)); |
| 97 int rv = user_sock_->Connect(&callback_, log); | 97 int rv = user_sock_->Connect(&callback_, log); |
| 98 EXPECT_EQ(ERR_IO_PENDING, rv); | 98 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 99 EXPECT_TRUE( | 99 EXPECT_TRUE( |
| 100 LogContains(*log, 0, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_BEGIN)); | 100 LogContains(*log, 0, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_BEGIN)); |
| 101 EXPECT_FALSE(user_sock_->IsConnected()); | 101 EXPECT_FALSE(user_sock_->IsConnected()); |
| 102 rv = callback_.WaitForResult(); | 102 rv = callback_.WaitForResult(); |
| 103 | 103 |
| 104 EXPECT_EQ(OK, rv); | 104 EXPECT_EQ(OK, rv); |
| 105 EXPECT_TRUE(user_sock_->IsConnected()); | 105 EXPECT_TRUE(user_sock_->IsConnected()); |
| 106 EXPECT_EQ(SOCKSClientSocket::kSOCKS4, user_sock_->socks_version_); | 106 EXPECT_EQ(SOCKSClientSocket::kSOCKS4, user_sock_->socks_version_); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 | 147 |
| 148 //--------------------------------------- | 148 //--------------------------------------- |
| 149 | 149 |
| 150 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { | 150 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { |
| 151 MockWrite data_writes[] = { | 151 MockWrite data_writes[] = { |
| 152 MockWrite(false, kSOCKSOkRequest, arraysize(kSOCKSOkRequest)) }; | 152 MockWrite(false, kSOCKSOkRequest, arraysize(kSOCKSOkRequest)) }; |
| 153 MockRead data_reads[] = { | 153 MockRead data_reads[] = { |
| 154 MockRead(false, tests[i].fail_reply, arraysize(tests[i].fail_reply)) }; | 154 MockRead(false, tests[i].fail_reply, arraysize(tests[i].fail_reply)) }; |
| 155 | 155 |
| 156 user_sock_.reset(BuildMockSocket(data_reads, data_writes, "localhost", 80)); | 156 user_sock_.reset(BuildMockSocket(data_reads, data_writes, "localhost", 80)); |
| 157 scoped_refptr<LoadLog> log(new LoadLog); | 157 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded)); |
| 158 | 158 |
| 159 int rv = user_sock_->Connect(&callback_, log); | 159 int rv = user_sock_->Connect(&callback_, log); |
| 160 EXPECT_EQ(ERR_IO_PENDING, rv); | 160 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 161 EXPECT_TRUE(LogContains( | 161 EXPECT_TRUE(LogContains( |
| 162 *log, 0, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_BEGIN)); | 162 *log, 0, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_BEGIN)); |
| 163 rv = callback_.WaitForResult(); | 163 rv = callback_.WaitForResult(); |
| 164 EXPECT_EQ(tests[i].fail_code, rv); | 164 EXPECT_EQ(tests[i].fail_code, rv); |
| 165 EXPECT_FALSE(user_sock_->IsConnected()); | 165 EXPECT_FALSE(user_sock_->IsConnected()); |
| 166 EXPECT_TRUE(tcp_sock_->IsConnected()); | 166 EXPECT_TRUE(tcp_sock_->IsConnected()); |
| 167 EXPECT_TRUE(LogContains( | 167 EXPECT_TRUE(LogContains( |
| 168 *log, -1, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_END)); | 168 *log, -1, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_END)); |
| 169 } | 169 } |
| 170 } | 170 } |
| 171 | 171 |
| 172 // Tests scenario when the server sends the handshake response in | 172 // Tests scenario when the server sends the handshake response in |
| 173 // more than one packet. | 173 // more than one packet. |
| 174 TEST_F(SOCKSClientSocketTest, PartialServerReads) { | 174 TEST_F(SOCKSClientSocketTest, PartialServerReads) { |
| 175 const char kSOCKSPartialReply1[] = { 0x00 }; | 175 const char kSOCKSPartialReply1[] = { 0x00 }; |
| 176 const char kSOCKSPartialReply2[] = { 0x5A, 0x00, 0x00, 0, 0, 0, 0 }; | 176 const char kSOCKSPartialReply2[] = { 0x5A, 0x00, 0x00, 0, 0, 0, 0 }; |
| 177 | 177 |
| 178 MockWrite data_writes[] = { | 178 MockWrite data_writes[] = { |
| 179 MockWrite(true, kSOCKSOkRequest, arraysize(kSOCKSOkRequest)) }; | 179 MockWrite(true, kSOCKSOkRequest, arraysize(kSOCKSOkRequest)) }; |
| 180 MockRead data_reads[] = { | 180 MockRead data_reads[] = { |
| 181 MockRead(true, kSOCKSPartialReply1, arraysize(kSOCKSPartialReply1)), | 181 MockRead(true, kSOCKSPartialReply1, arraysize(kSOCKSPartialReply1)), |
| 182 MockRead(true, kSOCKSPartialReply2, arraysize(kSOCKSPartialReply2)) }; | 182 MockRead(true, kSOCKSPartialReply2, arraysize(kSOCKSPartialReply2)) }; |
| 183 | 183 |
| 184 user_sock_.reset(BuildMockSocket(data_reads, data_writes, "localhost", 80)); | 184 user_sock_.reset(BuildMockSocket(data_reads, data_writes, "localhost", 80)); |
| 185 scoped_refptr<LoadLog> log(new LoadLog); | 185 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded)); |
| 186 | 186 |
| 187 int rv = user_sock_->Connect(&callback_, log); | 187 int rv = user_sock_->Connect(&callback_, log); |
| 188 EXPECT_EQ(ERR_IO_PENDING, rv); | 188 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 189 EXPECT_TRUE(LogContains( | 189 EXPECT_TRUE(LogContains( |
| 190 *log, 0, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_BEGIN)); | 190 *log, 0, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_BEGIN)); |
| 191 rv = callback_.WaitForResult(); | 191 rv = callback_.WaitForResult(); |
| 192 EXPECT_EQ(OK, rv); | 192 EXPECT_EQ(OK, rv); |
| 193 EXPECT_TRUE(user_sock_->IsConnected()); | 193 EXPECT_TRUE(user_sock_->IsConnected()); |
| 194 EXPECT_TRUE(LogContains( | 194 EXPECT_TRUE(LogContains( |
| 195 *log, -1, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_END)); | 195 *log, -1, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_END)); |
| 196 } | 196 } |
| 197 | 197 |
| 198 // Tests scenario when the client sends the handshake request in | 198 // Tests scenario when the client sends the handshake request in |
| 199 // more than one packet. | 199 // more than one packet. |
| 200 TEST_F(SOCKSClientSocketTest, PartialClientWrites) { | 200 TEST_F(SOCKSClientSocketTest, PartialClientWrites) { |
| 201 const char kSOCKSPartialRequest1[] = { 0x04, 0x01 }; | 201 const char kSOCKSPartialRequest1[] = { 0x04, 0x01 }; |
| 202 const char kSOCKSPartialRequest2[] = { 0x00, 0x50, 127, 0, 0, 1, 0 }; | 202 const char kSOCKSPartialRequest2[] = { 0x00, 0x50, 127, 0, 0, 1, 0 }; |
| 203 | 203 |
| 204 MockWrite data_writes[] = { | 204 MockWrite data_writes[] = { |
| 205 MockWrite(true, arraysize(kSOCKSPartialRequest1)), | 205 MockWrite(true, arraysize(kSOCKSPartialRequest1)), |
| 206 // simulate some empty writes | 206 // simulate some empty writes |
| 207 MockWrite(true, 0), | 207 MockWrite(true, 0), |
| 208 MockWrite(true, 0), | 208 MockWrite(true, 0), |
| 209 MockWrite(true, kSOCKSPartialRequest2, | 209 MockWrite(true, kSOCKSPartialRequest2, |
| 210 arraysize(kSOCKSPartialRequest2)) }; | 210 arraysize(kSOCKSPartialRequest2)) }; |
| 211 MockRead data_reads[] = { | 211 MockRead data_reads[] = { |
| 212 MockRead(true, kSOCKSOkReply, arraysize(kSOCKSOkReply)) }; | 212 MockRead(true, kSOCKSOkReply, arraysize(kSOCKSOkReply)) }; |
| 213 | 213 |
| 214 user_sock_.reset(BuildMockSocket(data_reads, data_writes, "localhost", 80)); | 214 user_sock_.reset(BuildMockSocket(data_reads, data_writes, "localhost", 80)); |
| 215 scoped_refptr<LoadLog> log(new LoadLog); | 215 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded)); |
| 216 | 216 |
| 217 int rv = user_sock_->Connect(&callback_, log); | 217 int rv = user_sock_->Connect(&callback_, log); |
| 218 EXPECT_EQ(ERR_IO_PENDING, rv); | 218 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 219 EXPECT_TRUE(LogContains( | 219 EXPECT_TRUE(LogContains( |
| 220 *log, 0, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_BEGIN)); | 220 *log, 0, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_BEGIN)); |
| 221 rv = callback_.WaitForResult(); | 221 rv = callback_.WaitForResult(); |
| 222 EXPECT_EQ(OK, rv); | 222 EXPECT_EQ(OK, rv); |
| 223 EXPECT_TRUE(user_sock_->IsConnected()); | 223 EXPECT_TRUE(user_sock_->IsConnected()); |
| 224 EXPECT_TRUE(LogContains( | 224 EXPECT_TRUE(LogContains( |
| 225 *log, -1, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_END)); | 225 *log, -1, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_END)); |
| 226 } | 226 } |
| 227 | 227 |
| 228 // Tests the case when the server sends a smaller sized handshake data | 228 // Tests the case when the server sends a smaller sized handshake data |
| 229 // and closes the connection. | 229 // and closes the connection. |
| 230 TEST_F(SOCKSClientSocketTest, FailedSocketRead) { | 230 TEST_F(SOCKSClientSocketTest, FailedSocketRead) { |
| 231 MockWrite data_writes[] = { | 231 MockWrite data_writes[] = { |
| 232 MockWrite(true, kSOCKSOkRequest, arraysize(kSOCKSOkRequest)) }; | 232 MockWrite(true, kSOCKSOkRequest, arraysize(kSOCKSOkRequest)) }; |
| 233 MockRead data_reads[] = { | 233 MockRead data_reads[] = { |
| 234 MockRead(true, kSOCKSOkReply, arraysize(kSOCKSOkReply) - 2), | 234 MockRead(true, kSOCKSOkReply, arraysize(kSOCKSOkReply) - 2), |
| 235 // close connection unexpectedly | 235 // close connection unexpectedly |
| 236 MockRead(false, 0) }; | 236 MockRead(false, 0) }; |
| 237 | 237 |
| 238 user_sock_.reset(BuildMockSocket(data_reads, data_writes, "localhost", 80)); | 238 user_sock_.reset(BuildMockSocket(data_reads, data_writes, "localhost", 80)); |
| 239 scoped_refptr<LoadLog> log(new LoadLog); | 239 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded)); |
| 240 | 240 |
| 241 int rv = user_sock_->Connect(&callback_, log); | 241 int rv = user_sock_->Connect(&callback_, log); |
| 242 EXPECT_EQ(ERR_IO_PENDING, rv); | 242 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 243 EXPECT_TRUE(LogContains( | 243 EXPECT_TRUE(LogContains( |
| 244 *log, 0, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_BEGIN)); | 244 *log, 0, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_BEGIN)); |
| 245 rv = callback_.WaitForResult(); | 245 rv = callback_.WaitForResult(); |
| 246 EXPECT_EQ(ERR_CONNECTION_CLOSED, rv); | 246 EXPECT_EQ(ERR_CONNECTION_CLOSED, rv); |
| 247 EXPECT_FALSE(user_sock_->IsConnected()); | 247 EXPECT_FALSE(user_sock_->IsConnected()); |
| 248 EXPECT_TRUE(LogContains( | 248 EXPECT_TRUE(LogContains( |
| 249 *log, -1, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_END)); | 249 *log, -1, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_END)); |
| 250 } | 250 } |
| 251 | 251 |
| 252 // Tries to connect to an unknown DNS and on failure should revert to SOCKS4A. | 252 // Tries to connect to an unknown DNS and on failure should revert to SOCKS4A. |
| 253 TEST_F(SOCKSClientSocketTest, SOCKS4AFailedDNS) { | 253 TEST_F(SOCKSClientSocketTest, SOCKS4AFailedDNS) { |
| 254 const char hostname[] = "unresolved.ipv4.address"; | 254 const char hostname[] = "unresolved.ipv4.address"; |
| 255 | 255 |
| 256 host_resolver_->rules()->AddSimulatedFailure(hostname); | 256 host_resolver_->rules()->AddSimulatedFailure(hostname); |
| 257 | 257 |
| 258 std::string request(kSOCKS4aInitialRequest, | 258 std::string request(kSOCKS4aInitialRequest, |
| 259 arraysize(kSOCKS4aInitialRequest)); | 259 arraysize(kSOCKS4aInitialRequest)); |
| 260 request.append(hostname, arraysize(hostname)); | 260 request.append(hostname, arraysize(hostname)); |
| 261 | 261 |
| 262 MockWrite data_writes[] = { | 262 MockWrite data_writes[] = { |
| 263 MockWrite(false, request.data(), request.size()) }; | 263 MockWrite(false, request.data(), request.size()) }; |
| 264 MockRead data_reads[] = { | 264 MockRead data_reads[] = { |
| 265 MockRead(false, kSOCKSOkReply, arraysize(kSOCKSOkReply)) }; | 265 MockRead(false, kSOCKSOkReply, arraysize(kSOCKSOkReply)) }; |
| 266 | 266 |
| 267 user_sock_.reset(BuildMockSocket(data_reads, data_writes, hostname, 80)); | 267 user_sock_.reset(BuildMockSocket(data_reads, data_writes, hostname, 80)); |
| 268 scoped_refptr<LoadLog> log(new LoadLog); | 268 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded)); |
| 269 | 269 |
| 270 int rv = user_sock_->Connect(&callback_, log); | 270 int rv = user_sock_->Connect(&callback_, log); |
| 271 EXPECT_EQ(ERR_IO_PENDING, rv); | 271 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 272 EXPECT_TRUE(LogContains( | 272 EXPECT_TRUE(LogContains( |
| 273 *log, 0, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_BEGIN)); | 273 *log, 0, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_BEGIN)); |
| 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 EXPECT_EQ(SOCKSClientSocket::kSOCKS4a, user_sock_->socks_version_); | 277 EXPECT_EQ(SOCKSClientSocket::kSOCKS4a, user_sock_->socks_version_); |
| 278 EXPECT_TRUE(LogContains( | 278 EXPECT_TRUE(LogContains( |
| (...skipping 10 matching lines...) Expand all Loading... |
| 289 std::string request(kSOCKS4aInitialRequest, | 289 std::string request(kSOCKS4aInitialRequest, |
| 290 arraysize(kSOCKS4aInitialRequest)); | 290 arraysize(kSOCKS4aInitialRequest)); |
| 291 request.append(hostname, arraysize(hostname)); | 291 request.append(hostname, arraysize(hostname)); |
| 292 | 292 |
| 293 MockWrite data_writes[] = { | 293 MockWrite data_writes[] = { |
| 294 MockWrite(false, request.data(), request.size()) }; | 294 MockWrite(false, request.data(), request.size()) }; |
| 295 MockRead data_reads[] = { | 295 MockRead data_reads[] = { |
| 296 MockRead(false, kSOCKSOkReply, arraysize(kSOCKSOkReply)) }; | 296 MockRead(false, kSOCKSOkReply, arraysize(kSOCKSOkReply)) }; |
| 297 | 297 |
| 298 user_sock_.reset(BuildMockSocket(data_reads, data_writes, hostname, 80)); | 298 user_sock_.reset(BuildMockSocket(data_reads, data_writes, hostname, 80)); |
| 299 scoped_refptr<LoadLog> log(new LoadLog); | 299 scoped_refptr<LoadLog> log(new LoadLog(LoadLog::kUnbounded)); |
| 300 | 300 |
| 301 int rv = user_sock_->Connect(&callback_, log); | 301 int rv = user_sock_->Connect(&callback_, log); |
| 302 EXPECT_EQ(ERR_IO_PENDING, rv); | 302 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 303 EXPECT_TRUE(LogContains( | 303 EXPECT_TRUE(LogContains( |
| 304 *log, 0, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_BEGIN)); | 304 *log, 0, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_BEGIN)); |
| 305 rv = callback_.WaitForResult(); | 305 rv = callback_.WaitForResult(); |
| 306 EXPECT_EQ(OK, rv); | 306 EXPECT_EQ(OK, rv); |
| 307 EXPECT_TRUE(user_sock_->IsConnected()); | 307 EXPECT_TRUE(user_sock_->IsConnected()); |
| 308 EXPECT_EQ(SOCKSClientSocket::kSOCKS4a, user_sock_->socks_version_); | 308 EXPECT_EQ(SOCKSClientSocket::kSOCKS4a, user_sock_->socks_version_); |
| 309 EXPECT_TRUE(LogContains( | 309 EXPECT_TRUE(LogContains( |
| 310 *log, -1, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_END)); | 310 *log, -1, LoadLog::TYPE_SOCKS_CONNECT, LoadLog::PHASE_END)); |
| 311 } | 311 } |
| 312 | 312 |
| 313 } // namespace net | 313 } // namespace net |
| OLD | NEW |