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 bool WasAlpnNegotiated() const override; 58 NextProto GetNegotiatedProtocol() const override; 59 bool GetSSLInfo(SSLInfo* ssl_info) override; 60 int64_t GetTotalReceivedBytes() const override; 61 void ApplySocketTag(const SocketTag& tag) override; 62 63 // Socket implementation. 64 int Read(IOBuffer* buf, 65 int buf_len, 66 CompletionOnceCallback callback) override; 67 int Write(IOBuffer* buf, 68 int buf_len, 69 CompletionOnceCallback callback, 70 const NetworkTrafficAnnotationTag& traffic_annotation) override; 71 72 int SetReceiveBufferSize(int32_t size) override; 73 int SetSendBufferSize(int32_t size) override; 74 75 int GetPeerAddress(IPEndPoint* address) const override; 76 int GetLocalAddress(IPEndPoint* address) const override; 77 78 private: 79 enum State { 80 STATE_GREET_WRITE, 81 STATE_GREET_WRITE_COMPLETE, 82 STATE_GREET_READ, 83 STATE_GREET_READ_COMPLETE, 84 STATE_HANDSHAKE_WRITE, 85 STATE_HANDSHAKE_WRITE_COMPLETE, 86 STATE_HANDSHAKE_READ, 87 STATE_HANDSHAKE_READ_COMPLETE, 88 STATE_NONE, 89 }; 90 91 // Addressing type that can be specified in requests or responses. 92 enum SocksEndPointAddressType { 93 kEndPointDomain = 0x03, 94 kEndPointResolvedIPv4 = 0x01, 95 kEndPointResolvedIPv6 = 0x04, 96 }; 97 98 static const unsigned int kGreetReadHeaderSize; 99 static const unsigned int kWriteHeaderSize; 100 static const unsigned int kReadHeaderSize; 101 static const uint8_t kSOCKS5Version; 102 static const uint8_t kTunnelCommand; 103 static const uint8_t kNullByte; 104 105 void DoCallback(int result); 106 void OnIOComplete(int result); 107 void OnReadWriteComplete(CompletionOnceCallback callback, int result); 108 109 int DoLoop(int last_io_result); 110 int DoHandshakeRead(); 111 int DoHandshakeReadComplete(int result); 112 int DoHandshakeWrite(); 113 int DoHandshakeWriteComplete(int result); 114 int DoGreetRead(); 115 int DoGreetReadComplete(int result); 116 int DoGreetWrite(); 117 int DoGreetWriteComplete(int result); 118 119 // Writes the SOCKS handshake buffer into |handshake| 120 // and return OK on success. 121 int BuildHandshakeWriteBuffer(std::string* handshake) const; 122 123 CompletionRepeatingCallback io_callback_; 124 125 // Stores the underlying socket. 126 std::unique_ptr<StreamSocket> transport_socket_; 127 128 State next_state_ = STATE_NONE; 129 130 // Stores the callback to the layer above, called on completing Connect(). 131 CompletionOnceCallback user_callback_; 132 133 // This IOBuffer is used by the class to read and write 134 // SOCKS handshake data. The length contains the expected size to 135 // read or write. 136 scoped_refptr<IOBuffer> handshake_buf_; 137 138 // While writing, this buffer stores the complete write handshake data. 139 // While reading, it stores the handshake information received so far. 140 std::string buffer_; 141 142 // This becomes true when the SOCKS handshake has completed and the 143 // overlying connection is free to communicate. 144 bool completed_handshake_ = false; 145 146 // These contain the bytes sent / received by the SOCKS handshake. 147 size_t bytes_sent_ = 0; 148 size_t bytes_received_ = 0; 149 150 size_t read_header_size; 151 152 bool was_ever_used_ = false; 153 154 const HostPortPair destination_; 155 156 NetLogWithSource net_log_; 157 158 // Traffic annotation for socket control. 159 NetworkTrafficAnnotationTag traffic_annotation_; 160 }; 161 162 } // namespace net 163 164 #endif // NET_SOCKET_SOCKS5_CLIENT_SOCKET_H_ 165