xref: /aosp_15_r20/external/cronet/net/socket/tcp_socket_win.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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/memory/raw_ptr.h"
15 #include "base/memory/scoped_refptr.h"
16 #include "base/threading/thread_checker.h"
17 #include "base/win/object_watcher.h"
18 #include "net/base/address_family.h"
19 #include "net/base/completion_once_callback.h"
20 #include "net/base/net_export.h"
21 #include "net/base/network_handle.h"
22 #include "net/log/net_log_with_source.h"
23 #include "net/socket/socket_descriptor.h"
24 #include "net/socket/socket_performance_watcher.h"
25 #include "net/traffic_annotation/network_traffic_annotation.h"
26 
27 namespace net {
28 
29 class AddressList;
30 class IOBuffer;
31 class IPEndPoint;
32 class NetLog;
33 struct NetLogSource;
34 class SocketTag;
35 
36 class NET_EXPORT TCPSocketWin : public base::win::ObjectWatcher::Delegate {
37  public:
38   TCPSocketWin(
39       std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher,
40       NetLog* net_log,
41       const NetLogSource& source);
42 
43   TCPSocketWin(
44       std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher,
45       NetLogWithSource net_log_source);
46 
47   TCPSocketWin(const TCPSocketWin&) = delete;
48   TCPSocketWin& operator=(const TCPSocketWin&) = delete;
49 
50   ~TCPSocketWin() override;
51 
52   int Open(AddressFamily family);
53 
54   // Takes ownership of |socket|, which is known to already be connected to the
55   // given peer address. However, peer address may be the empty address, for
56   // compatibility. The given peer address will be returned by GetPeerAddress.
57   int AdoptConnectedSocket(SocketDescriptor socket,
58                            const IPEndPoint& peer_address);
59   // Takes ownership of |socket|, which may or may not be open, bound, or
60   // listening. The caller must determine the state of the socket based on its
61   // provenance and act accordingly. The socket may have connections waiting
62   // to be accepted, but must not be actually connected.
63   int AdoptUnconnectedSocket(SocketDescriptor socket);
64 
65   int Bind(const IPEndPoint& address);
66 
67   int Listen(int backlog);
68   int Accept(std::unique_ptr<TCPSocketWin>* socket,
69              IPEndPoint* address,
70              CompletionOnceCallback callback);
71 
72   int Connect(const IPEndPoint& address, CompletionOnceCallback callback);
73   bool IsConnected() const;
74   bool IsConnectedAndIdle() const;
75 
76   // Multiple outstanding requests are not supported.
77   // Full duplex mode (reading and writing at the same time) is supported.
78   int Read(IOBuffer* buf, int buf_len, CompletionOnceCallback callback);
79   int ReadIfReady(IOBuffer* buf, int buf_len, CompletionOnceCallback callback);
80   int CancelReadIfReady();
81   int Write(IOBuffer* buf,
82             int buf_len,
83             CompletionOnceCallback callback,
84             const NetworkTrafficAnnotationTag& traffic_annotation);
85 
86   int GetLocalAddress(IPEndPoint* address) const;
87   int GetPeerAddress(IPEndPoint* address) const;
88 
89   // Sets various socket options.
90   // The commonly used options for server listening sockets:
91   // - SetExclusiveAddrUse().
92   int SetDefaultOptionsForServer();
93   // The commonly used options for client sockets and accepted sockets:
94   // - SetNoDelay(true);
95   // - SetKeepAlive(true, 45).
96   void SetDefaultOptionsForClient();
97   int SetExclusiveAddrUse();
98   int SetReceiveBufferSize(int32_t size);
99   int SetSendBufferSize(int32_t size);
100   bool SetKeepAlive(bool enable, int delay);
101   bool SetNoDelay(bool no_delay);
102   int SetIPv6Only(bool ipv6_only);
103 
104   // Gets the estimated RTT. Returns false if the RTT is
105   // unavailable. May also return false when estimated RTT is 0.
106   [[nodiscard]] bool GetEstimatedRoundTripTime(base::TimeDelta* out_rtt) const;
107 
108   void Close();
109 
IsValid()110   bool IsValid() const { return socket_ != INVALID_SOCKET; }
111 
112   // Detachs from the current thread, to allow the socket to be transferred to
113   // a new thread. Should only be called when the object is no longer used by
114   // the old thread.
115   void DetachFromThread();
116 
117   // Marks the start/end of a series of connect attempts for logging purpose.
118   //
119   // TCPClientSocket may attempt to connect to multiple addresses until it
120   // succeeds in establishing a connection. The corresponding log will have
121   // multiple NetLogEventType::TCP_CONNECT_ATTEMPT entries nested within a
122   // NetLogEventType::TCP_CONNECT. These methods set the start/end of
123   // NetLogEventType::TCP_CONNECT.
124   //
125   // TODO(yzshen): Change logging format and let TCPClientSocket log the
126   // start/end of a series of connect attempts itself.
127   void StartLoggingMultipleConnectAttempts(const AddressList& addresses);
128   void EndLoggingMultipleConnectAttempts(int net_error);
129 
net_log()130   const NetLogWithSource& net_log() const { return net_log_; }
131 
132   // Return the underlying SocketDescriptor and clean up this object, which may
133   // no longer be used. This method should be used only for testing. No read,
134   // write, or accept operations should be pending.
135   SocketDescriptor ReleaseSocketDescriptorForTesting();
136 
137   // Exposes the underlying socket descriptor for testing its state. Does not
138   // release ownership of the descriptor.
139   SocketDescriptor SocketDescriptorForTesting() const;
140 
141   // Apply |tag| to this socket.
142   void ApplySocketTag(const SocketTag& tag);
143 
144   // Not implemented. Returns ERR_NOT_IMPLEMENTED.
145   int BindToNetwork(handles::NetworkHandle network);
146 
147   // May return nullptr.
socket_performance_watcher()148   SocketPerformanceWatcher* socket_performance_watcher() const {
149     return socket_performance_watcher_.get();
150   }
151 
152  private:
153   class Core;
154 
155   // base::ObjectWatcher::Delegate implementation.
156   void OnObjectSignaled(HANDLE object) override;
157 
158   int AcceptInternal(std::unique_ptr<TCPSocketWin>* 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 RetryRead(int rv);
168   void DidCompleteConnect();
169   void DidCompleteWrite();
170   void DidSignalRead();
171 
172   SOCKET socket_;
173 
174   // |socket_performance_watcher_| may be nullptr.
175   std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher_;
176 
177   HANDLE accept_event_;
178   base::win::ObjectWatcher accept_watcher_;
179 
180   raw_ptr<std::unique_ptr<TCPSocketWin>> accept_socket_ = nullptr;
181   raw_ptr<IPEndPoint> accept_address_ = nullptr;
182   CompletionOnceCallback accept_callback_;
183 
184   // The various states that the socket could be in.
185   bool waiting_connect_ = false;
186   bool waiting_read_ = false;
187   bool waiting_write_ = false;
188 
189   // The core of the socket that can live longer than the socket itself. We pass
190   // resources to the Windows async IO functions and we have to make sure that
191   // they are not destroyed while the OS still references them.
192   scoped_refptr<Core> core_;
193 
194   // External callback; called when connect or read is complete.
195   CompletionOnceCallback read_callback_;
196 
197   // Non-null if a ReadIfReady() is to be completed asynchronously. This is an
198   // external callback if user used ReadIfReady() instead of Read(), but a
199   // wrapped callback on top of RetryRead() if Read() is used.
200   CompletionOnceCallback read_if_ready_callback_;
201 
202   // External callback; called when write is complete.
203   CompletionOnceCallback write_callback_;
204 
205   std::unique_ptr<IPEndPoint> peer_address_;
206   // The OS error that a connect attempt last completed with.
207   int connect_os_error_ = 0;
208 
209   bool logging_multiple_connect_attempts_ = false;
210 
211   NetLogWithSource net_log_;
212 
213   THREAD_CHECKER(thread_checker_);
214 };
215 
216 }  // namespace net
217 
218 #endif  // NET_SOCKET_TCP_SOCKET_WIN_H_
219