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