• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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