• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   bool SetReceiveBufferSize(int32 size);
65   bool 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;
IsValid()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 
net_log()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