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_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