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_SOCKS_CLIENT_SOCKET_H_
6#define NET_SOCKET_SOCKS_CLIENT_SOCKET_H_
7#pragma once
8
9#include <string>
10
11#include "base/basictypes.h"
12#include "base/gtest_prod_util.h"
13#include "base/memory/ref_counted.h"
14#include "base/memory/scoped_ptr.h"
15#include "googleurl/src/gurl.h"
16#include "net/base/address_list.h"
17#include "net/base/completion_callback.h"
18#include "net/base/host_resolver.h"
19#include "net/base/net_errors.h"
20#include "net/base/net_log.h"
21#include "net/socket/client_socket.h"
22
23namespace net {
24
25class ClientSocketHandle;
26class BoundNetLog;
27
28// The SOCKS client socket implementation
29class SOCKSClientSocket : public ClientSocket {
30 public:
31  // Takes ownership of the |transport_socket|, which should already be
32  // connected by the time Connect() is called.
33  //
34  // |req_info| contains the hostname and port to which the socket above will
35  // communicate to via the socks layer. For testing the referrer is optional.
36  SOCKSClientSocket(ClientSocketHandle* transport_socket,
37                    const HostResolver::RequestInfo& req_info,
38                    HostResolver* host_resolver);
39
40  // Deprecated constructor (http://crbug.com/37810) that takes a ClientSocket.
41  SOCKSClientSocket(ClientSocket* transport_socket,
42                    const HostResolver::RequestInfo& req_info,
43                    HostResolver* host_resolver);
44
45  // On destruction Disconnect() is called.
46  virtual ~SOCKSClientSocket();
47
48  // ClientSocket methods:
49
50  // Does the SOCKS handshake and completes the protocol.
51  virtual int Connect(CompletionCallback* callback
52#ifdef ANDROID
53                      , bool wait_for_connect
54                      , bool valid_uid
55                      , uid_t calling_uid
56#endif
57                     );
58  virtual void Disconnect();
59  virtual bool IsConnected() const;
60  virtual bool IsConnectedAndIdle() const;
61  virtual const BoundNetLog& NetLog() const;
62  virtual void SetSubresourceSpeculation();
63  virtual void SetOmniboxSpeculation();
64  virtual bool WasEverUsed() const;
65  virtual bool UsingTCPFastOpen() const;
66
67  // Socket methods:
68  virtual int Read(IOBuffer* buf, int buf_len, CompletionCallback* callback);
69  virtual int Write(IOBuffer* buf, int buf_len, CompletionCallback* callback);
70
71  virtual bool SetReceiveBufferSize(int32 size);
72  virtual bool SetSendBufferSize(int32 size);
73
74  virtual int GetPeerAddress(AddressList* address) const;
75  virtual int GetLocalAddress(IPEndPoint* address) const;
76
77 private:
78  FRIEND_TEST_ALL_PREFIXES(SOCKSClientSocketTest, CompleteHandshake);
79  FRIEND_TEST_ALL_PREFIXES(SOCKSClientSocketTest, SOCKS4AFailedDNS);
80  FRIEND_TEST_ALL_PREFIXES(SOCKSClientSocketTest, SOCKS4AIfDomainInIPv6);
81
82  enum State {
83    STATE_RESOLVE_HOST,
84    STATE_RESOLVE_HOST_COMPLETE,
85    STATE_HANDSHAKE_WRITE,
86    STATE_HANDSHAKE_WRITE_COMPLETE,
87    STATE_HANDSHAKE_READ,
88    STATE_HANDSHAKE_READ_COMPLETE,
89    STATE_NONE,
90  };
91
92  void DoCallback(int result);
93  void OnIOComplete(int result);
94
95  int DoLoop(int last_io_result);
96  int DoResolveHost();
97  int DoResolveHostComplete(int result);
98  int DoHandshakeRead();
99  int DoHandshakeReadComplete(int result);
100  int DoHandshakeWrite();
101  int DoHandshakeWriteComplete(int result);
102
103  const std::string BuildHandshakeWriteBuffer() const;
104
105  CompletionCallbackImpl<SOCKSClientSocket> io_callback_;
106
107  // Stores the underlying socket.
108  scoped_ptr<ClientSocketHandle> 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  // Used to resolve the hostname to which the SOCKS proxy will connect.
133  SingleRequestHostResolver host_resolver_;
134  AddressList addresses_;
135  HostResolver::RequestInfo host_request_info_;
136
137  BoundNetLog net_log_;
138
139  DISALLOW_COPY_AND_ASSIGN(SOCKSClientSocket);
140};
141
142}  // namespace net
143
144#endif  // NET_SOCKET_SOCKS_CLIENT_SOCKET_H_
145