| 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 "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
| 9 #include "base/trace_event.h" | 9 #include "base/trace_event.h" |
| 10 #include "net/base/io_buffer.h" | 10 #include "net/base/io_buffer.h" |
| 11 #include "net/base/load_log.h" | 11 #include "net/base/net_log.h" |
| 12 #include "net/base/net_util.h" | 12 #include "net/base/net_util.h" |
| 13 #include "net/base/sys_addrinfo.h" | 13 #include "net/base/sys_addrinfo.h" |
| 14 | 14 |
| 15 namespace net { | 15 namespace net { |
| 16 | 16 |
| 17 // Every SOCKS server requests a user-id from the client. It is optional | 17 // Every SOCKS server requests a user-id from the client. It is optional |
| 18 // and we send an empty string. | 18 // and we send an empty string. |
| 19 static const char kEmptyUserId[] = ""; | 19 static const char kEmptyUserId[] = ""; |
| 20 | 20 |
| 21 // The SOCKS4a implementation suggests to use an invalid IP in case the DNS | 21 // The SOCKS4a implementation suggests to use an invalid IP in case the DNS |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 bytes_received_(0), | 73 bytes_received_(0), |
| 74 host_resolver_(host_resolver), | 74 host_resolver_(host_resolver), |
| 75 host_request_info_(req_info) { | 75 host_request_info_(req_info) { |
| 76 } | 76 } |
| 77 | 77 |
| 78 SOCKSClientSocket::~SOCKSClientSocket() { | 78 SOCKSClientSocket::~SOCKSClientSocket() { |
| 79 Disconnect(); | 79 Disconnect(); |
| 80 } | 80 } |
| 81 | 81 |
| 82 int SOCKSClientSocket::Connect(CompletionCallback* callback, | 82 int SOCKSClientSocket::Connect(CompletionCallback* callback, |
| 83 LoadLog* load_log) { | 83 const BoundNetLog& net_log) { |
| 84 DCHECK(transport_.get()); | 84 DCHECK(transport_.get()); |
| 85 DCHECK(transport_->IsConnected()); | 85 DCHECK(transport_->IsConnected()); |
| 86 DCHECK_EQ(STATE_NONE, next_state_); | 86 DCHECK_EQ(STATE_NONE, next_state_); |
| 87 DCHECK(!user_callback_); | 87 DCHECK(!user_callback_); |
| 88 | 88 |
| 89 // If already connected, then just return OK. | 89 // If already connected, then just return OK. |
| 90 if (completed_handshake_) | 90 if (completed_handshake_) |
| 91 return OK; | 91 return OK; |
| 92 | 92 |
| 93 next_state_ = STATE_RESOLVE_HOST; | 93 next_state_ = STATE_RESOLVE_HOST; |
| 94 load_log_ = load_log; | 94 net_log_ = net_log; |
| 95 | 95 |
| 96 LoadLog::BeginEvent(load_log, LoadLog::TYPE_SOCKS_CONNECT); | 96 net_log.BeginEvent(NetLog::TYPE_SOCKS_CONNECT); |
| 97 | 97 |
| 98 int rv = DoLoop(OK); | 98 int rv = DoLoop(OK); |
| 99 if (rv == ERR_IO_PENDING) { | 99 if (rv == ERR_IO_PENDING) { |
| 100 user_callback_ = callback; | 100 user_callback_ = callback; |
| 101 } else { | 101 } else { |
| 102 LoadLog::EndEvent(load_log, LoadLog::TYPE_SOCKS_CONNECT); | 102 net_log.EndEvent(NetLog::TYPE_SOCKS_CONNECT); |
| 103 load_log_ = NULL; | 103 net_log_ = BoundNetLog(); |
| 104 } | 104 } |
| 105 return rv; | 105 return rv; |
| 106 } | 106 } |
| 107 | 107 |
| 108 void SOCKSClientSocket::Disconnect() { | 108 void SOCKSClientSocket::Disconnect() { |
| 109 completed_handshake_ = false; | 109 completed_handshake_ = false; |
| 110 host_resolver_.Cancel(); | 110 host_resolver_.Cancel(); |
| 111 transport_->Disconnect(); | 111 transport_->Disconnect(); |
| 112 | 112 |
| 113 // Reset other states to make sure they aren't mistakenly used later. | 113 // Reset other states to make sure they aren't mistakenly used later. |
| 114 // These are the states initialized by Connect(). | 114 // These are the states initialized by Connect(). |
| 115 next_state_ = STATE_NONE; | 115 next_state_ = STATE_NONE; |
| 116 user_callback_ = NULL; | 116 user_callback_ = NULL; |
| 117 load_log_ = NULL; | 117 net_log_ = BoundNetLog(); |
| 118 } | 118 } |
| 119 | 119 |
| 120 bool SOCKSClientSocket::IsConnected() const { | 120 bool SOCKSClientSocket::IsConnected() const { |
| 121 return completed_handshake_ && transport_->IsConnected(); | 121 return completed_handshake_ && transport_->IsConnected(); |
| 122 } | 122 } |
| 123 | 123 |
| 124 bool SOCKSClientSocket::IsConnectedAndIdle() const { | 124 bool SOCKSClientSocket::IsConnectedAndIdle() const { |
| 125 return completed_handshake_ && transport_->IsConnectedAndIdle(); | 125 return completed_handshake_ && transport_->IsConnectedAndIdle(); |
| 126 } | 126 } |
| 127 | 127 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 CompletionCallback* c = user_callback_; | 164 CompletionCallback* c = user_callback_; |
| 165 user_callback_ = NULL; | 165 user_callback_ = NULL; |
| 166 DLOG(INFO) << "Finished setting up SOCKS handshake"; | 166 DLOG(INFO) << "Finished setting up SOCKS handshake"; |
| 167 c->Run(result); | 167 c->Run(result); |
| 168 } | 168 } |
| 169 | 169 |
| 170 void SOCKSClientSocket::OnIOComplete(int result) { | 170 void SOCKSClientSocket::OnIOComplete(int result) { |
| 171 DCHECK_NE(STATE_NONE, next_state_); | 171 DCHECK_NE(STATE_NONE, next_state_); |
| 172 int rv = DoLoop(result); | 172 int rv = DoLoop(result); |
| 173 if (rv != ERR_IO_PENDING) { | 173 if (rv != ERR_IO_PENDING) { |
| 174 LoadLog::EndEvent(load_log_, LoadLog::TYPE_SOCKS_CONNECT); | 174 net_log_.EndEvent(NetLog::TYPE_SOCKS_CONNECT); |
| 175 load_log_ = NULL; | 175 net_log_ = BoundNetLog(); |
| 176 DoCallback(rv); | 176 DoCallback(rv); |
| 177 } | 177 } |
| 178 } | 178 } |
| 179 | 179 |
| 180 int SOCKSClientSocket::DoLoop(int last_io_result) { | 180 int SOCKSClientSocket::DoLoop(int last_io_result) { |
| 181 DCHECK_NE(next_state_, STATE_NONE); | 181 DCHECK_NE(next_state_, STATE_NONE); |
| 182 int rv = last_io_result; | 182 int rv = last_io_result; |
| 183 do { | 183 do { |
| 184 State state = next_state_; | 184 State state = next_state_; |
| 185 next_state_ = STATE_NONE; | 185 next_state_ = STATE_NONE; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 212 } | 212 } |
| 213 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); | 213 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); |
| 214 return rv; | 214 return rv; |
| 215 } | 215 } |
| 216 | 216 |
| 217 int SOCKSClientSocket::DoResolveHost() { | 217 int SOCKSClientSocket::DoResolveHost() { |
| 218 DCHECK_EQ(kSOCKS4Unresolved, socks_version_); | 218 DCHECK_EQ(kSOCKS4Unresolved, socks_version_); |
| 219 | 219 |
| 220 next_state_ = STATE_RESOLVE_HOST_COMPLETE; | 220 next_state_ = STATE_RESOLVE_HOST_COMPLETE; |
| 221 return host_resolver_.Resolve( | 221 return host_resolver_.Resolve( |
| 222 host_request_info_, &addresses_, &io_callback_, load_log_); | 222 host_request_info_, &addresses_, &io_callback_, net_log_); |
| 223 } | 223 } |
| 224 | 224 |
| 225 int SOCKSClientSocket::DoResolveHostComplete(int result) { | 225 int SOCKSClientSocket::DoResolveHostComplete(int result) { |
| 226 DCHECK_EQ(kSOCKS4Unresolved, socks_version_); | 226 DCHECK_EQ(kSOCKS4Unresolved, socks_version_); |
| 227 | 227 |
| 228 bool ok = (result == OK); | 228 bool ok = (result == OK); |
| 229 next_state_ = STATE_HANDSHAKE_WRITE; | 229 next_state_ = STATE_HANDSHAKE_WRITE; |
| 230 if (ok) { | 230 if (ok) { |
| 231 DCHECK(addresses_.head()); | 231 DCHECK(addresses_.head()); |
| 232 | 232 |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 DCHECK_NE(kSOCKS4Unresolved, socks_version_); | 349 DCHECK_NE(kSOCKS4Unresolved, socks_version_); |
| 350 | 350 |
| 351 if (result < 0) | 351 if (result < 0) |
| 352 return result; | 352 return result; |
| 353 | 353 |
| 354 // The underlying socket closed unexpectedly. | 354 // The underlying socket closed unexpectedly. |
| 355 if (result == 0) | 355 if (result == 0) |
| 356 return ERR_CONNECTION_CLOSED; | 356 return ERR_CONNECTION_CLOSED; |
| 357 | 357 |
| 358 if (bytes_received_ + result > kReadHeaderSize) { | 358 if (bytes_received_ + result > kReadHeaderSize) { |
| 359 // TODO(eroman): Describe failure in LoadLog. | 359 // TODO(eroman): Describe failure in NetLog. |
| 360 return ERR_SOCKS_CONNECTION_FAILED; | 360 return ERR_SOCKS_CONNECTION_FAILED; |
| 361 } | 361 } |
| 362 | 362 |
| 363 buffer_.append(handshake_buf_->data(), result); | 363 buffer_.append(handshake_buf_->data(), result); |
| 364 bytes_received_ += result; | 364 bytes_received_ += result; |
| 365 if (bytes_received_ < kReadHeaderSize) { | 365 if (bytes_received_ < kReadHeaderSize) { |
| 366 next_state_ = STATE_HANDSHAKE_READ; | 366 next_state_ = STATE_HANDSHAKE_READ; |
| 367 return OK; | 367 return OK; |
| 368 } | 368 } |
| 369 | 369 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 396 } | 396 } |
| 397 | 397 |
| 398 // Note: we ignore the last 6 bytes as specified by the SOCKS protocol | 398 // Note: we ignore the last 6 bytes as specified by the SOCKS protocol |
| 399 } | 399 } |
| 400 | 400 |
| 401 int SOCKSClientSocket::GetPeerAddress(AddressList* address) const { | 401 int SOCKSClientSocket::GetPeerAddress(AddressList* address) const { |
| 402 return transport_->GetPeerAddress(address); | 402 return transport_->GetPeerAddress(address); |
| 403 } | 403 } |
| 404 | 404 |
| 405 } // namespace net | 405 } // namespace net |
| OLD | NEW |