| OLD | NEW |
| 1 // Copyright (c) 2010 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/socks_client_socket.h" | 5 #include "net/socket/socks_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 "net/base/io_buffer.h" | 9 #include "net/base/io_buffer.h" |
| 10 #include "net/base/net_log.h" | 10 #include "net/base/net_log.h" |
| 11 #include "net/base/net_util.h" | 11 #include "net/base/net_util.h" |
| 12 #include "net/base/sys_addrinfo.h" | 12 #include "net/base/sys_addrinfo.h" |
| 13 #include "net/socket/client_socket_handle.h" | 13 #include "net/socket/client_socket_handle.h" |
| 14 | 14 |
| 15 namespace net { | 15 namespace net { |
| 16 | 16 |
| 17 // Every SOCKS server requests a user-id from the client. It is optional | 17 // Every SOCKS server requests a user-id from the client. It is optional |
| 18 // and we send an empty string. | 18 // and we send an empty string. |
| 19 static const char kEmptyUserId[] = ""; | 19 static const char kEmptyUserId[] = ""; |
| 20 | 20 |
| 21 // The SOCKS4a implementation suggests to use an invalid IP in case the DNS | |
| 22 // resolution at client fails. | |
| 23 static const uint8 kInvalidIp[] = { 0, 0, 0, 127 }; | |
| 24 | |
| 25 // For SOCKS4, the client sends 8 bytes plus the size of the user-id. | 21 // For SOCKS4, the client sends 8 bytes plus the size of the user-id. |
| 26 // For SOCKS4A, this increases to accomodate the unresolved hostname. | |
| 27 static const unsigned int kWriteHeaderSize = 8; | 22 static const unsigned int kWriteHeaderSize = 8; |
| 28 | 23 |
| 29 // For SOCKS4 and SOCKS4a, the server sends 8 bytes for acknowledgement. | 24 // For SOCKS4 the server sends 8 bytes for acknowledgement. |
| 30 static const unsigned int kReadHeaderSize = 8; | 25 static const unsigned int kReadHeaderSize = 8; |
| 31 | 26 |
| 32 // Server Response codes for SOCKS. | 27 // Server Response codes for SOCKS. |
| 33 static const uint8 kServerResponseOk = 0x5A; | 28 static const uint8 kServerResponseOk = 0x5A; |
| 34 static const uint8 kServerResponseRejected = 0x5B; | 29 static const uint8 kServerResponseRejected = 0x5B; |
| 35 static const uint8 kServerResponseNotReachable = 0x5C; | 30 static const uint8 kServerResponseNotReachable = 0x5C; |
| 36 static const uint8 kServerResponseMismatchedUserId = 0x5D; | 31 static const uint8 kServerResponseMismatchedUserId = 0x5D; |
| 37 | 32 |
| 38 static const uint8 kSOCKSVersion4 = 0x04; | 33 static const uint8 kSOCKSVersion4 = 0x04; |
| 39 static const uint8 kSOCKSStreamRequest = 0x01; | 34 static const uint8 kSOCKSStreamRequest = 0x01; |
| 40 | 35 |
| 41 // A struct holding the essential details of the SOCKS4/4a Server Request. | 36 // A struct holding the essential details of the SOCKS4 Server Request. |
| 42 // The port in the header is stored in network byte order. | 37 // The port in the header is stored in network byte order. |
| 43 struct SOCKS4ServerRequest { | 38 struct SOCKS4ServerRequest { |
| 44 uint8 version; | 39 uint8 version; |
| 45 uint8 command; | 40 uint8 command; |
| 46 uint16 nw_port; | 41 uint16 nw_port; |
| 47 uint8 ip[4]; | 42 uint8 ip[4]; |
| 48 }; | 43 }; |
| 49 COMPILE_ASSERT(sizeof(SOCKS4ServerRequest) == kWriteHeaderSize, | 44 COMPILE_ASSERT(sizeof(SOCKS4ServerRequest) == kWriteHeaderSize, |
| 50 socks4_server_request_struct_wrong_size); | 45 socks4_server_request_struct_wrong_size); |
| 51 | 46 |
| 52 // A struct holding details of the SOCKS4/4a Server Response. | 47 // A struct holding details of the SOCKS4 Server Response. |
| 53 struct SOCKS4ServerResponse { | 48 struct SOCKS4ServerResponse { |
| 54 uint8 reserved_null; | 49 uint8 reserved_null; |
| 55 uint8 code; | 50 uint8 code; |
| 56 uint16 port; | 51 uint16 port; |
| 57 uint8 ip[4]; | 52 uint8 ip[4]; |
| 58 }; | 53 }; |
| 59 COMPILE_ASSERT(sizeof(SOCKS4ServerResponse) == kReadHeaderSize, | 54 COMPILE_ASSERT(sizeof(SOCKS4ServerResponse) == kReadHeaderSize, |
| 60 socks4_server_response_struct_wrong_size); | 55 socks4_server_response_struct_wrong_size); |
| 61 | 56 |
| 62 SOCKSClientSocket::SOCKSClientSocket(ClientSocketHandle* transport_socket, | 57 SOCKSClientSocket::SOCKSClientSocket(ClientSocketHandle* transport_socket, |
| 63 const HostResolver::RequestInfo& req_info, | 58 const HostResolver::RequestInfo& req_info, |
| 64 HostResolver* host_resolver) | 59 HostResolver* host_resolver) |
| 65 : ALLOW_THIS_IN_INITIALIZER_LIST( | 60 : ALLOW_THIS_IN_INITIALIZER_LIST( |
| 66 io_callback_(this, &SOCKSClientSocket::OnIOComplete)), | 61 io_callback_(this, &SOCKSClientSocket::OnIOComplete)), |
| 67 transport_(transport_socket), | 62 transport_(transport_socket), |
| 68 next_state_(STATE_NONE), | 63 next_state_(STATE_NONE), |
| 69 socks_version_(kSOCKS4Unresolved), | |
| 70 user_callback_(NULL), | 64 user_callback_(NULL), |
| 71 completed_handshake_(false), | 65 completed_handshake_(false), |
| 72 bytes_sent_(0), | 66 bytes_sent_(0), |
| 73 bytes_received_(0), | 67 bytes_received_(0), |
| 74 host_resolver_(host_resolver), | 68 host_resolver_(host_resolver), |
| 75 host_request_info_(req_info), | 69 host_request_info_(req_info), |
| 76 net_log_(transport_socket->socket()->NetLog()) { | 70 net_log_(transport_socket->socket()->NetLog()) { |
| 77 } | 71 } |
| 78 | 72 |
| 79 SOCKSClientSocket::SOCKSClientSocket(ClientSocket* transport_socket, | 73 SOCKSClientSocket::SOCKSClientSocket(ClientSocket* transport_socket, |
| 80 const HostResolver::RequestInfo& req_info, | 74 const HostResolver::RequestInfo& req_info, |
| 81 HostResolver* host_resolver) | 75 HostResolver* host_resolver) |
| 82 : ALLOW_THIS_IN_INITIALIZER_LIST( | 76 : ALLOW_THIS_IN_INITIALIZER_LIST( |
| 83 io_callback_(this, &SOCKSClientSocket::OnIOComplete)), | 77 io_callback_(this, &SOCKSClientSocket::OnIOComplete)), |
| 84 transport_(new ClientSocketHandle()), | 78 transport_(new ClientSocketHandle()), |
| 85 next_state_(STATE_NONE), | 79 next_state_(STATE_NONE), |
| 86 socks_version_(kSOCKS4Unresolved), | |
| 87 user_callback_(NULL), | 80 user_callback_(NULL), |
| 88 completed_handshake_(false), | 81 completed_handshake_(false), |
| 89 bytes_sent_(0), | 82 bytes_sent_(0), |
| 90 bytes_received_(0), | 83 bytes_received_(0), |
| 91 host_resolver_(host_resolver), | 84 host_resolver_(host_resolver), |
| 92 host_request_info_(req_info), | 85 host_request_info_(req_info), |
| 93 net_log_(transport_socket->NetLog()) { | 86 net_log_(transport_socket->NetLog()) { |
| 94 transport_->set_socket(transport_socket); | 87 transport_->set_socket(transport_socket); |
| 95 } | 88 } |
| 96 | 89 |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 default: | 252 default: |
| 260 NOTREACHED() << "bad state"; | 253 NOTREACHED() << "bad state"; |
| 261 rv = ERR_UNEXPECTED; | 254 rv = ERR_UNEXPECTED; |
| 262 break; | 255 break; |
| 263 } | 256 } |
| 264 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); | 257 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); |
| 265 return rv; | 258 return rv; |
| 266 } | 259 } |
| 267 | 260 |
| 268 int SOCKSClientSocket::DoResolveHost() { | 261 int SOCKSClientSocket::DoResolveHost() { |
| 269 DCHECK_EQ(kSOCKS4Unresolved, socks_version_); | |
| 270 | |
| 271 next_state_ = STATE_RESOLVE_HOST_COMPLETE; | 262 next_state_ = STATE_RESOLVE_HOST_COMPLETE; |
| 263 // SOCKS4 only supports IPv4 addresses, so only try getting the IPv4 |
| 264 // addresses for the target host. |
| 265 host_request_info_.set_address_family(ADDRESS_FAMILY_IPV4); |
| 272 return host_resolver_.Resolve( | 266 return host_resolver_.Resolve( |
| 273 host_request_info_, &addresses_, &io_callback_, net_log_); | 267 host_request_info_, &addresses_, &io_callback_, net_log_); |
| 274 } | 268 } |
| 275 | 269 |
| 276 int SOCKSClientSocket::DoResolveHostComplete(int result) { | 270 int SOCKSClientSocket::DoResolveHostComplete(int result) { |
| 277 DCHECK_EQ(kSOCKS4Unresolved, socks_version_); | 271 if (result != OK) { |
| 278 | 272 // Resolving the hostname failed; fail the request rather than automatically |
| 279 bool ok = (result == OK); | 273 // falling back to SOCKS4a (since it can be confusing to see invalid IP |
| 280 next_state_ = STATE_HANDSHAKE_WRITE; | 274 // addresses being sent to the SOCKS4 server when it doesn't support 4A.) |
| 281 if (ok) { | 275 return result; |
| 282 DCHECK(addresses_.head()); | |
| 283 | |
| 284 // If the host is resolved to an IPv6 address, we revert to SOCKS4a | |
| 285 // since IPv6 is unsupported by SOCKS4/4a protocol. | |
| 286 struct sockaddr *host_info = addresses_.head()->ai_addr; | |
| 287 if (host_info->sa_family == AF_INET) { | |
| 288 DVLOG(1) << "Resolved host. Using SOCKS4 to communicate"; | |
| 289 socks_version_ = kSOCKS4; | |
| 290 } else { | |
| 291 DVLOG(1) << "Resolved host but to IPv6. Using SOCKS4a to communicate"; | |
| 292 socks_version_ = kSOCKS4a; | |
| 293 } | |
| 294 } else { | |
| 295 DVLOG(1) << "Could not resolve host. Using SOCKS4a to communicate"; | |
| 296 socks_version_ = kSOCKS4a; | |
| 297 } | 276 } |
| 298 | 277 |
| 299 // Even if DNS resolution fails, we send OK since the server | 278 next_state_ = STATE_HANDSHAKE_WRITE; |
| 300 // resolves the domain. | |
| 301 return OK; | 279 return OK; |
| 302 } | 280 } |
| 303 | 281 |
| 304 // Builds the buffer that is to be sent to the server. | 282 // Builds the buffer that is to be sent to the server. |
| 305 // We check whether the SOCKS proxy is 4 or 4A. | |
| 306 // In case it is 4A, the record size increases by size of the hostname. | |
| 307 const std::string SOCKSClientSocket::BuildHandshakeWriteBuffer() const { | 283 const std::string SOCKSClientSocket::BuildHandshakeWriteBuffer() const { |
| 308 DCHECK_NE(kSOCKS4Unresolved, socks_version_); | |
| 309 | |
| 310 SOCKS4ServerRequest request; | 284 SOCKS4ServerRequest request; |
| 311 request.version = kSOCKSVersion4; | 285 request.version = kSOCKSVersion4; |
| 312 request.command = kSOCKSStreamRequest; | 286 request.command = kSOCKSStreamRequest; |
| 313 request.nw_port = htons(host_request_info_.port()); | 287 request.nw_port = htons(host_request_info_.port()); |
| 314 | 288 |
| 315 if (socks_version_ == kSOCKS4) { | 289 const struct addrinfo* ai = addresses_.head(); |
| 316 const struct addrinfo* ai = addresses_.head(); | 290 DCHECK(ai); |
| 317 DCHECK(ai); | |
| 318 // If the sockaddr is IPv6, we have already marked the version to socks4a | |
| 319 // and so this step does not get hit. | |
| 320 struct sockaddr_in* ipv4_host = | |
| 321 reinterpret_cast<struct sockaddr_in*>(ai->ai_addr); | |
| 322 memcpy(&request.ip, &(ipv4_host->sin_addr), sizeof(ipv4_host->sin_addr)); | |
| 323 | 291 |
| 324 DVLOG(1) << "Resolved Host is : " << NetAddressToString(ai); | 292 // We disabled IPv6 results when resolving the hostname, so none of the |
| 325 } else if (socks_version_ == kSOCKS4a) { | 293 // results in the list will be IPv6. |
| 326 // invalid IP of the form 0.0.0.127 | 294 // TODO(eroman): we only ever use the first address in the list. It would be |
| 327 memcpy(&request.ip, kInvalidIp, arraysize(kInvalidIp)); | 295 // more robust to try all the IP addresses we have before |
| 328 } else { | 296 // failing the connect attempt. |
| 329 NOTREACHED(); | 297 CHECK_EQ(AF_INET, ai->ai_addr->sa_family); |
| 330 } | 298 struct sockaddr_in* ipv4_host = |
| 299 reinterpret_cast<struct sockaddr_in*>(ai->ai_addr); |
| 300 memcpy(&request.ip, &ipv4_host->sin_addr, sizeof(ipv4_host->sin_addr)); |
| 301 |
| 302 DVLOG(1) << "Resolved Host is : " << NetAddressToString(ai); |
| 331 | 303 |
| 332 std::string handshake_data(reinterpret_cast<char*>(&request), | 304 std::string handshake_data(reinterpret_cast<char*>(&request), |
| 333 sizeof(request)); | 305 sizeof(request)); |
| 334 handshake_data.append(kEmptyUserId, arraysize(kEmptyUserId)); | 306 handshake_data.append(kEmptyUserId, arraysize(kEmptyUserId)); |
| 335 | 307 |
| 336 // In case we are passing the domain also, pass the hostname | |
| 337 // terminated with a null character. | |
| 338 if (socks_version_ == kSOCKS4a) { | |
| 339 handshake_data.append(host_request_info_.hostname()); | |
| 340 handshake_data.push_back('\0'); | |
| 341 } | |
| 342 | |
| 343 return handshake_data; | 308 return handshake_data; |
| 344 } | 309 } |
| 345 | 310 |
| 346 // Writes the SOCKS handshake data to the underlying socket connection. | 311 // Writes the SOCKS handshake data to the underlying socket connection. |
| 347 int SOCKSClientSocket::DoHandshakeWrite() { | 312 int SOCKSClientSocket::DoHandshakeWrite() { |
| 348 next_state_ = STATE_HANDSHAKE_WRITE_COMPLETE; | 313 next_state_ = STATE_HANDSHAKE_WRITE_COMPLETE; |
| 349 | 314 |
| 350 if (buffer_.empty()) { | 315 if (buffer_.empty()) { |
| 351 buffer_ = BuildHandshakeWriteBuffer(); | 316 buffer_ = BuildHandshakeWriteBuffer(); |
| 352 bytes_sent_ = 0; | 317 bytes_sent_ = 0; |
| 353 } | 318 } |
| 354 | 319 |
| 355 int handshake_buf_len = buffer_.size() - bytes_sent_; | 320 int handshake_buf_len = buffer_.size() - bytes_sent_; |
| 356 DCHECK_GT(handshake_buf_len, 0); | 321 DCHECK_GT(handshake_buf_len, 0); |
| 357 handshake_buf_ = new IOBuffer(handshake_buf_len); | 322 handshake_buf_ = new IOBuffer(handshake_buf_len); |
| 358 memcpy(handshake_buf_->data(), &buffer_[bytes_sent_], | 323 memcpy(handshake_buf_->data(), &buffer_[bytes_sent_], |
| 359 handshake_buf_len); | 324 handshake_buf_len); |
| 360 return transport_->socket()->Write(handshake_buf_, handshake_buf_len, | 325 return transport_->socket()->Write(handshake_buf_, handshake_buf_len, |
| 361 &io_callback_); | 326 &io_callback_); |
| 362 } | 327 } |
| 363 | 328 |
| 364 int SOCKSClientSocket::DoHandshakeWriteComplete(int result) { | 329 int SOCKSClientSocket::DoHandshakeWriteComplete(int result) { |
| 365 DCHECK_NE(kSOCKS4Unresolved, socks_version_); | |
| 366 | |
| 367 if (result < 0) | 330 if (result < 0) |
| 368 return result; | 331 return result; |
| 369 | 332 |
| 370 // We ignore the case when result is 0, since the underlying Write | 333 // We ignore the case when result is 0, since the underlying Write |
| 371 // may return spurious writes while waiting on the socket. | 334 // may return spurious writes while waiting on the socket. |
| 372 | 335 |
| 373 bytes_sent_ += result; | 336 bytes_sent_ += result; |
| 374 if (bytes_sent_ == buffer_.size()) { | 337 if (bytes_sent_ == buffer_.size()) { |
| 375 next_state_ = STATE_HANDSHAKE_READ; | 338 next_state_ = STATE_HANDSHAKE_READ; |
| 376 buffer_.clear(); | 339 buffer_.clear(); |
| 377 } else if (bytes_sent_ < buffer_.size()) { | 340 } else if (bytes_sent_ < buffer_.size()) { |
| 378 next_state_ = STATE_HANDSHAKE_WRITE; | 341 next_state_ = STATE_HANDSHAKE_WRITE; |
| 379 } else { | 342 } else { |
| 380 return ERR_UNEXPECTED; | 343 return ERR_UNEXPECTED; |
| 381 } | 344 } |
| 382 | 345 |
| 383 return OK; | 346 return OK; |
| 384 } | 347 } |
| 385 | 348 |
| 386 int SOCKSClientSocket::DoHandshakeRead() { | 349 int SOCKSClientSocket::DoHandshakeRead() { |
| 387 DCHECK_NE(kSOCKS4Unresolved, socks_version_); | |
| 388 | |
| 389 next_state_ = STATE_HANDSHAKE_READ_COMPLETE; | 350 next_state_ = STATE_HANDSHAKE_READ_COMPLETE; |
| 390 | 351 |
| 391 if (buffer_.empty()) { | 352 if (buffer_.empty()) { |
| 392 bytes_received_ = 0; | 353 bytes_received_ = 0; |
| 393 } | 354 } |
| 394 | 355 |
| 395 int handshake_buf_len = kReadHeaderSize - bytes_received_; | 356 int handshake_buf_len = kReadHeaderSize - bytes_received_; |
| 396 handshake_buf_ = new IOBuffer(handshake_buf_len); | 357 handshake_buf_ = new IOBuffer(handshake_buf_len); |
| 397 return transport_->socket()->Read(handshake_buf_, handshake_buf_len, | 358 return transport_->socket()->Read(handshake_buf_, handshake_buf_len, |
| 398 &io_callback_); | 359 &io_callback_); |
| 399 } | 360 } |
| 400 | 361 |
| 401 int SOCKSClientSocket::DoHandshakeReadComplete(int result) { | 362 int SOCKSClientSocket::DoHandshakeReadComplete(int result) { |
| 402 DCHECK_NE(kSOCKS4Unresolved, socks_version_); | |
| 403 | |
| 404 if (result < 0) | 363 if (result < 0) |
| 405 return result; | 364 return result; |
| 406 | 365 |
| 407 // The underlying socket closed unexpectedly. | 366 // The underlying socket closed unexpectedly. |
| 408 if (result == 0) | 367 if (result == 0) |
| 409 return ERR_CONNECTION_CLOSED; | 368 return ERR_CONNECTION_CLOSED; |
| 410 | 369 |
| 411 if (bytes_received_ + result > kReadHeaderSize) { | 370 if (bytes_received_ + result > kReadHeaderSize) { |
| 412 // TODO(eroman): Describe failure in NetLog. | 371 // TODO(eroman): Describe failure in NetLog. |
| 413 return ERR_SOCKS_CONNECTION_FAILED; | 372 return ERR_SOCKS_CONNECTION_FAILED; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 449 } | 408 } |
| 450 | 409 |
| 451 // Note: we ignore the last 6 bytes as specified by the SOCKS protocol | 410 // Note: we ignore the last 6 bytes as specified by the SOCKS protocol |
| 452 } | 411 } |
| 453 | 412 |
| 454 int SOCKSClientSocket::GetPeerAddress(AddressList* address) const { | 413 int SOCKSClientSocket::GetPeerAddress(AddressList* address) const { |
| 455 return transport_->socket()->GetPeerAddress(address); | 414 return transport_->socket()->GetPeerAddress(address); |
| 456 } | 415 } |
| 457 | 416 |
| 458 } // namespace net | 417 } // namespace net |
| OLD | NEW |