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