Chromium Code Reviews| 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 16 matching lines...) Expand all Loading... | |
| 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_(this, &SOCKS5ClientSocket::OnIOComplete)), |
| 35 transport_(transport_socket), | 35 transport_(transport_socket), |
| 36 next_state_(STATE_NONE), | 36 next_state_(STATE_NONE), |
| 37 user_callback_(NULL), | 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_(this, &SOCKS5ClientSocket::OnIOComplete)), |
| 51 transport_(new ClientSocketHandle()), | 51 transport_(new ClientSocketHandle()), |
| 52 next_state_(STATE_NONE), | 52 next_state_(STATE_NONE), |
| 53 user_callback_(NULL), | 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(OldCompletionCallback* 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(!user_callback_); | 71 DCHECK(!old_user_callback_); |
|
csilv
2011/12/06 21:03:18
make this same as line 94
James Hawkins
2011/12/06 22:19:30
Done.
| |
| 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 user_callback_ = callback; | 84 old_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 } | |
| 90 | 113 |
| 91 void SOCKS5ClientSocket::Disconnect() { | 114 void SOCKS5ClientSocket::Disconnect() { |
| 92 completed_handshake_ = false; | 115 completed_handshake_ = false; |
| 93 transport_->socket()->Disconnect(); | 116 transport_->socket()->Disconnect(); |
| 94 | 117 |
| 95 // Reset other states to make sure they aren't mistakenly used later. | 118 // Reset other states to make sure they aren't mistakenly used later. |
| 96 // These are the states initialized by Connect(). | 119 // These are the states initialized by Connect(). |
| 97 next_state_ = STATE_NONE; | 120 next_state_ = STATE_NONE; |
| 98 user_callback_ = NULL; | 121 old_user_callback_ = NULL; |
| 122 user_callback_.Reset(); | |
| 99 } | 123 } |
| 100 | 124 |
| 101 bool SOCKS5ClientSocket::IsConnected() const { | 125 bool SOCKS5ClientSocket::IsConnected() const { |
| 102 return completed_handshake_ && transport_->socket()->IsConnected(); | 126 return completed_handshake_ && transport_->socket()->IsConnected(); |
| 103 } | 127 } |
| 104 | 128 |
| 105 bool SOCKS5ClientSocket::IsConnectedAndIdle() const { | 129 bool SOCKS5ClientSocket::IsConnectedAndIdle() const { |
| 106 return completed_handshake_ && transport_->socket()->IsConnectedAndIdle(); | 130 return completed_handshake_ && transport_->socket()->IsConnectedAndIdle(); |
| 107 } | 131 } |
| 108 | 132 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 157 NOTREACHED(); | 181 NOTREACHED(); |
| 158 return base::TimeDelta::FromMicroseconds(-1); | 182 return base::TimeDelta::FromMicroseconds(-1); |
| 159 } | 183 } |
| 160 | 184 |
| 161 // Read is called by the transport layer above to read. This can only be done | 185 // Read is called by the transport layer above to read. This can only be done |
| 162 // if the SOCKS handshake is complete. | 186 // if the SOCKS handshake is complete. |
| 163 int SOCKS5ClientSocket::Read(IOBuffer* buf, int buf_len, | 187 int SOCKS5ClientSocket::Read(IOBuffer* buf, int buf_len, |
| 164 OldCompletionCallback* callback) { | 188 OldCompletionCallback* callback) { |
| 165 DCHECK(completed_handshake_); | 189 DCHECK(completed_handshake_); |
| 166 DCHECK_EQ(STATE_NONE, next_state_); | 190 DCHECK_EQ(STATE_NONE, next_state_); |
| 167 DCHECK(!user_callback_); | 191 DCHECK(!old_user_callback_); |
| 168 | 192 |
| 169 return transport_->socket()->Read(buf, buf_len, callback); | 193 return transport_->socket()->Read(buf, buf_len, callback); |
| 170 } | 194 } |
| 171 | 195 |
| 172 // Write is called by the transport layer. This can only be done if the | 196 // Write is called by the transport layer. This can only be done if the |
| 173 // SOCKS handshake is complete. | 197 // SOCKS handshake is complete. |
| 174 int SOCKS5ClientSocket::Write(IOBuffer* buf, int buf_len, | 198 int SOCKS5ClientSocket::Write(IOBuffer* buf, int buf_len, |
| 175 OldCompletionCallback* callback) { | 199 OldCompletionCallback* callback) { |
| 176 DCHECK(completed_handshake_); | 200 DCHECK(completed_handshake_); |
| 177 DCHECK_EQ(STATE_NONE, next_state_); | 201 DCHECK_EQ(STATE_NONE, next_state_); |
| 178 DCHECK(!user_callback_); | 202 DCHECK(!old_user_callback_); |
| 179 | 203 |
| 180 return transport_->socket()->Write(buf, buf_len, callback); | 204 return transport_->socket()->Write(buf, buf_len, callback); |
| 181 } | 205 } |
| 182 | 206 |
| 183 bool SOCKS5ClientSocket::SetReceiveBufferSize(int32 size) { | 207 bool SOCKS5ClientSocket::SetReceiveBufferSize(int32 size) { |
| 184 return transport_->socket()->SetReceiveBufferSize(size); | 208 return transport_->socket()->SetReceiveBufferSize(size); |
| 185 } | 209 } |
| 186 | 210 |
| 187 bool SOCKS5ClientSocket::SetSendBufferSize(int32 size) { | 211 bool SOCKS5ClientSocket::SetSendBufferSize(int32 size) { |
| 188 return transport_->socket()->SetSendBufferSize(size); | 212 return transport_->socket()->SetSendBufferSize(size); |
| 189 } | 213 } |
| 190 | 214 |
| 191 void SOCKS5ClientSocket::DoCallback(int result) { | 215 void SOCKS5ClientSocket::DoCallback(int result) { |
| 192 DCHECK_NE(ERR_IO_PENDING, result); | 216 DCHECK_NE(ERR_IO_PENDING, result); |
| 193 DCHECK(user_callback_); | 217 DCHECK(old_user_callback_ || !user_callback_.is_null()); |
| 194 | 218 |
| 195 // Since Run() may result in Read being called, | 219 // Since Run() may result in Read being called, |
| 196 // clear user_callback_ up front. | 220 // clear user_callback_ up front. |
| 197 OldCompletionCallback* c = user_callback_; | 221 if (old_user_callback_) { |
| 198 user_callback_ = NULL; | 222 OldCompletionCallback* c = old_user_callback_; |
| 199 c->Run(result); | 223 old_user_callback_ = NULL; |
| 224 c->Run(result); | |
| 225 } else { | |
| 226 CompletionCallback c = user_callback_; | |
| 227 user_callback_.Reset(); | |
| 228 c.Run(result); | |
| 229 } | |
| 200 } | 230 } |
| 201 | 231 |
| 202 void SOCKS5ClientSocket::OnIOComplete(int result) { | 232 void SOCKS5ClientSocket::OnIOComplete(int result) { |
| 203 DCHECK_NE(STATE_NONE, next_state_); | 233 DCHECK_NE(STATE_NONE, next_state_); |
| 204 int rv = DoLoop(result); | 234 int rv = DoLoop(result); |
| 205 if (rv != ERR_IO_PENDING) { | 235 if (rv != ERR_IO_PENDING) { |
| 206 net_log_.EndEvent(NetLog::TYPE_SOCKS5_CONNECT, NULL); | 236 net_log_.EndEvent(NetLog::TYPE_SOCKS5_CONNECT, NULL); |
| 207 DoCallback(rv); | 237 DoCallback(rv); |
| 208 } | 238 } |
| 209 } | 239 } |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 497 | 527 |
| 498 int SOCKS5ClientSocket::GetPeerAddress(AddressList* address) const { | 528 int SOCKS5ClientSocket::GetPeerAddress(AddressList* address) const { |
| 499 return transport_->socket()->GetPeerAddress(address); | 529 return transport_->socket()->GetPeerAddress(address); |
| 500 } | 530 } |
| 501 | 531 |
| 502 int SOCKS5ClientSocket::GetLocalAddress(IPEndPoint* address) const { | 532 int SOCKS5ClientSocket::GetLocalAddress(IPEndPoint* address) const { |
| 503 return transport_->socket()->GetLocalAddress(address); | 533 return transport_->socket()->GetLocalAddress(address); |
| 504 } | 534 } |
| 505 | 535 |
| 506 } // namespace net | 536 } // namespace net |
| OLD | NEW |