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