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