1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "net/socket/socks5_client_socket.h" 6 7 #include "base/basictypes.h" 8 #include "base/compiler_specific.h" 9 #include "base/format_macros.h" 10 #include "base/string_util.h" 11 #include "base/trace_event.h" 12 #include "net/base/io_buffer.h" 13 #include "net/base/load_log.h" 14 #include "net/base/net_util.h" 15 #include "net/base/sys_addrinfo.h" 16 17 namespace net { 18 19 namespace { 20 21 // Returns a string description of |socks_error|, or NULL if |socks_error| is 22 // not a valid SOCKS reply. 23 const char* MapSOCKSReplyToErrorString(char socks_error) { 24 switch(socks_error) { 25 case 1: return "(1) General SOCKS server failure"; 26 case 2: return "(2) Connection not allowed by ruleset"; 27 case 3: return "(3) Network unreachable"; 28 case 4: return "(4) Host unreachable"; 29 case 5: return "(5) Connection refused"; 30 case 6: return "(6) TTL expired"; 31 case 7: return "(7) Command not supported"; 32 case 8: return "(8) Address type not supported"; 33 default: return NULL; 34 } 35 } 36 37 } // namespace 38 39 const unsigned int SOCKS5ClientSocket::kGreetReadHeaderSize = 2; 40 const unsigned int SOCKS5ClientSocket::kWriteHeaderSize = 10; 41 const unsigned int SOCKS5ClientSocket::kReadHeaderSize = 5; 42 const uint8 SOCKS5ClientSocket::kSOCKS5Version = 0x05; 43 const uint8 SOCKS5ClientSocket::kTunnelCommand = 0x01; 44 const uint8 SOCKS5ClientSocket::kNullByte = 0x00; 45 46 COMPILE_ASSERT(sizeof(struct in_addr) == 4, incorrect_system_size_of_IPv4); 47 COMPILE_ASSERT(sizeof(struct in6_addr) == 16, incorrect_system_size_of_IPv6); 48 49 SOCKS5ClientSocket::SOCKS5ClientSocket(ClientSocket* transport_socket, 50 const HostResolver::RequestInfo& req_info) 51 : ALLOW_THIS_IN_INITIALIZER_LIST( 52 io_callback_(this, &SOCKS5ClientSocket::OnIOComplete)), 53 transport_(transport_socket), 54 next_state_(STATE_NONE), 55 user_callback_(NULL), 56 completed_handshake_(false), 57 bytes_sent_(0), 58 bytes_received_(0), 59 read_header_size(kReadHeaderSize), 60 host_request_info_(req_info) { 61 } 62 63 SOCKS5ClientSocket::~SOCKS5ClientSocket() { 64 Disconnect(); 65 } 66 67 int SOCKS5ClientSocket::Connect(CompletionCallback* callback, 68 LoadLog* load_log) { 69 DCHECK(transport_.get()); 70 DCHECK(transport_->IsConnected()); 71 DCHECK_EQ(STATE_NONE, next_state_); 72 DCHECK(!user_callback_); 73 74 // If already connected, then just return OK. 75 if (completed_handshake_) 76 return OK; 77 78 load_log_ = load_log; 79 LoadLog::BeginEvent(load_log, LoadLog::TYPE_SOCKS5_CONNECT); 80 81 next_state_ = STATE_GREET_WRITE; 82 buffer_.clear(); 83 84 int rv = DoLoop(OK); 85 if (rv == ERR_IO_PENDING) { 86 user_callback_ = callback; 87 } else { 88 LoadLog::EndEvent(load_log, LoadLog::TYPE_SOCKS5_CONNECT); 89 load_log_ = NULL; 90 } 91 return rv; 92 } 93 94 void SOCKS5ClientSocket::Disconnect() { 95 completed_handshake_ = false; 96 transport_->Disconnect(); 97 98 // Reset other states to make sure they aren't mistakenly used later. 99 // These are the states initialized by Connect(). 100 next_state_ = STATE_NONE; 101 user_callback_ = NULL; 102 load_log_ = NULL; 103 } 104 105 bool SOCKS5ClientSocket::IsConnected() const { 106 return completed_handshake_ && transport_->IsConnected(); 107 } 108 109 bool SOCKS5ClientSocket::IsConnectedAndIdle() const { 110 return completed_handshake_ && transport_->IsConnectedAndIdle(); 111 } 112 113 // Read is called by the transport layer above to read. This can only be done 114 // if the SOCKS handshake is complete. 115 int SOCKS5ClientSocket::Read(IOBuffer* buf, int buf_len, 116 CompletionCallback* callback) { 117 DCHECK(completed_handshake_); 118 DCHECK_EQ(STATE_NONE, next_state_); 119 DCHECK(!user_callback_); 120 121 return transport_->Read(buf, buf_len, callback); 122 } 123 124 // Write is called by the transport layer. This can only be done if the 125 // SOCKS handshake is complete. 126 int SOCKS5ClientSocket::Write(IOBuffer* buf, int buf_len, 127 CompletionCallback* callback) { 128 DCHECK(completed_handshake_); 129 DCHECK_EQ(STATE_NONE, next_state_); 130 DCHECK(!user_callback_); 131 132 return transport_->Write(buf, buf_len, callback); 133 } 134 135 bool SOCKS5ClientSocket::SetReceiveBufferSize(int32 size) { 136 return transport_->SetReceiveBufferSize(size); 137 } 138 139 bool SOCKS5ClientSocket::SetSendBufferSize(int32 size) { 140 return transport_->SetSendBufferSize(size); 141 } 142 143 void SOCKS5ClientSocket::DoCallback(int result) { 144 DCHECK_NE(ERR_IO_PENDING, result); 145 DCHECK(user_callback_); 146 147 // Since Run() may result in Read being called, 148 // clear user_callback_ up front. 149 CompletionCallback* c = user_callback_; 150 user_callback_ = NULL; 151 c->Run(result); 152 } 153 154 void SOCKS5ClientSocket::OnIOComplete(int result) { 155 DCHECK_NE(STATE_NONE, next_state_); 156 int rv = DoLoop(result); 157 if (rv != ERR_IO_PENDING) { 158 LoadLog::EndEvent(load_log_, LoadLog::TYPE_SOCKS5_CONNECT); 159 load_log_ = NULL; 160 DoCallback(rv); 161 } 162 } 163 164 int SOCKS5ClientSocket::DoLoop(int last_io_result) { 165 DCHECK_NE(next_state_, STATE_NONE); 166 int rv = last_io_result; 167 do { 168 State state = next_state_; 169 next_state_ = STATE_NONE; 170 switch (state) { 171 case STATE_GREET_WRITE: 172 DCHECK_EQ(OK, rv); 173 LoadLog::BeginEvent(load_log_, LoadLog::TYPE_SOCKS5_GREET_WRITE); 174 rv = DoGreetWrite(); 175 break; 176 case STATE_GREET_WRITE_COMPLETE: 177 rv = DoGreetWriteComplete(rv); 178 LoadLog::EndEvent(load_log_, LoadLog::TYPE_SOCKS5_GREET_WRITE); 179 break; 180 case STATE_GREET_READ: 181 DCHECK_EQ(OK, rv); 182 LoadLog::BeginEvent(load_log_, LoadLog::TYPE_SOCKS5_GREET_READ); 183 rv = DoGreetRead(); 184 break; 185 case STATE_GREET_READ_COMPLETE: 186 rv = DoGreetReadComplete(rv); 187 LoadLog::EndEvent(load_log_, LoadLog::TYPE_SOCKS5_GREET_READ); 188 break; 189 case STATE_HANDSHAKE_WRITE: 190 DCHECK_EQ(OK, rv); 191 LoadLog::BeginEvent(load_log_, LoadLog::TYPE_SOCKS5_HANDSHAKE_WRITE); 192 rv = DoHandshakeWrite(); 193 break; 194 case STATE_HANDSHAKE_WRITE_COMPLETE: 195 rv = DoHandshakeWriteComplete(rv); 196 LoadLog::EndEvent(load_log_, LoadLog::TYPE_SOCKS5_HANDSHAKE_WRITE); 197 break; 198 case STATE_HANDSHAKE_READ: 199 DCHECK_EQ(OK, rv); 200 LoadLog::BeginEvent(load_log_, LoadLog::TYPE_SOCKS5_HANDSHAKE_READ); 201 rv = DoHandshakeRead(); 202 break; 203 case STATE_HANDSHAKE_READ_COMPLETE: 204 rv = DoHandshakeReadComplete(rv); 205 LoadLog::EndEvent(load_log_, LoadLog::TYPE_SOCKS5_HANDSHAKE_READ); 206 break; 207 default: 208 NOTREACHED() << "bad state"; 209 rv = ERR_UNEXPECTED; 210 break; 211 } 212 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); 213 return rv; 214 } 215 216 const char kSOCKS5GreetWriteData[] = { 0x05, 0x01, 0x00 }; // no authentication 217 const char kSOCKS5GreetReadData[] = { 0x05, 0x00 }; 218 219 int SOCKS5ClientSocket::DoGreetWrite() { 220 // Since we only have 1 byte to send the hostname length in, if the 221 // URL has a hostname longer than 255 characters we can't send it. 222 if (0xFF < host_request_info_.hostname().size()) { 223 LoadLog::AddStringLiteral(load_log_, 224 "Failed sending request because hostname is " 225 "longer than 255 characters"); 226 return ERR_INVALID_URL; 227 } 228 229 if (buffer_.empty()) { 230 buffer_ = std::string(kSOCKS5GreetWriteData, 231 arraysize(kSOCKS5GreetWriteData)); 232 bytes_sent_ = 0; 233 } 234 235 next_state_ = STATE_GREET_WRITE_COMPLETE; 236 size_t handshake_buf_len = buffer_.size() - bytes_sent_; 237 handshake_buf_ = new IOBuffer(handshake_buf_len); 238 memcpy(handshake_buf_->data(), &buffer_.data()[bytes_sent_], 239 handshake_buf_len); 240 return transport_->Write(handshake_buf_, handshake_buf_len, &io_callback_); 241 } 242 243 int SOCKS5ClientSocket::DoGreetWriteComplete(int result) { 244 if (result < 0) 245 return result; 246 247 bytes_sent_ += result; 248 if (bytes_sent_ == buffer_.size()) { 249 buffer_.clear(); 250 bytes_received_ = 0; 251 next_state_ = STATE_GREET_READ; 252 } else { 253 next_state_ = STATE_GREET_WRITE; 254 } 255 return OK; 256 } 257 258 int SOCKS5ClientSocket::DoGreetRead() { 259 next_state_ = STATE_GREET_READ_COMPLETE; 260 size_t handshake_buf_len = kGreetReadHeaderSize - bytes_received_; 261 handshake_buf_ = new IOBuffer(handshake_buf_len); 262 return transport_->Read(handshake_buf_, handshake_buf_len, &io_callback_); 263 } 264 265 int SOCKS5ClientSocket::DoGreetReadComplete(int result) { 266 if (result < 0) 267 return result; 268 269 if (result == 0) 270 return ERR_CONNECTION_CLOSED; // Unexpected socket close 271 272 bytes_received_ += result; 273 buffer_.append(handshake_buf_->data(), result); 274 if (bytes_received_ < kGreetReadHeaderSize) { 275 next_state_ = STATE_GREET_READ; 276 return OK; 277 } 278 279 // Got the greet data. 280 if (buffer_[0] != kSOCKS5Version) { 281 LoadLog::AddStringLiteral(load_log_, "Unexpected SOCKS version"); 282 LoadLog::AddString(load_log_, StringPrintf( 283 "buffer_[0] = 0x%x", static_cast<int>(buffer_[0]))); 284 return ERR_INVALID_RESPONSE; 285 } 286 if (buffer_[1] != 0x00) { 287 LoadLog::AddStringLiteral(load_log_, "Unexpected authentication method"); 288 LoadLog::AddString(load_log_, StringPrintf( 289 "buffer_[1] = 0x%x", static_cast<int>(buffer_[1]))); 290 return ERR_INVALID_RESPONSE; // Unknown error 291 } 292 293 buffer_.clear(); 294 next_state_ = STATE_HANDSHAKE_WRITE; 295 return OK; 296 } 297 298 int SOCKS5ClientSocket::BuildHandshakeWriteBuffer(std::string* handshake) 299 const { 300 DCHECK(handshake->empty()); 301 302 handshake->push_back(kSOCKS5Version); 303 handshake->push_back(kTunnelCommand); // Connect command 304 handshake->push_back(kNullByte); // Reserved null 305 306 handshake->push_back(kEndPointDomain); // The type of the address. 307 308 DCHECK_GE(static_cast<size_t>(0xFF), host_request_info_.hostname().size()); 309 310 // First add the size of the hostname, followed by the hostname. 311 handshake->push_back(static_cast<unsigned char>( 312 host_request_info_.hostname().size())); 313 handshake->append(host_request_info_.hostname()); 314 315 uint16 nw_port = htons(host_request_info_.port()); 316 handshake->append(reinterpret_cast<char*>(&nw_port), sizeof(nw_port)); 317 return OK; 318 } 319 320 // Writes the SOCKS handshake data to the underlying socket connection. 321 int SOCKS5ClientSocket::DoHandshakeWrite() { 322 next_state_ = STATE_HANDSHAKE_WRITE_COMPLETE; 323 324 if (buffer_.empty()) { 325 int rv = BuildHandshakeWriteBuffer(&buffer_); 326 if (rv != OK) 327 return rv; 328 bytes_sent_ = 0; 329 } 330 331 int handshake_buf_len = buffer_.size() - bytes_sent_; 332 DCHECK_LT(0, handshake_buf_len); 333 handshake_buf_ = new IOBuffer(handshake_buf_len); 334 memcpy(handshake_buf_->data(), &buffer_[bytes_sent_], 335 handshake_buf_len); 336 return transport_->Write(handshake_buf_, handshake_buf_len, &io_callback_); 337 } 338 339 int SOCKS5ClientSocket::DoHandshakeWriteComplete(int result) { 340 if (result < 0) 341 return result; 342 343 // We ignore the case when result is 0, since the underlying Write 344 // may return spurious writes while waiting on the socket. 345 346 bytes_sent_ += result; 347 if (bytes_sent_ == buffer_.size()) { 348 next_state_ = STATE_HANDSHAKE_READ; 349 buffer_.clear(); 350 } else if (bytes_sent_ < buffer_.size()) { 351 next_state_ = STATE_HANDSHAKE_WRITE; 352 } else { 353 NOTREACHED(); 354 } 355 356 return OK; 357 } 358 359 int SOCKS5ClientSocket::DoHandshakeRead() { 360 next_state_ = STATE_HANDSHAKE_READ_COMPLETE; 361 362 if (buffer_.empty()) { 363 bytes_received_ = 0; 364 read_header_size = kReadHeaderSize; 365 } 366 367 int handshake_buf_len = read_header_size - bytes_received_; 368 handshake_buf_ = new IOBuffer(handshake_buf_len); 369 return transport_->Read(handshake_buf_, handshake_buf_len, &io_callback_); 370 } 371 372 int SOCKS5ClientSocket::DoHandshakeReadComplete(int result) { 373 if (result < 0) 374 return result; 375 376 // The underlying socket closed unexpectedly. 377 if (result == 0) 378 return ERR_CONNECTION_CLOSED; 379 380 buffer_.append(handshake_buf_->data(), result); 381 bytes_received_ += result; 382 383 // When the first few bytes are read, check how many more are required 384 // and accordingly increase them 385 if (bytes_received_ == kReadHeaderSize) { 386 if (buffer_[0] != kSOCKS5Version || buffer_[2] != kNullByte) { 387 LoadLog::AddStringLiteral(load_log_, "Unexpected SOCKS version."); 388 LoadLog::AddString(load_log_, StringPrintf( 389 "buffer_[0] = 0x%x; buffer_[2] = 0x%x", 390 static_cast<int>(buffer_[0]), 391 static_cast<int>(buffer_[2]))); 392 return ERR_INVALID_RESPONSE; 393 } 394 if (buffer_[1] != 0x00) { 395 LoadLog::AddStringLiteral(load_log_, 396 "SOCKS server returned a failure code:"); 397 const char* error_string = MapSOCKSReplyToErrorString(buffer_[1]); 398 if (error_string) { 399 LoadLog::AddStringLiteral(load_log_, error_string); 400 } else { 401 LoadLog::AddString(load_log_, StringPrintf( 402 "buffer_[1] = 0x%x", static_cast<int>(buffer_[1]))); 403 } 404 return ERR_FAILED; 405 } 406 407 // We check the type of IP/Domain the server returns and accordingly 408 // increase the size of the response. For domains, we need to read the 409 // size of the domain, so the initial request size is upto the domain 410 // size. Since for IPv4/IPv6 the size is fixed and hence no 'size' is 411 // read, we substract 1 byte from the additional request size. 412 SocksEndPointAddressType address_type = 413 static_cast<SocksEndPointAddressType>(buffer_[3]); 414 if (address_type == kEndPointDomain) 415 read_header_size += static_cast<uint8>(buffer_[4]); 416 else if (address_type == kEndPointResolvedIPv4) 417 read_header_size += sizeof(struct in_addr) - 1; 418 else if (address_type == kEndPointResolvedIPv6) 419 read_header_size += sizeof(struct in6_addr) - 1; 420 else { 421 LoadLog::AddStringLiteral(load_log_, "Unknown address type in response"); 422 LoadLog::AddString(load_log_, StringPrintf( 423 "buffer_[3] = 0x%x", static_cast<int>(buffer_[3]))); 424 return ERR_INVALID_RESPONSE; 425 } 426 427 read_header_size += 2; // for the port. 428 next_state_ = STATE_HANDSHAKE_READ; 429 return OK; 430 } 431 432 // When the final bytes are read, setup handshake. We ignore the rest 433 // of the response since they represent the SOCKSv5 endpoint and have 434 // no use when doing a tunnel connection. 435 if (bytes_received_ == read_header_size) { 436 completed_handshake_ = true; 437 buffer_.clear(); 438 next_state_ = STATE_NONE; 439 return OK; 440 } 441 442 next_state_ = STATE_HANDSHAKE_READ; 443 return OK; 444 } 445 446 int SOCKS5ClientSocket::GetPeerName(struct sockaddr* name, 447 socklen_t* namelen) { 448 return transport_->GetPeerName(name, namelen); 449 } 450 451 } // namespace net 452