| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/socks5_client_socket.h" | 5 #include "net/socket/socks5_client_socket.h" |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
| 9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
| 10 #include "base/format_macros.h" | 10 #include "base/format_macros.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 const uint8 SOCKS5ClientSocket::kTunnelCommand = 0x01; | 24 const uint8 SOCKS5ClientSocket::kTunnelCommand = 0x01; |
| 25 const uint8 SOCKS5ClientSocket::kNullByte = 0x00; | 25 const uint8 SOCKS5ClientSocket::kNullByte = 0x00; |
| 26 | 26 |
| 27 COMPILE_ASSERT(sizeof(struct in_addr) == 4, incorrect_system_size_of_IPv4); | 27 COMPILE_ASSERT(sizeof(struct in_addr) == 4, incorrect_system_size_of_IPv4); |
| 28 COMPILE_ASSERT(sizeof(struct in6_addr) == 16, incorrect_system_size_of_IPv6); | 28 COMPILE_ASSERT(sizeof(struct in6_addr) == 16, incorrect_system_size_of_IPv6); |
| 29 | 29 |
| 30 SOCKS5ClientSocket::SOCKS5ClientSocket( | 30 SOCKS5ClientSocket::SOCKS5ClientSocket( |
| 31 ClientSocketHandle* transport_socket, | 31 ClientSocketHandle* transport_socket, |
| 32 const HostResolver::RequestInfo& req_info) | 32 const HostResolver::RequestInfo& req_info) |
| 33 : ALLOW_THIS_IN_INITIALIZER_LIST( | 33 : ALLOW_THIS_IN_INITIALIZER_LIST( |
| 34 io_callback_(this, &SOCKS5ClientSocket::OnIOComplete)), | 34 io_callback_(base::Bind(&SOCKS5ClientSocket::OnIOComplete, |
| 35 base::Unretained(this)))), |
| 35 transport_(transport_socket), | 36 transport_(transport_socket), |
| 36 next_state_(STATE_NONE), | 37 next_state_(STATE_NONE), |
| 37 old_user_callback_(NULL), | |
| 38 completed_handshake_(false), | 38 completed_handshake_(false), |
| 39 bytes_sent_(0), | 39 bytes_sent_(0), |
| 40 bytes_received_(0), | 40 bytes_received_(0), |
| 41 read_header_size(kReadHeaderSize), | 41 read_header_size(kReadHeaderSize), |
| 42 host_request_info_(req_info), | 42 host_request_info_(req_info), |
| 43 net_log_(transport_socket->socket()->NetLog()) { | 43 net_log_(transport_socket->socket()->NetLog()) { |
| 44 } | 44 } |
| 45 | 45 |
| 46 SOCKS5ClientSocket::SOCKS5ClientSocket( | 46 SOCKS5ClientSocket::SOCKS5ClientSocket( |
| 47 StreamSocket* transport_socket, | 47 StreamSocket* transport_socket, |
| 48 const HostResolver::RequestInfo& req_info) | 48 const HostResolver::RequestInfo& req_info) |
| 49 : ALLOW_THIS_IN_INITIALIZER_LIST( | 49 : ALLOW_THIS_IN_INITIALIZER_LIST( |
| 50 io_callback_(this, &SOCKS5ClientSocket::OnIOComplete)), | 50 io_callback_(base::Bind(&SOCKS5ClientSocket::OnIOComplete, |
| 51 base::Unretained(this)))), |
| 51 transport_(new ClientSocketHandle()), | 52 transport_(new ClientSocketHandle()), |
| 52 next_state_(STATE_NONE), | 53 next_state_(STATE_NONE), |
| 53 old_user_callback_(NULL), | |
| 54 completed_handshake_(false), | 54 completed_handshake_(false), |
| 55 bytes_sent_(0), | 55 bytes_sent_(0), |
| 56 bytes_received_(0), | 56 bytes_received_(0), |
| 57 read_header_size(kReadHeaderSize), | 57 read_header_size(kReadHeaderSize), |
| 58 host_request_info_(req_info), | 58 host_request_info_(req_info), |
| 59 net_log_(transport_socket->NetLog()) { | 59 net_log_(transport_socket->NetLog()) { |
| 60 transport_->set_socket(transport_socket); | 60 transport_->set_socket(transport_socket); |
| 61 } | 61 } |
| 62 | 62 |
| 63 SOCKS5ClientSocket::~SOCKS5ClientSocket() { | 63 SOCKS5ClientSocket::~SOCKS5ClientSocket() { |
| 64 Disconnect(); | 64 Disconnect(); |
| 65 } | 65 } |
| 66 | 66 |
| 67 int SOCKS5ClientSocket::Connect(OldCompletionCallback* callback) { | 67 int SOCKS5ClientSocket::Connect(const CompletionCallback& callback) { |
| 68 DCHECK(transport_.get()); | 68 DCHECK(transport_.get()); |
| 69 DCHECK(transport_->socket()); | 69 DCHECK(transport_->socket()); |
| 70 DCHECK_EQ(STATE_NONE, next_state_); | 70 DCHECK_EQ(STATE_NONE, next_state_); |
| 71 DCHECK(!old_user_callback_ && user_callback_.is_null()); | 71 DCHECK(user_callback_.is_null()); |
| 72 | 72 |
| 73 // If already connected, then just return OK. | 73 // If already connected, then just return OK. |
| 74 if (completed_handshake_) | 74 if (completed_handshake_) |
| 75 return OK; | 75 return OK; |
| 76 | 76 |
| 77 net_log_.BeginEvent(NetLog::TYPE_SOCKS5_CONNECT, NULL); | 77 net_log_.BeginEvent(NetLog::TYPE_SOCKS5_CONNECT, NULL); |
| 78 | 78 |
| 79 next_state_ = STATE_GREET_WRITE; | 79 next_state_ = STATE_GREET_WRITE; |
| 80 buffer_.clear(); | 80 buffer_.clear(); |
| 81 | 81 |
| 82 int rv = DoLoop(OK); | 82 int rv = DoLoop(OK); |
| 83 if (rv == ERR_IO_PENDING) { | 83 if (rv == ERR_IO_PENDING) { |
| 84 old_user_callback_ = callback; | 84 user_callback_ = callback; |
| 85 } else { | 85 } else { |
| 86 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SOCKS5_CONNECT, rv); | 86 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SOCKS5_CONNECT, rv); |
| 87 } | 87 } |
| 88 return rv; | 88 return rv; |
| 89 } | 89 } |
| 90 int SOCKS5ClientSocket::Connect(const CompletionCallback& callback) { | |
| 91 DCHECK(transport_.get()); | |
| 92 DCHECK(transport_->socket()); | |
| 93 DCHECK_EQ(STATE_NONE, next_state_); | |
| 94 DCHECK(!old_user_callback_ && user_callback_.is_null()); | |
| 95 | |
| 96 // If already connected, then just return OK. | |
| 97 if (completed_handshake_) | |
| 98 return OK; | |
| 99 | |
| 100 net_log_.BeginEvent(NetLog::TYPE_SOCKS5_CONNECT, NULL); | |
| 101 | |
| 102 next_state_ = STATE_GREET_WRITE; | |
| 103 buffer_.clear(); | |
| 104 | |
| 105 int rv = DoLoop(OK); | |
| 106 if (rv == ERR_IO_PENDING) | |
| 107 user_callback_ = callback; | |
| 108 else | |
| 109 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SOCKS5_CONNECT, rv); | |
| 110 | |
| 111 return rv; | |
| 112 } | |
| 113 | 90 |
| 114 void SOCKS5ClientSocket::Disconnect() { | 91 void SOCKS5ClientSocket::Disconnect() { |
| 115 completed_handshake_ = false; | 92 completed_handshake_ = false; |
| 116 transport_->socket()->Disconnect(); | 93 transport_->socket()->Disconnect(); |
| 117 | 94 |
| 118 // Reset other states to make sure they aren't mistakenly used later. | 95 // Reset other states to make sure they aren't mistakenly used later. |
| 119 // These are the states initialized by Connect(). | 96 // These are the states initialized by Connect(). |
| 120 next_state_ = STATE_NONE; | 97 next_state_ = STATE_NONE; |
| 121 old_user_callback_ = NULL; | |
| 122 user_callback_.Reset(); | 98 user_callback_.Reset(); |
| 123 } | 99 } |
| 124 | 100 |
| 125 bool SOCKS5ClientSocket::IsConnected() const { | 101 bool SOCKS5ClientSocket::IsConnected() const { |
| 126 return completed_handshake_ && transport_->socket()->IsConnected(); | 102 return completed_handshake_ && transport_->socket()->IsConnected(); |
| 127 } | 103 } |
| 128 | 104 |
| 129 bool SOCKS5ClientSocket::IsConnectedAndIdle() const { | 105 bool SOCKS5ClientSocket::IsConnectedAndIdle() const { |
| 130 return completed_handshake_ && transport_->socket()->IsConnectedAndIdle(); | 106 return completed_handshake_ && transport_->socket()->IsConnectedAndIdle(); |
| 131 } | 107 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 if (transport_.get() && transport_->socket()) { | 154 if (transport_.get() && transport_->socket()) { |
| 179 return transport_->socket()->GetConnectTimeMicros(); | 155 return transport_->socket()->GetConnectTimeMicros(); |
| 180 } | 156 } |
| 181 NOTREACHED(); | 157 NOTREACHED(); |
| 182 return base::TimeDelta::FromMicroseconds(-1); | 158 return base::TimeDelta::FromMicroseconds(-1); |
| 183 } | 159 } |
| 184 | 160 |
| 185 // Read is called by the transport layer above to read. This can only be done | 161 // Read is called by the transport layer above to read. This can only be done |
| 186 // if the SOCKS handshake is complete. | 162 // if the SOCKS handshake is complete. |
| 187 int SOCKS5ClientSocket::Read(IOBuffer* buf, int buf_len, | 163 int SOCKS5ClientSocket::Read(IOBuffer* buf, int buf_len, |
| 188 OldCompletionCallback* callback) { | |
| 189 DCHECK(completed_handshake_); | |
| 190 DCHECK_EQ(STATE_NONE, next_state_); | |
| 191 DCHECK(!old_user_callback_ && user_callback_.is_null()); | |
| 192 | |
| 193 return transport_->socket()->Read(buf, buf_len, callback); | |
| 194 } | |
| 195 int SOCKS5ClientSocket::Read(IOBuffer* buf, int buf_len, | |
| 196 const CompletionCallback& callback) { | 164 const CompletionCallback& callback) { |
| 197 DCHECK(completed_handshake_); | 165 DCHECK(completed_handshake_); |
| 198 DCHECK_EQ(STATE_NONE, next_state_); | 166 DCHECK_EQ(STATE_NONE, next_state_); |
| 199 DCHECK(!old_user_callback_ && user_callback_.is_null()); | 167 DCHECK(user_callback_.is_null()); |
| 200 | 168 |
| 201 return transport_->socket()->Read(buf, buf_len, callback); | 169 return transport_->socket()->Read(buf, buf_len, callback); |
| 202 } | 170 } |
| 203 | 171 |
| 204 // Write is called by the transport layer. This can only be done if the | 172 // Write is called by the transport layer. This can only be done if the |
| 205 // SOCKS handshake is complete. | 173 // SOCKS handshake is complete. |
| 206 int SOCKS5ClientSocket::Write(IOBuffer* buf, int buf_len, | 174 int SOCKS5ClientSocket::Write(IOBuffer* buf, int buf_len, |
| 207 OldCompletionCallback* callback) { | 175 const CompletionCallback& callback) { |
| 208 DCHECK(completed_handshake_); | 176 DCHECK(completed_handshake_); |
| 209 DCHECK_EQ(STATE_NONE, next_state_); | 177 DCHECK_EQ(STATE_NONE, next_state_); |
| 210 DCHECK(!old_user_callback_); | 178 DCHECK(user_callback_.is_null()); |
| 211 | 179 |
| 212 return transport_->socket()->Write(buf, buf_len, callback); | 180 return transport_->socket()->Write(buf, buf_len, callback); |
| 213 } | 181 } |
| 214 | 182 |
| 215 bool SOCKS5ClientSocket::SetReceiveBufferSize(int32 size) { | 183 bool SOCKS5ClientSocket::SetReceiveBufferSize(int32 size) { |
| 216 return transport_->socket()->SetReceiveBufferSize(size); | 184 return transport_->socket()->SetReceiveBufferSize(size); |
| 217 } | 185 } |
| 218 | 186 |
| 219 bool SOCKS5ClientSocket::SetSendBufferSize(int32 size) { | 187 bool SOCKS5ClientSocket::SetSendBufferSize(int32 size) { |
| 220 return transport_->socket()->SetSendBufferSize(size); | 188 return transport_->socket()->SetSendBufferSize(size); |
| 221 } | 189 } |
| 222 | 190 |
| 223 void SOCKS5ClientSocket::DoCallback(int result) { | 191 void SOCKS5ClientSocket::DoCallback(int result) { |
| 224 DCHECK_NE(ERR_IO_PENDING, result); | 192 DCHECK_NE(ERR_IO_PENDING, result); |
| 225 DCHECK(old_user_callback_ || !user_callback_.is_null()); | 193 DCHECK(!user_callback_.is_null()); |
| 226 | 194 |
| 227 // Since Run() may result in Read being called, | 195 // Since Run() may result in Read being called, |
| 228 // clear user_callback_ up front. | 196 // clear user_callback_ up front. |
| 229 if (old_user_callback_) { | 197 CompletionCallback c = user_callback_; |
| 230 OldCompletionCallback* c = old_user_callback_; | 198 user_callback_.Reset(); |
| 231 old_user_callback_ = NULL; | 199 c.Run(result); |
| 232 c->Run(result); | |
| 233 } else { | |
| 234 CompletionCallback c = user_callback_; | |
| 235 user_callback_.Reset(); | |
| 236 c.Run(result); | |
| 237 } | |
| 238 } | 200 } |
| 239 | 201 |
| 240 void SOCKS5ClientSocket::OnIOComplete(int result) { | 202 void SOCKS5ClientSocket::OnIOComplete(int result) { |
| 241 DCHECK_NE(STATE_NONE, next_state_); | 203 DCHECK_NE(STATE_NONE, next_state_); |
| 242 int rv = DoLoop(result); | 204 int rv = DoLoop(result); |
| 243 if (rv != ERR_IO_PENDING) { | 205 if (rv != ERR_IO_PENDING) { |
| 244 net_log_.EndEvent(NetLog::TYPE_SOCKS5_CONNECT, NULL); | 206 net_log_.EndEvent(NetLog::TYPE_SOCKS5_CONNECT, NULL); |
| 245 DoCallback(rv); | 207 DoCallback(rv); |
| 246 } | 208 } |
| 247 } | 209 } |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 316 arraysize(kSOCKS5GreetWriteData)); | 278 arraysize(kSOCKS5GreetWriteData)); |
| 317 bytes_sent_ = 0; | 279 bytes_sent_ = 0; |
| 318 } | 280 } |
| 319 | 281 |
| 320 next_state_ = STATE_GREET_WRITE_COMPLETE; | 282 next_state_ = STATE_GREET_WRITE_COMPLETE; |
| 321 size_t handshake_buf_len = buffer_.size() - bytes_sent_; | 283 size_t handshake_buf_len = buffer_.size() - bytes_sent_; |
| 322 handshake_buf_ = new IOBuffer(handshake_buf_len); | 284 handshake_buf_ = new IOBuffer(handshake_buf_len); |
| 323 memcpy(handshake_buf_->data(), &buffer_.data()[bytes_sent_], | 285 memcpy(handshake_buf_->data(), &buffer_.data()[bytes_sent_], |
| 324 handshake_buf_len); | 286 handshake_buf_len); |
| 325 return transport_->socket()->Write(handshake_buf_, handshake_buf_len, | 287 return transport_->socket()->Write(handshake_buf_, handshake_buf_len, |
| 326 &io_callback_); | 288 io_callback_); |
| 327 } | 289 } |
| 328 | 290 |
| 329 int SOCKS5ClientSocket::DoGreetWriteComplete(int result) { | 291 int SOCKS5ClientSocket::DoGreetWriteComplete(int result) { |
| 330 if (result < 0) | 292 if (result < 0) |
| 331 return result; | 293 return result; |
| 332 | 294 |
| 333 bytes_sent_ += result; | 295 bytes_sent_ += result; |
| 334 if (bytes_sent_ == buffer_.size()) { | 296 if (bytes_sent_ == buffer_.size()) { |
| 335 buffer_.clear(); | 297 buffer_.clear(); |
| 336 bytes_received_ = 0; | 298 bytes_received_ = 0; |
| 337 next_state_ = STATE_GREET_READ; | 299 next_state_ = STATE_GREET_READ; |
| 338 } else { | 300 } else { |
| 339 next_state_ = STATE_GREET_WRITE; | 301 next_state_ = STATE_GREET_WRITE; |
| 340 } | 302 } |
| 341 return OK; | 303 return OK; |
| 342 } | 304 } |
| 343 | 305 |
| 344 int SOCKS5ClientSocket::DoGreetRead() { | 306 int SOCKS5ClientSocket::DoGreetRead() { |
| 345 next_state_ = STATE_GREET_READ_COMPLETE; | 307 next_state_ = STATE_GREET_READ_COMPLETE; |
| 346 size_t handshake_buf_len = kGreetReadHeaderSize - bytes_received_; | 308 size_t handshake_buf_len = kGreetReadHeaderSize - bytes_received_; |
| 347 handshake_buf_ = new IOBuffer(handshake_buf_len); | 309 handshake_buf_ = new IOBuffer(handshake_buf_len); |
| 348 return transport_->socket()->Read(handshake_buf_, handshake_buf_len, | 310 return transport_->socket()->Read(handshake_buf_, handshake_buf_len, |
| 349 &io_callback_); | 311 io_callback_); |
| 350 } | 312 } |
| 351 | 313 |
| 352 int SOCKS5ClientSocket::DoGreetReadComplete(int result) { | 314 int SOCKS5ClientSocket::DoGreetReadComplete(int result) { |
| 353 if (result < 0) | 315 if (result < 0) |
| 354 return result; | 316 return result; |
| 355 | 317 |
| 356 if (result == 0) { | 318 if (result == 0) { |
| 357 net_log_.AddEvent(NetLog::TYPE_SOCKS_UNEXPECTEDLY_CLOSED_DURING_GREETING, | 319 net_log_.AddEvent(NetLog::TYPE_SOCKS_UNEXPECTEDLY_CLOSED_DURING_GREETING, |
| 358 NULL); | 320 NULL); |
| 359 return ERR_SOCKS_CONNECTION_FAILED; | 321 return ERR_SOCKS_CONNECTION_FAILED; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 417 return rv; | 379 return rv; |
| 418 bytes_sent_ = 0; | 380 bytes_sent_ = 0; |
| 419 } | 381 } |
| 420 | 382 |
| 421 int handshake_buf_len = buffer_.size() - bytes_sent_; | 383 int handshake_buf_len = buffer_.size() - bytes_sent_; |
| 422 DCHECK_LT(0, handshake_buf_len); | 384 DCHECK_LT(0, handshake_buf_len); |
| 423 handshake_buf_ = new IOBuffer(handshake_buf_len); | 385 handshake_buf_ = new IOBuffer(handshake_buf_len); |
| 424 memcpy(handshake_buf_->data(), &buffer_[bytes_sent_], | 386 memcpy(handshake_buf_->data(), &buffer_[bytes_sent_], |
| 425 handshake_buf_len); | 387 handshake_buf_len); |
| 426 return transport_->socket()->Write(handshake_buf_, handshake_buf_len, | 388 return transport_->socket()->Write(handshake_buf_, handshake_buf_len, |
| 427 &io_callback_); | 389 io_callback_); |
| 428 } | 390 } |
| 429 | 391 |
| 430 int SOCKS5ClientSocket::DoHandshakeWriteComplete(int result) { | 392 int SOCKS5ClientSocket::DoHandshakeWriteComplete(int result) { |
| 431 if (result < 0) | 393 if (result < 0) |
| 432 return result; | 394 return result; |
| 433 | 395 |
| 434 // We ignore the case when result is 0, since the underlying Write | 396 // We ignore the case when result is 0, since the underlying Write |
| 435 // may return spurious writes while waiting on the socket. | 397 // may return spurious writes while waiting on the socket. |
| 436 | 398 |
| 437 bytes_sent_ += result; | 399 bytes_sent_ += result; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 451 next_state_ = STATE_HANDSHAKE_READ_COMPLETE; | 413 next_state_ = STATE_HANDSHAKE_READ_COMPLETE; |
| 452 | 414 |
| 453 if (buffer_.empty()) { | 415 if (buffer_.empty()) { |
| 454 bytes_received_ = 0; | 416 bytes_received_ = 0; |
| 455 read_header_size = kReadHeaderSize; | 417 read_header_size = kReadHeaderSize; |
| 456 } | 418 } |
| 457 | 419 |
| 458 int handshake_buf_len = read_header_size - bytes_received_; | 420 int handshake_buf_len = read_header_size - bytes_received_; |
| 459 handshake_buf_ = new IOBuffer(handshake_buf_len); | 421 handshake_buf_ = new IOBuffer(handshake_buf_len); |
| 460 return transport_->socket()->Read(handshake_buf_, handshake_buf_len, | 422 return transport_->socket()->Read(handshake_buf_, handshake_buf_len, |
| 461 &io_callback_); | 423 io_callback_); |
| 462 } | 424 } |
| 463 | 425 |
| 464 int SOCKS5ClientSocket::DoHandshakeReadComplete(int result) { | 426 int SOCKS5ClientSocket::DoHandshakeReadComplete(int result) { |
| 465 if (result < 0) | 427 if (result < 0) |
| 466 return result; | 428 return result; |
| 467 | 429 |
| 468 // The underlying socket closed unexpectedly. | 430 // The underlying socket closed unexpectedly. |
| 469 if (result == 0) { | 431 if (result == 0) { |
| 470 net_log_.AddEvent(NetLog::TYPE_SOCKS_UNEXPECTEDLY_CLOSED_DURING_HANDSHAKE, | 432 net_log_.AddEvent(NetLog::TYPE_SOCKS_UNEXPECTEDLY_CLOSED_DURING_HANDSHAKE, |
| 471 NULL); | 433 NULL); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 535 | 497 |
| 536 int SOCKS5ClientSocket::GetPeerAddress(AddressList* address) const { | 498 int SOCKS5ClientSocket::GetPeerAddress(AddressList* address) const { |
| 537 return transport_->socket()->GetPeerAddress(address); | 499 return transport_->socket()->GetPeerAddress(address); |
| 538 } | 500 } |
| 539 | 501 |
| 540 int SOCKS5ClientSocket::GetLocalAddress(IPEndPoint* address) const { | 502 int SOCKS5ClientSocket::GetLocalAddress(IPEndPoint* address) const { |
| 541 return transport_->socket()->GetLocalAddress(address); | 503 return transport_->socket()->GetLocalAddress(address); |
| 542 } | 504 } |
| 543 | 505 |
| 544 } // namespace net | 506 } // namespace net |
| OLD | NEW |