| 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/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/callback_helpers.h" |
| 9 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
| 10 #include "base/sys_byteorder.h" | 11 #include "base/sys_byteorder.h" |
| 11 #include "net/base/io_buffer.h" | 12 #include "net/base/io_buffer.h" |
| 12 #include "net/base/net_log.h" | 13 #include "net/base/net_log.h" |
| 13 #include "net/base/net_util.h" | 14 #include "net/base/net_util.h" |
| 14 #include "net/socket/client_socket_handle.h" | 15 #include "net/socket/client_socket_handle.h" |
| 15 | 16 |
| 16 namespace net { | 17 namespace net { |
| 17 | 18 |
| 18 // Every SOCKS server requests a user-id from the client. It is optional | 19 // Every SOCKS server requests a user-id from the client. It is optional |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 SOCKSClientSocket::SOCKSClientSocket( | 59 SOCKSClientSocket::SOCKSClientSocket( |
| 59 scoped_ptr<ClientSocketHandle> transport_socket, | 60 scoped_ptr<ClientSocketHandle> transport_socket, |
| 60 const HostResolver::RequestInfo& req_info, | 61 const HostResolver::RequestInfo& req_info, |
| 61 RequestPriority priority, | 62 RequestPriority priority, |
| 62 HostResolver* host_resolver) | 63 HostResolver* host_resolver) |
| 63 : transport_(transport_socket.Pass()), | 64 : transport_(transport_socket.Pass()), |
| 64 next_state_(STATE_NONE), | 65 next_state_(STATE_NONE), |
| 65 completed_handshake_(false), | 66 completed_handshake_(false), |
| 66 bytes_sent_(0), | 67 bytes_sent_(0), |
| 67 bytes_received_(0), | 68 bytes_received_(0), |
| 69 was_used_to_convey_data_(false), |
| 68 host_resolver_(host_resolver), | 70 host_resolver_(host_resolver), |
| 69 host_request_info_(req_info), | 71 host_request_info_(req_info), |
| 70 priority_(priority), | 72 priority_(priority), |
| 71 net_log_(transport_->socket()->NetLog()) {} | 73 net_log_(transport_->socket()->NetLog()) {} |
| 72 | 74 |
| 73 SOCKSClientSocket::~SOCKSClientSocket() { | 75 SOCKSClientSocket::~SOCKSClientSocket() { |
| 74 Disconnect(); | 76 Disconnect(); |
| 75 } | 77 } |
| 76 | 78 |
| 77 int SOCKSClientSocket::Connect(const CompletionCallback& callback) { | 79 int SOCKSClientSocket::Connect(const CompletionCallback& callback) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 | 132 |
| 131 void SOCKSClientSocket::SetOmniboxSpeculation() { | 133 void SOCKSClientSocket::SetOmniboxSpeculation() { |
| 132 if (transport_.get() && transport_->socket()) { | 134 if (transport_.get() && transport_->socket()) { |
| 133 transport_->socket()->SetOmniboxSpeculation(); | 135 transport_->socket()->SetOmniboxSpeculation(); |
| 134 } else { | 136 } else { |
| 135 NOTREACHED(); | 137 NOTREACHED(); |
| 136 } | 138 } |
| 137 } | 139 } |
| 138 | 140 |
| 139 bool SOCKSClientSocket::WasEverUsed() const { | 141 bool SOCKSClientSocket::WasEverUsed() const { |
| 140 if (transport_.get() && transport_->socket()) { | 142 return was_used_to_convey_data_; |
| 141 return transport_->socket()->WasEverUsed(); | |
| 142 } | |
| 143 NOTREACHED(); | |
| 144 return false; | |
| 145 } | 143 } |
| 146 | 144 |
| 147 bool SOCKSClientSocket::UsingTCPFastOpen() const { | 145 bool SOCKSClientSocket::UsingTCPFastOpen() const { |
| 148 if (transport_.get() && transport_->socket()) { | 146 if (transport_.get() && transport_->socket()) { |
| 149 return transport_->socket()->UsingTCPFastOpen(); | 147 return transport_->socket()->UsingTCPFastOpen(); |
| 150 } | 148 } |
| 151 NOTREACHED(); | 149 NOTREACHED(); |
| 152 return false; | 150 return false; |
| 153 } | 151 } |
| 154 | 152 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 178 } | 176 } |
| 179 | 177 |
| 180 // Read is called by the transport layer above to read. This can only be done | 178 // Read is called by the transport layer above to read. This can only be done |
| 181 // if the SOCKS handshake is complete. | 179 // if the SOCKS handshake is complete. |
| 182 int SOCKSClientSocket::Read(IOBuffer* buf, int buf_len, | 180 int SOCKSClientSocket::Read(IOBuffer* buf, int buf_len, |
| 183 const CompletionCallback& callback) { | 181 const CompletionCallback& callback) { |
| 184 DCHECK(completed_handshake_); | 182 DCHECK(completed_handshake_); |
| 185 DCHECK_EQ(STATE_NONE, next_state_); | 183 DCHECK_EQ(STATE_NONE, next_state_); |
| 186 DCHECK(user_callback_.is_null()); | 184 DCHECK(user_callback_.is_null()); |
| 187 | 185 |
| 188 return transport_->socket()->Read(buf, buf_len, callback); | 186 int rv = transport_->socket()->Read( |
| 187 buf, buf_len, |
| 188 base::Bind(&SOCKSClientSocket::OnReadWriteComplete, |
| 189 base::Unretained(this), callback)); |
| 190 if (rv > 0) |
| 191 was_used_to_convey_data_ = true; |
| 192 return rv; |
| 189 } | 193 } |
| 190 | 194 |
| 191 // Write is called by the transport layer. This can only be done if the | 195 // Write is called by the transport layer. This can only be done if the |
| 192 // SOCKS handshake is complete. | 196 // SOCKS handshake is complete. |
| 193 int SOCKSClientSocket::Write(IOBuffer* buf, int buf_len, | 197 int SOCKSClientSocket::Write(IOBuffer* buf, int buf_len, |
| 194 const CompletionCallback& callback) { | 198 const CompletionCallback& callback) { |
| 195 DCHECK(completed_handshake_); | 199 DCHECK(completed_handshake_); |
| 196 DCHECK_EQ(STATE_NONE, next_state_); | 200 DCHECK_EQ(STATE_NONE, next_state_); |
| 197 DCHECK(user_callback_.is_null()); | 201 DCHECK(user_callback_.is_null()); |
| 198 | 202 |
| 199 return transport_->socket()->Write(buf, buf_len, callback); | 203 int rv = transport_->socket()->Write( |
| 204 buf, buf_len, |
| 205 base::Bind(&SOCKSClientSocket::OnReadWriteComplete, |
| 206 base::Unretained(this), callback)); |
| 207 if (rv > 0) |
| 208 was_used_to_convey_data_ = true; |
| 209 return rv; |
| 200 } | 210 } |
| 201 | 211 |
| 202 bool SOCKSClientSocket::SetReceiveBufferSize(int32 size) { | 212 bool SOCKSClientSocket::SetReceiveBufferSize(int32 size) { |
| 203 return transport_->socket()->SetReceiveBufferSize(size); | 213 return transport_->socket()->SetReceiveBufferSize(size); |
| 204 } | 214 } |
| 205 | 215 |
| 206 bool SOCKSClientSocket::SetSendBufferSize(int32 size) { | 216 bool SOCKSClientSocket::SetSendBufferSize(int32 size) { |
| 207 return transport_->socket()->SetSendBufferSize(size); | 217 return transport_->socket()->SetSendBufferSize(size); |
| 208 } | 218 } |
| 209 | 219 |
| 210 void SOCKSClientSocket::DoCallback(int result) { | 220 void SOCKSClientSocket::DoCallback(int result) { |
| 211 DCHECK_NE(ERR_IO_PENDING, result); | 221 DCHECK_NE(ERR_IO_PENDING, result); |
| 212 DCHECK(!user_callback_.is_null()); | 222 DCHECK(!user_callback_.is_null()); |
| 213 | 223 |
| 214 // Since Run() may result in Read being called, | 224 // Since Run() may result in Read being called, |
| 215 // clear user_callback_ up front. | 225 // clear user_callback_ up front. |
| 216 CompletionCallback c = user_callback_; | |
| 217 user_callback_.Reset(); | |
| 218 DVLOG(1) << "Finished setting up SOCKS handshake"; | 226 DVLOG(1) << "Finished setting up SOCKS handshake"; |
| 219 c.Run(result); | 227 base::ResetAndReturn(&user_callback_).Run(result); |
| 220 } | 228 } |
| 221 | 229 |
| 222 void SOCKSClientSocket::OnIOComplete(int result) { | 230 void SOCKSClientSocket::OnIOComplete(int result) { |
| 223 DCHECK_NE(STATE_NONE, next_state_); | 231 DCHECK_NE(STATE_NONE, next_state_); |
| 224 int rv = DoLoop(result); | 232 int rv = DoLoop(result); |
| 225 if (rv != ERR_IO_PENDING) { | 233 if (rv != ERR_IO_PENDING) { |
| 226 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SOCKS_CONNECT, rv); | 234 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SOCKS_CONNECT, rv); |
| 227 DoCallback(rv); | 235 DoCallback(rv); |
| 228 } | 236 } |
| 229 } | 237 } |
| 230 | 238 |
| 239 void SOCKSClientSocket::OnReadWriteComplete(const CompletionCallback& callback, |
| 240 int result) { |
| 241 DCHECK_NE(ERR_IO_PENDING, result); |
| 242 DCHECK(!callback.is_null()); |
| 243 |
| 244 if (result > 0) |
| 245 was_used_to_convey_data_ = true; |
| 246 callback.Run(result); |
| 247 } |
| 248 |
| 231 int SOCKSClientSocket::DoLoop(int last_io_result) { | 249 int SOCKSClientSocket::DoLoop(int last_io_result) { |
| 232 DCHECK_NE(next_state_, STATE_NONE); | 250 DCHECK_NE(next_state_, STATE_NONE); |
| 233 int rv = last_io_result; | 251 int rv = last_io_result; |
| 234 do { | 252 do { |
| 235 State state = next_state_; | 253 State state = next_state_; |
| 236 next_state_ = STATE_NONE; | 254 next_state_ = STATE_NONE; |
| 237 switch (state) { | 255 switch (state) { |
| 238 case STATE_RESOLVE_HOST: | 256 case STATE_RESOLVE_HOST: |
| 239 DCHECK_EQ(OK, rv); | 257 DCHECK_EQ(OK, rv); |
| 240 rv = DoResolveHost(); | 258 rv = DoResolveHost(); |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 426 | 444 |
| 427 int SOCKSClientSocket::GetPeerAddress(IPEndPoint* address) const { | 445 int SOCKSClientSocket::GetPeerAddress(IPEndPoint* address) const { |
| 428 return transport_->socket()->GetPeerAddress(address); | 446 return transport_->socket()->GetPeerAddress(address); |
| 429 } | 447 } |
| 430 | 448 |
| 431 int SOCKSClientSocket::GetLocalAddress(IPEndPoint* address) const { | 449 int SOCKSClientSocket::GetLocalAddress(IPEndPoint* address) const { |
| 432 return transport_->socket()->GetLocalAddress(address); | 450 return transport_->socket()->GetLocalAddress(address); |
| 433 } | 451 } |
| 434 | 452 |
| 435 } // namespace net | 453 } // namespace net |
| OLD | NEW |