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/ref_counted.h"
     12 #include "base/memory/scoped_ptr.h"
     13 #include "base/message_loop/message_loop.h"
     14 #include "base/threading/non_thread_safe.h"
     15 #include "net/base/address_family.h"
     16 #include "net/base/completion_callback.h"
     17 #include "net/base/net_export.h"
     18 #include "net/base/net_log.h"
     19 #include "net/socket/socket_descriptor.h"
     20 
     21 namespace net {
     22 
     23 class AddressList;
     24 class IOBuffer;
     25 class IPEndPoint;
     26 
     27 class NET_EXPORT TCPSocketLibevent : public base::NonThreadSafe {
     28  public:
     29   TCPSocketLibevent(NetLog* net_log, const NetLog::Source& source);
     30   virtual ~TCPSocketLibevent();
     31 
     32   int Open(AddressFamily family);
     33   // Takes ownership of |socket|.
     34   int AdoptConnectedSocket(int socket, const IPEndPoint& peer_address);
     35 
     36   int Bind(const IPEndPoint& address);
     37 
     38   int Listen(int backlog);
     39   int Accept(scoped_ptr<TCPSocketLibevent>* socket,
     40              IPEndPoint* address,
     41              const CompletionCallback& callback);
     42 
     43   int Connect(const IPEndPoint& address, const CompletionCallback& callback);
     44   bool IsConnected() const;
     45   bool IsConnectedAndIdle() const;
     46 
     47   // Multiple outstanding requests are not supported.
     48   // Full duplex mode (reading and writing at the same time) is supported.
     49   int Read(IOBuffer* buf, int buf_len, const CompletionCallback& callback);
     50   int Write(IOBuffer* buf, int buf_len, const CompletionCallback& callback);
     51 
     52   int GetLocalAddress(IPEndPoint* address) const;
     53   int GetPeerAddress(IPEndPoint* address) const;
     54 
     55   // Sets various socket options.
     56   // The commonly used options for server listening sockets:
     57   // - SetAddressReuse(true).
     58   int SetDefaultOptionsForServer();
     59   // The commonly used options for client sockets and accepted sockets:
     60   // - SetNoDelay(true);
     61   // - SetKeepAlive(true, 45).
     62   void SetDefaultOptionsForClient();
     63   int SetAddressReuse(bool allow);
     64   int SetReceiveBufferSize(int32 size);
     65   int SetSendBufferSize(int32 size);
     66   bool SetKeepAlive(bool enable, int delay);
     67   bool SetNoDelay(bool no_delay);
     68 
     69   void Close();
     70 
     71   bool UsingTCPFastOpen() const;
     72   bool IsValid() const { return socket_ != kInvalidSocket; }
     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 a fast open socket attempt can result in.
     91   enum FastOpenStatus {
     92     FAST_OPEN_STATUS_UNKNOWN,
     93 
     94     // The initial fast open 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 fast open 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     // fast open would have worked.
    104     FAST_OPEN_ERROR,
    105 
    106     // An attempt to do a fast open 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 fast open 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 fast open succeeded immediately
    117     // (FAST_OPEN_FAST_CONNECT_RETURN) and our probe to determine if the
    118     // socket was using fast open failed.
    119     FAST_OPEN_SYN_DATA_FAILED,
    120 
    121     // An attempt to do a fast open 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 fast open 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 fast open 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   // Watcher simply forwards notifications to Closure objects set via the
    140   // constructor.
    141   class Watcher: public base::MessageLoopForIO::Watcher {
    142    public:
    143     Watcher(const base::Closure& read_ready_callback,
    144             const base::Closure& write_ready_callback);
    145     virtual ~Watcher();
    146 
    147     // base::MessageLoopForIO::Watcher methods.
    148     virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE;
    149     virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE;
    150 
    151    private:
    152     base::Closure read_ready_callback_;
    153     base::Closure write_ready_callback_;
    154 
    155     DISALLOW_COPY_AND_ASSIGN(Watcher);
    156   };
    157 
    158   int AcceptInternal(scoped_ptr<TCPSocketLibevent>* socket,
    159                      IPEndPoint* address);
    160 
    161   int DoConnect();
    162   void DoConnectComplete(int result);
    163 
    164   void LogConnectBegin(const AddressList& addresses);
    165   void LogConnectEnd(int net_error);
    166 
    167   void DidCompleteRead();
    168   void DidCompleteWrite();
    169   void DidCompleteConnect();
    170   void DidCompleteConnectOrWrite();
    171   void DidCompleteAccept();
    172 
    173   // Internal function to write to a socket. Returns an OS error.
    174   int InternalWrite(IOBuffer* buf, int buf_len);
    175 
    176   // Called when the socket is known to be in a connected state.
    177   void RecordFastOpenStatus();
    178 
    179   int socket_;
    180 
    181   base::MessageLoopForIO::FileDescriptorWatcher accept_socket_watcher_;
    182   Watcher accept_watcher_;
    183 
    184   scoped_ptr<TCPSocketLibevent>* accept_socket_;
    185   IPEndPoint* accept_address_;
    186   CompletionCallback accept_callback_;
    187 
    188   // The socket's libevent wrappers for reads and writes.
    189   base::MessageLoopForIO::FileDescriptorWatcher read_socket_watcher_;
    190   base::MessageLoopForIO::FileDescriptorWatcher write_socket_watcher_;
    191 
    192   // The corresponding watchers for reads and writes.
    193   Watcher read_watcher_;
    194   Watcher write_watcher_;
    195 
    196   // The buffer used for reads.
    197   scoped_refptr<IOBuffer> read_buf_;
    198   int read_buf_len_;
    199 
    200   // The buffer used for writes.
    201   scoped_refptr<IOBuffer> write_buf_;
    202   int write_buf_len_;
    203 
    204   // External callback; called when read is complete.
    205   CompletionCallback read_callback_;
    206 
    207   // External callback; called when write or connect is complete.
    208   CompletionCallback write_callback_;
    209 
    210   // Enables experimental TCP FastOpen option.
    211   const bool use_tcp_fastopen_;
    212 
    213   // True when TCP FastOpen is in use and we have done the connect.
    214   bool tcp_fastopen_connected_;
    215 
    216   FastOpenStatus fast_open_status_;
    217 
    218   // A connect operation is pending. In this case, |write_callback_| needs to be
    219   // called when connect is complete.
    220   bool waiting_connect_;
    221 
    222   scoped_ptr<IPEndPoint> peer_address_;
    223   // The OS error that a connect attempt last completed with.
    224   int connect_os_error_;
    225 
    226   bool logging_multiple_connect_attempts_;
    227 
    228   BoundNetLog net_log_;
    229 
    230   DISALLOW_COPY_AND_ASSIGN(TCPSocketLibevent);
    231 };
    232 
    233 }  // namespace net
    234 
    235 #endif  // NET_SOCKET_TCP_SOCKET_LIBEVENT_H_
    236