1 // Copyright 2012 The Chromium Authors 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 <stddef.h> 9 #include <stdint.h> 10 11 #include <memory> 12 #include <string> 13 14 #include "base/memory/scoped_refptr.h" 15 #include "net/base/address_list.h" 16 #include "net/base/completion_once_callback.h" 17 #include "net/base/completion_repeating_callback.h" 18 #include "net/base/host_port_pair.h" 19 #include "net/base/net_errors.h" 20 #include "net/base/net_export.h" 21 #include "net/log/net_log_with_source.h" 22 #include "net/socket/stream_socket.h" 23 #include "net/traffic_annotation/network_traffic_annotation.h" 24 #include "url/gurl.h" 25 26 namespace net { 27 28 // This StreamSocket is used to setup a SOCKSv5 handshake with a socks proxy. 29 // Currently no SOCKSv5 authentication is supported. 30 class NET_EXPORT_PRIVATE SOCKS5ClientSocket : public StreamSocket { 31 public: 32 // |destination| 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(std::unique_ptr<StreamSocket> transport_socket, 39 const HostPortPair& destination, 40 const NetworkTrafficAnnotationTag& traffic_annotation); 41 42 SOCKS5ClientSocket(const SOCKS5ClientSocket&) = delete; 43 SOCKS5ClientSocket& operator=(const SOCKS5ClientSocket&) = delete; 44 45 // On destruction Disconnect() is called. 46 ~SOCKS5ClientSocket() override; 47 48 // StreamSocket implementation. 49 50 // Does the SOCKS handshake and completes the protocol. 51 int Connect(CompletionOnceCallback callback) override; 52 void Disconnect() override; 53 bool IsConnected() const override; 54 bool IsConnectedAndIdle() const override; 55 const NetLogWithSource& NetLog() const override; 56 bool WasEverUsed() const override; 57 NextProto GetNegotiatedProtocol() const override; 58 bool GetSSLInfo(SSLInfo* ssl_info) override; 59 int64_t GetTotalReceivedBytes() const override; 60 void ApplySocketTag(const SocketTag& tag) override; 61 62 // Socket implementation. 63 int Read(IOBuffer* buf, 64 int buf_len, 65 CompletionOnceCallback callback) override; 66 int Write(IOBuffer* buf, 67 int buf_len, 68 CompletionOnceCallback callback, 69 const NetworkTrafficAnnotationTag& traffic_annotation) override; 70 71 int SetReceiveBufferSize(int32_t size) override; 72 int SetSendBufferSize(int32_t size) override; 73 74 int GetPeerAddress(IPEndPoint* address) const override; 75 int GetLocalAddress(IPEndPoint* address) const override; 76 77 private: 78 enum State { 79 STATE_GREET_WRITE, 80 STATE_GREET_WRITE_COMPLETE, 81 STATE_GREET_READ, 82 STATE_GREET_READ_COMPLETE, 83 STATE_HANDSHAKE_WRITE, 84 STATE_HANDSHAKE_WRITE_COMPLETE, 85 STATE_HANDSHAKE_READ, 86 STATE_HANDSHAKE_READ_COMPLETE, 87 STATE_NONE, 88 }; 89 90 // Addressing type that can be specified in requests or responses. 91 enum SocksEndPointAddressType { 92 kEndPointDomain = 0x03, 93 kEndPointResolvedIPv4 = 0x01, 94 kEndPointResolvedIPv6 = 0x04, 95 }; 96 97 static const unsigned int kGreetReadHeaderSize; 98 static const unsigned int kWriteHeaderSize; 99 static const unsigned int kReadHeaderSize; 100 static const uint8_t kSOCKS5Version; 101 static const uint8_t kTunnelCommand; 102 static const uint8_t kNullByte; 103 104 void DoCallback(int result); 105 void OnIOComplete(int result); 106 void OnReadWriteComplete(CompletionOnceCallback callback, int result); 107 108 int DoLoop(int last_io_result); 109 int DoHandshakeRead(); 110 int DoHandshakeReadComplete(int result); 111 int DoHandshakeWrite(); 112 int DoHandshakeWriteComplete(int result); 113 int DoGreetRead(); 114 int DoGreetReadComplete(int result); 115 int DoGreetWrite(); 116 int DoGreetWriteComplete(int result); 117 118 // Writes the SOCKS handshake buffer into |handshake| 119 // and return OK on success. 120 int BuildHandshakeWriteBuffer(std::string* handshake) const; 121 122 CompletionRepeatingCallback io_callback_; 123 124 // Stores the underlying socket. 125 std::unique_ptr<StreamSocket> transport_socket_; 126 127 State next_state_ = STATE_NONE; 128 129 // Stores the callback to the layer above, called on completing Connect(). 130 CompletionOnceCallback user_callback_; 131 132 // This IOBuffer is used by the class to read and write 133 // SOCKS handshake data. The length contains the expected size to 134 // read or write. 135 scoped_refptr<IOBuffer> handshake_buf_; 136 137 // While writing, this buffer stores the complete write handshake data. 138 // While reading, it stores the handshake information received so far. 139 std::string buffer_; 140 141 // This becomes true when the SOCKS handshake has completed and the 142 // overlying connection is free to communicate. 143 bool completed_handshake_ = false; 144 145 // These contain the bytes sent / received by the SOCKS handshake. 146 size_t bytes_sent_ = 0; 147 size_t bytes_received_ = 0; 148 149 size_t read_header_size; 150 151 bool was_ever_used_ = false; 152 153 const HostPortPair destination_; 154 155 NetLogWithSource net_log_; 156 157 // Traffic annotation for socket control. 158 NetworkTrafficAnnotationTag traffic_annotation_; 159 }; 160 161 } // namespace net 162 163 #endif // NET_SOCKET_SOCKS5_CLIENT_SOCKET_H_ 164