Home | History | Annotate | Download | only in socket
      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_SOCKS5_CLIENT_SOCKET_H_
      6 #define NET_SOCKET_SOCKS5_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 // This ClientSocket is used to setup a SOCKSv5 handshake with a socks proxy.
     26 // Currently no SOCKSv5 authentication is supported.
     27 class SOCKS5ClientSocket : public ClientSocket {
     28  public:
     29   // Takes ownership of the |transport_socket|, which should already be
     30   // connected by the time Connect() is called.
     31   //
     32   // |req_info| 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(ClientSocket* transport_socket,
     39                      const HostResolver::RequestInfo& req_info);
     40 
     41   // On destruction Disconnect() is called.
     42   virtual ~SOCKS5ClientSocket();
     43 
     44   // ClientSocket methods:
     45 
     46   // Does the SOCKS handshake and completes the protocol.
     47   virtual int Connect(CompletionCallback* callback, LoadLog* load_log);
     48   virtual void Disconnect();
     49   virtual bool IsConnected() const;
     50   virtual bool IsConnectedAndIdle() const;
     51 
     52   // Socket methods:
     53   virtual int Read(IOBuffer* buf, int buf_len, CompletionCallback* callback);
     54   virtual int Write(IOBuffer* buf, int buf_len, CompletionCallback* callback);
     55 
     56   virtual bool SetReceiveBufferSize(int32 size);
     57   virtual bool SetSendBufferSize(int32 size);
     58 
     59   virtual int GetPeerName(struct sockaddr* name, socklen_t* namelen);
     60 
     61  private:
     62   enum State {
     63     STATE_GREET_WRITE,
     64     STATE_GREET_WRITE_COMPLETE,
     65     STATE_GREET_READ,
     66     STATE_GREET_READ_COMPLETE,
     67     STATE_HANDSHAKE_WRITE,
     68     STATE_HANDSHAKE_WRITE_COMPLETE,
     69     STATE_HANDSHAKE_READ,
     70     STATE_HANDSHAKE_READ_COMPLETE,
     71     STATE_NONE,
     72   };
     73 
     74   // Addressing type that can be specified in requests or responses.
     75   enum SocksEndPointAddressType {
     76     kEndPointDomain = 0x03,
     77     kEndPointResolvedIPv4 = 0x01,
     78     kEndPointResolvedIPv6 = 0x04,
     79   };
     80 
     81   static const unsigned int kGreetReadHeaderSize;
     82   static const unsigned int kWriteHeaderSize;
     83   static const unsigned int kReadHeaderSize;
     84   static const uint8 kSOCKS5Version;
     85   static const uint8 kTunnelCommand;
     86   static const uint8 kNullByte;
     87 
     88   void DoCallback(int result);
     89   void OnIOComplete(int result);
     90 
     91   int DoLoop(int last_io_result);
     92   int DoHandshakeRead();
     93   int DoHandshakeReadComplete(int result);
     94   int DoHandshakeWrite();
     95   int DoHandshakeWriteComplete(int result);
     96   int DoGreetRead();
     97   int DoGreetReadComplete(int result);
     98   int DoGreetWrite();
     99   int DoGreetWriteComplete(int result);
    100 
    101   // Writes the SOCKS handshake buffer into |handshake|
    102   // and return OK on success.
    103   int BuildHandshakeWriteBuffer(std::string* handshake) const;
    104 
    105   CompletionCallbackImpl<SOCKS5ClientSocket> io_callback_;
    106 
    107   // Stores the underlying socket.
    108   scoped_ptr<ClientSocket> 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   size_t read_header_size;
    133 
    134   HostResolver::RequestInfo host_request_info_;
    135 
    136   scoped_refptr<LoadLog> load_log_;
    137 
    138   DISALLOW_COPY_AND_ASSIGN(SOCKS5ClientSocket);
    139 };
    140 
    141 }  // namespace net
    142 
    143 #endif  // NET_SOCKET_SOCKS5_CLIENT_SOCKET_H_
    144