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_ && 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 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 |