| 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/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/callback_helpers.h" |
| 8 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 9 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
| 10 #include "base/format_macros.h" | 11 #include "base/format_macros.h" |
| 11 #include "base/strings/string_util.h" | 12 #include "base/strings/string_util.h" |
| 12 #include "base/sys_byteorder.h" | 13 #include "base/sys_byteorder.h" |
| 13 #include "net/base/io_buffer.h" | 14 #include "net/base/io_buffer.h" |
| 14 #include "net/base/net_log.h" | 15 #include "net/base/net_log.h" |
| 15 #include "net/base/net_util.h" | 16 #include "net/base/net_util.h" |
| 16 #include "net/socket/client_socket_handle.h" | 17 #include "net/socket/client_socket_handle.h" |
| 17 | 18 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 31 scoped_ptr<ClientSocketHandle> transport_socket, | 32 scoped_ptr<ClientSocketHandle> transport_socket, |
| 32 const HostResolver::RequestInfo& req_info) | 33 const HostResolver::RequestInfo& req_info) |
| 33 : io_callback_(base::Bind(&SOCKS5ClientSocket::OnIOComplete, | 34 : io_callback_(base::Bind(&SOCKS5ClientSocket::OnIOComplete, |
| 34 base::Unretained(this))), | 35 base::Unretained(this))), |
| 35 transport_(transport_socket.Pass()), | 36 transport_(transport_socket.Pass()), |
| 36 next_state_(STATE_NONE), | 37 next_state_(STATE_NONE), |
| 37 completed_handshake_(false), | 38 completed_handshake_(false), |
| 38 bytes_sent_(0), | 39 bytes_sent_(0), |
| 39 bytes_received_(0), | 40 bytes_received_(0), |
| 40 read_header_size(kReadHeaderSize), | 41 read_header_size(kReadHeaderSize), |
| 42 was_used_to_convey_data_(false), |
| 41 host_request_info_(req_info), | 43 host_request_info_(req_info), |
| 42 net_log_(transport_->socket()->NetLog()) { | 44 net_log_(transport_->socket()->NetLog()) { |
| 43 } | 45 } |
| 44 | 46 |
| 45 SOCKS5ClientSocket::~SOCKS5ClientSocket() { | 47 SOCKS5ClientSocket::~SOCKS5ClientSocket() { |
| 46 Disconnect(); | 48 Disconnect(); |
| 47 } | 49 } |
| 48 | 50 |
| 49 int SOCKS5ClientSocket::Connect(const CompletionCallback& callback) { | 51 int SOCKS5ClientSocket::Connect(const CompletionCallback& callback) { |
| 50 DCHECK(transport_.get()); | 52 DCHECK(transport_.get()); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 | 104 |
| 103 void SOCKS5ClientSocket::SetOmniboxSpeculation() { | 105 void SOCKS5ClientSocket::SetOmniboxSpeculation() { |
| 104 if (transport_.get() && transport_->socket()) { | 106 if (transport_.get() && transport_->socket()) { |
| 105 transport_->socket()->SetOmniboxSpeculation(); | 107 transport_->socket()->SetOmniboxSpeculation(); |
| 106 } else { | 108 } else { |
| 107 NOTREACHED(); | 109 NOTREACHED(); |
| 108 } | 110 } |
| 109 } | 111 } |
| 110 | 112 |
| 111 bool SOCKS5ClientSocket::WasEverUsed() const { | 113 bool SOCKS5ClientSocket::WasEverUsed() const { |
| 112 if (transport_.get() && transport_->socket()) { | 114 return was_used_to_convey_data_; |
| 113 return transport_->socket()->WasEverUsed(); | |
| 114 } | |
| 115 NOTREACHED(); | |
| 116 return false; | |
| 117 } | 115 } |
| 118 | 116 |
| 119 bool SOCKS5ClientSocket::UsingTCPFastOpen() const { | 117 bool SOCKS5ClientSocket::UsingTCPFastOpen() const { |
| 120 if (transport_.get() && transport_->socket()) { | 118 if (transport_.get() && transport_->socket()) { |
| 121 return transport_->socket()->UsingTCPFastOpen(); | 119 return transport_->socket()->UsingTCPFastOpen(); |
| 122 } | 120 } |
| 123 NOTREACHED(); | 121 NOTREACHED(); |
| 124 return false; | 122 return false; |
| 125 } | 123 } |
| 126 | 124 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 150 } | 148 } |
| 151 | 149 |
| 152 // Read is called by the transport layer above to read. This can only be done | 150 // Read is called by the transport layer above to read. This can only be done |
| 153 // if the SOCKS handshake is complete. | 151 // if the SOCKS handshake is complete. |
| 154 int SOCKS5ClientSocket::Read(IOBuffer* buf, int buf_len, | 152 int SOCKS5ClientSocket::Read(IOBuffer* buf, int buf_len, |
| 155 const CompletionCallback& callback) { | 153 const CompletionCallback& callback) { |
| 156 DCHECK(completed_handshake_); | 154 DCHECK(completed_handshake_); |
| 157 DCHECK_EQ(STATE_NONE, next_state_); | 155 DCHECK_EQ(STATE_NONE, next_state_); |
| 158 DCHECK(user_callback_.is_null()); | 156 DCHECK(user_callback_.is_null()); |
| 159 | 157 |
| 160 return transport_->socket()->Read(buf, buf_len, callback); | 158 int rv = transport_->socket()->Read( |
| 159 buf, buf_len, |
| 160 base::Bind(&SOCKS5ClientSocket::OnReadWriteComplete, |
| 161 base::Unretained(this), callback)); |
| 162 if (rv > 0) |
| 163 was_used_to_convey_data_ = true; |
| 164 return rv; |
| 161 } | 165 } |
| 162 | 166 |
| 163 // Write is called by the transport layer. This can only be done if the | 167 // Write is called by the transport layer. This can only be done if the |
| 164 // SOCKS handshake is complete. | 168 // SOCKS handshake is complete. |
| 165 int SOCKS5ClientSocket::Write(IOBuffer* buf, int buf_len, | 169 int SOCKS5ClientSocket::Write(IOBuffer* buf, int buf_len, |
| 166 const CompletionCallback& callback) { | 170 const CompletionCallback& callback) { |
| 167 DCHECK(completed_handshake_); | 171 DCHECK(completed_handshake_); |
| 168 DCHECK_EQ(STATE_NONE, next_state_); | 172 DCHECK_EQ(STATE_NONE, next_state_); |
| 169 DCHECK(user_callback_.is_null()); | 173 DCHECK(user_callback_.is_null()); |
| 170 | 174 |
| 171 return transport_->socket()->Write(buf, buf_len, callback); | 175 int rv = transport_->socket()->Write( |
| 176 buf, buf_len, |
| 177 base::Bind(&SOCKS5ClientSocket::OnReadWriteComplete, |
| 178 base::Unretained(this), callback)); |
| 179 if (rv > 0) |
| 180 was_used_to_convey_data_ = true; |
| 181 return rv; |
| 172 } | 182 } |
| 173 | 183 |
| 174 bool SOCKS5ClientSocket::SetReceiveBufferSize(int32 size) { | 184 bool SOCKS5ClientSocket::SetReceiveBufferSize(int32 size) { |
| 175 return transport_->socket()->SetReceiveBufferSize(size); | 185 return transport_->socket()->SetReceiveBufferSize(size); |
| 176 } | 186 } |
| 177 | 187 |
| 178 bool SOCKS5ClientSocket::SetSendBufferSize(int32 size) { | 188 bool SOCKS5ClientSocket::SetSendBufferSize(int32 size) { |
| 179 return transport_->socket()->SetSendBufferSize(size); | 189 return transport_->socket()->SetSendBufferSize(size); |
| 180 } | 190 } |
| 181 | 191 |
| 182 void SOCKS5ClientSocket::DoCallback(int result) { | 192 void SOCKS5ClientSocket::DoCallback(int result) { |
| 183 DCHECK_NE(ERR_IO_PENDING, result); | 193 DCHECK_NE(ERR_IO_PENDING, result); |
| 184 DCHECK(!user_callback_.is_null()); | 194 DCHECK(!user_callback_.is_null()); |
| 185 | 195 |
| 186 // Since Run() may result in Read being called, | 196 // Since Run() may result in Read being called, |
| 187 // clear user_callback_ up front. | 197 // clear user_callback_ up front. |
| 188 CompletionCallback c = user_callback_; | 198 base::ResetAndReturn(&user_callback_).Run(result); |
| 189 user_callback_.Reset(); | |
| 190 c.Run(result); | |
| 191 } | 199 } |
| 192 | 200 |
| 193 void SOCKS5ClientSocket::OnIOComplete(int result) { | 201 void SOCKS5ClientSocket::OnIOComplete(int result) { |
| 194 DCHECK_NE(STATE_NONE, next_state_); | 202 DCHECK_NE(STATE_NONE, next_state_); |
| 195 int rv = DoLoop(result); | 203 int rv = DoLoop(result); |
| 196 if (rv != ERR_IO_PENDING) { | 204 if (rv != ERR_IO_PENDING) { |
| 197 net_log_.EndEvent(NetLog::TYPE_SOCKS5_CONNECT); | 205 net_log_.EndEvent(NetLog::TYPE_SOCKS5_CONNECT); |
| 198 DoCallback(rv); | 206 DoCallback(rv); |
| 199 } | 207 } |
| 200 } | 208 } |
| 201 | 209 |
| 210 void SOCKS5ClientSocket::OnReadWriteComplete(const CompletionCallback& callback, |
| 211 int result) { |
| 212 DCHECK_NE(ERR_IO_PENDING, result); |
| 213 DCHECK(!callback.is_null()); |
| 214 |
| 215 if (result > 0) |
| 216 was_used_to_convey_data_ = true; |
| 217 callback.Run(result); |
| 218 } |
| 219 |
| 202 int SOCKS5ClientSocket::DoLoop(int last_io_result) { | 220 int SOCKS5ClientSocket::DoLoop(int last_io_result) { |
| 203 DCHECK_NE(next_state_, STATE_NONE); | 221 DCHECK_NE(next_state_, STATE_NONE); |
| 204 int rv = last_io_result; | 222 int rv = last_io_result; |
| 205 do { | 223 do { |
| 206 State state = next_state_; | 224 State state = next_state_; |
| 207 next_state_ = STATE_NONE; | 225 next_state_ = STATE_NONE; |
| 208 switch (state) { | 226 switch (state) { |
| 209 case STATE_GREET_WRITE: | 227 case STATE_GREET_WRITE: |
| 210 DCHECK_EQ(OK, rv); | 228 DCHECK_EQ(OK, rv); |
| 211 net_log_.BeginEvent(NetLog::TYPE_SOCKS5_GREET_WRITE); | 229 net_log_.BeginEvent(NetLog::TYPE_SOCKS5_GREET_WRITE); |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 477 | 495 |
| 478 int SOCKS5ClientSocket::GetPeerAddress(IPEndPoint* address) const { | 496 int SOCKS5ClientSocket::GetPeerAddress(IPEndPoint* address) const { |
| 479 return transport_->socket()->GetPeerAddress(address); | 497 return transport_->socket()->GetPeerAddress(address); |
| 480 } | 498 } |
| 481 | 499 |
| 482 int SOCKS5ClientSocket::GetLocalAddress(IPEndPoint* address) const { | 500 int SOCKS5ClientSocket::GetLocalAddress(IPEndPoint* address) const { |
| 483 return transport_->socket()->GetLocalAddress(address); | 501 return transport_->socket()->GetLocalAddress(address); |
| 484 } | 502 } |
| 485 | 503 |
| 486 } // namespace net | 504 } // namespace net |
| OLD | NEW |