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