Home | History | Annotate | Download | only in socket
      1 // Copyright 2013 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_SOCKET_LIBEVENT_H_
      6 #define NET_SOCKET_TCP_SOCKET_LIBEVENT_H_
      7 
      8 #include "base/basictypes.h"
      9 #include "base/callback.h"
     10 #include "base/compiler_specific.h"
     11 #include "base/memory/scoped_ptr.h"
     12 #include "net/base/address_family.h"
     13 #include "net/base/completion_callback.h"
     14 #include "net/base/net_export.h"
     15 #include "net/base/net_log.h"
     16 
     17 namespace net {
     18 
     19 class AddressList;
     20 class IOBuffer;
     21 class IPEndPoint;
     22 class SocketLibevent;
     23 
     24 class NET_EXPORT TCPSocketLibevent {
     25  public:
     26   TCPSocketLibevent(NetLog* net_log, const NetLog::Source& source);
     27   virtual ~TCPSocketLibevent();
     28 
     29   int Open(AddressFamily family);
     30   // Takes ownership of |socket_fd|.
     31   int AdoptConnectedSocket(int socket_fd, const IPEndPoint& peer_address);
     32 
     33   int Bind(const IPEndPoint& address);
     34 
     35   int Listen(int backlog);
     36   int Accept(scoped_ptr<TCPSocketLibevent>* socket,
     37              IPEndPoint* address,
     38              const CompletionCallback& callback);
     39 
     40   int Connect(const IPEndPoint& address, const CompletionCallback& callback);
     41   bool IsConnected() const;
     42   bool IsConnectedAndIdle() const;
     43 
     44   // Multiple outstanding requests are not supported.
     45   // Full duplex mode (reading and writing at the same time) is supported.
     46   int Read(IOBuffer* buf, int buf_len, const CompletionCallback& callback);
     47   int Write(IOBuffer* buf, int buf_len, const CompletionCallback& callback);
     48 
     49   int GetLocalAddress(IPEndPoint* address) const;
     50   int GetPeerAddress(IPEndPoint* address) const;
     51 
     52   // Sets various socket options.
     53   // The commonly used options for server listening sockets:
     54   // - SetAddressReuse(true).
     55   int SetDefaultOptionsForServer();
     56   // The commonly used options for client sockets and accepted sockets:
     57   // - SetNoDelay(true);
     58   // - SetKeepAlive(true, 45).
     59   void SetDefaultOptionsForClient();
     60   int SetAddressReuse(bool allow);
     61   int SetReceiveBufferSize(int32 size);
     62   int SetSendBufferSize(int32 size);
     63   bool SetKeepAlive(bool enable, int delay);
     64   bool SetNoDelay(bool no_delay);
     65 
     66   void Close();
     67 
     68   // Setter/Getter methods for TCP FastOpen socket option.
     69   bool UsingTCPFastOpen() const;
     70   void EnableTCPFastOpenIfSupported();
     71 
     72   bool IsValid() const;
     73 
     74   // Marks the start/end of a series of connect attempts for logging purpose.
     75   //
     76   // TCPClientSocket may attempt to connect to multiple addresses until it
     77   // succeeds in establishing a connection. The corresponding log will have
     78   // multiple NetLog::TYPE_TCP_CONNECT_ATTEMPT entries nested within a
     79   // NetLog::TYPE_TCP_CONNECT. These methods set the start/end of
     80   // NetLog::TYPE_TCP_CONNECT.
     81   //
     82   // TODO(yzshen): Change logging format and let TCPClientSocket log the
     83   // start/end of a series of connect attempts itself.
     84   void StartLoggingMultipleConnectAttempts(const AddressList& addresses);
     85   void EndLoggingMultipleConnectAttempts(int net_error);
     86 
     87   const BoundNetLog& net_log() const { return net_log_; }
     88 
     89  private:
     90   // States that using a socket with TCP FastOpen can lead to.
     91   enum FastOpenStatus {
     92     FAST_OPEN_STATUS_UNKNOWN,
     93 
     94     // The initial TCP FastOpen connect attempted returned synchronously,
     95     // indicating that we had and sent a cookie along with the initial data.
     96     FAST_OPEN_FAST_CONNECT_RETURN,
     97 
     98     // The initial TCP FastOpen connect attempted returned asynchronously,
     99     // indicating that we did not have a cookie for the server.
    100     FAST_OPEN_SLOW_CONNECT_RETURN,
    101 
    102     // Some other error occurred on connection, so we couldn't tell if
    103     // TCP FastOpen would have worked.
    104     FAST_OPEN_ERROR,
    105 
    106     // An attempt to do a TCP FastOpen succeeded immediately
    107     // (FAST_OPEN_FAST_CONNECT_RETURN) and we later confirmed that the server
    108     // had acked the data we sent.
    109     FAST_OPEN_SYN_DATA_ACK,
    110 
    111     // An attempt to do a TCP FastOpen succeeded immediately
    112     // (FAST_OPEN_FAST_CONNECT_RETURN) and we later confirmed that the server
    113     // had nacked the data we sent.
    114     FAST_OPEN_SYN_DATA_NACK,
    115 
    116     // An attempt to do a TCP FastOpen succeeded immediately
    117     // (FAST_OPEN_FAST_CONNECT_RETURN) and our probe to determine if the
    118     // socket was using TCP FastOpen failed.
    119     FAST_OPEN_SYN_DATA_FAILED,
    120 
    121     // An attempt to do a TCP FastOpen failed (FAST_OPEN_SLOW_CONNECT_RETURN)
    122     // and we later confirmed that the server had acked initial data.  This
    123     // should never happen (we didn't send data, so it shouldn't have
    124     // been acked).
    125     FAST_OPEN_NO_SYN_DATA_ACK,
    126 
    127     // An attempt to do a TCP FastOpen failed (FAST_OPEN_SLOW_CONNECT_RETURN)
    128     // and we later discovered that the server had nacked initial data.  This
    129     // is the expected case results for FAST_OPEN_SLOW_CONNECT_RETURN.
    130     FAST_OPEN_NO_SYN_DATA_NACK,
    131 
    132     // An attempt to do a TCP FastOpen failed (FAST_OPEN_SLOW_CONNECT_RETURN)
    133     // and our later probe for ack/nack state failed.
    134     FAST_OPEN_NO_SYN_DATA_FAILED,
    135 
    136     FAST_OPEN_MAX_VALUE
    137   };
    138 
    139   void AcceptCompleted(scoped_ptr<TCPSocketLibevent>* tcp_socket,
    140                        IPEndPoint* address,
    141                        const CompletionCallback& callback,
    142                        int rv);
    143   int HandleAcceptCompleted(scoped_ptr<TCPSocketLibevent>* tcp_socket,
    144                             IPEndPoint* address,
    145                             int rv);
    146   int BuildTcpSocketLibevent(scoped_ptr<TCPSocketLibevent>* tcp_socket,
    147                              IPEndPoint* address);
    148 
    149   void ConnectCompleted(const CompletionCallback& callback, int rv) const;
    150   int HandleConnectCompleted(int rv) const;
    151   void LogConnectBegin(const AddressList& addresses) const;
    152   void LogConnectEnd(int net_error) const;
    153 
    154   void ReadCompleted(const scoped_refptr<IOBuffer>& buf,
    155                      const CompletionCallback& callback,
    156                      int rv);
    157   int HandleReadCompleted(IOBuffer* buf, int rv);
    158 
    159   void WriteCompleted(const scoped_refptr<IOBuffer>& buf,
    160                       const CompletionCallback& callback,
    161                       int rv) const;
    162   int HandleWriteCompleted(IOBuffer* buf, int rv) const;
    163   int TcpFastOpenWrite(IOBuffer* buf,
    164                        int buf_len,
    165                        const CompletionCallback& callback);
    166 
    167   // Called when the socket is known to be in a connected state.
    168   void RecordFastOpenStatus();
    169 
    170   scoped_ptr<SocketLibevent> socket_;
    171   scoped_ptr<SocketLibevent> accept_socket_;
    172 
    173   // Enables experimental TCP FastOpen option.
    174   bool use_tcp_fastopen_;
    175 
    176   // True when TCP FastOpen is in use and we have done the connect.
    177   bool tcp_fastopen_connected_;
    178   FastOpenStatus fast_open_status_;
    179 
    180   bool logging_multiple_connect_attempts_;
    181 
    182   BoundNetLog net_log_;
    183 
    184   DISALLOW_COPY_AND_ASSIGN(TCPSocketLibevent);
    185 };
    186 
    187 }  // namespace net
    188 
    189 #endif  // NET_SOCKET_TCP_SOCKET_LIBEVENT_H_
    190