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