1 // Copyright (c) 2011 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 #pragma once 8 9 #include "base/memory/ref_counted.h" 10 #include "base/memory/scoped_ptr.h" 11 #include "base/message_loop.h" 12 #include "base/threading/non_thread_safe.h" 13 #include "net/base/address_list.h" 14 #include "net/base/completion_callback.h" 15 #include "net/base/net_log.h" 16 #include "net/socket/client_socket.h" 17 18 struct event; // From libevent 19 20 namespace net { 21 22 class BoundNetLog; 23 24 // A client socket that uses TCP as the transport layer. 25 class TCPClientSocketLibevent : public ClientSocket, base::NonThreadSafe { 26 public: 27 // The IP address(es) and port number to connect to. The TCP socket will try 28 // each IP address in the list until it succeeds in establishing a 29 // connection. 30 TCPClientSocketLibevent(const AddressList& addresses, 31 net::NetLog* net_log, 32 const net::NetLog::Source& source); 33 34 virtual ~TCPClientSocketLibevent(); 35 36 // AdoptSocket causes the given, connected socket to be adopted as a TCP 37 // socket. This object must not be connected. This object takes ownership of 38 // the given socket and then acts as if Connect() had been called. This 39 // function is used by TCPServerSocket() to adopt accepted connections 40 // and for testing. 41 void AdoptSocket(int socket); 42 43 // ClientSocket methods: 44 virtual int Connect(CompletionCallback* callback 45 #ifdef ANDROID 46 , bool wait_for_connect 47 , bool valid_uid 48 , uid_t calling_uid 49 #endif 50 ); 51 virtual void Disconnect(); 52 virtual bool IsConnected() const; 53 virtual bool IsConnectedAndIdle() const; 54 virtual int GetPeerAddress(AddressList* address) const; 55 virtual int GetLocalAddress(IPEndPoint* address) const; 56 virtual const BoundNetLog& NetLog() const; 57 virtual void SetSubresourceSpeculation(); 58 virtual void SetOmniboxSpeculation(); 59 virtual bool WasEverUsed() const; 60 virtual bool UsingTCPFastOpen() const; 61 62 // Socket methods: 63 // Multiple outstanding requests are not supported. 64 // Full duplex mode (reading and writing at the same time) is supported 65 virtual int Read(IOBuffer* buf, int buf_len, CompletionCallback* callback); 66 virtual int Write(IOBuffer* buf, int buf_len, CompletionCallback* callback); 67 virtual bool SetReceiveBufferSize(int32 size); 68 virtual bool SetSendBufferSize(int32 size); 69 70 private: 71 // State machine for connecting the socket. 72 enum ConnectState { 73 CONNECT_STATE_CONNECT, 74 CONNECT_STATE_CONNECT_COMPLETE, 75 CONNECT_STATE_NONE, 76 }; 77 78 class ReadWatcher : public MessageLoopForIO::Watcher { 79 public: ReadWatcher(TCPClientSocketLibevent * socket)80 explicit ReadWatcher(TCPClientSocketLibevent* socket) : socket_(socket) {} 81 82 // MessageLoopForIO::Watcher methods 83 OnFileCanReadWithoutBlocking(int)84 virtual void OnFileCanReadWithoutBlocking(int /* fd */) { 85 if (socket_->read_callback_) 86 socket_->DidCompleteRead(); 87 } 88 OnFileCanWriteWithoutBlocking(int)89 virtual void OnFileCanWriteWithoutBlocking(int /* fd */) {} 90 91 private: 92 TCPClientSocketLibevent* const socket_; 93 94 DISALLOW_COPY_AND_ASSIGN(ReadWatcher); 95 }; 96 97 class WriteWatcher : public MessageLoopForIO::Watcher { 98 public: WriteWatcher(TCPClientSocketLibevent * socket)99 explicit WriteWatcher(TCPClientSocketLibevent* socket) : socket_(socket) {} 100 101 // MessageLoopForIO::Watcher methods 102 OnFileCanReadWithoutBlocking(int)103 virtual void OnFileCanReadWithoutBlocking(int /* fd */) {} 104 OnFileCanWriteWithoutBlocking(int)105 virtual void OnFileCanWriteWithoutBlocking(int /* fd */) { 106 if (socket_->waiting_connect()) { 107 socket_->DidCompleteConnect(); 108 } else if (socket_->write_callback_) { 109 socket_->DidCompleteWrite(); 110 } 111 } 112 113 private: 114 TCPClientSocketLibevent* const socket_; 115 116 DISALLOW_COPY_AND_ASSIGN(WriteWatcher); 117 }; 118 119 // State machine used by Connect(). 120 int DoConnectLoop(int result); 121 int DoConnect(); 122 int DoConnectComplete(int result); 123 124 // Helper used by Disconnect(), which disconnects minus the logging and 125 // resetting of current_ai_. 126 void DoDisconnect(); 127 128 void DoReadCallback(int rv); 129 void DoWriteCallback(int rv); 130 void DidCompleteRead(); 131 void DidCompleteWrite(); 132 void DidCompleteConnect(); 133 134 // Returns true if a Connect() is in progress. waiting_connect()135 bool waiting_connect() const { 136 return next_connect_state_ != CONNECT_STATE_NONE; 137 } 138 139 // Returns the OS error code (or 0 on success). 140 int CreateSocket(const struct addrinfo* ai); 141 142 // Returns the OS error code (or 0 on success). 143 int SetupSocket(); 144 145 // Helper to add a TCP_CONNECT (end) event to the NetLog. 146 void LogConnectCompletion(int net_error); 147 148 // Internal function to write to a socket. 149 int InternalWrite(IOBuffer* buf, int buf_len); 150 151 int socket_; 152 153 // The list of addresses we should try in order to establish a connection. 154 AddressList addresses_; 155 156 // Where we are in above list, or NULL if all addrinfos have been tried. 157 const struct addrinfo* current_ai_; 158 159 // The socket's libevent wrappers 160 MessageLoopForIO::FileDescriptorWatcher read_socket_watcher_; 161 MessageLoopForIO::FileDescriptorWatcher write_socket_watcher_; 162 163 // The corresponding watchers for reads and writes. 164 ReadWatcher read_watcher_; 165 WriteWatcher write_watcher_; 166 167 // The buffer used by OnSocketReady to retry Read requests 168 scoped_refptr<IOBuffer> read_buf_; 169 int read_buf_len_; 170 171 // The buffer used by OnSocketReady to retry Write requests 172 scoped_refptr<IOBuffer> write_buf_; 173 int write_buf_len_; 174 175 // External callback; called when read is complete. 176 CompletionCallback* read_callback_; 177 178 // External callback; called when write is complete. 179 CompletionCallback* write_callback_; 180 181 // The next state for the Connect() state machine. 182 ConnectState next_connect_state_; 183 184 // The OS error that CONNECT_STATE_CONNECT last completed with. 185 int connect_os_error_; 186 187 BoundNetLog net_log_; 188 189 // This socket was previously disconnected and has not been re-connected. 190 bool previously_disconnected_; 191 192 // Record of connectivity and transmissions, for use in speculative connection 193 // histograms. 194 UseHistory use_history_; 195 196 // Enables experimental TCP FastOpen option. 197 bool use_tcp_fastopen_; 198 199 // True when TCP FastOpen is in use and we have done the connect. 200 bool tcp_fastopen_connected_; 201 202 #ifdef ANDROID 203 // True if connect should block and not return before the socket is connected 204 bool wait_for_connect_; 205 bool valid_uid_; 206 uid_t calling_uid_; 207 #endif 208 DISALLOW_COPY_AND_ASSIGN(TCPClientSocketLibevent); 209 }; 210 211 } // namespace net 212 213 #endif // NET_SOCKET_TCP_CLIENT_SOCKET_LIBEVENT_H_ 214