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 |