• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 The Chromium Authors
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_WIN_H_
6 #define NET_SOCKET_TCP_SOCKET_WIN_H_
7 
8 #include <winsock2.h>
9 
10 #include <stdint.h>
11 
12 #include <memory>
13 
14 #include "base/check_deref.h"
15 #include "base/memory/raw_ptr.h"
16 #include "base/memory/scoped_refptr.h"
17 #include "base/threading/thread_checker.h"
18 #include "base/win/object_watcher.h"
19 #include "net/base/address_family.h"
20 #include "net/base/completion_once_callback.h"
21 #include "net/base/net_export.h"
22 #include "net/base/network_handle.h"
23 #include "net/log/net_log_with_source.h"
24 #include "net/socket/socket_descriptor.h"
25 #include "net/socket/socket_performance_watcher.h"
26 #include "net/traffic_annotation/network_traffic_annotation.h"
27 
28 namespace net {
29 
30 class TCPSocketDefaultWin;
31 
32 class AddressList;
33 class IOBuffer;
34 class IPEndPoint;
35 class NetLog;
36 struct NetLogSource;
37 class SocketTag;
38 
39 class NET_EXPORT TCPSocketWin : public base::win::ObjectWatcher::Delegate {
40  public:
41   static std::unique_ptr<TCPSocketWin> Create(
42       std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher,
43       NetLog* net_log,
44       const NetLogSource& source);
45   static std::unique_ptr<TCPSocketWin> Create(
46       std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher,
47       NetLogWithSource net_log_source);
48 
49   TCPSocketWin(const TCPSocketWin&) = delete;
50   TCPSocketWin& operator=(const TCPSocketWin&) = delete;
51 
52   // IMPORTANT: All subclasses must call `Close`. The base class cannot do it
53   // because `Close` invokes virtual methods, but it CHECKs that the socket is
54   // closed.
55   ~TCPSocketWin() override;
56 
57   int Open(AddressFamily family);
58 
59   // Takes ownership of `socket`, which is known to already be connected to the
60   // given peer address. However, peer address may be the empty address, for
61   // compatibility. The given peer address will be returned by GetPeerAddress.
62   // `socket` must support overlapped I/O operations operations.
63   int AdoptConnectedSocket(SocketDescriptor socket,
64                            const IPEndPoint& peer_address);
65   // Takes ownership of |socket|, which may or may not be open, bound, or
66   // listening. The caller must determine the state of the socket based on its
67   // provenance and act accordingly. The socket may have connections waiting to
68   // be accepted, but must not be actually connected. `socket` must support
69   // overlapped I/O operations operations.
70   int AdoptUnconnectedSocket(SocketDescriptor socket);
71 
72   int Bind(const IPEndPoint& address);
73 
74   int Listen(int backlog);
75   int Accept(std::unique_ptr<TCPSocketWin>* socket,
76              IPEndPoint* address,
77              CompletionOnceCallback callback);
78 
79   int Connect(const IPEndPoint& address, CompletionOnceCallback callback);
80   bool IsConnected() const;
81   bool IsConnectedAndIdle() const;
82 
83   // Multiple outstanding requests are not supported.
84   // Full duplex mode (reading and writing at the same time) is supported.
85   // These methods can only be called from an IO thread.
86   virtual int Read(IOBuffer* buf,
87                    int buf_len,
88                    CompletionOnceCallback callback) = 0;
89   virtual int ReadIfReady(IOBuffer* buf,
90                           int buf_len,
91                           CompletionOnceCallback callback) = 0;
92   virtual int CancelReadIfReady() = 0;
93   virtual int Write(IOBuffer* buf,
94                     int buf_len,
95                     CompletionOnceCallback callback,
96                     const NetworkTrafficAnnotationTag& traffic_annotation) = 0;
97 
98   int GetLocalAddress(IPEndPoint* address) const;
99   int GetPeerAddress(IPEndPoint* address) const;
100 
101   // Sets various socket options.
102   // The commonly used options for server listening sockets:
103   // - SetExclusiveAddrUse().
104   int SetDefaultOptionsForServer();
105   // The commonly used options for client sockets and accepted sockets:
106   // - SetNoDelay(true);
107   // - SetKeepAlive(true, 45).
108   void SetDefaultOptionsForClient();
109   int SetExclusiveAddrUse();
110   int SetReceiveBufferSize(int32_t size);
111   int SetSendBufferSize(int32_t size);
112   bool SetKeepAlive(bool enable, int delay);
113   bool SetNoDelay(bool no_delay);
114   int SetIPv6Only(bool ipv6_only);
115 
116   // Gets the estimated RTT. Returns false if the RTT is
117   // unavailable. May also return false when estimated RTT is 0.
118   [[nodiscard]] bool GetEstimatedRoundTripTime(base::TimeDelta* out_rtt) const;
119 
120   void Close();
121 
IsValid()122   bool IsValid() const { return socket_ != INVALID_SOCKET; }
123 
124   // Detachs from the current thread, to allow the socket to be transferred to
125   // a new thread. Should only be called when the object is no longer used by
126   // the old thread.
127   void DetachFromThread();
128 
129   // Marks the start/end of a series of connect attempts for logging purpose.
130   //
131   // TCPClientSocket may attempt to connect to multiple addresses until it
132   // succeeds in establishing a connection. The corresponding log will have
133   // multiple NetLogEventType::TCP_CONNECT_ATTEMPT entries nested within a
134   // NetLogEventType::TCP_CONNECT. These methods set the start/end of
135   // NetLogEventType::TCP_CONNECT.
136   //
137   // TODO(yzshen): Change logging format and let TCPClientSocket log the
138   // start/end of a series of connect attempts itself.
139   void StartLoggingMultipleConnectAttempts(const AddressList& addresses);
140   void EndLoggingMultipleConnectAttempts(int net_error);
141 
net_log()142   const NetLogWithSource& net_log() const { return net_log_; }
143 
144   // Return the underlying SocketDescriptor and clean up this object, which may
145   // no longer be used. This method should be used only for testing. No read,
146   // write, or accept operations should be pending.
147   SocketDescriptor ReleaseSocketDescriptorForTesting();
148 
149   // Exposes the underlying socket descriptor for testing its state. Does not
150   // release ownership of the descriptor.
151   SocketDescriptor SocketDescriptorForTesting() const;
152 
153   // Closes the underlying socket descriptor but otherwise keeps this object
154   // functional. Should only be used in `TCPSocketTest`.
155   void CloseSocketDescriptorForTesting();
156 
157   // Apply |tag| to this socket.
158   void ApplySocketTag(const SocketTag& tag);
159 
160   // Not implemented. Returns ERR_NOT_IMPLEMENTED.
161   int BindToNetwork(handles::NetworkHandle network);
162 
163   // May return nullptr.
socket_performance_watcher()164   SocketPerformanceWatcher* socket_performance_watcher() const {
165     return socket_performance_watcher_.get();
166   }
167 
168  protected:
169   friend class TCPSocketDefaultWin;
170 
171   // Encapsulates state that must be preserved while network IO operations are
172   // in progress. If the owning TCPSocketWin is destroyed while an operation is
173   // in progress, the Core is detached and lives until the operation completes
174   // and the OS doesn't reference any resource owned by it.
175   class Core : public base::RefCounted<Core> {
176    public:
177     Core(const Core&) = delete;
178     Core& operator=(const Core&) = delete;
179 
180     // Invoked when the socket is closed. Clears any reference from the `Core`
181     // to its parent socket.
182     virtual void Detach() = 0;
183 
184     // Returns the event to use for watching the completion of a connect()
185     // operation.
186     virtual HANDLE GetConnectEvent() = 0;
187 
188     // Must be invoked after initiating a connect() operation. Will invoke
189     // `DidCompleteConnect()` when the connect() operation is complete.
190     virtual void WatchForConnect() = 0;
191 
192    protected:
193     friend class base::RefCounted<Core>;
194 
195     Core();
196     virtual ~Core();
197   };
198 
199   TCPSocketWin(
200       std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher,
201       NetLog* net_log,
202       const NetLogSource& source);
203 
204   TCPSocketWin(
205       std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher,
206       NetLogWithSource net_log_source);
207 
208   // Instantiates a `Core` object for this socket.
209   virtual scoped_refptr<Core> CreateCore() = 0;
210 
211   // Whether there is a pending read operation on this socket.
212   virtual bool HasPendingRead() const = 0;
213 
214   // Invoked when the socket is closed.
215   virtual void OnClosed() = 0;
216 
217   // base::ObjectWatcher::Delegate implementation.
218   void OnObjectSignaled(HANDLE object) override;
219 
220   int AcceptInternal(std::unique_ptr<TCPSocketWin>* socket,
221                      IPEndPoint* address);
222 
223   int DoConnect();
224   void DoConnectComplete(int result);
225 
226   void LogConnectBegin(const AddressList& addresses);
227   void LogConnectEnd(int net_error);
228 
229   void DidCompleteConnect();
230 
231   SOCKET socket_;
232 
233   // Whether `core_` is registered as an IO handler for `socket_` (see
234   // `base::CurrentIOThread::RegisterIOHandler`). Calling
235   // `ReleaseSocketDescriptorForTesting()` is disallowed when this is true, as
236   // that could result in `core_` being notified of operations that weren't
237   // issued by `this` (possibly after `core_` has been deleted).
238   bool registered_as_io_handler_ = false;
239 
240   // |socket_performance_watcher_| may be nullptr.
241   std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher_;
242 
243   HANDLE accept_event_;
244   base::win::ObjectWatcher accept_watcher_;
245 
246   raw_ptr<std::unique_ptr<TCPSocketWin>> accept_socket_ = nullptr;
247   raw_ptr<IPEndPoint> accept_address_ = nullptr;
248   CompletionOnceCallback accept_callback_;
249 
250   // The core of the socket that can live longer than the socket itself. We pass
251   // resources to the Windows async IO functions and we have to make sure that
252   // they are not destroyed while the OS still references them.
253   scoped_refptr<Core> core_;
254 
255   // Callback invoked when connect is complete.
256   CompletionOnceCallback connect_callback_;
257 
258   std::unique_ptr<IPEndPoint> peer_address_;
259   // The OS error that a connect attempt last completed with.
260   int connect_os_error_ = 0;
261 
262   bool logging_multiple_connect_attempts_ = false;
263 
264   NetLogWithSource net_log_;
265 
266   THREAD_CHECKER(thread_checker_);
267 };
268 
269 }  // namespace net
270 
271 #endif  // NET_SOCKET_TCP_SOCKET_WIN_H_
272