158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// found in the LICENSE file.
458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#ifndef NET_SOCKET_TCP_SOCKET_LIBEVENT_H_
658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#define NET_SOCKET_TCP_SOCKET_LIBEVENT_H_
758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/basictypes.h"
9d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/callback.h"
1058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/compiler_specific.h"
1158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
1258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "net/base/address_family.h"
1358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "net/base/completion_callback.h"
1458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "net/base/net_export.h"
1558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "net/base/net_log.h"
1658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace net {
1858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
19d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class AddressList;
20d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class IOBuffer;
2158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class IPEndPoint;
22116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass SocketLibevent;
2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
24116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass NET_EXPORT TCPSocketLibevent {
2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public:
2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  TCPSocketLibevent(NetLog* net_log, const NetLog::Source& source);
2758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual ~TCPSocketLibevent();
2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
29d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  int Open(AddressFamily family);
30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Takes ownership of |socket_fd|.
31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  int AdoptConnectedSocket(int socket_fd, const IPEndPoint& peer_address);
32d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  int Bind(const IPEndPoint& address);
34d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
3558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  int Listen(int backlog);
3658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  int Accept(scoped_ptr<TCPSocketLibevent>* socket,
3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)             IPEndPoint* address,
3858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)             const CompletionCallback& callback);
39d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
40d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  int Connect(const IPEndPoint& address, const CompletionCallback& callback);
41d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  bool IsConnected() const;
42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  bool IsConnectedAndIdle() const;
43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
44d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Multiple outstanding requests are not supported.
45d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Full duplex mode (reading and writing at the same time) is supported.
46d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  int Read(IOBuffer* buf, int buf_len, const CompletionCallback& callback);
47d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  int Write(IOBuffer* buf, int buf_len, const CompletionCallback& callback);
48d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
49d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  int GetLocalAddress(IPEndPoint* address) const;
50d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  int GetPeerAddress(IPEndPoint* address) const;
51d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
52d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Sets various socket options.
53d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // The commonly used options for server listening sockets:
54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // - SetAddressReuse(true).
5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  int SetDefaultOptionsForServer();
56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // The commonly used options for client sockets and accepted sockets:
57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // - SetNoDelay(true);
58d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // - SetKeepAlive(true, 45).
59d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void SetDefaultOptionsForClient();
6058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  int SetAddressReuse(bool allow);
61c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  int SetReceiveBufferSize(int32 size);
62c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  int SetSendBufferSize(int32 size);
63d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  bool SetKeepAlive(bool enable, int delay);
64d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  bool SetNoDelay(bool no_delay);
65d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
6658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void Close();
6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Setter/Getter methods for TCP FastOpen socket option.
69d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  bool UsingTCPFastOpen() const;
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void EnableTCPFastOpenIfSupported();
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool IsValid() const;
73d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
74d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Marks the start/end of a series of connect attempts for logging purpose.
75d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  //
76d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // TCPClientSocket may attempt to connect to multiple addresses until it
77d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // succeeds in establishing a connection. The corresponding log will have
78d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // multiple NetLog::TYPE_TCP_CONNECT_ATTEMPT entries nested within a
79d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // NetLog::TYPE_TCP_CONNECT. These methods set the start/end of
80d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // NetLog::TYPE_TCP_CONNECT.
81d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  //
82d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // TODO(yzshen): Change logging format and let TCPClientSocket log the
83d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // start/end of a series of connect attempts itself.
84d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void StartLoggingMultipleConnectAttempts(const AddressList& addresses);
85d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void EndLoggingMultipleConnectAttempts(int net_error);
8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
87d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  const BoundNetLog& net_log() const { return net_log_; }
8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) private:
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // States that using a socket with TCP FastOpen can lead to.
91d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  enum FastOpenStatus {
92d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    FAST_OPEN_STATUS_UNKNOWN,
93d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // The initial TCP FastOpen connect attempted returned synchronously,
95d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // indicating that we had and sent a cookie along with the initial data.
96d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    FAST_OPEN_FAST_CONNECT_RETURN,
97d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // The initial TCP FastOpen connect attempted returned asynchronously,
99d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // indicating that we did not have a cookie for the server.
100d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    FAST_OPEN_SLOW_CONNECT_RETURN,
101d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
102d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // Some other error occurred on connection, so we couldn't tell if
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // TCP FastOpen would have worked.
104d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    FAST_OPEN_ERROR,
105d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // An attempt to do a TCP FastOpen succeeded immediately
107d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // (FAST_OPEN_FAST_CONNECT_RETURN) and we later confirmed that the server
108d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // had acked the data we sent.
109d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    FAST_OPEN_SYN_DATA_ACK,
110d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // An attempt to do a TCP FastOpen succeeded immediately
112d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // (FAST_OPEN_FAST_CONNECT_RETURN) and we later confirmed that the server
113d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // had nacked the data we sent.
114d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    FAST_OPEN_SYN_DATA_NACK,
115d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // An attempt to do a TCP FastOpen succeeded immediately
117d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // (FAST_OPEN_FAST_CONNECT_RETURN) and our probe to determine if the
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // socket was using TCP FastOpen failed.
119d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    FAST_OPEN_SYN_DATA_FAILED,
120d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // An attempt to do a TCP FastOpen failed (FAST_OPEN_SLOW_CONNECT_RETURN)
122d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // and we later confirmed that the server had acked initial data.  This
123d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // should never happen (we didn't send data, so it shouldn't have
124d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // been acked).
125d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    FAST_OPEN_NO_SYN_DATA_ACK,
126d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // An attempt to do a TCP FastOpen failed (FAST_OPEN_SLOW_CONNECT_RETURN)
128d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // and we later discovered that the server had nacked initial data.  This
129d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // is the expected case results for FAST_OPEN_SLOW_CONNECT_RETURN.
130d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    FAST_OPEN_NO_SYN_DATA_NACK,
131d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // An attempt to do a TCP FastOpen failed (FAST_OPEN_SLOW_CONNECT_RETURN)
133d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // and our later probe for ack/nack state failed.
134d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    FAST_OPEN_NO_SYN_DATA_FAILED,
135d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
136d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    FAST_OPEN_MAX_VALUE
137d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  };
138d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void AcceptCompleted(scoped_ptr<TCPSocketLibevent>* tcp_socket,
140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       IPEndPoint* address,
141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       const CompletionCallback& callback,
142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       int rv);
143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  int HandleAcceptCompleted(scoped_ptr<TCPSocketLibevent>* tcp_socket,
144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            IPEndPoint* address,
145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            int rv);
146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  int BuildTcpSocketLibevent(scoped_ptr<TCPSocketLibevent>* tcp_socket,
147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                             IPEndPoint* address);
148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void ConnectCompleted(const CompletionCallback& callback, int rv) const;
150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  int HandleConnectCompleted(int rv) const;
151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void LogConnectBegin(const AddressList& addresses) const;
152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void LogConnectEnd(int net_error) const;
153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void ReadCompleted(const scoped_refptr<IOBuffer>& buf,
155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                     const CompletionCallback& callback,
156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                     int rv);
157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  int HandleReadCompleted(IOBuffer* buf, int rv);
158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void WriteCompleted(const scoped_refptr<IOBuffer>& buf,
160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                      const CompletionCallback& callback,
161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                      int rv) const;
162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  int HandleWriteCompleted(IOBuffer* buf, int rv) const;
163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  int TcpFastOpenWrite(IOBuffer* buf,
164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       int buf_len,
165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       const CompletionCallback& callback);
166d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
167d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Called when the socket is known to be in a connected state.
168d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void RecordFastOpenStatus();
169d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<SocketLibevent> socket_;
171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<SocketLibevent> accept_socket_;
172d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
173d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Enables experimental TCP FastOpen option.
1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool use_tcp_fastopen_;
175d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
176d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // True when TCP FastOpen is in use and we have done the connect.
177d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  bool tcp_fastopen_connected_;
178d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  FastOpenStatus fast_open_status_;
179d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
180d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  bool logging_multiple_connect_attempts_;
181d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
18258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BoundNetLog net_log_;
18358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
18458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TCPSocketLibevent);
18558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
18658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
18758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}  // namespace net
18858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
18958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif  // NET_SOCKET_TCP_SOCKET_LIBEVENT_H_
190