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/callback_helpers.h" |
9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 NOTREACHED(); | 137 NOTREACHED(); |
138 return kProtoUnknown; | 138 return kProtoUnknown; |
139 } | 139 } |
140 | 140 |
141 bool SOCKS5ClientSocket::GetSSLInfo(SSLInfo* ssl_info) { | 141 bool SOCKS5ClientSocket::GetSSLInfo(SSLInfo* ssl_info) { |
142 if (transport_.get() && transport_->socket()) { | 142 if (transport_.get() && transport_->socket()) { |
143 return transport_->socket()->GetSSLInfo(ssl_info); | 143 return transport_->socket()->GetSSLInfo(ssl_info); |
144 } | 144 } |
145 NOTREACHED(); | 145 NOTREACHED(); |
146 return false; | 146 return false; |
147 | |
148 } | 147 } |
149 | 148 |
150 // Read is called by the transport layer above to read. This can only be done | 149 // Read is called by the transport layer above to read. This can only be done |
151 // if the SOCKS handshake is complete. | 150 // if the SOCKS handshake is complete. |
152 int SOCKS5ClientSocket::Read(IOBuffer* buf, int buf_len, | 151 int SOCKS5ClientSocket::Read(IOBuffer* buf, |
| 152 int buf_len, |
153 const CompletionCallback& callback) { | 153 const CompletionCallback& callback) { |
154 DCHECK(completed_handshake_); | 154 DCHECK(completed_handshake_); |
155 DCHECK_EQ(STATE_NONE, next_state_); | 155 DCHECK_EQ(STATE_NONE, next_state_); |
156 DCHECK(user_callback_.is_null()); | 156 DCHECK(user_callback_.is_null()); |
157 DCHECK(!callback.is_null()); | 157 DCHECK(!callback.is_null()); |
158 | 158 |
159 int rv = transport_->socket()->Read( | 159 int rv = transport_->socket()->Read( |
160 buf, buf_len, | 160 buf, |
| 161 buf_len, |
161 base::Bind(&SOCKS5ClientSocket::OnReadWriteComplete, | 162 base::Bind(&SOCKS5ClientSocket::OnReadWriteComplete, |
162 base::Unretained(this), callback)); | 163 base::Unretained(this), |
| 164 callback)); |
163 if (rv > 0) | 165 if (rv > 0) |
164 was_ever_used_ = true; | 166 was_ever_used_ = true; |
165 return rv; | 167 return rv; |
166 } | 168 } |
167 | 169 |
168 // Write is called by the transport layer. This can only be done if the | 170 // Write is called by the transport layer. This can only be done if the |
169 // SOCKS handshake is complete. | 171 // SOCKS handshake is complete. |
170 int SOCKS5ClientSocket::Write(IOBuffer* buf, int buf_len, | 172 int SOCKS5ClientSocket::Write(IOBuffer* buf, |
| 173 int buf_len, |
171 const CompletionCallback& callback) { | 174 const CompletionCallback& callback) { |
172 DCHECK(completed_handshake_); | 175 DCHECK(completed_handshake_); |
173 DCHECK_EQ(STATE_NONE, next_state_); | 176 DCHECK_EQ(STATE_NONE, next_state_); |
174 DCHECK(user_callback_.is_null()); | 177 DCHECK(user_callback_.is_null()); |
175 DCHECK(!callback.is_null()); | 178 DCHECK(!callback.is_null()); |
176 | 179 |
177 int rv = transport_->socket()->Write( | 180 int rv = transport_->socket()->Write( |
178 buf, buf_len, | 181 buf, |
| 182 buf_len, |
179 base::Bind(&SOCKS5ClientSocket::OnReadWriteComplete, | 183 base::Bind(&SOCKS5ClientSocket::OnReadWriteComplete, |
180 base::Unretained(this), callback)); | 184 base::Unretained(this), |
| 185 callback)); |
181 if (rv > 0) | 186 if (rv > 0) |
182 was_ever_used_ = true; | 187 was_ever_used_ = true; |
183 return rv; | 188 return rv; |
184 } | 189 } |
185 | 190 |
186 int SOCKS5ClientSocket::SetReceiveBufferSize(int32 size) { | 191 int SOCKS5ClientSocket::SetReceiveBufferSize(int32 size) { |
187 return transport_->socket()->SetReceiveBufferSize(size); | 192 return transport_->socket()->SetReceiveBufferSize(size); |
188 } | 193 } |
189 | 194 |
190 int SOCKS5ClientSocket::SetSendBufferSize(int32 size) { | 195 int SOCKS5ClientSocket::SetSendBufferSize(int32 size) { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 rv = DoGreetReadComplete(rv); | 249 rv = DoGreetReadComplete(rv); |
245 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SOCKS5_GREET_READ, rv); | 250 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SOCKS5_GREET_READ, rv); |
246 break; | 251 break; |
247 case STATE_HANDSHAKE_WRITE: | 252 case STATE_HANDSHAKE_WRITE: |
248 DCHECK_EQ(OK, rv); | 253 DCHECK_EQ(OK, rv); |
249 net_log_.BeginEvent(NetLog::TYPE_SOCKS5_HANDSHAKE_WRITE); | 254 net_log_.BeginEvent(NetLog::TYPE_SOCKS5_HANDSHAKE_WRITE); |
250 rv = DoHandshakeWrite(); | 255 rv = DoHandshakeWrite(); |
251 break; | 256 break; |
252 case STATE_HANDSHAKE_WRITE_COMPLETE: | 257 case STATE_HANDSHAKE_WRITE_COMPLETE: |
253 rv = DoHandshakeWriteComplete(rv); | 258 rv = DoHandshakeWriteComplete(rv); |
254 net_log_.EndEventWithNetErrorCode( | 259 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SOCKS5_HANDSHAKE_WRITE, |
255 NetLog::TYPE_SOCKS5_HANDSHAKE_WRITE, rv); | 260 rv); |
256 break; | 261 break; |
257 case STATE_HANDSHAKE_READ: | 262 case STATE_HANDSHAKE_READ: |
258 DCHECK_EQ(OK, rv); | 263 DCHECK_EQ(OK, rv); |
259 net_log_.BeginEvent(NetLog::TYPE_SOCKS5_HANDSHAKE_READ); | 264 net_log_.BeginEvent(NetLog::TYPE_SOCKS5_HANDSHAKE_READ); |
260 rv = DoHandshakeRead(); | 265 rv = DoHandshakeRead(); |
261 break; | 266 break; |
262 case STATE_HANDSHAKE_READ_COMPLETE: | 267 case STATE_HANDSHAKE_READ_COMPLETE: |
263 rv = DoHandshakeReadComplete(rv); | 268 rv = DoHandshakeReadComplete(rv); |
264 net_log_.EndEventWithNetErrorCode( | 269 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SOCKS5_HANDSHAKE_READ, |
265 NetLog::TYPE_SOCKS5_HANDSHAKE_READ, rv); | 270 rv); |
266 break; | 271 break; |
267 default: | 272 default: |
268 NOTREACHED() << "bad state"; | 273 NOTREACHED() << "bad state"; |
269 rv = ERR_UNEXPECTED; | 274 rv = ERR_UNEXPECTED; |
270 break; | 275 break; |
271 } | 276 } |
272 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); | 277 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); |
273 return rv; | 278 return rv; |
274 } | 279 } |
275 | 280 |
276 const char kSOCKS5GreetWriteData[] = { 0x05, 0x01, 0x00 }; // no authentication | 281 const char kSOCKS5GreetWriteData[] = {0x05, 0x01, 0x00}; // no authentication |
277 | 282 |
278 int SOCKS5ClientSocket::DoGreetWrite() { | 283 int SOCKS5ClientSocket::DoGreetWrite() { |
279 // Since we only have 1 byte to send the hostname length in, if the | 284 // Since we only have 1 byte to send the hostname length in, if the |
280 // URL has a hostname longer than 255 characters we can't send it. | 285 // URL has a hostname longer than 255 characters we can't send it. |
281 if (0xFF < host_request_info_.hostname().size()) { | 286 if (0xFF < host_request_info_.hostname().size()) { |
282 net_log_.AddEvent(NetLog::TYPE_SOCKS_HOSTNAME_TOO_BIG); | 287 net_log_.AddEvent(NetLog::TYPE_SOCKS_HOSTNAME_TOO_BIG); |
283 return ERR_SOCKS_CONNECTION_FAILED; | 288 return ERR_SOCKS_CONNECTION_FAILED; |
284 } | 289 } |
285 | 290 |
286 if (buffer_.empty()) { | 291 if (buffer_.empty()) { |
287 buffer_ = std::string(kSOCKS5GreetWriteData, | 292 buffer_ = |
288 arraysize(kSOCKS5GreetWriteData)); | 293 std::string(kSOCKS5GreetWriteData, arraysize(kSOCKS5GreetWriteData)); |
289 bytes_sent_ = 0; | 294 bytes_sent_ = 0; |
290 } | 295 } |
291 | 296 |
292 next_state_ = STATE_GREET_WRITE_COMPLETE; | 297 next_state_ = STATE_GREET_WRITE_COMPLETE; |
293 size_t handshake_buf_len = buffer_.size() - bytes_sent_; | 298 size_t handshake_buf_len = buffer_.size() - bytes_sent_; |
294 handshake_buf_ = new IOBuffer(handshake_buf_len); | 299 handshake_buf_ = new IOBuffer(handshake_buf_len); |
295 memcpy(handshake_buf_->data(), &buffer_.data()[bytes_sent_], | 300 memcpy( |
296 handshake_buf_len); | 301 handshake_buf_->data(), &buffer_.data()[bytes_sent_], handshake_buf_len); |
297 return transport_->socket() | 302 return transport_->socket()->Write( |
298 ->Write(handshake_buf_.get(), handshake_buf_len, io_callback_); | 303 handshake_buf_.get(), handshake_buf_len, io_callback_); |
299 } | 304 } |
300 | 305 |
301 int SOCKS5ClientSocket::DoGreetWriteComplete(int result) { | 306 int SOCKS5ClientSocket::DoGreetWriteComplete(int result) { |
302 if (result < 0) | 307 if (result < 0) |
303 return result; | 308 return result; |
304 | 309 |
305 bytes_sent_ += result; | 310 bytes_sent_ += result; |
306 if (bytes_sent_ == buffer_.size()) { | 311 if (bytes_sent_ == buffer_.size()) { |
307 buffer_.clear(); | 312 buffer_.clear(); |
308 bytes_received_ = 0; | 313 bytes_received_ = 0; |
309 next_state_ = STATE_GREET_READ; | 314 next_state_ = STATE_GREET_READ; |
310 } else { | 315 } else { |
311 next_state_ = STATE_GREET_WRITE; | 316 next_state_ = STATE_GREET_WRITE; |
312 } | 317 } |
313 return OK; | 318 return OK; |
314 } | 319 } |
315 | 320 |
316 int SOCKS5ClientSocket::DoGreetRead() { | 321 int SOCKS5ClientSocket::DoGreetRead() { |
317 next_state_ = STATE_GREET_READ_COMPLETE; | 322 next_state_ = STATE_GREET_READ_COMPLETE; |
318 size_t handshake_buf_len = kGreetReadHeaderSize - bytes_received_; | 323 size_t handshake_buf_len = kGreetReadHeaderSize - bytes_received_; |
319 handshake_buf_ = new IOBuffer(handshake_buf_len); | 324 handshake_buf_ = new IOBuffer(handshake_buf_len); |
320 return transport_->socket() | 325 return transport_->socket()->Read( |
321 ->Read(handshake_buf_.get(), handshake_buf_len, io_callback_); | 326 handshake_buf_.get(), handshake_buf_len, io_callback_); |
322 } | 327 } |
323 | 328 |
324 int SOCKS5ClientSocket::DoGreetReadComplete(int result) { | 329 int SOCKS5ClientSocket::DoGreetReadComplete(int result) { |
325 if (result < 0) | 330 if (result < 0) |
326 return result; | 331 return result; |
327 | 332 |
328 if (result == 0) { | 333 if (result == 0) { |
329 net_log_.AddEvent(NetLog::TYPE_SOCKS_UNEXPECTEDLY_CLOSED_DURING_GREETING); | 334 net_log_.AddEvent(NetLog::TYPE_SOCKS_UNEXPECTEDLY_CLOSED_DURING_GREETING); |
330 return ERR_SOCKS_CONNECTION_FAILED; | 335 return ERR_SOCKS_CONNECTION_FAILED; |
331 } | 336 } |
(...skipping 15 matching lines...) Expand all Loading... |
347 net_log_.AddEvent(NetLog::TYPE_SOCKS_UNEXPECTED_AUTH, | 352 net_log_.AddEvent(NetLog::TYPE_SOCKS_UNEXPECTED_AUTH, |
348 NetLog::IntegerCallback("method", buffer_[1])); | 353 NetLog::IntegerCallback("method", buffer_[1])); |
349 return ERR_SOCKS_CONNECTION_FAILED; | 354 return ERR_SOCKS_CONNECTION_FAILED; |
350 } | 355 } |
351 | 356 |
352 buffer_.clear(); | 357 buffer_.clear(); |
353 next_state_ = STATE_HANDSHAKE_WRITE; | 358 next_state_ = STATE_HANDSHAKE_WRITE; |
354 return OK; | 359 return OK; |
355 } | 360 } |
356 | 361 |
357 int SOCKS5ClientSocket::BuildHandshakeWriteBuffer(std::string* handshake) | 362 int SOCKS5ClientSocket::BuildHandshakeWriteBuffer( |
358 const { | 363 std::string* handshake) const { |
359 DCHECK(handshake->empty()); | 364 DCHECK(handshake->empty()); |
360 | 365 |
361 handshake->push_back(kSOCKS5Version); | 366 handshake->push_back(kSOCKS5Version); |
362 handshake->push_back(kTunnelCommand); // Connect command | 367 handshake->push_back(kTunnelCommand); // Connect command |
363 handshake->push_back(kNullByte); // Reserved null | 368 handshake->push_back(kNullByte); // Reserved null |
364 | 369 |
365 handshake->push_back(kEndPointDomain); // The type of the address. | 370 handshake->push_back(kEndPointDomain); // The type of the address. |
366 | 371 |
367 DCHECK_GE(static_cast<size_t>(0xFF), host_request_info_.hostname().size()); | 372 DCHECK_GE(static_cast<size_t>(0xFF), host_request_info_.hostname().size()); |
368 | 373 |
369 // First add the size of the hostname, followed by the hostname. | 374 // First add the size of the hostname, followed by the hostname. |
370 handshake->push_back(static_cast<unsigned char>( | 375 handshake->push_back( |
371 host_request_info_.hostname().size())); | 376 static_cast<unsigned char>(host_request_info_.hostname().size())); |
372 handshake->append(host_request_info_.hostname()); | 377 handshake->append(host_request_info_.hostname()); |
373 | 378 |
374 uint16 nw_port = base::HostToNet16(host_request_info_.port()); | 379 uint16 nw_port = base::HostToNet16(host_request_info_.port()); |
375 handshake->append(reinterpret_cast<char*>(&nw_port), sizeof(nw_port)); | 380 handshake->append(reinterpret_cast<char*>(&nw_port), sizeof(nw_port)); |
376 return OK; | 381 return OK; |
377 } | 382 } |
378 | 383 |
379 // Writes the SOCKS handshake data to the underlying socket connection. | 384 // Writes the SOCKS handshake data to the underlying socket connection. |
380 int SOCKS5ClientSocket::DoHandshakeWrite() { | 385 int SOCKS5ClientSocket::DoHandshakeWrite() { |
381 next_state_ = STATE_HANDSHAKE_WRITE_COMPLETE; | 386 next_state_ = STATE_HANDSHAKE_WRITE_COMPLETE; |
382 | 387 |
383 if (buffer_.empty()) { | 388 if (buffer_.empty()) { |
384 int rv = BuildHandshakeWriteBuffer(&buffer_); | 389 int rv = BuildHandshakeWriteBuffer(&buffer_); |
385 if (rv != OK) | 390 if (rv != OK) |
386 return rv; | 391 return rv; |
387 bytes_sent_ = 0; | 392 bytes_sent_ = 0; |
388 } | 393 } |
389 | 394 |
390 int handshake_buf_len = buffer_.size() - bytes_sent_; | 395 int handshake_buf_len = buffer_.size() - bytes_sent_; |
391 DCHECK_LT(0, handshake_buf_len); | 396 DCHECK_LT(0, handshake_buf_len); |
392 handshake_buf_ = new IOBuffer(handshake_buf_len); | 397 handshake_buf_ = new IOBuffer(handshake_buf_len); |
393 memcpy(handshake_buf_->data(), &buffer_[bytes_sent_], | 398 memcpy(handshake_buf_->data(), &buffer_[bytes_sent_], handshake_buf_len); |
394 handshake_buf_len); | 399 return transport_->socket()->Write( |
395 return transport_->socket() | 400 handshake_buf_.get(), handshake_buf_len, io_callback_); |
396 ->Write(handshake_buf_.get(), handshake_buf_len, io_callback_); | |
397 } | 401 } |
398 | 402 |
399 int SOCKS5ClientSocket::DoHandshakeWriteComplete(int result) { | 403 int SOCKS5ClientSocket::DoHandshakeWriteComplete(int result) { |
400 if (result < 0) | 404 if (result < 0) |
401 return result; | 405 return result; |
402 | 406 |
403 // We ignore the case when result is 0, since the underlying Write | 407 // We ignore the case when result is 0, since the underlying Write |
404 // may return spurious writes while waiting on the socket. | 408 // may return spurious writes while waiting on the socket. |
405 | 409 |
406 bytes_sent_ += result; | 410 bytes_sent_ += result; |
(...skipping 12 matching lines...) Expand all Loading... |
419 int SOCKS5ClientSocket::DoHandshakeRead() { | 423 int SOCKS5ClientSocket::DoHandshakeRead() { |
420 next_state_ = STATE_HANDSHAKE_READ_COMPLETE; | 424 next_state_ = STATE_HANDSHAKE_READ_COMPLETE; |
421 | 425 |
422 if (buffer_.empty()) { | 426 if (buffer_.empty()) { |
423 bytes_received_ = 0; | 427 bytes_received_ = 0; |
424 read_header_size = kReadHeaderSize; | 428 read_header_size = kReadHeaderSize; |
425 } | 429 } |
426 | 430 |
427 int handshake_buf_len = read_header_size - bytes_received_; | 431 int handshake_buf_len = read_header_size - bytes_received_; |
428 handshake_buf_ = new IOBuffer(handshake_buf_len); | 432 handshake_buf_ = new IOBuffer(handshake_buf_len); |
429 return transport_->socket() | 433 return transport_->socket()->Read( |
430 ->Read(handshake_buf_.get(), handshake_buf_len, io_callback_); | 434 handshake_buf_.get(), handshake_buf_len, io_callback_); |
431 } | 435 } |
432 | 436 |
433 int SOCKS5ClientSocket::DoHandshakeReadComplete(int result) { | 437 int SOCKS5ClientSocket::DoHandshakeReadComplete(int result) { |
434 if (result < 0) | 438 if (result < 0) |
435 return result; | 439 return result; |
436 | 440 |
437 // The underlying socket closed unexpectedly. | 441 // The underlying socket closed unexpectedly. |
438 if (result == 0) { | 442 if (result == 0) { |
439 net_log_.AddEvent(NetLog::TYPE_SOCKS_UNEXPECTEDLY_CLOSED_DURING_HANDSHAKE); | 443 net_log_.AddEvent(NetLog::TYPE_SOCKS_UNEXPECTEDLY_CLOSED_DURING_HANDSHAKE); |
440 return ERR_SOCKS_CONNECTION_FAILED; | 444 return ERR_SOCKS_CONNECTION_FAILED; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
497 | 501 |
498 int SOCKS5ClientSocket::GetPeerAddress(IPEndPoint* address) const { | 502 int SOCKS5ClientSocket::GetPeerAddress(IPEndPoint* address) const { |
499 return transport_->socket()->GetPeerAddress(address); | 503 return transport_->socket()->GetPeerAddress(address); |
500 } | 504 } |
501 | 505 |
502 int SOCKS5ClientSocket::GetLocalAddress(IPEndPoint* address) const { | 506 int SOCKS5ClientSocket::GetLocalAddress(IPEndPoint* address) const { |
503 return transport_->socket()->GetLocalAddress(address); | 507 return transport_->socket()->GetLocalAddress(address); |
504 } | 508 } |
505 | 509 |
506 } // namespace net | 510 } // namespace net |
OLD | NEW |