xref: /aosp_15_r20/external/cronet/net/socket/socket_posix.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2014 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "net/socket/socket_posix.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <errno.h>
8*6777b538SAndroid Build Coastguard Worker #include <netinet/in.h>
9*6777b538SAndroid Build Coastguard Worker #include <sys/socket.h>
10*6777b538SAndroid Build Coastguard Worker 
11*6777b538SAndroid Build Coastguard Worker #include <memory>
12*6777b538SAndroid Build Coastguard Worker #include <utility>
13*6777b538SAndroid Build Coastguard Worker 
14*6777b538SAndroid Build Coastguard Worker #include "base/files/file_util.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback_helpers.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/logging.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/posix/eintr_wrapper.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/task/current_thread.h"
20*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
21*6777b538SAndroid Build Coastguard Worker #include "net/base/io_buffer.h"
22*6777b538SAndroid Build Coastguard Worker #include "net/base/ip_endpoint.h"
23*6777b538SAndroid Build Coastguard Worker #include "net/base/net_errors.h"
24*6777b538SAndroid Build Coastguard Worker #include "net/base/sockaddr_storage.h"
25*6777b538SAndroid Build Coastguard Worker #include "net/base/trace_constants.h"
26*6777b538SAndroid Build Coastguard Worker #include "net/base/tracing.h"
27*6777b538SAndroid Build Coastguard Worker #include "net/traffic_annotation/network_traffic_annotation.h"
28*6777b538SAndroid Build Coastguard Worker 
29*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_FUCHSIA)
30*6777b538SAndroid Build Coastguard Worker #include <poll.h>
31*6777b538SAndroid Build Coastguard Worker #include <sys/ioctl.h>
32*6777b538SAndroid Build Coastguard Worker #endif  // BUILDFLAG(IS_FUCHSIA)
33*6777b538SAndroid Build Coastguard Worker 
34*6777b538SAndroid Build Coastguard Worker namespace net {
35*6777b538SAndroid Build Coastguard Worker 
36*6777b538SAndroid Build Coastguard Worker namespace {
37*6777b538SAndroid Build Coastguard Worker 
MapAcceptError(int os_error)38*6777b538SAndroid Build Coastguard Worker int MapAcceptError(int os_error) {
39*6777b538SAndroid Build Coastguard Worker   switch (os_error) {
40*6777b538SAndroid Build Coastguard Worker     // If the client aborts the connection before the server calls accept,
41*6777b538SAndroid Build Coastguard Worker     // POSIX specifies accept should fail with ECONNABORTED. The server can
42*6777b538SAndroid Build Coastguard Worker     // ignore the error and just call accept again, so we map the error to
43*6777b538SAndroid Build Coastguard Worker     // ERR_IO_PENDING. See UNIX Network Programming, Vol. 1, 3rd Ed., Sec.
44*6777b538SAndroid Build Coastguard Worker     // 5.11, "Connection Abort before accept Returns".
45*6777b538SAndroid Build Coastguard Worker     case ECONNABORTED:
46*6777b538SAndroid Build Coastguard Worker       return ERR_IO_PENDING;
47*6777b538SAndroid Build Coastguard Worker     default:
48*6777b538SAndroid Build Coastguard Worker       return MapSystemError(os_error);
49*6777b538SAndroid Build Coastguard Worker   }
50*6777b538SAndroid Build Coastguard Worker }
51*6777b538SAndroid Build Coastguard Worker 
MapConnectError(int os_error)52*6777b538SAndroid Build Coastguard Worker int MapConnectError(int os_error) {
53*6777b538SAndroid Build Coastguard Worker   switch (os_error) {
54*6777b538SAndroid Build Coastguard Worker     case EINPROGRESS:
55*6777b538SAndroid Build Coastguard Worker       return ERR_IO_PENDING;
56*6777b538SAndroid Build Coastguard Worker     case EACCES:
57*6777b538SAndroid Build Coastguard Worker       return ERR_NETWORK_ACCESS_DENIED;
58*6777b538SAndroid Build Coastguard Worker     case ETIMEDOUT:
59*6777b538SAndroid Build Coastguard Worker       return ERR_CONNECTION_TIMED_OUT;
60*6777b538SAndroid Build Coastguard Worker     default: {
61*6777b538SAndroid Build Coastguard Worker       int net_error = MapSystemError(os_error);
62*6777b538SAndroid Build Coastguard Worker       if (net_error == ERR_FAILED)
63*6777b538SAndroid Build Coastguard Worker         return ERR_CONNECTION_FAILED;  // More specific than ERR_FAILED.
64*6777b538SAndroid Build Coastguard Worker       return net_error;
65*6777b538SAndroid Build Coastguard Worker     }
66*6777b538SAndroid Build Coastguard Worker   }
67*6777b538SAndroid Build Coastguard Worker }
68*6777b538SAndroid Build Coastguard Worker 
69*6777b538SAndroid Build Coastguard Worker }  // namespace
70*6777b538SAndroid Build Coastguard Worker 
SocketPosix()71*6777b538SAndroid Build Coastguard Worker SocketPosix::SocketPosix()
72*6777b538SAndroid Build Coastguard Worker     : socket_fd_(kInvalidSocket),
73*6777b538SAndroid Build Coastguard Worker       accept_socket_watcher_(FROM_HERE),
74*6777b538SAndroid Build Coastguard Worker       read_socket_watcher_(FROM_HERE),
75*6777b538SAndroid Build Coastguard Worker       write_socket_watcher_(FROM_HERE) {}
76*6777b538SAndroid Build Coastguard Worker 
~SocketPosix()77*6777b538SAndroid Build Coastguard Worker SocketPosix::~SocketPosix() {
78*6777b538SAndroid Build Coastguard Worker   Close();
79*6777b538SAndroid Build Coastguard Worker }
80*6777b538SAndroid Build Coastguard Worker 
Open(int address_family)81*6777b538SAndroid Build Coastguard Worker int SocketPosix::Open(int address_family) {
82*6777b538SAndroid Build Coastguard Worker   DCHECK(thread_checker_.CalledOnValidThread());
83*6777b538SAndroid Build Coastguard Worker   DCHECK_EQ(kInvalidSocket, socket_fd_);
84*6777b538SAndroid Build Coastguard Worker   DCHECK(address_family == AF_INET ||
85*6777b538SAndroid Build Coastguard Worker          address_family == AF_INET6 ||
86*6777b538SAndroid Build Coastguard Worker          address_family == AF_UNIX);
87*6777b538SAndroid Build Coastguard Worker 
88*6777b538SAndroid Build Coastguard Worker   socket_fd_ = CreatePlatformSocket(
89*6777b538SAndroid Build Coastguard Worker       address_family,
90*6777b538SAndroid Build Coastguard Worker       SOCK_STREAM,
91*6777b538SAndroid Build Coastguard Worker       address_family == AF_UNIX ? 0 : IPPROTO_TCP);
92*6777b538SAndroid Build Coastguard Worker   if (socket_fd_ < 0) {
93*6777b538SAndroid Build Coastguard Worker     PLOG(ERROR) << "CreatePlatformSocket() failed";
94*6777b538SAndroid Build Coastguard Worker     return MapSystemError(errno);
95*6777b538SAndroid Build Coastguard Worker   }
96*6777b538SAndroid Build Coastguard Worker 
97*6777b538SAndroid Build Coastguard Worker   if (!base::SetNonBlocking(socket_fd_)) {
98*6777b538SAndroid Build Coastguard Worker     int rv = MapSystemError(errno);
99*6777b538SAndroid Build Coastguard Worker     Close();
100*6777b538SAndroid Build Coastguard Worker     return rv;
101*6777b538SAndroid Build Coastguard Worker   }
102*6777b538SAndroid Build Coastguard Worker 
103*6777b538SAndroid Build Coastguard Worker   return OK;
104*6777b538SAndroid Build Coastguard Worker }
105*6777b538SAndroid Build Coastguard Worker 
AdoptConnectedSocket(SocketDescriptor socket,const SockaddrStorage & address)106*6777b538SAndroid Build Coastguard Worker int SocketPosix::AdoptConnectedSocket(SocketDescriptor socket,
107*6777b538SAndroid Build Coastguard Worker                                       const SockaddrStorage& address) {
108*6777b538SAndroid Build Coastguard Worker   int rv = AdoptUnconnectedSocket(socket);
109*6777b538SAndroid Build Coastguard Worker   if (rv != OK)
110*6777b538SAndroid Build Coastguard Worker     return rv;
111*6777b538SAndroid Build Coastguard Worker 
112*6777b538SAndroid Build Coastguard Worker   SetPeerAddress(address);
113*6777b538SAndroid Build Coastguard Worker   return OK;
114*6777b538SAndroid Build Coastguard Worker }
115*6777b538SAndroid Build Coastguard Worker 
AdoptUnconnectedSocket(SocketDescriptor socket)116*6777b538SAndroid Build Coastguard Worker int SocketPosix::AdoptUnconnectedSocket(SocketDescriptor socket) {
117*6777b538SAndroid Build Coastguard Worker   DCHECK(thread_checker_.CalledOnValidThread());
118*6777b538SAndroid Build Coastguard Worker   DCHECK_EQ(kInvalidSocket, socket_fd_);
119*6777b538SAndroid Build Coastguard Worker 
120*6777b538SAndroid Build Coastguard Worker   socket_fd_ = socket;
121*6777b538SAndroid Build Coastguard Worker 
122*6777b538SAndroid Build Coastguard Worker   if (!base::SetNonBlocking(socket_fd_)) {
123*6777b538SAndroid Build Coastguard Worker     int rv = MapSystemError(errno);
124*6777b538SAndroid Build Coastguard Worker     Close();
125*6777b538SAndroid Build Coastguard Worker     return rv;
126*6777b538SAndroid Build Coastguard Worker   }
127*6777b538SAndroid Build Coastguard Worker 
128*6777b538SAndroid Build Coastguard Worker   return OK;
129*6777b538SAndroid Build Coastguard Worker }
130*6777b538SAndroid Build Coastguard Worker 
ReleaseConnectedSocket()131*6777b538SAndroid Build Coastguard Worker SocketDescriptor SocketPosix::ReleaseConnectedSocket() {
132*6777b538SAndroid Build Coastguard Worker   // It's not safe to release a socket with a pending write.
133*6777b538SAndroid Build Coastguard Worker   DCHECK(!write_buf_);
134*6777b538SAndroid Build Coastguard Worker 
135*6777b538SAndroid Build Coastguard Worker   StopWatchingAndCleanUp(false /* close_socket */);
136*6777b538SAndroid Build Coastguard Worker   SocketDescriptor socket_fd = socket_fd_;
137*6777b538SAndroid Build Coastguard Worker   socket_fd_ = kInvalidSocket;
138*6777b538SAndroid Build Coastguard Worker   return socket_fd;
139*6777b538SAndroid Build Coastguard Worker }
140*6777b538SAndroid Build Coastguard Worker 
Bind(const SockaddrStorage & address)141*6777b538SAndroid Build Coastguard Worker int SocketPosix::Bind(const SockaddrStorage& address) {
142*6777b538SAndroid Build Coastguard Worker   DCHECK(thread_checker_.CalledOnValidThread());
143*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(kInvalidSocket, socket_fd_);
144*6777b538SAndroid Build Coastguard Worker 
145*6777b538SAndroid Build Coastguard Worker   int rv = bind(socket_fd_, address.addr, address.addr_len);
146*6777b538SAndroid Build Coastguard Worker   if (rv < 0) {
147*6777b538SAndroid Build Coastguard Worker     PLOG(ERROR) << "bind() failed";
148*6777b538SAndroid Build Coastguard Worker     return MapSystemError(errno);
149*6777b538SAndroid Build Coastguard Worker   }
150*6777b538SAndroid Build Coastguard Worker 
151*6777b538SAndroid Build Coastguard Worker   return OK;
152*6777b538SAndroid Build Coastguard Worker }
153*6777b538SAndroid Build Coastguard Worker 
Listen(int backlog)154*6777b538SAndroid Build Coastguard Worker int SocketPosix::Listen(int backlog) {
155*6777b538SAndroid Build Coastguard Worker   DCHECK(thread_checker_.CalledOnValidThread());
156*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(kInvalidSocket, socket_fd_);
157*6777b538SAndroid Build Coastguard Worker   DCHECK_LT(0, backlog);
158*6777b538SAndroid Build Coastguard Worker 
159*6777b538SAndroid Build Coastguard Worker   int rv = listen(socket_fd_, backlog);
160*6777b538SAndroid Build Coastguard Worker   if (rv < 0) {
161*6777b538SAndroid Build Coastguard Worker     PLOG(ERROR) << "listen() failed";
162*6777b538SAndroid Build Coastguard Worker     return MapSystemError(errno);
163*6777b538SAndroid Build Coastguard Worker   }
164*6777b538SAndroid Build Coastguard Worker 
165*6777b538SAndroid Build Coastguard Worker   return OK;
166*6777b538SAndroid Build Coastguard Worker }
167*6777b538SAndroid Build Coastguard Worker 
Accept(std::unique_ptr<SocketPosix> * socket,CompletionOnceCallback callback)168*6777b538SAndroid Build Coastguard Worker int SocketPosix::Accept(std::unique_ptr<SocketPosix>* socket,
169*6777b538SAndroid Build Coastguard Worker                         CompletionOnceCallback callback) {
170*6777b538SAndroid Build Coastguard Worker   DCHECK(thread_checker_.CalledOnValidThread());
171*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(kInvalidSocket, socket_fd_);
172*6777b538SAndroid Build Coastguard Worker   DCHECK(accept_callback_.is_null());
173*6777b538SAndroid Build Coastguard Worker   DCHECK(socket);
174*6777b538SAndroid Build Coastguard Worker   DCHECK(!callback.is_null());
175*6777b538SAndroid Build Coastguard Worker 
176*6777b538SAndroid Build Coastguard Worker   int rv = DoAccept(socket);
177*6777b538SAndroid Build Coastguard Worker   if (rv != ERR_IO_PENDING)
178*6777b538SAndroid Build Coastguard Worker     return rv;
179*6777b538SAndroid Build Coastguard Worker 
180*6777b538SAndroid Build Coastguard Worker   if (!base::CurrentIOThread::Get()->WatchFileDescriptor(
181*6777b538SAndroid Build Coastguard Worker           socket_fd_, true, base::MessagePumpForIO::WATCH_READ,
182*6777b538SAndroid Build Coastguard Worker           &accept_socket_watcher_, this)) {
183*6777b538SAndroid Build Coastguard Worker     PLOG(ERROR) << "WatchFileDescriptor failed on accept";
184*6777b538SAndroid Build Coastguard Worker     return MapSystemError(errno);
185*6777b538SAndroid Build Coastguard Worker   }
186*6777b538SAndroid Build Coastguard Worker 
187*6777b538SAndroid Build Coastguard Worker   accept_socket_ = socket;
188*6777b538SAndroid Build Coastguard Worker   accept_callback_ = std::move(callback);
189*6777b538SAndroid Build Coastguard Worker   return ERR_IO_PENDING;
190*6777b538SAndroid Build Coastguard Worker }
191*6777b538SAndroid Build Coastguard Worker 
Connect(const SockaddrStorage & address,CompletionOnceCallback callback)192*6777b538SAndroid Build Coastguard Worker int SocketPosix::Connect(const SockaddrStorage& address,
193*6777b538SAndroid Build Coastguard Worker                          CompletionOnceCallback callback) {
194*6777b538SAndroid Build Coastguard Worker   DCHECK(thread_checker_.CalledOnValidThread());
195*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(kInvalidSocket, socket_fd_);
196*6777b538SAndroid Build Coastguard Worker   DCHECK(!waiting_connect_);
197*6777b538SAndroid Build Coastguard Worker   DCHECK(!callback.is_null());
198*6777b538SAndroid Build Coastguard Worker 
199*6777b538SAndroid Build Coastguard Worker   SetPeerAddress(address);
200*6777b538SAndroid Build Coastguard Worker 
201*6777b538SAndroid Build Coastguard Worker   int rv = DoConnect();
202*6777b538SAndroid Build Coastguard Worker   if (rv != ERR_IO_PENDING)
203*6777b538SAndroid Build Coastguard Worker     return rv;
204*6777b538SAndroid Build Coastguard Worker 
205*6777b538SAndroid Build Coastguard Worker   if (!base::CurrentIOThread::Get()->WatchFileDescriptor(
206*6777b538SAndroid Build Coastguard Worker           socket_fd_, true, base::MessagePumpForIO::WATCH_WRITE,
207*6777b538SAndroid Build Coastguard Worker           &write_socket_watcher_, this)) {
208*6777b538SAndroid Build Coastguard Worker     PLOG(ERROR) << "WatchFileDescriptor failed on connect";
209*6777b538SAndroid Build Coastguard Worker     return MapSystemError(errno);
210*6777b538SAndroid Build Coastguard Worker   }
211*6777b538SAndroid Build Coastguard Worker 
212*6777b538SAndroid Build Coastguard Worker   // There is a race-condition in the above code if the kernel receive a RST
213*6777b538SAndroid Build Coastguard Worker   // packet for the "connect" call before the registration of the socket file
214*6777b538SAndroid Build Coastguard Worker   // descriptor to the message loop pump. On most platform it is benign as the
215*6777b538SAndroid Build Coastguard Worker   // message loop pump is awakened for that socket in an error state, but on
216*6777b538SAndroid Build Coastguard Worker   // iOS this does not happens. Check the status of the socket at this point
217*6777b538SAndroid Build Coastguard Worker   // and if in error, consider the connection as failed.
218*6777b538SAndroid Build Coastguard Worker   int os_error = 0;
219*6777b538SAndroid Build Coastguard Worker   socklen_t len = sizeof(os_error);
220*6777b538SAndroid Build Coastguard Worker   if (getsockopt(socket_fd_, SOL_SOCKET, SO_ERROR, &os_error, &len) == 0) {
221*6777b538SAndroid Build Coastguard Worker     // TCPSocketPosix expects errno to be set.
222*6777b538SAndroid Build Coastguard Worker     errno = os_error;
223*6777b538SAndroid Build Coastguard Worker   }
224*6777b538SAndroid Build Coastguard Worker 
225*6777b538SAndroid Build Coastguard Worker   rv = MapConnectError(errno);
226*6777b538SAndroid Build Coastguard Worker   if (rv != OK && rv != ERR_IO_PENDING) {
227*6777b538SAndroid Build Coastguard Worker     write_socket_watcher_.StopWatchingFileDescriptor();
228*6777b538SAndroid Build Coastguard Worker     return rv;
229*6777b538SAndroid Build Coastguard Worker   }
230*6777b538SAndroid Build Coastguard Worker 
231*6777b538SAndroid Build Coastguard Worker   write_callback_ = std::move(callback);
232*6777b538SAndroid Build Coastguard Worker   waiting_connect_ = true;
233*6777b538SAndroid Build Coastguard Worker   return ERR_IO_PENDING;
234*6777b538SAndroid Build Coastguard Worker }
235*6777b538SAndroid Build Coastguard Worker 
IsConnected() const236*6777b538SAndroid Build Coastguard Worker bool SocketPosix::IsConnected() const {
237*6777b538SAndroid Build Coastguard Worker   DCHECK(thread_checker_.CalledOnValidThread());
238*6777b538SAndroid Build Coastguard Worker 
239*6777b538SAndroid Build Coastguard Worker   if (socket_fd_ == kInvalidSocket || waiting_connect_)
240*6777b538SAndroid Build Coastguard Worker     return false;
241*6777b538SAndroid Build Coastguard Worker 
242*6777b538SAndroid Build Coastguard Worker   // Checks if connection is alive.
243*6777b538SAndroid Build Coastguard Worker   char c;
244*6777b538SAndroid Build Coastguard Worker   int rv = HANDLE_EINTR(recv(socket_fd_, &c, 1, MSG_PEEK));
245*6777b538SAndroid Build Coastguard Worker   if (rv == 0)
246*6777b538SAndroid Build Coastguard Worker     return false;
247*6777b538SAndroid Build Coastguard Worker   if (rv == -1 && errno != EAGAIN && errno != EWOULDBLOCK)
248*6777b538SAndroid Build Coastguard Worker     return false;
249*6777b538SAndroid Build Coastguard Worker 
250*6777b538SAndroid Build Coastguard Worker   return true;
251*6777b538SAndroid Build Coastguard Worker }
252*6777b538SAndroid Build Coastguard Worker 
IsConnectedAndIdle() const253*6777b538SAndroid Build Coastguard Worker bool SocketPosix::IsConnectedAndIdle() const {
254*6777b538SAndroid Build Coastguard Worker   DCHECK(thread_checker_.CalledOnValidThread());
255*6777b538SAndroid Build Coastguard Worker 
256*6777b538SAndroid Build Coastguard Worker   if (socket_fd_ == kInvalidSocket || waiting_connect_)
257*6777b538SAndroid Build Coastguard Worker     return false;
258*6777b538SAndroid Build Coastguard Worker 
259*6777b538SAndroid Build Coastguard Worker   // Check if connection is alive and we haven't received any data
260*6777b538SAndroid Build Coastguard Worker   // unexpectedly.
261*6777b538SAndroid Build Coastguard Worker   char c;
262*6777b538SAndroid Build Coastguard Worker   int rv = HANDLE_EINTR(recv(socket_fd_, &c, 1, MSG_PEEK));
263*6777b538SAndroid Build Coastguard Worker   if (rv >= 0)
264*6777b538SAndroid Build Coastguard Worker     return false;
265*6777b538SAndroid Build Coastguard Worker   if (errno != EAGAIN && errno != EWOULDBLOCK)
266*6777b538SAndroid Build Coastguard Worker     return false;
267*6777b538SAndroid Build Coastguard Worker 
268*6777b538SAndroid Build Coastguard Worker   return true;
269*6777b538SAndroid Build Coastguard Worker }
270*6777b538SAndroid Build Coastguard Worker 
Read(IOBuffer * buf,int buf_len,CompletionOnceCallback callback)271*6777b538SAndroid Build Coastguard Worker int SocketPosix::Read(IOBuffer* buf,
272*6777b538SAndroid Build Coastguard Worker                       int buf_len,
273*6777b538SAndroid Build Coastguard Worker                       CompletionOnceCallback callback) {
274*6777b538SAndroid Build Coastguard Worker   // Use base::Unretained() is safe here because OnFileCanReadWithoutBlocking()
275*6777b538SAndroid Build Coastguard Worker   // won't be called if |this| is gone.
276*6777b538SAndroid Build Coastguard Worker   int rv = ReadIfReady(
277*6777b538SAndroid Build Coastguard Worker       buf, buf_len,
278*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&SocketPosix::RetryRead, base::Unretained(this)));
279*6777b538SAndroid Build Coastguard Worker   if (rv == ERR_IO_PENDING) {
280*6777b538SAndroid Build Coastguard Worker     read_buf_ = buf;
281*6777b538SAndroid Build Coastguard Worker     read_buf_len_ = buf_len;
282*6777b538SAndroid Build Coastguard Worker     read_callback_ = std::move(callback);
283*6777b538SAndroid Build Coastguard Worker   }
284*6777b538SAndroid Build Coastguard Worker   return rv;
285*6777b538SAndroid Build Coastguard Worker }
286*6777b538SAndroid Build Coastguard Worker 
ReadIfReady(IOBuffer * buf,int buf_len,CompletionOnceCallback callback)287*6777b538SAndroid Build Coastguard Worker int SocketPosix::ReadIfReady(IOBuffer* buf,
288*6777b538SAndroid Build Coastguard Worker                              int buf_len,
289*6777b538SAndroid Build Coastguard Worker                              CompletionOnceCallback callback) {
290*6777b538SAndroid Build Coastguard Worker   DCHECK(thread_checker_.CalledOnValidThread());
291*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(kInvalidSocket, socket_fd_);
292*6777b538SAndroid Build Coastguard Worker   DCHECK(!waiting_connect_);
293*6777b538SAndroid Build Coastguard Worker   CHECK(read_if_ready_callback_.is_null());
294*6777b538SAndroid Build Coastguard Worker   DCHECK(!callback.is_null());
295*6777b538SAndroid Build Coastguard Worker   DCHECK_LT(0, buf_len);
296*6777b538SAndroid Build Coastguard Worker 
297*6777b538SAndroid Build Coastguard Worker   int rv = DoRead(buf, buf_len);
298*6777b538SAndroid Build Coastguard Worker   if (rv != ERR_IO_PENDING)
299*6777b538SAndroid Build Coastguard Worker     return rv;
300*6777b538SAndroid Build Coastguard Worker 
301*6777b538SAndroid Build Coastguard Worker   if (!base::CurrentIOThread::Get()->WatchFileDescriptor(
302*6777b538SAndroid Build Coastguard Worker           socket_fd_, true, base::MessagePumpForIO::WATCH_READ,
303*6777b538SAndroid Build Coastguard Worker           &read_socket_watcher_, this)) {
304*6777b538SAndroid Build Coastguard Worker     PLOG(ERROR) << "WatchFileDescriptor failed on read";
305*6777b538SAndroid Build Coastguard Worker     return MapSystemError(errno);
306*6777b538SAndroid Build Coastguard Worker   }
307*6777b538SAndroid Build Coastguard Worker 
308*6777b538SAndroid Build Coastguard Worker   read_if_ready_callback_ = std::move(callback);
309*6777b538SAndroid Build Coastguard Worker   return ERR_IO_PENDING;
310*6777b538SAndroid Build Coastguard Worker }
311*6777b538SAndroid Build Coastguard Worker 
CancelReadIfReady()312*6777b538SAndroid Build Coastguard Worker int SocketPosix::CancelReadIfReady() {
313*6777b538SAndroid Build Coastguard Worker   DCHECK(read_if_ready_callback_);
314*6777b538SAndroid Build Coastguard Worker 
315*6777b538SAndroid Build Coastguard Worker   bool ok = read_socket_watcher_.StopWatchingFileDescriptor();
316*6777b538SAndroid Build Coastguard Worker   DCHECK(ok);
317*6777b538SAndroid Build Coastguard Worker 
318*6777b538SAndroid Build Coastguard Worker   read_if_ready_callback_.Reset();
319*6777b538SAndroid Build Coastguard Worker   return net::OK;
320*6777b538SAndroid Build Coastguard Worker }
321*6777b538SAndroid Build Coastguard Worker 
Write(IOBuffer * buf,int buf_len,CompletionOnceCallback callback,const NetworkTrafficAnnotationTag &)322*6777b538SAndroid Build Coastguard Worker int SocketPosix::Write(
323*6777b538SAndroid Build Coastguard Worker     IOBuffer* buf,
324*6777b538SAndroid Build Coastguard Worker     int buf_len,
325*6777b538SAndroid Build Coastguard Worker     CompletionOnceCallback callback,
326*6777b538SAndroid Build Coastguard Worker     const NetworkTrafficAnnotationTag& /* traffic_annotation */) {
327*6777b538SAndroid Build Coastguard Worker   DCHECK(thread_checker_.CalledOnValidThread());
328*6777b538SAndroid Build Coastguard Worker   CHECK_NE(kInvalidSocket, socket_fd_);
329*6777b538SAndroid Build Coastguard Worker   CHECK(!waiting_connect_);
330*6777b538SAndroid Build Coastguard Worker   CHECK(write_callback_.is_null());
331*6777b538SAndroid Build Coastguard Worker   // Synchronous operation not supported
332*6777b538SAndroid Build Coastguard Worker   CHECK(!callback.is_null());
333*6777b538SAndroid Build Coastguard Worker   CHECK_LT(0, buf_len);
334*6777b538SAndroid Build Coastguard Worker 
335*6777b538SAndroid Build Coastguard Worker   int rv = DoWrite(buf, buf_len);
336*6777b538SAndroid Build Coastguard Worker   if (rv == ERR_IO_PENDING)
337*6777b538SAndroid Build Coastguard Worker     rv = WaitForWrite(buf, buf_len, std::move(callback));
338*6777b538SAndroid Build Coastguard Worker   return rv;
339*6777b538SAndroid Build Coastguard Worker }
340*6777b538SAndroid Build Coastguard Worker 
WaitForWrite(IOBuffer * buf,int buf_len,CompletionOnceCallback callback)341*6777b538SAndroid Build Coastguard Worker int SocketPosix::WaitForWrite(IOBuffer* buf,
342*6777b538SAndroid Build Coastguard Worker                               int buf_len,
343*6777b538SAndroid Build Coastguard Worker                               CompletionOnceCallback callback) {
344*6777b538SAndroid Build Coastguard Worker   DCHECK(thread_checker_.CalledOnValidThread());
345*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(kInvalidSocket, socket_fd_);
346*6777b538SAndroid Build Coastguard Worker   DCHECK(write_callback_.is_null());
347*6777b538SAndroid Build Coastguard Worker   // Synchronous operation not supported
348*6777b538SAndroid Build Coastguard Worker   DCHECK(!callback.is_null());
349*6777b538SAndroid Build Coastguard Worker   DCHECK_LT(0, buf_len);
350*6777b538SAndroid Build Coastguard Worker 
351*6777b538SAndroid Build Coastguard Worker   if (!base::CurrentIOThread::Get()->WatchFileDescriptor(
352*6777b538SAndroid Build Coastguard Worker           socket_fd_, true, base::MessagePumpForIO::WATCH_WRITE,
353*6777b538SAndroid Build Coastguard Worker           &write_socket_watcher_, this)) {
354*6777b538SAndroid Build Coastguard Worker     PLOG(ERROR) << "WatchFileDescriptor failed on write";
355*6777b538SAndroid Build Coastguard Worker     return MapSystemError(errno);
356*6777b538SAndroid Build Coastguard Worker   }
357*6777b538SAndroid Build Coastguard Worker 
358*6777b538SAndroid Build Coastguard Worker   write_buf_ = buf;
359*6777b538SAndroid Build Coastguard Worker   write_buf_len_ = buf_len;
360*6777b538SAndroid Build Coastguard Worker   write_callback_ = std::move(callback);
361*6777b538SAndroid Build Coastguard Worker   return ERR_IO_PENDING;
362*6777b538SAndroid Build Coastguard Worker }
363*6777b538SAndroid Build Coastguard Worker 
GetLocalAddress(SockaddrStorage * address) const364*6777b538SAndroid Build Coastguard Worker int SocketPosix::GetLocalAddress(SockaddrStorage* address) const {
365*6777b538SAndroid Build Coastguard Worker   DCHECK(thread_checker_.CalledOnValidThread());
366*6777b538SAndroid Build Coastguard Worker   DCHECK(address);
367*6777b538SAndroid Build Coastguard Worker 
368*6777b538SAndroid Build Coastguard Worker   if (getsockname(socket_fd_, address->addr, &address->addr_len) < 0)
369*6777b538SAndroid Build Coastguard Worker     return MapSystemError(errno);
370*6777b538SAndroid Build Coastguard Worker   return OK;
371*6777b538SAndroid Build Coastguard Worker }
372*6777b538SAndroid Build Coastguard Worker 
GetPeerAddress(SockaddrStorage * address) const373*6777b538SAndroid Build Coastguard Worker int SocketPosix::GetPeerAddress(SockaddrStorage* address) const {
374*6777b538SAndroid Build Coastguard Worker   DCHECK(thread_checker_.CalledOnValidThread());
375*6777b538SAndroid Build Coastguard Worker   DCHECK(address);
376*6777b538SAndroid Build Coastguard Worker 
377*6777b538SAndroid Build Coastguard Worker   if (!HasPeerAddress())
378*6777b538SAndroid Build Coastguard Worker     return ERR_SOCKET_NOT_CONNECTED;
379*6777b538SAndroid Build Coastguard Worker 
380*6777b538SAndroid Build Coastguard Worker   *address = *peer_address_;
381*6777b538SAndroid Build Coastguard Worker   return OK;
382*6777b538SAndroid Build Coastguard Worker }
383*6777b538SAndroid Build Coastguard Worker 
SetPeerAddress(const SockaddrStorage & address)384*6777b538SAndroid Build Coastguard Worker void SocketPosix::SetPeerAddress(const SockaddrStorage& address) {
385*6777b538SAndroid Build Coastguard Worker   DCHECK(thread_checker_.CalledOnValidThread());
386*6777b538SAndroid Build Coastguard Worker   // |peer_address_| will be non-nullptr if Connect() has been called. Unless
387*6777b538SAndroid Build Coastguard Worker   // Close() is called to reset the internal state, a second call to Connect()
388*6777b538SAndroid Build Coastguard Worker   // is not allowed.
389*6777b538SAndroid Build Coastguard Worker   // Please note that we don't allow a second Connect() even if the previous
390*6777b538SAndroid Build Coastguard Worker   // Connect() has failed. Connecting the same |socket_| again after a
391*6777b538SAndroid Build Coastguard Worker   // connection attempt failed results in unspecified behavior according to
392*6777b538SAndroid Build Coastguard Worker   // POSIX.
393*6777b538SAndroid Build Coastguard Worker   DCHECK(!peer_address_);
394*6777b538SAndroid Build Coastguard Worker   peer_address_ = std::make_unique<SockaddrStorage>(address);
395*6777b538SAndroid Build Coastguard Worker }
396*6777b538SAndroid Build Coastguard Worker 
HasPeerAddress() const397*6777b538SAndroid Build Coastguard Worker bool SocketPosix::HasPeerAddress() const {
398*6777b538SAndroid Build Coastguard Worker   DCHECK(thread_checker_.CalledOnValidThread());
399*6777b538SAndroid Build Coastguard Worker   return peer_address_ != nullptr;
400*6777b538SAndroid Build Coastguard Worker }
401*6777b538SAndroid Build Coastguard Worker 
Close()402*6777b538SAndroid Build Coastguard Worker void SocketPosix::Close() {
403*6777b538SAndroid Build Coastguard Worker   DCHECK(thread_checker_.CalledOnValidThread());
404*6777b538SAndroid Build Coastguard Worker 
405*6777b538SAndroid Build Coastguard Worker   StopWatchingAndCleanUp(true /* close_socket */);
406*6777b538SAndroid Build Coastguard Worker }
407*6777b538SAndroid Build Coastguard Worker 
DetachFromThread()408*6777b538SAndroid Build Coastguard Worker void SocketPosix::DetachFromThread() {
409*6777b538SAndroid Build Coastguard Worker   thread_checker_.DetachFromThread();
410*6777b538SAndroid Build Coastguard Worker }
411*6777b538SAndroid Build Coastguard Worker 
OnFileCanReadWithoutBlocking(int fd)412*6777b538SAndroid Build Coastguard Worker void SocketPosix::OnFileCanReadWithoutBlocking(int fd) {
413*6777b538SAndroid Build Coastguard Worker   TRACE_EVENT0(NetTracingCategory(),
414*6777b538SAndroid Build Coastguard Worker                "SocketPosix::OnFileCanReadWithoutBlocking");
415*6777b538SAndroid Build Coastguard Worker   if (!accept_callback_.is_null()) {
416*6777b538SAndroid Build Coastguard Worker     AcceptCompleted();
417*6777b538SAndroid Build Coastguard Worker   } else {
418*6777b538SAndroid Build Coastguard Worker     DCHECK(!read_if_ready_callback_.is_null());
419*6777b538SAndroid Build Coastguard Worker     ReadCompleted();
420*6777b538SAndroid Build Coastguard Worker   }
421*6777b538SAndroid Build Coastguard Worker }
422*6777b538SAndroid Build Coastguard Worker 
OnFileCanWriteWithoutBlocking(int fd)423*6777b538SAndroid Build Coastguard Worker void SocketPosix::OnFileCanWriteWithoutBlocking(int fd) {
424*6777b538SAndroid Build Coastguard Worker   DCHECK(!write_callback_.is_null());
425*6777b538SAndroid Build Coastguard Worker   if (waiting_connect_) {
426*6777b538SAndroid Build Coastguard Worker     ConnectCompleted();
427*6777b538SAndroid Build Coastguard Worker   } else {
428*6777b538SAndroid Build Coastguard Worker     WriteCompleted();
429*6777b538SAndroid Build Coastguard Worker   }
430*6777b538SAndroid Build Coastguard Worker }
431*6777b538SAndroid Build Coastguard Worker 
DoAccept(std::unique_ptr<SocketPosix> * socket)432*6777b538SAndroid Build Coastguard Worker int SocketPosix::DoAccept(std::unique_ptr<SocketPosix>* socket) {
433*6777b538SAndroid Build Coastguard Worker   SockaddrStorage new_peer_address;
434*6777b538SAndroid Build Coastguard Worker   int new_socket = HANDLE_EINTR(accept(socket_fd_,
435*6777b538SAndroid Build Coastguard Worker                                        new_peer_address.addr,
436*6777b538SAndroid Build Coastguard Worker                                        &new_peer_address.addr_len));
437*6777b538SAndroid Build Coastguard Worker   if (new_socket < 0)
438*6777b538SAndroid Build Coastguard Worker     return MapAcceptError(errno);
439*6777b538SAndroid Build Coastguard Worker 
440*6777b538SAndroid Build Coastguard Worker   auto accepted_socket = std::make_unique<SocketPosix>();
441*6777b538SAndroid Build Coastguard Worker   int rv = accepted_socket->AdoptConnectedSocket(new_socket, new_peer_address);
442*6777b538SAndroid Build Coastguard Worker   if (rv != OK)
443*6777b538SAndroid Build Coastguard Worker     return rv;
444*6777b538SAndroid Build Coastguard Worker 
445*6777b538SAndroid Build Coastguard Worker   *socket = std::move(accepted_socket);
446*6777b538SAndroid Build Coastguard Worker   return OK;
447*6777b538SAndroid Build Coastguard Worker }
448*6777b538SAndroid Build Coastguard Worker 
AcceptCompleted()449*6777b538SAndroid Build Coastguard Worker void SocketPosix::AcceptCompleted() {
450*6777b538SAndroid Build Coastguard Worker   DCHECK(accept_socket_);
451*6777b538SAndroid Build Coastguard Worker   int rv = DoAccept(accept_socket_);
452*6777b538SAndroid Build Coastguard Worker   if (rv == ERR_IO_PENDING)
453*6777b538SAndroid Build Coastguard Worker     return;
454*6777b538SAndroid Build Coastguard Worker 
455*6777b538SAndroid Build Coastguard Worker   bool ok = accept_socket_watcher_.StopWatchingFileDescriptor();
456*6777b538SAndroid Build Coastguard Worker   DCHECK(ok);
457*6777b538SAndroid Build Coastguard Worker   accept_socket_ = nullptr;
458*6777b538SAndroid Build Coastguard Worker   std::move(accept_callback_).Run(rv);
459*6777b538SAndroid Build Coastguard Worker }
460*6777b538SAndroid Build Coastguard Worker 
DoConnect()461*6777b538SAndroid Build Coastguard Worker int SocketPosix::DoConnect() {
462*6777b538SAndroid Build Coastguard Worker   int rv = HANDLE_EINTR(connect(socket_fd_,
463*6777b538SAndroid Build Coastguard Worker                                 peer_address_->addr,
464*6777b538SAndroid Build Coastguard Worker                                 peer_address_->addr_len));
465*6777b538SAndroid Build Coastguard Worker   DCHECK_GE(0, rv);
466*6777b538SAndroid Build Coastguard Worker   return rv == 0 ? OK : MapConnectError(errno);
467*6777b538SAndroid Build Coastguard Worker }
468*6777b538SAndroid Build Coastguard Worker 
ConnectCompleted()469*6777b538SAndroid Build Coastguard Worker void SocketPosix::ConnectCompleted() {
470*6777b538SAndroid Build Coastguard Worker   // Get the error that connect() completed with.
471*6777b538SAndroid Build Coastguard Worker   int os_error = 0;
472*6777b538SAndroid Build Coastguard Worker   socklen_t len = sizeof(os_error);
473*6777b538SAndroid Build Coastguard Worker   if (getsockopt(socket_fd_, SOL_SOCKET, SO_ERROR, &os_error, &len) == 0) {
474*6777b538SAndroid Build Coastguard Worker     // TCPSocketPosix expects errno to be set.
475*6777b538SAndroid Build Coastguard Worker     errno = os_error;
476*6777b538SAndroid Build Coastguard Worker   }
477*6777b538SAndroid Build Coastguard Worker 
478*6777b538SAndroid Build Coastguard Worker   int rv = MapConnectError(errno);
479*6777b538SAndroid Build Coastguard Worker   if (rv == ERR_IO_PENDING)
480*6777b538SAndroid Build Coastguard Worker     return;
481*6777b538SAndroid Build Coastguard Worker 
482*6777b538SAndroid Build Coastguard Worker   bool ok = write_socket_watcher_.StopWatchingFileDescriptor();
483*6777b538SAndroid Build Coastguard Worker   DCHECK(ok);
484*6777b538SAndroid Build Coastguard Worker   waiting_connect_ = false;
485*6777b538SAndroid Build Coastguard Worker   std::move(write_callback_).Run(rv);
486*6777b538SAndroid Build Coastguard Worker }
487*6777b538SAndroid Build Coastguard Worker 
DoRead(IOBuffer * buf,int buf_len)488*6777b538SAndroid Build Coastguard Worker int SocketPosix::DoRead(IOBuffer* buf, int buf_len) {
489*6777b538SAndroid Build Coastguard Worker   int rv = HANDLE_EINTR(read(socket_fd_, buf->data(), buf_len));
490*6777b538SAndroid Build Coastguard Worker   return rv >= 0 ? rv : MapSystemError(errno);
491*6777b538SAndroid Build Coastguard Worker }
492*6777b538SAndroid Build Coastguard Worker 
RetryRead(int rv)493*6777b538SAndroid Build Coastguard Worker void SocketPosix::RetryRead(int rv) {
494*6777b538SAndroid Build Coastguard Worker   DCHECK(read_callback_);
495*6777b538SAndroid Build Coastguard Worker   DCHECK(read_buf_);
496*6777b538SAndroid Build Coastguard Worker   DCHECK_LT(0, read_buf_len_);
497*6777b538SAndroid Build Coastguard Worker 
498*6777b538SAndroid Build Coastguard Worker   if (rv == OK) {
499*6777b538SAndroid Build Coastguard Worker     rv = ReadIfReady(
500*6777b538SAndroid Build Coastguard Worker         read_buf_.get(), read_buf_len_,
501*6777b538SAndroid Build Coastguard Worker         base::BindOnce(&SocketPosix::RetryRead, base::Unretained(this)));
502*6777b538SAndroid Build Coastguard Worker     if (rv == ERR_IO_PENDING)
503*6777b538SAndroid Build Coastguard Worker       return;
504*6777b538SAndroid Build Coastguard Worker   }
505*6777b538SAndroid Build Coastguard Worker   read_buf_ = nullptr;
506*6777b538SAndroid Build Coastguard Worker   read_buf_len_ = 0;
507*6777b538SAndroid Build Coastguard Worker   std::move(read_callback_).Run(rv);
508*6777b538SAndroid Build Coastguard Worker }
509*6777b538SAndroid Build Coastguard Worker 
ReadCompleted()510*6777b538SAndroid Build Coastguard Worker void SocketPosix::ReadCompleted() {
511*6777b538SAndroid Build Coastguard Worker   DCHECK(read_if_ready_callback_);
512*6777b538SAndroid Build Coastguard Worker 
513*6777b538SAndroid Build Coastguard Worker   bool ok = read_socket_watcher_.StopWatchingFileDescriptor();
514*6777b538SAndroid Build Coastguard Worker   DCHECK(ok);
515*6777b538SAndroid Build Coastguard Worker   std::move(read_if_ready_callback_).Run(OK);
516*6777b538SAndroid Build Coastguard Worker }
517*6777b538SAndroid Build Coastguard Worker 
DoWrite(IOBuffer * buf,int buf_len)518*6777b538SAndroid Build Coastguard Worker int SocketPosix::DoWrite(IOBuffer* buf, int buf_len) {
519*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
520*6777b538SAndroid Build Coastguard Worker   // Disable SIGPIPE for this write. Although Chromium globally disables
521*6777b538SAndroid Build Coastguard Worker   // SIGPIPE, the net stack may be used in other consumers which do not do
522*6777b538SAndroid Build Coastguard Worker   // this. MSG_NOSIGNAL is a Linux-only API. On OS X, this is a setsockopt on
523*6777b538SAndroid Build Coastguard Worker   // socket creation.
524*6777b538SAndroid Build Coastguard Worker   int rv = HANDLE_EINTR(send(socket_fd_, buf->data(), buf_len, MSG_NOSIGNAL));
525*6777b538SAndroid Build Coastguard Worker #else
526*6777b538SAndroid Build Coastguard Worker   int rv = HANDLE_EINTR(write(socket_fd_, buf->data(), buf_len));
527*6777b538SAndroid Build Coastguard Worker #endif
528*6777b538SAndroid Build Coastguard Worker   if (rv >= 0) {
529*6777b538SAndroid Build Coastguard Worker     CHECK_LE(rv, buf_len);
530*6777b538SAndroid Build Coastguard Worker   }
531*6777b538SAndroid Build Coastguard Worker   return rv >= 0 ? rv : MapSystemError(errno);
532*6777b538SAndroid Build Coastguard Worker }
533*6777b538SAndroid Build Coastguard Worker 
WriteCompleted()534*6777b538SAndroid Build Coastguard Worker void SocketPosix::WriteCompleted() {
535*6777b538SAndroid Build Coastguard Worker   int rv = DoWrite(write_buf_.get(), write_buf_len_);
536*6777b538SAndroid Build Coastguard Worker   if (rv == ERR_IO_PENDING)
537*6777b538SAndroid Build Coastguard Worker     return;
538*6777b538SAndroid Build Coastguard Worker 
539*6777b538SAndroid Build Coastguard Worker   bool ok = write_socket_watcher_.StopWatchingFileDescriptor();
540*6777b538SAndroid Build Coastguard Worker   DCHECK(ok);
541*6777b538SAndroid Build Coastguard Worker   write_buf_.reset();
542*6777b538SAndroid Build Coastguard Worker   write_buf_len_ = 0;
543*6777b538SAndroid Build Coastguard Worker   std::move(write_callback_).Run(rv);
544*6777b538SAndroid Build Coastguard Worker }
545*6777b538SAndroid Build Coastguard Worker 
StopWatchingAndCleanUp(bool close_socket)546*6777b538SAndroid Build Coastguard Worker void SocketPosix::StopWatchingAndCleanUp(bool close_socket) {
547*6777b538SAndroid Build Coastguard Worker   bool ok = accept_socket_watcher_.StopWatchingFileDescriptor();
548*6777b538SAndroid Build Coastguard Worker   DCHECK(ok);
549*6777b538SAndroid Build Coastguard Worker   ok = read_socket_watcher_.StopWatchingFileDescriptor();
550*6777b538SAndroid Build Coastguard Worker   DCHECK(ok);
551*6777b538SAndroid Build Coastguard Worker   ok = write_socket_watcher_.StopWatchingFileDescriptor();
552*6777b538SAndroid Build Coastguard Worker   DCHECK(ok);
553*6777b538SAndroid Build Coastguard Worker 
554*6777b538SAndroid Build Coastguard Worker   // These needs to be done after the StopWatchingFileDescriptor() calls, but
555*6777b538SAndroid Build Coastguard Worker   // before deleting the write buffer.
556*6777b538SAndroid Build Coastguard Worker   if (close_socket) {
557*6777b538SAndroid Build Coastguard Worker     if (socket_fd_ != kInvalidSocket) {
558*6777b538SAndroid Build Coastguard Worker       if (IGNORE_EINTR(close(socket_fd_)) < 0)
559*6777b538SAndroid Build Coastguard Worker         DPLOG(ERROR) << "close() failed";
560*6777b538SAndroid Build Coastguard Worker       socket_fd_ = kInvalidSocket;
561*6777b538SAndroid Build Coastguard Worker     }
562*6777b538SAndroid Build Coastguard Worker   }
563*6777b538SAndroid Build Coastguard Worker 
564*6777b538SAndroid Build Coastguard Worker   if (!accept_callback_.is_null()) {
565*6777b538SAndroid Build Coastguard Worker     accept_socket_ = nullptr;
566*6777b538SAndroid Build Coastguard Worker     accept_callback_.Reset();
567*6777b538SAndroid Build Coastguard Worker   }
568*6777b538SAndroid Build Coastguard Worker 
569*6777b538SAndroid Build Coastguard Worker   if (!read_callback_.is_null()) {
570*6777b538SAndroid Build Coastguard Worker     read_buf_.reset();
571*6777b538SAndroid Build Coastguard Worker     read_buf_len_ = 0;
572*6777b538SAndroid Build Coastguard Worker     read_callback_.Reset();
573*6777b538SAndroid Build Coastguard Worker   }
574*6777b538SAndroid Build Coastguard Worker 
575*6777b538SAndroid Build Coastguard Worker   read_if_ready_callback_.Reset();
576*6777b538SAndroid Build Coastguard Worker 
577*6777b538SAndroid Build Coastguard Worker   if (!write_callback_.is_null()) {
578*6777b538SAndroid Build Coastguard Worker     write_buf_.reset();
579*6777b538SAndroid Build Coastguard Worker     write_buf_len_ = 0;
580*6777b538SAndroid Build Coastguard Worker     write_callback_.Reset();
581*6777b538SAndroid Build Coastguard Worker   }
582*6777b538SAndroid Build Coastguard Worker 
583*6777b538SAndroid Build Coastguard Worker   waiting_connect_ = false;
584*6777b538SAndroid Build Coastguard Worker   peer_address_.reset();
585*6777b538SAndroid Build Coastguard Worker }
586*6777b538SAndroid Build Coastguard Worker 
587*6777b538SAndroid Build Coastguard Worker }  // namespace net
588