Home | History | Annotate | Download | only in socket
      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_TCP_CLIENT_SOCKET_LIBEVENT_H_
      6 #define NET_SOCKET_TCP_CLIENT_SOCKET_LIBEVENT_H_
      7 #pragma once
      8 
      9 #include "base/memory/ref_counted.h"
     10 #include "base/memory/scoped_ptr.h"
     11 #include "base/message_loop.h"
     12 #include "base/threading/non_thread_safe.h"
     13 #include "net/base/address_list.h"
     14 #include "net/base/completion_callback.h"
     15 #include "net/base/net_log.h"
     16 #include "net/socket/client_socket.h"
     17 
     18 struct event;  // From libevent
     19 
     20 namespace net {
     21 
     22 class BoundNetLog;
     23 
     24 // A client socket that uses TCP as the transport layer.
     25 class TCPClientSocketLibevent : public ClientSocket, base::NonThreadSafe {
     26  public:
     27   // The IP address(es) and port number to connect to.  The TCP socket will try
     28   // each IP address in the list until it succeeds in establishing a
     29   // connection.
     30   TCPClientSocketLibevent(const AddressList& addresses,
     31                           net::NetLog* net_log,
     32                           const net::NetLog::Source& source);
     33 
     34   virtual ~TCPClientSocketLibevent();
     35 
     36   // AdoptSocket causes the given, connected socket to be adopted as a TCP
     37   // socket. This object must not be connected. This object takes ownership of
     38   // the given socket and then acts as if Connect() had been called. This
     39   // function is used by TCPServerSocket() to adopt accepted connections
     40   // and for testing.
     41   void AdoptSocket(int socket);
     42 
     43   // ClientSocket methods:
     44   virtual int Connect(CompletionCallback* callback
     45 #ifdef ANDROID
     46                       , bool wait_for_connect
     47                       , bool valid_uid
     48                       , uid_t calling_uid
     49 #endif
     50                      );
     51   virtual void Disconnect();
     52   virtual bool IsConnected() const;
     53   virtual bool IsConnectedAndIdle() const;
     54   virtual int GetPeerAddress(AddressList* address) const;
     55   virtual int GetLocalAddress(IPEndPoint* address) const;
     56   virtual const BoundNetLog& NetLog() const;
     57   virtual void SetSubresourceSpeculation();
     58   virtual void SetOmniboxSpeculation();
     59   virtual bool WasEverUsed() const;
     60   virtual bool UsingTCPFastOpen() const;
     61 
     62   // Socket methods:
     63   // Multiple outstanding requests are not supported.
     64   // Full duplex mode (reading and writing at the same time) is supported
     65   virtual int Read(IOBuffer* buf, int buf_len, CompletionCallback* callback);
     66   virtual int Write(IOBuffer* buf, int buf_len, CompletionCallback* callback);
     67   virtual bool SetReceiveBufferSize(int32 size);
     68   virtual bool SetSendBufferSize(int32 size);
     69 
     70  private:
     71   // State machine for connecting the socket.
     72   enum ConnectState {
     73     CONNECT_STATE_CONNECT,
     74     CONNECT_STATE_CONNECT_COMPLETE,
     75     CONNECT_STATE_NONE,
     76   };
     77 
     78   class ReadWatcher : public MessageLoopForIO::Watcher {
     79    public:
     80     explicit ReadWatcher(TCPClientSocketLibevent* socket) : socket_(socket) {}
     81 
     82     // MessageLoopForIO::Watcher methods
     83 
     84     virtual void OnFileCanReadWithoutBlocking(int /* fd */) {
     85       if (socket_->read_callback_)
     86         socket_->DidCompleteRead();
     87     }
     88 
     89     virtual void OnFileCanWriteWithoutBlocking(int /* fd */) {}
     90 
     91    private:
     92     TCPClientSocketLibevent* const socket_;
     93 
     94     DISALLOW_COPY_AND_ASSIGN(ReadWatcher);
     95   };
     96 
     97   class WriteWatcher : public MessageLoopForIO::Watcher {
     98    public:
     99     explicit WriteWatcher(TCPClientSocketLibevent* socket) : socket_(socket) {}
    100 
    101     // MessageLoopForIO::Watcher methods
    102 
    103     virtual void OnFileCanReadWithoutBlocking(int /* fd */) {}
    104 
    105     virtual void OnFileCanWriteWithoutBlocking(int /* fd */) {
    106       if (socket_->waiting_connect()) {
    107         socket_->DidCompleteConnect();
    108       } else if (socket_->write_callback_) {
    109         socket_->DidCompleteWrite();
    110       }
    111     }
    112 
    113    private:
    114     TCPClientSocketLibevent* const socket_;
    115 
    116     DISALLOW_COPY_AND_ASSIGN(WriteWatcher);
    117   };
    118 
    119   // State machine used by Connect().
    120   int DoConnectLoop(int result);
    121   int DoConnect();
    122   int DoConnectComplete(int result);
    123 
    124   // Helper used by Disconnect(), which disconnects minus the logging and
    125   // resetting of current_ai_.
    126   void DoDisconnect();
    127 
    128   void DoReadCallback(int rv);
    129   void DoWriteCallback(int rv);
    130   void DidCompleteRead();
    131   void DidCompleteWrite();
    132   void DidCompleteConnect();
    133 
    134   // Returns true if a Connect() is in progress.
    135   bool waiting_connect() const {
    136     return next_connect_state_ != CONNECT_STATE_NONE;
    137   }
    138 
    139   // Returns the OS error code (or 0 on success).
    140   int CreateSocket(const struct addrinfo* ai);
    141 
    142   // Returns the OS error code (or 0 on success).
    143   int SetupSocket();
    144 
    145   // Helper to add a TCP_CONNECT (end) event to the NetLog.
    146   void LogConnectCompletion(int net_error);
    147 
    148   // Internal function to write to a socket.
    149   int InternalWrite(IOBuffer* buf, int buf_len);
    150 
    151   int socket_;
    152 
    153   // The list of addresses we should try in order to establish a connection.
    154   AddressList addresses_;
    155 
    156   // Where we are in above list, or NULL if all addrinfos have been tried.
    157   const struct addrinfo* current_ai_;
    158 
    159   // The socket's libevent wrappers
    160   MessageLoopForIO::FileDescriptorWatcher read_socket_watcher_;
    161   MessageLoopForIO::FileDescriptorWatcher write_socket_watcher_;
    162 
    163   // The corresponding watchers for reads and writes.
    164   ReadWatcher read_watcher_;
    165   WriteWatcher write_watcher_;
    166 
    167   // The buffer used by OnSocketReady to retry Read requests
    168   scoped_refptr<IOBuffer> read_buf_;
    169   int read_buf_len_;
    170 
    171   // The buffer used by OnSocketReady to retry Write requests
    172   scoped_refptr<IOBuffer> write_buf_;
    173   int write_buf_len_;
    174 
    175   // External callback; called when read is complete.
    176   CompletionCallback* read_callback_;
    177 
    178   // External callback; called when write is complete.
    179   CompletionCallback* write_callback_;
    180 
    181   // The next state for the Connect() state machine.
    182   ConnectState next_connect_state_;
    183 
    184   // The OS error that CONNECT_STATE_CONNECT last completed with.
    185   int connect_os_error_;
    186 
    187   BoundNetLog net_log_;
    188 
    189   // This socket was previously disconnected and has not been re-connected.
    190   bool previously_disconnected_;
    191 
    192   // Record of connectivity and transmissions, for use in speculative connection
    193   // histograms.
    194   UseHistory use_history_;
    195 
    196   // Enables experimental TCP FastOpen option.
    197   bool use_tcp_fastopen_;
    198 
    199   // True when TCP FastOpen is in use and we have done the connect.
    200   bool tcp_fastopen_connected_;
    201 
    202 #ifdef ANDROID
    203   // True if connect should block and not return before the socket is connected
    204   bool wait_for_connect_;
    205   bool valid_uid_;
    206   uid_t calling_uid_;
    207 #endif
    208   DISALLOW_COPY_AND_ASSIGN(TCPClientSocketLibevent);
    209 };
    210 
    211 }  // namespace net
    212 
    213 #endif  // NET_SOCKET_TCP_CLIENT_SOCKET_LIBEVENT_H_
    214