• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "perfetto/ext/base/unix_socket.h"
18 
19 #include <errno.h>
20 #include <fcntl.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <sys/stat.h>
24 #include <sys/types.h>
25 #include "perfetto/base/compiler.h"
26 #include "perfetto/ext/base/android_utils.h"
27 #include "perfetto/ext/base/string_utils.h"
28 
29 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
30 // The include order matters on these three Windows header groups.
31 #include <Windows.h>
32 
33 #include <WS2tcpip.h>
34 #include <WinSock2.h>
35 
36 #include <afunix.h>
37 #else
38 #include <arpa/inet.h>
39 #include <netdb.h>
40 #include <netinet/in.h>
41 #include <netinet/tcp.h>
42 #include <poll.h>
43 #include <sys/socket.h>
44 #include <sys/un.h>
45 #include <unistd.h>
46 #endif
47 
48 #if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
49 #include <sys/ucred.h>
50 #endif
51 
52 #include <algorithm>
53 #include <memory>
54 
55 #include "perfetto/base/build_config.h"
56 #include "perfetto/base/logging.h"
57 #include "perfetto/base/task_runner.h"
58 #include "perfetto/base/time.h"
59 #include "perfetto/ext/base/string_utils.h"
60 #include "perfetto/ext/base/utils.h"
61 
62 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
63     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
64 // Use a local stripped copy of vm_sockets.h from UAPI.
65 #include "src/base/vm_sockets.h"
66 #endif
67 
68 #if PERFETTO_BUILDFLAG(PERFETTO_OS_QNX)
69 #include <sys/time.h>
70 #endif
71 
72 namespace perfetto {
73 namespace base {
74 
75 // The CMSG_* macros use NULL instead of nullptr.
76 // Note: MSVC doesn't have #pragma GCC diagnostic, hence the if __GNUC__.
77 #if defined(__GNUC__) && !PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
78 #pragma GCC diagnostic push
79 #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
80 #endif
81 
82 namespace {
83 
84 // Android takes an int instead of socklen_t for the control buffer size.
85 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
86 using CBufLenType = size_t;
87 #else
88 using CBufLenType = socklen_t;
89 #endif
90 
91 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
92     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
93 constexpr char kVsockNamePrefix[] = "vsock://";
94 #endif
95 
96 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
IsVirtualized()97 bool IsVirtualized() {
98   static bool is_virtualized = [] {
99     return base::GetAndroidProp("ro.traced.hypervisor") == "true";
100   }();
101   return is_virtualized;
102 }
103 #endif
104 
105 // A wrapper around variable-size sockaddr structs.
106 // This is solving the following problem: when calling connect() or bind(), the
107 // caller needs to take care to allocate the right struct (sockaddr_un for
108 // AF_UNIX, sockaddr_in for AF_INET).   Those structs have different sizes and,
109 // more importantly, are bigger than the base struct sockaddr.
110 struct SockaddrAny {
SockaddrAnyperfetto::base::__anone7fe09a00111::SockaddrAny111   SockaddrAny() : size() {}
SockaddrAnyperfetto::base::__anone7fe09a00111::SockaddrAny112   SockaddrAny(const void* addr, socklen_t sz)
113       : data(new char[static_cast<size_t>(sz)]), size(sz) {
114     memcpy(data.get(), addr, static_cast<size_t>(size));
115   }
116 
addrperfetto::base::__anone7fe09a00111::SockaddrAny117   const struct sockaddr* addr() const {
118     return reinterpret_cast<const struct sockaddr*>(data.get());
119   }
120 
121   std::unique_ptr<char[]> data;
122   socklen_t size;
123 };
124 
MkSockFamily(SockFamily family)125 inline int MkSockFamily(SockFamily family) {
126   switch (family) {
127     case SockFamily::kUnix:
128       return AF_UNIX;
129     case SockFamily::kInet:
130       return AF_INET;
131     case SockFamily::kInet6:
132       return AF_INET6;
133     case SockFamily::kVsock:
134 #ifdef AF_VSOCK
135       return AF_VSOCK;
136 #else
137       return AF_UNSPEC;  // Return AF_UNSPEC on unsupported platforms.
138 #endif
139     case SockFamily::kUnspec:
140       return AF_UNSPEC;
141   }
142   PERFETTO_CHECK(false);  // For GCC.
143 }
144 
MkSockType(SockType type)145 inline int MkSockType(SockType type) {
146 #if defined(SOCK_CLOEXEC)
147   constexpr int kSockCloExec = SOCK_CLOEXEC;
148 #else
149   constexpr int kSockCloExec = 0;
150 #endif
151   switch (type) {
152     case SockType::kStream:
153       return SOCK_STREAM | kSockCloExec;
154     case SockType::kDgram:
155       return SOCK_DGRAM | kSockCloExec;
156     case SockType::kSeqPacket:
157       return SOCK_SEQPACKET | kSockCloExec;
158   }
159   PERFETTO_CHECK(false);  // For GCC.
160 }
161 
MakeSockAddr(SockFamily family,const std::string & socket_name)162 SockaddrAny MakeSockAddr(SockFamily family, const std::string& socket_name) {
163   switch (family) {
164     case SockFamily::kUnix: {
165       struct sockaddr_un saddr {};
166       const size_t name_len = socket_name.size();
167       if (name_len + 1 /* for trailing \0 */ >= sizeof(saddr.sun_path)) {
168         errno = ENAMETOOLONG;
169         return SockaddrAny();
170       }
171       memcpy(saddr.sun_path, socket_name.data(), name_len);
172       if (saddr.sun_path[0] == '@') {
173         saddr.sun_path[0] = '\0';
174 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
175         // The MSDN blog claims that abstract (non-filesystem based) AF_UNIX
176         // socket are supported, but that doesn't seem true.
177         PERFETTO_ELOG(
178             "Abstract AF_UNIX sockets are not supported on Windows, see "
179             "https://github.com/microsoft/WSL/issues/4240");
180         return SockaddrAny();
181 #endif
182       }
183       saddr.sun_family = AF_UNIX;
184       auto size = static_cast<socklen_t>(
185           __builtin_offsetof(sockaddr_un, sun_path) + name_len + 1);
186 
187       // Abstract sockets do NOT require a trailing null terminator (which is
188       // instad mandatory for filesystem sockets). Any byte up to `size`,
189       // including '\0' will become part of the socket name.
190       if (saddr.sun_path[0] == '\0')
191         --size;
192       PERFETTO_CHECK(static_cast<size_t>(size) <= sizeof(saddr));
193       return SockaddrAny(&saddr, size);
194     }
195     case SockFamily::kInet: {
196       auto parts = SplitString(socket_name, ":");
197       PERFETTO_CHECK(parts.size() == 2);
198       struct addrinfo* addr_info = nullptr;
199       struct addrinfo hints {};
200       hints.ai_family = AF_INET;
201       PERFETTO_CHECK(getaddrinfo(parts[0].c_str(), parts[1].c_str(), &hints,
202                                  &addr_info) == 0);
203       PERFETTO_CHECK(addr_info->ai_family == AF_INET);
204       SockaddrAny res(addr_info->ai_addr,
205                       static_cast<socklen_t>(addr_info->ai_addrlen));
206       freeaddrinfo(addr_info);
207       return res;
208     }
209     case SockFamily::kInet6: {
210       auto parts = SplitString(socket_name, "]");
211       PERFETTO_CHECK(parts.size() == 2);
212       auto address = SplitString(parts[0], "[");
213       PERFETTO_CHECK(address.size() == 1);
214       auto port = SplitString(parts[1], ":");
215       PERFETTO_CHECK(port.size() == 1);
216       struct addrinfo* addr_info = nullptr;
217       struct addrinfo hints {};
218       hints.ai_family = AF_INET6;
219       PERFETTO_CHECK(getaddrinfo(address[0].c_str(), port[0].c_str(), &hints,
220                                  &addr_info) == 0);
221       PERFETTO_CHECK(addr_info->ai_family == AF_INET6);
222       SockaddrAny res(addr_info->ai_addr,
223                       static_cast<socklen_t>(addr_info->ai_addrlen));
224       freeaddrinfo(addr_info);
225       return res;
226     }
227     case SockFamily::kVsock: {
228 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
229     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
230       PERFETTO_CHECK(StartsWith(socket_name, kVsockNamePrefix));
231       auto address_port = StripPrefix(socket_name, kVsockNamePrefix);
232       auto parts = SplitString(address_port, ":");
233       PERFETTO_CHECK(parts.size() == 2);
234       sockaddr_vm addr;
235       memset(&addr, 0, sizeof(addr));
236       addr.svm_family = AF_VSOCK;
237       addr.svm_cid = *base::StringToUInt32(parts[0]);
238       addr.svm_port = *base::StringToUInt32(parts[1]);
239 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
240       if (IsVirtualized()) {
241         // VM-to-VM VSOCK communication requires messages to be
242         // routed through the host.
243         addr.svm_flags = VMADDR_FLAG_TO_HOST;
244       }
245 #endif
246       SockaddrAny res(&addr, sizeof(addr));
247       return res;
248 #else
249       errno = ENOTSOCK;
250       return SockaddrAny();
251 #endif
252     }
253     case SockFamily::kUnspec:
254       errno = ENOTSOCK;
255       return SockaddrAny();
256   }
257   PERFETTO_CHECK(false);  // For GCC.
258 }
259 
CreateSocketHandle(SockFamily family,SockType type)260 ScopedSocketHandle CreateSocketHandle(SockFamily family, SockType type) {
261 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
262   static bool init_winsock_once = [] {
263     WSADATA ignored{};
264     return WSAStartup(MAKEWORD(2, 2), &ignored) == 0;
265   }();
266   PERFETTO_CHECK(init_winsock_once);
267 #endif
268   return ScopedSocketHandle(socket(MkSockFamily(family), MkSockType(type), 0));
269 }
270 
271 }  // namespace
272 
273 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
CloseSocket(SocketHandle s)274 int CloseSocket(SocketHandle s) {
275   return ::closesocket(s);
276 }
277 #endif
278 
GetSockFamily(const char * addr)279 SockFamily GetSockFamily(const char* addr) {
280   if (strlen(addr) == 0)
281     return SockFamily::kUnspec;
282 
283   if (addr[0] == '@')
284     return SockFamily::kUnix;  // Abstract AF_UNIX sockets.
285 
286 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
287     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
288   // Vsock address starts with vsock://.
289   if (strncmp(addr, kVsockNamePrefix, strlen(kVsockNamePrefix)) == 0)
290     return SockFamily::kVsock;
291 #endif
292 
293   // If `addr` ends in :NNNN it's either a kInet or kInet6 socket.
294   const char* col = strrchr(addr, ':');
295   if (col && CStringToInt32(col + 1).has_value()) {
296     return addr[0] == '[' ? SockFamily::kInet6 : SockFamily::kInet;
297   }
298 
299   return SockFamily::kUnix;  // For anything else assume it's a linked AF_UNIX.
300 }
301 
302 // +-----------------------+
303 // | UnixSocketRaw methods |
304 // +-----------------------+
305 
306 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
307 // static
ShiftMsgHdrPosix(size_t n,struct msghdr * msg)308 void UnixSocketRaw::ShiftMsgHdrPosix(size_t n, struct msghdr* msg) {
309   using LenType = decltype(msg->msg_iovlen);  // Mac and Linux don't agree.
310   for (LenType i = 0; i < msg->msg_iovlen; ++i) {
311     struct iovec* vec = &msg->msg_iov[i];
312     if (n < vec->iov_len) {
313       // We sent a part of this iovec.
314       vec->iov_base = reinterpret_cast<char*>(vec->iov_base) + n;
315       vec->iov_len -= n;
316       msg->msg_iov = vec;
317       msg->msg_iovlen -= i;
318       return;
319     }
320     // We sent the whole iovec.
321     n -= vec->iov_len;
322   }
323   // We sent all the iovecs.
324   PERFETTO_CHECK(n == 0);
325   msg->msg_iovlen = 0;
326   msg->msg_iov = nullptr;
327 }
328 
329 // static
CreatePairPosix(SockFamily family,SockType type)330 std::pair<UnixSocketRaw, UnixSocketRaw> UnixSocketRaw::CreatePairPosix(
331     SockFamily family,
332     SockType type) {
333   int fds[2];
334   if (socketpair(MkSockFamily(family), MkSockType(type), 0, fds) != 0) {
335     return std::make_pair(UnixSocketRaw(), UnixSocketRaw());
336   }
337   return std::make_pair(UnixSocketRaw(ScopedFile(fds[0]), family, type),
338                         UnixSocketRaw(ScopedFile(fds[1]), family, type));
339 }
340 #endif
341 
342 // static
CreateMayFail(SockFamily family,SockType type)343 UnixSocketRaw UnixSocketRaw::CreateMayFail(SockFamily family, SockType type) {
344   auto fd = CreateSocketHandle(family, type);
345   if (!fd)
346     return UnixSocketRaw();
347   return UnixSocketRaw(std::move(fd), family, type);
348 }
349 
350 UnixSocketRaw::UnixSocketRaw() = default;
351 
UnixSocketRaw(SockFamily family,SockType type)352 UnixSocketRaw::UnixSocketRaw(SockFamily family, SockType type)
353     : UnixSocketRaw(CreateSocketHandle(family, type), family, type) {}
354 
UnixSocketRaw(ScopedSocketHandle fd,SockFamily family,SockType type)355 UnixSocketRaw::UnixSocketRaw(ScopedSocketHandle fd,
356                              SockFamily family,
357                              SockType type)
358     : fd_(std::move(fd)), family_(family), type_(type) {
359   PERFETTO_CHECK(fd_);
360 #if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
361   const int no_sigpipe = 1;
362   setsockopt(*fd_, SOL_SOCKET, SO_NOSIGPIPE, &no_sigpipe, sizeof(no_sigpipe));
363 #endif
364 
365 // QNX doesn't support setting SO_REUSEADDR option when using vsocks.
366 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_QNX)
367   if (family == SockFamily::kVsock) {
368     int flag = 1;
369     // The reinterpret_cast<const char*> is needed for Windows, where the 4th
370     // arg is a const char* (on other POSIX system is a const void*).
371     PERFETTO_CHECK(!setsockopt(*fd_, SOL_SOCKET, SO_REUSEADDR,
372                                reinterpret_cast<const char*>(&flag),
373                                sizeof(flag)));
374   }
375 #endif
376 
377   if (family == SockFamily::kInet || family == SockFamily::kInet6) {
378     int flag = 1;
379     // The reinterpret_cast<const char*> is needed for Windows, where the 4th
380     // arg is a const char* (on other POSIX system is a const void*).
381     PERFETTO_CHECK(!setsockopt(*fd_, SOL_SOCKET, SO_REUSEADDR,
382                                reinterpret_cast<const char*>(&flag),
383                                sizeof(flag)));
384     // Disable Nagle's algorithm, optimize for low-latency.
385     // See https://github.com/google/perfetto/issues/70.
386     setsockopt(*fd_, IPPROTO_TCP, TCP_NODELAY,
387                reinterpret_cast<const char*>(&flag), sizeof(flag));
388   }
389 
390 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
391   // We use one event handle for all socket events, to stay consistent to what
392   // we do on UNIX with the base::TaskRunner's poll().
393   event_handle_.reset(WSACreateEvent());
394   PERFETTO_CHECK(event_handle_);
395 #else
396   // There is no reason why a socket should outlive the process in case of
397   // exec() by default, this is just working around a broken unix design.
398   SetRetainOnExec(false);
399 #endif
400 }
401 
SetBlocking(bool is_blocking)402 void UnixSocketRaw::SetBlocking(bool is_blocking) {
403   PERFETTO_DCHECK(fd_);
404 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
405   unsigned long flag = is_blocking ? 0 : 1;  // FIONBIO has reverse logic.
406   if (is_blocking) {
407     // When switching between non-blocking -> blocking mode, we need to reset
408     // the event handle registration, otherwise the call will fail.
409     PERFETTO_CHECK(WSAEventSelect(*fd_, *event_handle_, 0) == 0);
410   }
411   PERFETTO_CHECK(ioctlsocket(*fd_, static_cast<long>(FIONBIO), &flag) == 0);
412   if (!is_blocking) {
413     PERFETTO_CHECK(
414         WSAEventSelect(*fd_, *event_handle_,
415                        FD_ACCEPT | FD_CONNECT | FD_READ | FD_CLOSE) == 0);
416   }
417 #else
418   int flags = fcntl(*fd_, F_GETFL, 0);
419   if (!is_blocking) {
420     flags |= O_NONBLOCK;
421   } else {
422     flags &= ~static_cast<int>(O_NONBLOCK);
423   }
424   int fcntl_res = fcntl(*fd_, F_SETFL, flags);
425   PERFETTO_CHECK(fcntl_res == 0);
426 #endif
427 }
428 
SetRetainOnExec(bool retain)429 void UnixSocketRaw::SetRetainOnExec(bool retain) {
430 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
431     !PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
432   PERFETTO_DCHECK(fd_);
433   int flags = fcntl(*fd_, F_GETFD, 0);
434   if (retain) {
435     flags &= ~static_cast<int>(FD_CLOEXEC);
436   } else {
437     flags |= FD_CLOEXEC;
438   }
439   int fcntl_res = fcntl(*fd_, F_SETFD, flags);
440   PERFETTO_CHECK(fcntl_res == 0);
441 #else
442   ignore_result(retain);
443 #endif
444 }
445 
DcheckIsBlocking(bool expected) const446 void UnixSocketRaw::DcheckIsBlocking(bool expected) const {
447 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
448   ignore_result(expected);
449 #else
450   PERFETTO_DCHECK(fd_);
451   bool is_blocking = (fcntl(*fd_, F_GETFL, 0) & O_NONBLOCK) == 0;
452   PERFETTO_DCHECK(is_blocking == expected);
453 #endif
454 }
455 
Bind(const std::string & socket_name)456 bool UnixSocketRaw::Bind(const std::string& socket_name) {
457   PERFETTO_DCHECK(fd_);
458   SockaddrAny addr = MakeSockAddr(family_, socket_name);
459   if (addr.size == 0)
460     return false;
461 
462   if (bind(*fd_, addr.addr(), addr.size)) {
463     PERFETTO_DPLOG("bind(%s)", socket_name.c_str());
464     return false;
465   }
466 
467   return true;
468 }
469 
Listen()470 bool UnixSocketRaw::Listen() {
471   PERFETTO_DCHECK(fd_);
472   PERFETTO_DCHECK(type_ == SockType::kStream || type_ == SockType::kSeqPacket);
473   return listen(*fd_, SOMAXCONN) == 0;
474 }
475 
Connect(const std::string & socket_name)476 bool UnixSocketRaw::Connect(const std::string& socket_name) {
477   PERFETTO_DCHECK(fd_);
478   SockaddrAny addr = MakeSockAddr(family_, socket_name);
479   if (addr.size == 0)
480     return false;
481 
482   int res = PERFETTO_EINTR(connect(*fd_, addr.addr(), addr.size));
483 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
484   bool continue_async = WSAGetLastError() == WSAEWOULDBLOCK;
485 #else
486   bool continue_async = errno == EINPROGRESS;
487 #if PERFETTO_BUILDFLAG(PERFETTO_OS_QNX)
488   // QNX doesn't support the SO_ERROR socket option for vsock.
489   // Therefore block the connect call by polling the socket
490   // until it is writable.
491   bool is_blocking_call = family_ == SockFamily::kVsock;
492 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
493   // For VM-to-VM communication block until the socket is writable.
494   // Not blocking leads to race condition where no error is found
495   // with SO_ERROR socket option but the socket is still not writable
496   // so subsequent socket calls fail.
497   bool is_blocking_call = family_ == SockFamily::kVsock && IsVirtualized();
498 #else
499   bool is_blocking_call = false;
500 #endif
501   if (is_blocking_call && res < 0 && continue_async) {
502     pollfd pfd{*fd_, POLLOUT, 0};
503     if (PERFETTO_EINTR(poll(&pfd, 1 /*nfds*/, 3000 /*timeout*/)) <= 0)
504       return false;
505     return (pfd.revents & POLLOUT) != 0;
506   }
507 #endif
508   if (res && !continue_async)
509     return false;
510 
511   return true;
512 }
513 
Shutdown()514 void UnixSocketRaw::Shutdown() {
515 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
516   // Somebody felt very strongly about the naming of this constant.
517   shutdown(*fd_, SD_BOTH);
518 #else
519   shutdown(*fd_, SHUT_RDWR);
520 #endif
521   fd_.reset();
522 }
523 
524 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
525 
Send(const void * msg,size_t len,const int *,size_t num_fds)526 ssize_t UnixSocketRaw::Send(const void* msg,
527                             size_t len,
528                             const int* /*send_fds*/,
529                             size_t num_fds) {
530   PERFETTO_DCHECK(num_fds == 0);
531   return sendto(*fd_, static_cast<const char*>(msg), static_cast<int>(len), 0,
532                 nullptr, 0);
533 }
534 
Receive(void * msg,size_t len,ScopedFile *,size_t)535 ssize_t UnixSocketRaw::Receive(void* msg,
536                                size_t len,
537                                ScopedFile* /*fd_vec*/,
538                                size_t /*max_files*/) {
539   return recv(*fd_, static_cast<char*>(msg), static_cast<int>(len), 0);
540 }
541 
542 #else
543 // For the interested reader, Linux kernel dive to verify this is not only a
544 // theoretical possibility: sock_stream_sendmsg, if sock_alloc_send_pskb returns
545 // NULL [1] (which it does when it gets interrupted [2]), returns early with the
546 // amount of bytes already sent.
547 //
548 // [1]:
549 // https://elixir.bootlin.com/linux/v4.18.10/source/net/unix/af_unix.c#L1872
550 // [2]: https://elixir.bootlin.com/linux/v4.18.10/source/net/core/sock.c#L2101
SendMsgAllPosix(struct msghdr * msg)551 ssize_t UnixSocketRaw::SendMsgAllPosix(struct msghdr* msg) {
552   // This does not make sense on non-blocking sockets.
553   PERFETTO_DCHECK(fd_);
554 
555   const bool is_blocking_with_timeout =
556       tx_timeout_ms_ > 0 && ((fcntl(*fd_, F_GETFL, 0) & O_NONBLOCK) == 0);
557   const int64_t start_ms = GetWallTimeMs().count();
558 
559   // Waits until some space is available in the tx buffer.
560   // Returns true if some buffer space is available, false if times out.
561   auto poll_or_timeout = [&] {
562     PERFETTO_DCHECK(is_blocking_with_timeout);
563     const int64_t deadline = start_ms + tx_timeout_ms_;
564     const int64_t now_ms = GetWallTimeMs().count();
565     if (now_ms >= deadline)
566       return false;  // Timed out
567     const int timeout_ms = static_cast<int>(deadline - now_ms);
568     pollfd pfd{*fd_, POLLOUT, 0};
569     return PERFETTO_EINTR(poll(&pfd, 1, timeout_ms)) > 0;
570   };
571 
572 // We implement blocking sends that require a timeout as non-blocking + poll.
573 // This is because SO_SNDTIMEO doesn't work as expected (b/193234818). On linux
574 // we can just pass MSG_DONTWAIT to force the send to be non-blocking. On Mac,
575 // instead we need to flip the O_NONBLOCK flag back and forth.
576 #if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
577   // MSG_NOSIGNAL is not supported on Mac OS X, but in that case the socket is
578   // created with SO_NOSIGPIPE (See InitializeSocket()).
579   int send_flags = 0;
580 
581   if (is_blocking_with_timeout)
582     SetBlocking(false);
583 
584   auto reset_nonblock_on_exit = OnScopeExit([&] {
585     if (is_blocking_with_timeout)
586       SetBlocking(true);
587   });
588 #else
589   int send_flags = MSG_NOSIGNAL | (is_blocking_with_timeout ? MSG_DONTWAIT : 0);
590 #endif
591 
592   ssize_t total_sent = 0;
593   while (msg->msg_iov) {
594     ssize_t send_res = PERFETTO_EINTR(sendmsg(*fd_, msg, send_flags));
595     if (send_res == -1 && IsAgain(errno)) {
596       if (is_blocking_with_timeout && poll_or_timeout()) {
597         continue;  // Tx buffer unblocked, repeat the loop.
598       }
599       return total_sent;
600     } else if (send_res <= 0) {
601       return send_res;  // An error occurred.
602     } else {
603       total_sent += send_res;
604       ShiftMsgHdrPosix(static_cast<size_t>(send_res), msg);
605       // Only send the ancillary data with the first sendmsg call.
606       msg->msg_control = nullptr;
607       msg->msg_controllen = 0;
608     }
609   }
610   return total_sent;
611 }
612 
Send(const void * msg,size_t len,const int * send_fds,size_t num_fds)613 ssize_t UnixSocketRaw::Send(const void* msg,
614                             size_t len,
615                             const int* send_fds,
616                             size_t num_fds) {
617   PERFETTO_DCHECK(fd_);
618   msghdr msg_hdr = {};
619   iovec iov = {const_cast<void*>(msg), len};
620   msg_hdr.msg_iov = &iov;
621   msg_hdr.msg_iovlen = 1;
622   alignas(cmsghdr) char control_buf[256];
623 
624   if (num_fds > 0) {
625     const auto raw_ctl_data_sz = num_fds * sizeof(int);
626     const CBufLenType control_buf_len =
627         static_cast<CBufLenType>(CMSG_SPACE(raw_ctl_data_sz));
628     PERFETTO_CHECK(control_buf_len <= sizeof(control_buf));
629     memset(control_buf, 0, sizeof(control_buf));
630     msg_hdr.msg_control = control_buf;
631     msg_hdr.msg_controllen = control_buf_len;  // used by CMSG_FIRSTHDR
632     struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg_hdr);
633     cmsg->cmsg_level = SOL_SOCKET;
634     cmsg->cmsg_type = SCM_RIGHTS;
635     cmsg->cmsg_len = static_cast<CBufLenType>(CMSG_LEN(raw_ctl_data_sz));
636     memcpy(CMSG_DATA(cmsg), send_fds, num_fds * sizeof(int));
637     // note: if we were to send multiple cmsghdr structures, then
638     // msg_hdr.msg_controllen would need to be adjusted, see "man 3 cmsg".
639   }
640 
641   return SendMsgAllPosix(&msg_hdr);
642 }
643 
Receive(void * msg,size_t len,ScopedFile * fd_vec,size_t max_files)644 ssize_t UnixSocketRaw::Receive(void* msg,
645                                size_t len,
646                                ScopedFile* fd_vec,
647                                size_t max_files) {
648   PERFETTO_DCHECK(fd_);
649   msghdr msg_hdr = {};
650   iovec iov = {msg, len};
651   msg_hdr.msg_iov = &iov;
652   msg_hdr.msg_iovlen = 1;
653   alignas(cmsghdr) char control_buf[256];
654 
655   if (max_files > 0) {
656     msg_hdr.msg_control = control_buf;
657     msg_hdr.msg_controllen =
658         static_cast<CBufLenType>(CMSG_SPACE(max_files * sizeof(int)));
659     PERFETTO_CHECK(msg_hdr.msg_controllen <= sizeof(control_buf));
660   }
661   const ssize_t sz = PERFETTO_EINTR(recvmsg(*fd_, &msg_hdr, 0));
662   if (sz <= 0) {
663     return sz;
664   }
665   PERFETTO_CHECK(static_cast<size_t>(sz) <= len);
666 
667   int* fds = nullptr;
668   uint32_t fds_len = 0;
669 
670   if (max_files > 0) {
671     for (cmsghdr* cmsg = CMSG_FIRSTHDR(&msg_hdr); cmsg;
672          cmsg = CMSG_NXTHDR(&msg_hdr, cmsg)) {
673       const size_t payload_len = cmsg->cmsg_len - CMSG_LEN(0);
674       if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
675         PERFETTO_DCHECK(payload_len % sizeof(int) == 0u);
676         PERFETTO_CHECK(fds == nullptr);
677         fds = reinterpret_cast<int*>(CMSG_DATA(cmsg));
678         fds_len = static_cast<uint32_t>(payload_len / sizeof(int));
679       }
680     }
681   }
682 
683   if (msg_hdr.msg_flags & MSG_TRUNC || msg_hdr.msg_flags & MSG_CTRUNC) {
684     for (size_t i = 0; fds && i < fds_len; ++i)
685       close(fds[i]);
686     PERFETTO_ELOG(
687         "Socket message truncated. This might be due to a SELinux denial on "
688         "fd:use.");
689     errno = EMSGSIZE;
690     return -1;
691   }
692 
693   for (size_t i = 0; fds && i < fds_len; ++i) {
694     if (i < max_files)
695       fd_vec[i].reset(fds[i]);
696     else
697       close(fds[i]);
698   }
699 
700   return sz;
701 }
702 #endif  // OS_WIN
703 
SetTxTimeout(uint32_t timeout_ms)704 bool UnixSocketRaw::SetTxTimeout(uint32_t timeout_ms) {
705   PERFETTO_DCHECK(fd_);
706   // On Unix-based systems, SO_SNDTIMEO isn't used for Send() because it's
707   // unreliable (b/193234818). Instead we use non-blocking sendmsg() + poll().
708   // See SendMsgAllPosix(). We still make the setsockopt call because
709   // SO_SNDTIMEO also affects connect().
710   tx_timeout_ms_ = timeout_ms;
711 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
712   DWORD timeout = timeout_ms;
713   ignore_result(tx_timeout_ms_);
714 #else
715   struct timeval timeout {};
716   uint32_t timeout_sec = timeout_ms / 1000;
717   timeout.tv_sec = static_cast<decltype(timeout.tv_sec)>(timeout_sec);
718   timeout.tv_usec = static_cast<decltype(timeout.tv_usec)>(
719       (timeout_ms - (timeout_sec * 1000)) * 1000);
720 #endif
721 #if PERFETTO_BUILDFLAG(PERFETTO_OS_QNX)
722   if (family() == SockFamily::kVsock) {
723       // QNX doesn't support SO_SNDTIMEO for vsocks.
724       return true;
725   }
726 #endif
727 
728   return setsockopt(*fd_, SOL_SOCKET, SO_SNDTIMEO,
729                     reinterpret_cast<const char*>(&timeout),
730                     sizeof(timeout)) == 0;
731 }
732 
SetRxTimeout(uint32_t timeout_ms)733 bool UnixSocketRaw::SetRxTimeout(uint32_t timeout_ms) {
734   PERFETTO_DCHECK(fd_);
735 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
736   DWORD timeout = timeout_ms;
737 #else
738   struct timeval timeout {};
739   uint32_t timeout_sec = timeout_ms / 1000;
740   timeout.tv_sec = static_cast<decltype(timeout.tv_sec)>(timeout_sec);
741   timeout.tv_usec = static_cast<decltype(timeout.tv_usec)>(
742       (timeout_ms - (timeout_sec * 1000)) * 1000);
743 #endif
744   return setsockopt(*fd_, SOL_SOCKET, SO_RCVTIMEO,
745                     reinterpret_cast<const char*>(&timeout),
746                     sizeof(timeout)) == 0;
747 }
748 
GetSockAddr() const749 std::string UnixSocketRaw::GetSockAddr() const {
750   struct sockaddr_storage stg {};
751   socklen_t slen = sizeof(stg);
752   PERFETTO_CHECK(
753       getsockname(*fd_, reinterpret_cast<struct sockaddr*>(&stg), &slen) == 0);
754   char addr[255]{};
755 
756   if (stg.ss_family == AF_UNIX) {
757     auto* saddr = reinterpret_cast<struct sockaddr_un*>(&stg);
758     static_assert(sizeof(addr) >= sizeof(saddr->sun_path), "addr too small");
759     memcpy(addr, saddr->sun_path, sizeof(saddr->sun_path));
760     addr[0] = addr[0] == '\0' ? '@' : addr[0];
761     addr[sizeof(saddr->sun_path) - 1] = '\0';
762     return std::string(addr);
763   }
764 
765   if (stg.ss_family == AF_INET) {
766     auto* saddr = reinterpret_cast<struct sockaddr_in*>(&stg);
767     PERFETTO_CHECK(inet_ntop(AF_INET, &saddr->sin_addr, addr, sizeof(addr)));
768     uint16_t port = ntohs(saddr->sin_port);
769     base::StackString<255> addr_and_port("%s:%" PRIu16, addr, port);
770     return addr_and_port.ToStdString();
771   }
772 
773   if (stg.ss_family == AF_INET6) {
774     auto* saddr = reinterpret_cast<struct sockaddr_in6*>(&stg);
775     PERFETTO_CHECK(inet_ntop(AF_INET6, &saddr->sin6_addr, addr, sizeof(addr)));
776     auto port = ntohs(saddr->sin6_port);
777     base::StackString<255> addr_and_port("[%s]:%" PRIu16, addr, port);
778     return addr_and_port.ToStdString();
779   }
780 
781 #if defined(AF_VSOCK) && (PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
782                           PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID))
783   if (stg.ss_family == AF_VSOCK) {
784     auto* saddr = reinterpret_cast<struct sockaddr_vm*>(&stg);
785     base::StackString<255> addr_and_port("%s%u:%u", kVsockNamePrefix,
786                                          saddr->svm_cid, saddr->svm_port);
787     return addr_and_port.ToStdString();
788   }
789 #endif
790 
791   PERFETTO_FATAL("GetSockAddr() unsupported on family %d", stg.ss_family);
792 }
793 
794 #if defined(__GNUC__) && !PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
795 #pragma GCC diagnostic pop
796 #endif
797 
798 // +--------------------+
799 // | UnixSocket methods |
800 // +--------------------+
801 
802 // TODO(primiano): Add ThreadChecker to methods of this class.
803 
804 // static
Listen(const std::string & socket_name,EventListener * event_listener,TaskRunner * task_runner,SockFamily sock_family,SockType sock_type)805 std::unique_ptr<UnixSocket> UnixSocket::Listen(const std::string& socket_name,
806                                                EventListener* event_listener,
807                                                TaskRunner* task_runner,
808                                                SockFamily sock_family,
809                                                SockType sock_type) {
810   auto sock_raw = UnixSocketRaw::CreateMayFail(sock_family, sock_type);
811   if (!sock_raw || !sock_raw.Bind(socket_name))
812     return nullptr;
813 
814   // Forward the call to the Listen() overload below.
815   return Listen(sock_raw.ReleaseFd(), event_listener, task_runner, sock_family,
816                 sock_type);
817 }
818 
819 // static
Listen(ScopedSocketHandle fd,EventListener * event_listener,TaskRunner * task_runner,SockFamily sock_family,SockType sock_type)820 std::unique_ptr<UnixSocket> UnixSocket::Listen(ScopedSocketHandle fd,
821                                                EventListener* event_listener,
822                                                TaskRunner* task_runner,
823                                                SockFamily sock_family,
824                                                SockType sock_type) {
825   return std::unique_ptr<UnixSocket>(new UnixSocket(
826       event_listener, task_runner, std::move(fd), State::kListening,
827       sock_family, sock_type, SockPeerCredMode::kDefault));
828 }
829 
830 // static
Connect(const std::string & socket_name,EventListener * event_listener,TaskRunner * task_runner,SockFamily sock_family,SockType sock_type,SockPeerCredMode peer_cred_mode)831 std::unique_ptr<UnixSocket> UnixSocket::Connect(
832     const std::string& socket_name,
833     EventListener* event_listener,
834     TaskRunner* task_runner,
835     SockFamily sock_family,
836     SockType sock_type,
837     SockPeerCredMode peer_cred_mode) {
838   std::unique_ptr<UnixSocket> sock(new UnixSocket(
839       event_listener, task_runner, sock_family, sock_type, peer_cred_mode));
840   sock->DoConnect(socket_name);
841   return sock;
842 }
843 
844 // static
AdoptConnected(ScopedSocketHandle fd,EventListener * event_listener,TaskRunner * task_runner,SockFamily sock_family,SockType sock_type,SockPeerCredMode peer_cred_mode)845 std::unique_ptr<UnixSocket> UnixSocket::AdoptConnected(
846     ScopedSocketHandle fd,
847     EventListener* event_listener,
848     TaskRunner* task_runner,
849     SockFamily sock_family,
850     SockType sock_type,
851     SockPeerCredMode peer_cred_mode) {
852   return std::unique_ptr<UnixSocket>(new UnixSocket(
853       event_listener, task_runner, std::move(fd), State::kConnected,
854       sock_family, sock_type, peer_cred_mode));
855 }
856 
UnixSocket(EventListener * event_listener,TaskRunner * task_runner,SockFamily sock_family,SockType sock_type,SockPeerCredMode peer_cred_mode)857 UnixSocket::UnixSocket(EventListener* event_listener,
858                        TaskRunner* task_runner,
859                        SockFamily sock_family,
860                        SockType sock_type,
861                        SockPeerCredMode peer_cred_mode)
862     : UnixSocket(event_listener,
863                  task_runner,
864                  ScopedSocketHandle(),
865                  State::kDisconnected,
866                  sock_family,
867                  sock_type,
868                  peer_cred_mode) {}
869 
UnixSocket(EventListener * event_listener,TaskRunner * task_runner,ScopedSocketHandle adopt_fd,State adopt_state,SockFamily sock_family,SockType sock_type,SockPeerCredMode peer_cred_mode)870 UnixSocket::UnixSocket(EventListener* event_listener,
871                        TaskRunner* task_runner,
872                        ScopedSocketHandle adopt_fd,
873                        State adopt_state,
874                        SockFamily sock_family,
875                        SockType sock_type,
876                        SockPeerCredMode peer_cred_mode)
877     : peer_cred_mode_(peer_cred_mode),
878       event_listener_(event_listener),
879       task_runner_(task_runner),
880       weak_ptr_factory_(this) {
881   state_ = State::kDisconnected;
882   if (adopt_state == State::kDisconnected) {
883     PERFETTO_DCHECK(!adopt_fd);
884     sock_raw_ = UnixSocketRaw::CreateMayFail(sock_family, sock_type);
885     if (!sock_raw_)
886       return;
887   } else if (adopt_state == State::kConnected) {
888     PERFETTO_DCHECK(adopt_fd);
889     sock_raw_ = UnixSocketRaw(std::move(adopt_fd), sock_family, sock_type);
890     state_ = State::kConnected;
891 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
892     if (peer_cred_mode_ == SockPeerCredMode::kReadOnConnect)
893       ReadPeerCredentialsPosix();
894 #endif
895   } else if (adopt_state == State::kListening) {
896     // We get here from Listen().
897 
898     // |adopt_fd| might genuinely be invalid if the bind() failed.
899     if (!adopt_fd)
900       return;
901 
902     sock_raw_ = UnixSocketRaw(std::move(adopt_fd), sock_family, sock_type);
903     if (!sock_raw_.Listen()) {
904       PERFETTO_DPLOG("listen() failed");
905       return;
906     }
907     state_ = State::kListening;
908   } else {
909     PERFETTO_FATAL("Unexpected adopt_state");  // Unfeasible.
910   }
911 
912   PERFETTO_CHECK(sock_raw_);
913 
914   sock_raw_.SetBlocking(false);
915 
916   WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
917 
918   task_runner_->AddFileDescriptorWatch(sock_raw_.watch_handle(), [weak_ptr] {
919     if (weak_ptr)
920       weak_ptr->OnEvent();
921   });
922 }
923 
~UnixSocket()924 UnixSocket::~UnixSocket() {
925   // The implicit dtor of |weak_ptr_factory_| will no-op pending callbacks.
926   Shutdown(true);
927 }
928 
ReleaseSocket()929 UnixSocketRaw UnixSocket::ReleaseSocket() {
930   // This will invalidate any pending calls to OnEvent.
931   state_ = State::kDisconnected;
932   if (sock_raw_)
933     task_runner_->RemoveFileDescriptorWatch(sock_raw_.watch_handle());
934 
935   return std::move(sock_raw_);
936 }
937 
938 // Called only by the Connect() static constructor.
DoConnect(const std::string & socket_name)939 void UnixSocket::DoConnect(const std::string& socket_name) {
940   PERFETTO_DCHECK(state_ == State::kDisconnected);
941 
942   // This is the only thing that can gracefully fail in the ctor.
943   if (!sock_raw_)
944     return NotifyConnectionState(false);
945 
946   if (!sock_raw_.Connect(socket_name))
947     return NotifyConnectionState(false);
948 
949   // At this point either connect() succeeded or started asynchronously
950   // (errno = EINPROGRESS).
951   state_ = State::kConnecting;
952 
953   // Even if the socket is non-blocking, connecting to a UNIX socket can be
954   // acknowledged straight away rather than returning EINPROGRESS.
955   // The decision here is to deal with the two cases uniformly, at the cost of
956   // delaying the straight-away-connect() case by one task, to avoid depending
957   // on implementation details of UNIX socket on the various OSes.
958   // Posting the OnEvent() below emulates a wakeup of the FD watch. OnEvent(),
959   // which knows how to deal with spurious wakeups, will poll the SO_ERROR and
960   // evolve, if necessary, the state into either kConnected or kDisconnected.
961   WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
962   task_runner_->PostTask([weak_ptr] {
963     if (weak_ptr)
964       weak_ptr->OnEvent();
965   });
966 }
967 
968 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
ReadPeerCredentialsPosix()969 void UnixSocket::ReadPeerCredentialsPosix() {
970   // Peer credentials are supported only on AF_UNIX sockets.
971   if (sock_raw_.family() != SockFamily::kUnix)
972     return;
973   PERFETTO_CHECK(peer_cred_mode_ != SockPeerCredMode::kIgnore);
974 
975 #if PERFETTO_BUILDFLAG(PERFETTO_OS_QNX)
976   int fd = sock_raw_.fd();
977   int res = getpeereid(fd, &peer_uid_, nullptr);
978   PERFETTO_CHECK(res == 0);
979   // There is no pid when obtaining peer credentials for QNX
980 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
981     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
982   struct ucred user_cred;
983   socklen_t len = sizeof(user_cred);
984   int fd = sock_raw_.fd();
985   int res = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &user_cred, &len);
986   PERFETTO_CHECK(res == 0);
987   peer_uid_ = user_cred.uid;
988   peer_pid_ = user_cred.pid;
989 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
990   struct xucred user_cred;
991   socklen_t len = sizeof(user_cred);
992   int res = getsockopt(sock_raw_.fd(), 0, LOCAL_PEERCRED, &user_cred, &len);
993   PERFETTO_CHECK(res == 0 && user_cred.cr_version == XUCRED_VERSION);
994   peer_uid_ = static_cast<uid_t>(user_cred.cr_uid);
995   // There is no pid in the LOCAL_PEERCREDS for MacOS / FreeBSD.
996 #endif
997 }
998 #endif  // !OS_WIN
999 
1000 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
OnEvent()1001 void UnixSocket::OnEvent() {
1002   WSANETWORKEVENTS evts{};
1003   PERFETTO_CHECK(WSAEnumNetworkEvents(sock_raw_.fd(), sock_raw_.watch_handle(),
1004                                       &evts) == 0);
1005   if (state_ == State::kDisconnected)
1006     return;  // Some spurious event, typically queued just before Shutdown().
1007 
1008   if (state_ == State::kConnecting && (evts.lNetworkEvents & FD_CONNECT)) {
1009     PERFETTO_DCHECK(sock_raw_);
1010     int err = evts.iErrorCode[FD_CONNECT_BIT];
1011     if (err) {
1012       PERFETTO_DPLOG("Connection error: %d", err);
1013       Shutdown(false);
1014       event_listener_->OnConnect(this, false /* connected */);
1015       return;
1016     }
1017 
1018     // kReadOnConnect is not supported on Windows.
1019     PERFETTO_DCHECK(peer_cred_mode_ != SockPeerCredMode::kReadOnConnect);
1020     state_ = State::kConnected;
1021     event_listener_->OnConnect(this, true /* connected */);
1022   }
1023 
1024   // This is deliberately NOT an else-if. When a client socket connects and
1025   // there is already data queued, the following will happen within the same
1026   // OnEvent() call:
1027   // 1. The block above will transition kConnecting -> kConnected.
1028   // 2. This block will cause an OnDataAvailable() call.
1029   // Unlike UNIX, where poll() keeps signalling the event until the client
1030   // does a recv(), Windows is more picky and stops signalling the event until
1031   // the next call to recv() is made. In other words, in Windows we cannot
1032   // miss an OnDataAvailable() call or the event pump will stop.
1033   if (state_ == State::kConnected) {
1034     if (evts.lNetworkEvents & FD_READ) {
1035       event_listener_->OnDataAvailable(this);
1036       // TODO(primiano): I am very conflicted here. Because of the behavior
1037       // described above, if the event listener doesn't do a Recv() call in
1038       // the OnDataAvailable() callback, WinSock won't notify the event ever
1039       // again. On one side, I don't see any reason why a client should decide
1040       // to not do a Recv() in OnDataAvailable. On the other side, the
1041       // behavior here diverges from UNIX, where OnDataAvailable() would be
1042       // re-posted immediately. In both cases, not doing a Recv() in
1043       // OnDataAvailable, leads to something bad (getting stuck on Windows,
1044       // getting in a hot loop on Linux), so doesn't feel we should worry too
1045       // much about this. If we wanted to keep the behavrior consistent, here
1046       // we should do something like: `if (sock_raw_)
1047       // sock_raw_.SetBlocking(false)` (Note that the socket might be closed
1048       // by the time we come back here, hence the if part).
1049       return;
1050     }
1051     // Could read EOF and disconnect here.
1052     if (evts.lNetworkEvents & FD_CLOSE) {
1053       Shutdown(true);
1054       return;
1055     }
1056   }
1057 
1058   // New incoming connection.
1059   if (state_ == State::kListening && (evts.lNetworkEvents & FD_ACCEPT)) {
1060     // There could be more than one incoming connection behind each FD watch
1061     // notification. Drain'em all.
1062     for (;;) {
1063       // Note: right now we don't need the remote endpoint, hence we pass
1064       // nullptr to |addr| and |addrlen|. If we ever need to do so, be
1065       // extremely careful. Windows' WinSock API will happily write more than
1066       // |addrlen| (hence corrupt the stack) if the |addr| argument passed is
1067       // not big enough (e.g. passing a struct sockaddr_in to a AF_UNIX
1068       // socket, where sizeof(sockaddr_un) is >> sizef(sockaddr_in)). It seems
1069       // a Windows / CRT bug in the AF_UNIX implementation.
1070       ScopedSocketHandle new_fd(accept(sock_raw_.fd(), nullptr, nullptr));
1071       if (!new_fd)
1072         return;
1073       std::unique_ptr<UnixSocket> new_sock(new UnixSocket(
1074           event_listener_, task_runner_, std::move(new_fd), State::kConnected,
1075           sock_raw_.family(), sock_raw_.type(), peer_cred_mode_));
1076       event_listener_->OnNewIncomingConnection(this, std::move(new_sock));
1077     }
1078   }
1079 }
1080 #else
OnEvent()1081 void UnixSocket::OnEvent() {
1082   if (state_ == State::kDisconnected)
1083     return;  // Some spurious event, typically queued just before Shutdown().
1084 
1085   if (state_ == State::kConnected)
1086     return event_listener_->OnDataAvailable(this);
1087 
1088   if (state_ == State::kConnecting) {
1089     PERFETTO_DCHECK(sock_raw_);
1090     int res = 0, sock_err = 0;
1091     bool is_error_opt_supported = true;
1092 #if PERFETTO_BUILDFLAG(PERFETTO_OS_QNX)
1093     // QNX doesn't support the SO_ERROR socket option for vsock.
1094     // Since, we make the connect call blocking, it is fine to skip
1095     // the error check and simply continue with the connection flow.
1096     if (sock_raw_.family() == SockFamily::kVsock) {
1097       is_error_opt_supported = false;
1098     }
1099 #endif
1100     if (is_error_opt_supported) {
1101       sock_err = EINVAL;
1102       socklen_t err_len = sizeof(sock_err);
1103       res =
1104           getsockopt(sock_raw_.fd(), SOL_SOCKET, SO_ERROR, &sock_err, &err_len);
1105     }
1106     if (res == 0 && sock_err == EINPROGRESS)
1107       return;  // Not connected yet, just a spurious FD watch wakeup.
1108     if (res == 0 && sock_err == 0) {
1109       if (peer_cred_mode_ == SockPeerCredMode::kReadOnConnect)
1110         ReadPeerCredentialsPosix();
1111       state_ = State::kConnected;
1112       return event_listener_->OnConnect(this, true /* connected */);
1113     }
1114     PERFETTO_DLOG("Connection error: %s", strerror(sock_err));
1115     Shutdown(false);
1116     return event_listener_->OnConnect(this, false /* connected */);
1117   }
1118 
1119   // New incoming connection.
1120   if (state_ == State::kListening) {
1121     // There could be more than one incoming connection behind each FD watch
1122     // notification. Drain'em all.
1123     for (;;) {
1124       ScopedFile new_fd(
1125           PERFETTO_EINTR(accept(sock_raw_.fd(), nullptr, nullptr)));
1126       if (!new_fd)
1127         return;
1128       std::unique_ptr<UnixSocket> new_sock(new UnixSocket(
1129           event_listener_, task_runner_, std::move(new_fd), State::kConnected,
1130           sock_raw_.family(), sock_raw_.type(), peer_cred_mode_));
1131       event_listener_->OnNewIncomingConnection(this, std::move(new_sock));
1132     }
1133   }
1134 }
1135 #endif
1136 
Send(const void * msg,size_t len,const int * send_fds,size_t num_fds)1137 bool UnixSocket::Send(const void* msg,
1138                       size_t len,
1139                       const int* send_fds,
1140                       size_t num_fds) {
1141   if (state_ != State::kConnected) {
1142     errno = ENOTCONN;
1143     return false;
1144   }
1145 
1146   sock_raw_.SetBlocking(true);
1147   const ssize_t sz = sock_raw_.Send(msg, len, send_fds, num_fds);
1148   sock_raw_.SetBlocking(false);
1149 
1150   if (sz == static_cast<ssize_t>(len)) {
1151     return true;
1152   }
1153 
1154   // If we ever decide to support non-blocking sends again, here we should
1155   // watch for both EAGAIN and EWOULDBLOCK (see base::IsAgain()).
1156 
1157   // If sendmsg() succeeds but the returned size is >= 0 and < |len| it means
1158   // that the endpoint disconnected in the middle of the read, and we managed
1159   // to send only a portion of the buffer.
1160   // If sz < 0, either the other endpoint disconnected (ECONNRESET) or some
1161   // other error happened. In both cases we should just give up.
1162   PERFETTO_DPLOG("sendmsg() failed");
1163   Shutdown(true);
1164   return false;
1165 }
1166 
Shutdown(bool notify)1167 void UnixSocket::Shutdown(bool notify) {
1168   WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
1169   if (notify) {
1170     if (state_ == State::kConnected) {
1171       task_runner_->PostTask([weak_ptr] {
1172         if (weak_ptr)
1173           weak_ptr->event_listener_->OnDisconnect(weak_ptr.get());
1174       });
1175     } else if (state_ == State::kConnecting) {
1176       task_runner_->PostTask([weak_ptr] {
1177         if (weak_ptr)
1178           weak_ptr->event_listener_->OnConnect(weak_ptr.get(), false);
1179       });
1180     }
1181   }
1182 
1183   if (sock_raw_) {
1184     task_runner_->RemoveFileDescriptorWatch(sock_raw_.watch_handle());
1185     sock_raw_.Shutdown();
1186   }
1187   state_ = State::kDisconnected;
1188 }
1189 
Receive(void * msg,size_t len,ScopedFile * fd_vec,size_t max_files)1190 size_t UnixSocket::Receive(void* msg,
1191                            size_t len,
1192                            ScopedFile* fd_vec,
1193                            size_t max_files) {
1194   if (state_ != State::kConnected)
1195     return 0;
1196 
1197   const ssize_t sz = sock_raw_.Receive(msg, len, fd_vec, max_files);
1198 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1199   bool async_would_block = WSAGetLastError() == WSAEWOULDBLOCK;
1200 #else
1201   bool async_would_block = IsAgain(errno);
1202 #endif
1203   if (sz < 0 && async_would_block)
1204     return 0;
1205 
1206   if (sz <= 0) {
1207     Shutdown(true);
1208     return 0;
1209   }
1210   PERFETTO_CHECK(static_cast<size_t>(sz) <= len);
1211   return static_cast<size_t>(sz);
1212 }
1213 
ReceiveString(size_t max_length)1214 std::string UnixSocket::ReceiveString(size_t max_length) {
1215   std::unique_ptr<char[]> buf(new char[max_length + 1]);
1216   size_t rsize = Receive(buf.get(), max_length);
1217   PERFETTO_CHECK(rsize <= max_length);
1218   buf[rsize] = '\0';
1219   return std::string(buf.get());
1220 }
1221 
NotifyConnectionState(bool success)1222 void UnixSocket::NotifyConnectionState(bool success) {
1223   if (!success)
1224     Shutdown(false);
1225 
1226   WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
1227   task_runner_->PostTask([weak_ptr, success] {
1228     if (weak_ptr)
1229       weak_ptr->event_listener_->OnConnect(weak_ptr.get(), success);
1230   });
1231 }
1232 
~EventListener()1233 UnixSocket::EventListener::~EventListener() {}
OnNewIncomingConnection(UnixSocket *,std::unique_ptr<UnixSocket>)1234 void UnixSocket::EventListener::OnNewIncomingConnection(
1235     UnixSocket*,
1236     std::unique_ptr<UnixSocket>) {}
OnConnect(UnixSocket *,bool)1237 void UnixSocket::EventListener::OnConnect(UnixSocket*, bool) {}
OnDisconnect(UnixSocket *)1238 void UnixSocket::EventListener::OnDisconnect(UnixSocket*) {}
OnDataAvailable(UnixSocket *)1239 void UnixSocket::EventListener::OnDataAvailable(UnixSocket*) {}
1240 
1241 }  // namespace base
1242 }  // namespace perfetto
1243