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 #ifndef NET_SOCKET_SOCKS5_CLIENT_SOCKET_H_ 6 #define NET_SOCKET_SOCKS5_CLIENT_SOCKET_H_ 7 8 #include <string> 9 10 #include "base/logging.h" 11 #include "base/ref_counted.h" 12 #include "base/scoped_ptr.h" 13 #include "googleurl/src/gurl.h" 14 #include "net/base/address_list.h" 15 #include "net/base/completion_callback.h" 16 #include "net/base/host_resolver.h" 17 #include "net/base/net_errors.h" 18 #include "net/socket/client_socket.h" 19 #include "testing/gtest/include/gtest/gtest_prod.h" 20 21 namespace net { 22 23 class LoadLog; 24 25 // This ClientSocket is used to setup a SOCKSv5 handshake with a socks proxy. 26 // Currently no SOCKSv5 authentication is supported. 27 class SOCKS5ClientSocket : public ClientSocket { 28 public: 29 // Takes ownership of the |transport_socket|, which should already be 30 // connected by the time Connect() is called. 31 // 32 // |req_info| contains the hostname and port to which the socket above will 33 // communicate to via the SOCKS layer. 34 // 35 // Although SOCKS 5 supports 3 different modes of addressing, we will 36 // always pass it a hostname. This means the DNS resolving is done 37 // proxy side. 38 SOCKS5ClientSocket(ClientSocket* transport_socket, 39 const HostResolver::RequestInfo& req_info); 40 41 // On destruction Disconnect() is called. 42 virtual ~SOCKS5ClientSocket(); 43 44 // ClientSocket methods: 45 46 // Does the SOCKS handshake and completes the protocol. 47 virtual int Connect(CompletionCallback* callback, LoadLog* load_log); 48 virtual void Disconnect(); 49 virtual bool IsConnected() const; 50 virtual bool IsConnectedAndIdle() const; 51 52 // Socket methods: 53 virtual int Read(IOBuffer* buf, int buf_len, CompletionCallback* callback); 54 virtual int Write(IOBuffer* buf, int buf_len, CompletionCallback* callback); 55 56 virtual bool SetReceiveBufferSize(int32 size); 57 virtual bool SetSendBufferSize(int32 size); 58 59 virtual int GetPeerName(struct sockaddr* name, socklen_t* namelen); 60 61 private: 62 enum State { 63 STATE_GREET_WRITE, 64 STATE_GREET_WRITE_COMPLETE, 65 STATE_GREET_READ, 66 STATE_GREET_READ_COMPLETE, 67 STATE_HANDSHAKE_WRITE, 68 STATE_HANDSHAKE_WRITE_COMPLETE, 69 STATE_HANDSHAKE_READ, 70 STATE_HANDSHAKE_READ_COMPLETE, 71 STATE_NONE, 72 }; 73 74 // Addressing type that can be specified in requests or responses. 75 enum SocksEndPointAddressType { 76 kEndPointDomain = 0x03, 77 kEndPointResolvedIPv4 = 0x01, 78 kEndPointResolvedIPv6 = 0x04, 79 }; 80 81 static const unsigned int kGreetReadHeaderSize; 82 static const unsigned int kWriteHeaderSize; 83 static const unsigned int kReadHeaderSize; 84 static const uint8 kSOCKS5Version; 85 static const uint8 kTunnelCommand; 86 static const uint8 kNullByte; 87 88 void DoCallback(int result); 89 void OnIOComplete(int result); 90 91 int DoLoop(int last_io_result); 92 int DoHandshakeRead(); 93 int DoHandshakeReadComplete(int result); 94 int DoHandshakeWrite(); 95 int DoHandshakeWriteComplete(int result); 96 int DoGreetRead(); 97 int DoGreetReadComplete(int result); 98 int DoGreetWrite(); 99 int DoGreetWriteComplete(int result); 100 101 // Writes the SOCKS handshake buffer into |handshake| 102 // and return OK on success. 103 int BuildHandshakeWriteBuffer(std::string* handshake) const; 104 105 CompletionCallbackImpl<SOCKS5ClientSocket> io_callback_; 106 107 // Stores the underlying socket. 108 scoped_ptr<ClientSocket> transport_; 109 110 State next_state_; 111 112 // Stores the callback to the layer above, called on completing Connect(). 113 CompletionCallback* user_callback_; 114 115 // This IOBuffer is used by the class to read and write 116 // SOCKS handshake data. The length contains the expected size to 117 // read or write. 118 scoped_refptr<IOBuffer> handshake_buf_; 119 120 // While writing, this buffer stores the complete write handshake data. 121 // While reading, it stores the handshake information received so far. 122 std::string buffer_; 123 124 // This becomes true when the SOCKS handshake has completed and the 125 // overlying connection is free to communicate. 126 bool completed_handshake_; 127 128 // These contain the bytes sent / received by the SOCKS handshake. 129 size_t bytes_sent_; 130 size_t bytes_received_; 131 132 size_t read_header_size; 133 134 HostResolver::RequestInfo host_request_info_; 135 136 scoped_refptr<LoadLog> load_log_; 137 138 DISALLOW_COPY_AND_ASSIGN(SOCKS5ClientSocket); 139 }; 140 141 } // namespace net 142 143 #endif // NET_SOCKET_SOCKS5_CLIENT_SOCKET_H_ 144