| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 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 | |
| 8 #include "base/memory/ref_counted.h" | |
| 9 #include "base/memory/scoped_ptr.h" | |
| 10 #include "base/message_loop/message_loop.h" | |
| 11 #include "base/threading/non_thread_safe.h" | |
| 12 #include "net/base/address_list.h" | |
| 13 #include "net/base/completion_callback.h" | |
| 14 #include "net/base/net_log.h" | |
| 15 #include "net/socket/stream_socket.h" | |
| 16 | |
| 17 namespace net { | |
| 18 | |
| 19 class BoundNetLog; | |
| 20 | |
| 21 // A client socket that uses TCP as the transport layer. | |
| 22 class NET_EXPORT_PRIVATE TCPClientSocketLibevent : public StreamSocket, | |
| 23 public base::NonThreadSafe { | |
| 24 public: | |
| 25 // The IP address(es) and port number to connect to. The TCP socket will try | |
| 26 // each IP address in the list until it succeeds in establishing a | |
| 27 // connection. | |
| 28 TCPClientSocketLibevent(const AddressList& addresses, | |
| 29 net::NetLog* net_log, | |
| 30 const net::NetLog::Source& source); | |
| 31 | |
| 32 virtual ~TCPClientSocketLibevent(); | |
| 33 | |
| 34 // AdoptSocket causes the given, connected socket to be adopted as a TCP | |
| 35 // socket. This object must not be connected. This object takes ownership of | |
| 36 // the given socket and then acts as if Connect() had been called. This | |
| 37 // function is used by TCPServerSocket() to adopt accepted connections | |
| 38 // and for testing. | |
| 39 int AdoptSocket(int socket); | |
| 40 | |
| 41 // Binds the socket to a local IP address and port. | |
| 42 int Bind(const IPEndPoint& address); | |
| 43 | |
| 44 // StreamSocket implementation. | |
| 45 virtual int Connect(const CompletionCallback& callback) OVERRIDE; | |
| 46 virtual void Disconnect() OVERRIDE; | |
| 47 virtual bool IsConnected() const OVERRIDE; | |
| 48 virtual bool IsConnectedAndIdle() const OVERRIDE; | |
| 49 virtual int GetPeerAddress(IPEndPoint* address) const OVERRIDE; | |
| 50 virtual int GetLocalAddress(IPEndPoint* address) const OVERRIDE; | |
| 51 virtual const BoundNetLog& NetLog() const OVERRIDE; | |
| 52 virtual void SetSubresourceSpeculation() OVERRIDE; | |
| 53 virtual void SetOmniboxSpeculation() OVERRIDE; | |
| 54 virtual bool WasEverUsed() const OVERRIDE; | |
| 55 virtual bool UsingTCPFastOpen() const OVERRIDE; | |
| 56 virtual bool WasNpnNegotiated() const OVERRIDE; | |
| 57 virtual NextProto GetNegotiatedProtocol() const OVERRIDE; | |
| 58 virtual bool GetSSLInfo(SSLInfo* ssl_info) OVERRIDE; | |
| 59 | |
| 60 // Socket implementation. | |
| 61 // Multiple outstanding requests are not supported. | |
| 62 // Full duplex mode (reading and writing at the same time) is supported | |
| 63 virtual int Read(IOBuffer* buf, | |
| 64 int buf_len, | |
| 65 const CompletionCallback& callback) OVERRIDE; | |
| 66 virtual int Write(IOBuffer* buf, | |
| 67 int buf_len, | |
| 68 const CompletionCallback& callback) OVERRIDE; | |
| 69 virtual bool SetReceiveBufferSize(int32 size) OVERRIDE; | |
| 70 virtual bool SetSendBufferSize(int32 size) OVERRIDE; | |
| 71 | |
| 72 virtual bool SetKeepAlive(bool enable, int delay); | |
| 73 virtual bool SetNoDelay(bool no_delay); | |
| 74 | |
| 75 private: | |
| 76 // State machine for connecting the socket. | |
| 77 enum ConnectState { | |
| 78 CONNECT_STATE_CONNECT, | |
| 79 CONNECT_STATE_CONNECT_COMPLETE, | |
| 80 CONNECT_STATE_NONE, | |
| 81 }; | |
| 82 | |
| 83 // States that a fast open socket attempt can result in. | |
| 84 enum FastOpenStatus { | |
| 85 FAST_OPEN_STATUS_UNKNOWN, | |
| 86 | |
| 87 // The initial fast open connect attempted returned synchronously, | |
| 88 // indicating that we had and sent a cookie along with the initial data. | |
| 89 FAST_OPEN_FAST_CONNECT_RETURN, | |
| 90 | |
| 91 // The initial fast open connect attempted returned asynchronously, | |
| 92 // indicating that we did not have a cookie for the server. | |
| 93 FAST_OPEN_SLOW_CONNECT_RETURN, | |
| 94 | |
| 95 // Some other error occurred on connection, so we couldn't tell if | |
| 96 // fast open would have worked. | |
| 97 FAST_OPEN_ERROR, | |
| 98 | |
| 99 // An attempt to do a fast open succeeded immediately | |
| 100 // (FAST_OPEN_FAST_CONNECT_RETURN) and we later confirmed that the server | |
| 101 // had acked the data we sent. | |
| 102 FAST_OPEN_SYN_DATA_ACK, | |
| 103 | |
| 104 // An attempt to do a fast open succeeded immediately | |
| 105 // (FAST_OPEN_FAST_CONNECT_RETURN) and we later confirmed that the server | |
| 106 // had nacked the data we sent. | |
| 107 FAST_OPEN_SYN_DATA_NACK, | |
| 108 | |
| 109 // An attempt to do a fast open succeeded immediately | |
| 110 // (FAST_OPEN_FAST_CONNECT_RETURN) and our probe to determine if the | |
| 111 // socket was using fast open failed. | |
| 112 FAST_OPEN_SYN_DATA_FAILED, | |
| 113 | |
| 114 // An attempt to do a fast open failed (FAST_OPEN_SLOW_CONNECT_RETURN) | |
| 115 // and we later confirmed that the server had acked initial data. This | |
| 116 // should never happen (we didn't send data, so it shouldn't have | |
| 117 // been acked). | |
| 118 FAST_OPEN_NO_SYN_DATA_ACK, | |
| 119 | |
| 120 // An attempt to do a fast open failed (FAST_OPEN_SLOW_CONNECT_RETURN) | |
| 121 // and we later discovered that the server had nacked initial data. This | |
| 122 // is the expected case results for FAST_OPEN_SLOW_CONNECT_RETURN. | |
| 123 FAST_OPEN_NO_SYN_DATA_NACK, | |
| 124 | |
| 125 // An attempt to do a fast open failed (FAST_OPEN_SLOW_CONNECT_RETURN) | |
| 126 // and our later probe for ack/nack state failed. | |
| 127 FAST_OPEN_NO_SYN_DATA_FAILED, | |
| 128 | |
| 129 FAST_OPEN_MAX_VALUE | |
| 130 }; | |
| 131 | |
| 132 class ReadWatcher : public base::MessageLoopForIO::Watcher { | |
| 133 public: | |
| 134 explicit ReadWatcher(TCPClientSocketLibevent* socket) : socket_(socket) {} | |
| 135 | |
| 136 // MessageLoopForIO::Watcher methods | |
| 137 | |
| 138 virtual void OnFileCanReadWithoutBlocking(int /* fd */) OVERRIDE; | |
| 139 | |
| 140 virtual void OnFileCanWriteWithoutBlocking(int /* fd */) OVERRIDE {} | |
| 141 | |
| 142 private: | |
| 143 TCPClientSocketLibevent* const socket_; | |
| 144 | |
| 145 DISALLOW_COPY_AND_ASSIGN(ReadWatcher); | |
| 146 }; | |
| 147 | |
| 148 class WriteWatcher : public base::MessageLoopForIO::Watcher { | |
| 149 public: | |
| 150 explicit WriteWatcher(TCPClientSocketLibevent* socket) : socket_(socket) {} | |
| 151 | |
| 152 // MessageLoopForIO::Watcher implementation. | |
| 153 virtual void OnFileCanReadWithoutBlocking(int /* fd */) OVERRIDE {} | |
| 154 virtual void OnFileCanWriteWithoutBlocking(int /* fd */) OVERRIDE; | |
| 155 | |
| 156 private: | |
| 157 TCPClientSocketLibevent* const socket_; | |
| 158 | |
| 159 DISALLOW_COPY_AND_ASSIGN(WriteWatcher); | |
| 160 }; | |
| 161 | |
| 162 // State machine used by Connect(). | |
| 163 int DoConnectLoop(int result); | |
| 164 int DoConnect(); | |
| 165 int DoConnectComplete(int result); | |
| 166 | |
| 167 // Helper used by Disconnect(), which disconnects minus the logging and | |
| 168 // resetting of current_address_index_. | |
| 169 void DoDisconnect(); | |
| 170 | |
| 171 void DoReadCallback(int rv); | |
| 172 void DoWriteCallback(int rv); | |
| 173 void DidCompleteRead(); | |
| 174 void DidCompleteWrite(); | |
| 175 void DidCompleteConnect(); | |
| 176 | |
| 177 // Returns true if a Connect() is in progress. | |
| 178 bool waiting_connect() const { | |
| 179 return next_connect_state_ != CONNECT_STATE_NONE; | |
| 180 } | |
| 181 | |
| 182 // Helper to add a TCP_CONNECT (end) event to the NetLog. | |
| 183 void LogConnectCompletion(int net_error); | |
| 184 | |
| 185 // Internal function to write to a socket. | |
| 186 int InternalWrite(IOBuffer* buf, int buf_len); | |
| 187 | |
| 188 // Called when the socket is known to be in a connected state. | |
| 189 void RecordFastOpenStatus(); | |
| 190 | |
| 191 int socket_; | |
| 192 | |
| 193 // Local IP address and port we are bound to. Set to NULL if Bind() | |
| 194 // was't called (in that cases OS chooses address/port). | |
| 195 scoped_ptr<IPEndPoint> bind_address_; | |
| 196 | |
| 197 // Stores bound socket between Bind() and Connect() calls. | |
| 198 int bound_socket_; | |
| 199 | |
| 200 // The list of addresses we should try in order to establish a connection. | |
| 201 AddressList addresses_; | |
| 202 | |
| 203 // Where we are in above list. Set to -1 if uninitialized. | |
| 204 int current_address_index_; | |
| 205 | |
| 206 // The socket's libevent wrappers | |
| 207 base::MessageLoopForIO::FileDescriptorWatcher read_socket_watcher_; | |
| 208 base::MessageLoopForIO::FileDescriptorWatcher write_socket_watcher_; | |
| 209 | |
| 210 // The corresponding watchers for reads and writes. | |
| 211 ReadWatcher read_watcher_; | |
| 212 WriteWatcher write_watcher_; | |
| 213 | |
| 214 // The buffer used by OnSocketReady to retry Read requests | |
| 215 scoped_refptr<IOBuffer> read_buf_; | |
| 216 int read_buf_len_; | |
| 217 | |
| 218 // The buffer used by OnSocketReady to retry Write requests | |
| 219 scoped_refptr<IOBuffer> write_buf_; | |
| 220 int write_buf_len_; | |
| 221 | |
| 222 // External callback; called when read is complete. | |
| 223 CompletionCallback read_callback_; | |
| 224 | |
| 225 // External callback; called when write is complete. | |
| 226 CompletionCallback write_callback_; | |
| 227 | |
| 228 // The next state for the Connect() state machine. | |
| 229 ConnectState next_connect_state_; | |
| 230 | |
| 231 // The OS error that CONNECT_STATE_CONNECT last completed with. | |
| 232 int connect_os_error_; | |
| 233 | |
| 234 BoundNetLog net_log_; | |
| 235 | |
| 236 // This socket was previously disconnected and has not been re-connected. | |
| 237 bool previously_disconnected_; | |
| 238 | |
| 239 // Record of connectivity and transmissions, for use in speculative connection | |
| 240 // histograms. | |
| 241 UseHistory use_history_; | |
| 242 | |
| 243 // Enables experimental TCP FastOpen option. | |
| 244 const bool use_tcp_fastopen_; | |
| 245 | |
| 246 // True when TCP FastOpen is in use and we have done the connect. | |
| 247 bool tcp_fastopen_connected_; | |
| 248 | |
| 249 enum FastOpenStatus fast_open_status_; | |
| 250 | |
| 251 DISALLOW_COPY_AND_ASSIGN(TCPClientSocketLibevent); | |
| 252 }; | |
| 253 | |
| 254 } // namespace net | |
| 255 | |
| 256 #endif // NET_SOCKET_TCP_CLIENT_SOCKET_LIBEVENT_H_ | |
| OLD | NEW |