• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_SOCKS_CLIENT_SOCKET_H_
6 #define NET_SOCKET_SOCKS_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 // The SOCKS client socket implementation
26 class SOCKSClientSocket : public ClientSocket {
27  public:
28   // Takes ownership of the |transport_socket|, which should already be
29   // connected by the time Connect() is called.
30   //
31   // |req_info| contains the hostname and port to which the socket above will
32   // communicate to via the socks layer. For testing the referrer is optional.
33   SOCKSClientSocket(ClientSocket* transport_socket,
34                     const HostResolver::RequestInfo& req_info,
35                     HostResolver* host_resolver);
36 
37   // On destruction Disconnect() is called.
38   virtual ~SOCKSClientSocket();
39 
40   // ClientSocket methods:
41 
42   // Does the SOCKS handshake and completes the protocol.
43   virtual int Connect(CompletionCallback* callback, LoadLog* load_log);
44   virtual void Disconnect();
45   virtual bool IsConnected() const;
46   virtual bool IsConnectedAndIdle() const;
47 
48   // Socket methods:
49   virtual int Read(IOBuffer* buf, int buf_len, CompletionCallback* callback);
50   virtual int Write(IOBuffer* buf, int buf_len, CompletionCallback* callback);
51 
52   virtual bool SetReceiveBufferSize(int32 size);
53   virtual bool SetSendBufferSize(int32 size);
54 
55   virtual int GetPeerName(struct sockaddr* name, socklen_t* namelen);
56 
57  private:
58   FRIEND_TEST(SOCKSClientSocketTest, CompleteHandshake);
59   FRIEND_TEST(SOCKSClientSocketTest, SOCKS4AFailedDNS);
60   FRIEND_TEST(SOCKSClientSocketTest, SOCKS4AIfDomainInIPv6);
61 
62   enum State {
63     STATE_RESOLVE_HOST,
64     STATE_RESOLVE_HOST_COMPLETE,
65     STATE_HANDSHAKE_WRITE,
66     STATE_HANDSHAKE_WRITE_COMPLETE,
67     STATE_HANDSHAKE_READ,
68     STATE_HANDSHAKE_READ_COMPLETE,
69     STATE_NONE,
70   };
71 
72   // The SOCKS proxy connection either has the hostname resolved via the
73   // client or via the server. This enum stores the state of the SOCKS
74   // connection. If the client can resolve the hostname, the connection is
75   // SOCKS4, otherwise it is SOCKS4A.
76   enum SocksVersion {
77     kSOCKS4Unresolved,
78     kSOCKS4,
79     kSOCKS4a,
80   };
81 
82   void DoCallback(int result);
83   void OnIOComplete(int result);
84 
85   int DoLoop(int last_io_result);
86   int DoResolveHost();
87   int DoResolveHostComplete(int result);
88   int DoHandshakeRead();
89   int DoHandshakeReadComplete(int result);
90   int DoHandshakeWrite();
91   int DoHandshakeWriteComplete(int result);
92 
93   const std::string BuildHandshakeWriteBuffer() const;
94 
95   CompletionCallbackImpl<SOCKSClientSocket> io_callback_;
96 
97   // Stores the underlying socket.
98   scoped_ptr<ClientSocket> transport_;
99 
100   State next_state_;
101   SocksVersion socks_version_;
102 
103   // Stores the callback to the layer above, called on completing Connect().
104   CompletionCallback* user_callback_;
105 
106   // This IOBuffer is used by the class to read and write
107   // SOCKS handshake data. The length contains the expected size to
108   // read or write.
109   scoped_refptr<IOBuffer> handshake_buf_;
110 
111   // While writing, this buffer stores the complete write handshake data.
112   // While reading, it stores the handshake information received so far.
113   std::string buffer_;
114 
115   // This becomes true when the SOCKS handshake has completed and the
116   // overlying connection is free to communicate.
117   bool completed_handshake_;
118 
119   // These contain the bytes sent / received by the SOCKS handshake.
120   size_t bytes_sent_;
121   size_t bytes_received_;
122 
123   // Used to resolve the hostname to which the SOCKS proxy will connect.
124   SingleRequestHostResolver host_resolver_;
125   AddressList addresses_;
126   HostResolver::RequestInfo host_request_info_;
127 
128   scoped_refptr<LoadLog> load_log_;
129 
130   DISALLOW_COPY_AND_ASSIGN(SOCKSClientSocket);
131 };
132 
133 }  // namespace net
134 
135 #endif  // NET_SOCKET_SOCKS_CLIENT_SOCKET_H_
136