xref: /aosp_15_r20/external/perfetto/src/base/unix_socket_unittest.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
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 <signal.h>
20 #include <sys/types.h>
21 #include <list>
22 #include <thread>
23 
24 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
25 #include <sys/mman.h>
26 #include <sys/socket.h>
27 #include <sys/un.h>
28 #endif
29 
30 #include "perfetto/base/build_config.h"
31 #include "perfetto/base/logging.h"
32 #include "perfetto/ext/base/file_utils.h"
33 #include "perfetto/ext/base/periodic_task.h"
34 #include "perfetto/ext/base/pipe.h"
35 #include "perfetto/ext/base/string_utils.h"
36 #include "perfetto/ext/base/temp_file.h"
37 #include "perfetto/ext/base/utils.h"
38 #include "src/base/test/test_task_runner.h"
39 #include "src/ipc/test/test_socket.h"
40 #include "test/gtest_and_gmock.h"
41 
42 #if (PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
43      PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID))
44 #define SKIP_IF_VSOCK_LOOPBACK_NOT_SUPPORTED()                                 \
45   do {                                                                         \
46     if (!UnixSocketRaw::CreateMayFail(SockFamily::kVsock, SockType::kStream)   \
47              .Bind("vsock://1:10000")) {                                       \
48       GTEST_SKIP() << "vsock testing skipped: loopback address unsupported.\n" \
49                    << "Please run sudo modprobe vsock-loopback";               \
50     }                                                                          \
51   } while (0)
52 #endif
53 
54 namespace perfetto {
55 namespace base {
56 namespace {
57 
58 using ::testing::_;
59 using ::testing::AtLeast;
60 using ::testing::Invoke;
61 using ::testing::InvokeWithoutArgs;
62 using ::testing::Mock;
63 
64 ipc::TestSocket kTestSocket{"unix_socket_unittest"};
65 
66 class MockEventListener : public UnixSocket::EventListener {
67  public:
68   MOCK_METHOD(void, OnNewIncomingConnection, (UnixSocket*, UnixSocket*));
69   MOCK_METHOD(void, OnConnect, (UnixSocket*, bool), (override));
70   MOCK_METHOD(void, OnDisconnect, (UnixSocket*), (override));
71   MOCK_METHOD(void, OnDataAvailable, (UnixSocket*), (override));
72 
73   // GMock doesn't support mocking methods with non-copiable args.
OnNewIncomingConnection(UnixSocket * self,std::unique_ptr<UnixSocket> new_connection)74   void OnNewIncomingConnection(
75       UnixSocket* self,
76       std::unique_ptr<UnixSocket> new_connection) override {
77     incoming_connections_.emplace_back(std::move(new_connection));
78     OnNewIncomingConnection(self, incoming_connections_.back().get());
79   }
80 
GetIncomingConnection()81   std::unique_ptr<UnixSocket> GetIncomingConnection() {
82     if (incoming_connections_.empty())
83       return nullptr;
84     std::unique_ptr<UnixSocket> sock = std::move(incoming_connections_.front());
85     incoming_connections_.pop_front();
86     return sock;
87   }
88 
89  private:
90   std::list<std::unique_ptr<UnixSocket>> incoming_connections_;
91 };
92 
93 class UnixSocketTest : public ::testing::Test {
94  protected:
SetUp()95   void SetUp() override { kTestSocket.Destroy(); }
TearDown()96   void TearDown() override { kTestSocket.Destroy(); }
97 
98   TestTaskRunner task_runner_;
99   MockEventListener event_listener_;
100 };
101 
TEST_F(UnixSocketTest,ConnectionFailureIfUnreachable)102 TEST_F(UnixSocketTest, ConnectionFailureIfUnreachable) {
103   auto cli =
104       UnixSocket::Connect(kTestSocket.name(), &event_listener_, &task_runner_,
105                           kTestSocket.family(), SockType::kStream);
106   ASSERT_FALSE(cli->is_connected());
107   auto checkpoint = task_runner_.CreateCheckpoint("failure");
108   EXPECT_CALL(event_listener_, OnConnect(cli.get(), false))
109       .WillOnce(InvokeWithoutArgs(checkpoint));
110   task_runner_.RunUntilCheckpoint("failure");
111 }
112 
113 // Both server and client should see an OnDisconnect() if the server drops
114 // incoming connections immediately as they are created.
TEST_F(UnixSocketTest,ConnectionImmediatelyDroppedByServer)115 TEST_F(UnixSocketTest, ConnectionImmediatelyDroppedByServer) {
116   auto srv =
117       UnixSocket::Listen(kTestSocket.name(), &event_listener_, &task_runner_,
118                          kTestSocket.family(), SockType::kStream);
119   ASSERT_TRUE(srv->is_listening());
120 
121   // The server will immediately shutdown the connection upon
122   // OnNewIncomingConnection().
123   auto srv_did_shutdown = task_runner_.CreateCheckpoint("srv_did_shutdown");
124   EXPECT_CALL(event_listener_, OnNewIncomingConnection(srv.get(), _))
125       .WillOnce(
126           Invoke([this, srv_did_shutdown](UnixSocket*, UnixSocket* new_conn) {
127             EXPECT_CALL(event_listener_, OnDisconnect(new_conn));
128             new_conn->Shutdown(true);
129             srv_did_shutdown();
130           }));
131 
132   auto checkpoint = task_runner_.CreateCheckpoint("cli_connected");
133   auto cli =
134       UnixSocket::Connect(kTestSocket.name(), &event_listener_, &task_runner_,
135                           kTestSocket.family(), SockType::kStream);
136   EXPECT_CALL(event_listener_, OnConnect(cli.get(), true))
137       .WillOnce(InvokeWithoutArgs(checkpoint));
138   task_runner_.RunUntilCheckpoint("cli_connected");
139   task_runner_.RunUntilCheckpoint("srv_did_shutdown");
140 
141   // Trying to send something will trigger the disconnection notification.
142   auto cli_disconnected = task_runner_.CreateCheckpoint("cli_disconnected");
143   EXPECT_CALL(event_listener_, OnDisconnect(cli.get()))
144       .WillOnce(InvokeWithoutArgs(cli_disconnected));
145 
146   // On Windows the first send immediately after the disconnection succeeds, the
147   // kernel will detect the disconnection only later.
148   cli->SendStr(".");
149   EXPECT_FALSE(cli->SendStr("should_fail_both_on_win_and_unix"));
150   task_runner_.RunUntilCheckpoint("cli_disconnected");
151 }
152 
TEST_F(UnixSocketTest,ClientAndServerExchangeData)153 TEST_F(UnixSocketTest, ClientAndServerExchangeData) {
154   auto srv =
155       UnixSocket::Listen(kTestSocket.name(), &event_listener_, &task_runner_,
156                          kTestSocket.family(), SockType::kStream);
157   ASSERT_TRUE(srv->is_listening());
158 
159   auto cli =
160       UnixSocket::Connect(kTestSocket.name(), &event_listener_, &task_runner_,
161                           kTestSocket.family(), SockType::kStream);
162   auto cli_connected = task_runner_.CreateCheckpoint("cli_connected");
163   EXPECT_CALL(event_listener_, OnConnect(cli.get(), true))
164       .WillOnce(InvokeWithoutArgs(cli_connected));
165   auto srv_conn_seen = task_runner_.CreateCheckpoint("srv_conn_seen");
166   auto srv_disconnected = task_runner_.CreateCheckpoint("srv_disconnected");
167   EXPECT_CALL(event_listener_, OnNewIncomingConnection(srv.get(), _))
168       .WillOnce(Invoke([this, srv_conn_seen, srv_disconnected](
169                            UnixSocket*, UnixSocket* srv_conn) {
170         EXPECT_CALL(event_listener_, OnDisconnect(srv_conn))
171             .WillOnce(InvokeWithoutArgs(srv_disconnected));
172         srv_conn_seen();
173       }));
174   task_runner_.RunUntilCheckpoint("srv_conn_seen");
175   task_runner_.RunUntilCheckpoint("cli_connected");
176 
177   auto srv_conn = event_listener_.GetIncomingConnection();
178   ASSERT_TRUE(srv_conn);
179   ASSERT_TRUE(cli->is_connected());
180 
181   auto cli_did_recv = task_runner_.CreateCheckpoint("cli_did_recv");
182   EXPECT_CALL(event_listener_, OnDataAvailable(cli.get()))
183       .WillOnce(Invoke([cli_did_recv](UnixSocket* s) {
184         ASSERT_EQ("srv>cli", s->ReceiveString());
185         cli_did_recv();
186       }));
187 
188   auto srv_did_recv = task_runner_.CreateCheckpoint("srv_did_recv");
189   EXPECT_CALL(event_listener_, OnDataAvailable(srv_conn.get()))
190       .WillOnce(Invoke([srv_did_recv](UnixSocket* s) {
191         ASSERT_EQ("cli>srv", s->ReceiveString());
192         srv_did_recv();
193       }));
194   ASSERT_TRUE(cli->SendStr("cli>srv"));
195   ASSERT_TRUE(srv_conn->SendStr("srv>cli"));
196   task_runner_.RunUntilCheckpoint("cli_did_recv");
197   task_runner_.RunUntilCheckpoint("srv_did_recv");
198 
199   // Check that Send/Receive() fails gracefully once the socket is closed.
200   auto cli_disconnected = task_runner_.CreateCheckpoint("cli_disconnected");
201   EXPECT_CALL(event_listener_, OnDisconnect(cli.get()))
202       .WillOnce(InvokeWithoutArgs(cli_disconnected));
203   cli->Shutdown(true);
204   char msg[4];
205   ASSERT_EQ(0u, cli->Receive(&msg, sizeof(msg)));
206   ASSERT_EQ("", cli->ReceiveString());
207   ASSERT_EQ(0u, srv_conn->Receive(&msg, sizeof(msg)));
208   ASSERT_EQ("", srv_conn->ReceiveString());
209   ASSERT_FALSE(cli->SendStr("foo"));
210   ASSERT_FALSE(srv_conn->SendStr("bar"));
211   srv->Shutdown(true);
212   task_runner_.RunUntilCheckpoint("cli_disconnected");
213   task_runner_.RunUntilCheckpoint("srv_disconnected");
214 }
215 
TEST_F(UnixSocketTest,ListenWithPassedSocketHandle)216 TEST_F(UnixSocketTest, ListenWithPassedSocketHandle) {
217   auto sock_raw =
218       UnixSocketRaw::CreateMayFail(kTestSocket.family(), SockType::kStream);
219   ASSERT_TRUE(sock_raw.Bind(kTestSocket.name()));
220   auto fd = sock_raw.ReleaseFd();
221   auto srv = UnixSocket::Listen(std::move(fd), &event_listener_, &task_runner_,
222                                 kTestSocket.family(), SockType::kStream);
223   ASSERT_TRUE(srv->is_listening());
224 
225   auto cli_connected = task_runner_.CreateCheckpoint("cli_connected");
226   auto cli =
227       UnixSocket::Connect(kTestSocket.name(), &event_listener_, &task_runner_,
228                           kTestSocket.family(), SockType::kStream);
229   EXPECT_CALL(event_listener_, OnConnect(cli.get(), true))
230       .WillOnce(InvokeWithoutArgs(cli_connected));
231   auto srv_connected = task_runner_.CreateCheckpoint("srv_connected");
232   auto srv_disconnected = task_runner_.CreateCheckpoint("srv_disconnected");
233   EXPECT_CALL(event_listener_, OnNewIncomingConnection(srv.get(), _))
234       .WillOnce(Invoke([this, srv_connected, srv_disconnected](
235                            UnixSocket*, UnixSocket* srv_conn) {
236         // An empty OnDataAvailable might be raised to signal the EOF state.
237         EXPECT_CALL(event_listener_, OnDataAvailable(srv_conn))
238             .WillRepeatedly(
239                 InvokeWithoutArgs([srv_conn] { srv_conn->ReceiveString(); }));
240         EXPECT_CALL(event_listener_, OnDisconnect(srv_conn))
241             .WillOnce(InvokeWithoutArgs(srv_disconnected));
242         srv_connected();
243       }));
244   task_runner_.RunUntilCheckpoint("srv_connected");
245   task_runner_.RunUntilCheckpoint("cli_connected");
246   ASSERT_TRUE(cli->is_connected());
247   cli.reset();
248   task_runner_.RunUntilCheckpoint("srv_disconnected");
249 }
250 
251 // Mostly a stress tests. Connects kNumClients clients to the same server and
252 // tests that all can exchange data and can see the expected sequence of events.
TEST_F(UnixSocketTest,SeveralClients)253 TEST_F(UnixSocketTest, SeveralClients) {
254   auto srv =
255       UnixSocket::Listen(kTestSocket.name(), &event_listener_, &task_runner_,
256                          kTestSocket.family(), SockType::kStream);
257   ASSERT_TRUE(srv->is_listening());
258   constexpr size_t kNumClients = 32;
259   std::unique_ptr<UnixSocket> cli[kNumClients];
260 
261   EXPECT_CALL(event_listener_, OnNewIncomingConnection(srv.get(), _))
262       .Times(kNumClients)
263       .WillRepeatedly(Invoke([this](UnixSocket*, UnixSocket* s) {
264         EXPECT_CALL(event_listener_, OnDataAvailable(s))
265             .WillOnce(Invoke([](UnixSocket* t) {
266               ASSERT_EQ("PING", t->ReceiveString());
267               ASSERT_TRUE(t->SendStr("PONG"));
268             }));
269       }));
270 
271   for (size_t i = 0; i < kNumClients; i++) {
272     cli[i] =
273         UnixSocket::Connect(kTestSocket.name(), &event_listener_, &task_runner_,
274                             kTestSocket.family(), SockType::kStream);
275     EXPECT_CALL(event_listener_, OnConnect(cli[i].get(), true))
276         .WillOnce(Invoke([](UnixSocket* s, bool success) {
277           ASSERT_TRUE(success);
278           ASSERT_TRUE(s->SendStr("PING"));
279         }));
280 
281     auto checkpoint = task_runner_.CreateCheckpoint(std::to_string(i));
282     EXPECT_CALL(event_listener_, OnDataAvailable(cli[i].get()))
283         .WillOnce(Invoke([checkpoint](UnixSocket* s) {
284           ASSERT_EQ("PONG", s->ReceiveString());
285           checkpoint();
286         }));
287   }
288 
289   for (size_t i = 0; i < kNumClients; i++) {
290     task_runner_.RunUntilCheckpoint(std::to_string(i));
291     ASSERT_TRUE(Mock::VerifyAndClearExpectations(cli[i].get()));
292   }
293 }
294 
TEST_F(UnixSocketTest,BlockingSend)295 TEST_F(UnixSocketTest, BlockingSend) {
296   auto srv =
297       UnixSocket::Listen(kTestSocket.name(), &event_listener_, &task_runner_,
298                          kTestSocket.family(), SockType::kStream);
299   ASSERT_TRUE(srv->is_listening());
300 
301   auto all_frames_done = task_runner_.CreateCheckpoint("all_frames_done");
302   size_t total_bytes_received = 0;
303   static constexpr size_t kTotalBytes = 1024 * 1024 * 4;
304   EXPECT_CALL(event_listener_, OnNewIncomingConnection(srv.get(), _))
305       .WillOnce(Invoke([this, &total_bytes_received, all_frames_done](
306                            UnixSocket*, UnixSocket* srv_conn) {
307         EXPECT_CALL(event_listener_, OnDataAvailable(srv_conn))
308             .WillRepeatedly(
309                 Invoke([&total_bytes_received, all_frames_done](UnixSocket* s) {
310                   char buf[1024];
311                   size_t res = s->Receive(buf, sizeof(buf));
312                   total_bytes_received += res;
313                   if (total_bytes_received == kTotalBytes)
314                     all_frames_done();
315                 }));
316       }));
317 
318   // Override default timeout as this test can take time on the emulator.
319   static constexpr int kTimeoutMs = 60000 * 3;
320 
321   // Perform the blocking send form another thread.
322   std::thread tx_thread([] {
323     TestTaskRunner tx_task_runner;
324     MockEventListener tx_events;
325     auto cli =
326         UnixSocket::Connect(kTestSocket.name(), &tx_events, &tx_task_runner,
327                             kTestSocket.family(), SockType::kStream);
328 
329     auto cli_connected = tx_task_runner.CreateCheckpoint("cli_connected");
330     EXPECT_CALL(tx_events, OnConnect(cli.get(), true))
331         .WillOnce(InvokeWithoutArgs(cli_connected));
332     tx_task_runner.RunUntilCheckpoint("cli_connected");
333 
334     auto all_sent = tx_task_runner.CreateCheckpoint("all_sent");
335     std::string buf(1024 * 32, '\0');
336     tx_task_runner.PostTask([&cli, &buf, all_sent] {
337       for (size_t i = 0; i < kTotalBytes / buf.size(); i++)
338         cli->Send(buf.data(), buf.size());
339       all_sent();
340     });
341     tx_task_runner.RunUntilCheckpoint("all_sent", kTimeoutMs);
342   });
343 
344   task_runner_.RunUntilCheckpoint("all_frames_done", kTimeoutMs);
345   tx_thread.join();
346 }
347 
348 // Regression test for b/76155349 . If the receiver end disconnects while the
349 // sender is in the middle of a large send(), the socket should gracefully give
350 // up (i.e. Shutdown()) but not crash.
TEST_F(UnixSocketTest,ReceiverDisconnectsDuringSend)351 TEST_F(UnixSocketTest, ReceiverDisconnectsDuringSend) {
352   auto srv =
353       UnixSocket::Listen(kTestSocket.name(), &event_listener_, &task_runner_,
354                          kTestSocket.family(), SockType::kStream);
355   ASSERT_TRUE(srv->is_listening());
356   static constexpr int kTimeoutMs = 30000;
357 
358   auto receive_done = task_runner_.CreateCheckpoint("receive_done");
359   EXPECT_CALL(event_listener_, OnNewIncomingConnection(srv.get(), _))
360       .WillOnce(Invoke([this, receive_done](UnixSocket*, UnixSocket* srv_conn) {
361         EXPECT_CALL(event_listener_, OnDataAvailable(srv_conn))
362             .WillOnce(Invoke([receive_done](UnixSocket* s) {
363               char buf[1024];
364               size_t res = s->Receive(buf, sizeof(buf));
365               ASSERT_EQ(1024u, res);
366               s->Shutdown(false /*notify*/);
367               receive_done();
368             }));
369       }));
370 
371   // Perform the blocking send form another thread.
372   std::thread tx_thread([] {
373     TestTaskRunner tx_task_runner;
374     MockEventListener tx_events;
375     auto cli =
376         UnixSocket::Connect(kTestSocket.name(), &tx_events, &tx_task_runner,
377                             kTestSocket.family(), SockType::kStream);
378 
379     auto cli_connected = tx_task_runner.CreateCheckpoint("cli_connected");
380     EXPECT_CALL(tx_events, OnConnect(cli.get(), true))
381         .WillOnce(InvokeWithoutArgs(cli_connected));
382     tx_task_runner.RunUntilCheckpoint("cli_connected");
383 
384     auto send_done = tx_task_runner.CreateCheckpoint("send_done");
385     static constexpr size_t kBufSize = 32 * 1024 * 1024;
386     std::unique_ptr<char[]> buf(new char[kBufSize]());
387     tx_task_runner.PostTask([&cli, &buf, send_done] {
388       cli->Send(buf.get(), kBufSize);
389       send_done();
390     });
391 
392     tx_task_runner.RunUntilCheckpoint("send_done", kTimeoutMs);
393   });
394   task_runner_.RunUntilCheckpoint("receive_done", kTimeoutMs);
395   tx_thread.join();
396 }
397 
TEST_F(UnixSocketTest,ReleaseSocket)398 TEST_F(UnixSocketTest, ReleaseSocket) {
399   auto srv =
400       UnixSocket::Listen(kTestSocket.name(), &event_listener_, &task_runner_,
401                          kTestSocket.family(), SockType::kStream);
402   ASSERT_TRUE(srv->is_listening());
403   auto srv_connected = task_runner_.CreateCheckpoint("srv_connected");
404   UnixSocket* peer = nullptr;
405   EXPECT_CALL(event_listener_, OnNewIncomingConnection(srv.get(), _))
406       .WillOnce(
407           Invoke([srv_connected, &peer](UnixSocket*, UnixSocket* new_conn) {
408             peer = new_conn;
409             srv_connected();
410           }));
411 
412   auto cli =
413       UnixSocket::Connect(kTestSocket.name(), &event_listener_, &task_runner_,
414                           kTestSocket.family(), SockType::kStream);
415   auto cli_connected = task_runner_.CreateCheckpoint("cli_connected");
416   EXPECT_CALL(event_listener_, OnConnect(cli.get(), true))
417       .WillOnce(InvokeWithoutArgs(cli_connected));
418   task_runner_.RunUntilCheckpoint("srv_connected");
419   task_runner_.RunUntilCheckpoint("cli_connected");
420   srv->Shutdown(true);
421 
422   cli->SendStr("test");
423 
424   ASSERT_NE(peer, nullptr);
425   auto raw_sock = peer->ReleaseSocket();
426 
427   EXPECT_CALL(event_listener_, OnDataAvailable(_)).Times(0);
428   task_runner_.RunUntilIdle();
429 
430   char buf[5];
431   ASSERT_TRUE(raw_sock);
432   ASSERT_EQ(raw_sock.Receive(buf, sizeof(buf)), 4);
433   buf[sizeof(buf) - 1] = '\0';
434   ASSERT_STREQ(buf, "test");
435 }
436 
437 // Tests that the return value of GetSockAddr() returns a well formatted address
438 // that can be passed to UnixSocket::Connect().
TEST_F(UnixSocketTest,GetSockAddrTcp4)439 TEST_F(UnixSocketTest, GetSockAddrTcp4) {
440   auto srv = UnixSocket::Listen("127.0.0.1:0", &event_listener_, &task_runner_,
441                                 SockFamily::kInet, SockType::kStream);
442   ASSERT_TRUE(srv->is_listening());
443 
444   auto cli =
445       UnixSocket::Connect(srv->GetSockAddr(), &event_listener_, &task_runner_,
446                           SockFamily::kInet, SockType::kStream);
447   EXPECT_CALL(event_listener_, OnConnect(cli.get(), true))
448       .WillOnce(InvokeWithoutArgs(task_runner_.CreateCheckpoint("connected")));
449   task_runner_.RunUntilCheckpoint("connected");
450 }
451 
TEST_F(UnixSocketTest,GetSockAddrTcp6)452 TEST_F(UnixSocketTest, GetSockAddrTcp6) {
453   auto srv = UnixSocket::Listen("[::1]:0", &event_listener_, &task_runner_,
454                                 SockFamily::kInet6, SockType::kStream);
455   if (!srv)
456     GTEST_SKIP() << "This test requires IPv6 support in the OS. Skipping";
457 
458   ASSERT_TRUE(srv->is_listening());
459   auto cli =
460       UnixSocket::Connect(srv->GetSockAddr(), &event_listener_, &task_runner_,
461                           SockFamily::kInet6, SockType::kStream);
462 
463   EXPECT_CALL(event_listener_, OnConnect(cli.get(), true))
464       .WillOnce(InvokeWithoutArgs(task_runner_.CreateCheckpoint("connected")));
465   task_runner_.RunUntilCheckpoint("connected");
466 }
467 
468 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
469     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
470     PERFETTO_BUILDFLAG(PERFETTO_OS_MAC)
TEST_F(UnixSocketTest,GetSockAddrUnixLinked)471 TEST_F(UnixSocketTest, GetSockAddrUnixLinked) {
472   TempDir tmp_dir = TempDir::Create();
473   std::string sock_path = tmp_dir.path() + "/test.sock";
474   auto srv = UnixSocket::Listen(sock_path, &event_listener_, &task_runner_,
475                                 SockFamily::kUnix, SockType::kStream);
476   ASSERT_TRUE(srv->is_listening());
477   EXPECT_EQ(sock_path, srv->GetSockAddr());
478   auto cli =
479       UnixSocket::Connect(srv->GetSockAddr(), &event_listener_, &task_runner_,
480                           SockFamily::kUnix, SockType::kStream);
481   EXPECT_CALL(event_listener_, OnConnect(cli.get(), true))
482       .WillOnce(InvokeWithoutArgs(task_runner_.CreateCheckpoint("connected")));
483   task_runner_.RunUntilCheckpoint("connected");
484   cli.reset();
485   srv.reset();
486   remove(sock_path.c_str());
487 }
488 #endif
489 
490 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
491     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
TEST_F(UnixSocketTest,GetSockAddrUnixAbstract)492 TEST_F(UnixSocketTest, GetSockAddrUnixAbstract) {
493   StackString<128> sock_name("@perfetto_sock_%d_%d", getpid(), rand() % 100000);
494 
495   auto srv =
496       UnixSocket::Listen(sock_name.ToStdString(), &event_listener_,
497                          &task_runner_, SockFamily::kUnix, SockType::kStream);
498   ASSERT_TRUE(srv->is_listening());
499   EXPECT_EQ(sock_name.ToStdString(), srv->GetSockAddr());
500   auto cli =
501       UnixSocket::Connect(srv->GetSockAddr(), &event_listener_, &task_runner_,
502                           SockFamily::kUnix, SockType::kStream);
503   EXPECT_CALL(event_listener_, OnConnect(cli.get(), true))
504       .WillOnce(InvokeWithoutArgs(task_runner_.CreateCheckpoint("connected")));
505   task_runner_.RunUntilCheckpoint("connected");
506 }
507 #endif
508 
509 #if (PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
510      PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID))
TEST_F(UnixSocketTest,GetSockAddrVsock)511 TEST_F(UnixSocketTest, GetSockAddrVsock) {
512   SKIP_IF_VSOCK_LOOPBACK_NOT_SUPPORTED();
513 
514   auto srv = UnixSocket::Listen("vsock://1:-1", &event_listener_, &task_runner_,
515                                 SockFamily::kVsock, SockType::kStream);
516   ASSERT_TRUE(srv->is_listening());
517   auto cli =
518       UnixSocket::Connect(srv->GetSockAddr(), &event_listener_, &task_runner_,
519                           SockFamily::kVsock, SockType::kStream);
520 
521   EXPECT_CALL(event_listener_, OnConnect(cli.get(), true))
522       .WillOnce(InvokeWithoutArgs(task_runner_.CreateCheckpoint("connected")));
523   task_runner_.RunUntilCheckpoint("connected");
524 }
525 #endif
526 
TEST_F(UnixSocketTest,TcpStream)527 TEST_F(UnixSocketTest, TcpStream) {
528   // Listen on a random port.
529   std::unique_ptr<UnixSocket> srv =
530       UnixSocket::Listen("127.0.0.1:0", &event_listener_, &task_runner_,
531                          SockFamily::kInet, SockType::kStream);
532   ASSERT_TRUE(srv->is_listening());
533   std::string host_and_port = srv->GetSockAddr();
534   constexpr size_t kNumClients = 3;
535   std::unique_ptr<UnixSocket> cli[kNumClients];
536   EXPECT_CALL(event_listener_, OnNewIncomingConnection(srv.get(), _))
537       .Times(kNumClients)
538       .WillRepeatedly(Invoke([&](UnixSocket*, UnixSocket* s) {
539         // OnDisconnect() might spuriously happen depending on the dtor order.
540         EXPECT_CALL(event_listener_, OnDisconnect(s)).Times(AtLeast(0));
541         EXPECT_CALL(event_listener_, OnDataAvailable(s))
542             .WillRepeatedly(Invoke([](UnixSocket* cli_sock) {
543               cli_sock->ReceiveString();  // Read connection EOF;
544             }));
545         ASSERT_TRUE(s->SendStr("welcome"));
546       }));
547 
548   for (size_t i = 0; i < kNumClients; i++) {
549     cli[i] = UnixSocket::Connect(host_and_port, &event_listener_, &task_runner_,
550                                  SockFamily::kInet, SockType::kStream);
551     auto checkpoint = task_runner_.CreateCheckpoint(std::to_string(i));
552     EXPECT_CALL(event_listener_, OnDisconnect(cli[i].get())).Times(AtLeast(0));
553     EXPECT_CALL(event_listener_, OnConnect(cli[i].get(), true));
554     EXPECT_CALL(event_listener_, OnDataAvailable(cli[i].get()))
555         .WillRepeatedly(Invoke([checkpoint](UnixSocket* s) {
556           auto str = s->ReceiveString();
557           if (str == "")
558             return;  // Connection EOF.
559           ASSERT_EQ("welcome", str);
560           checkpoint();
561         }));
562   }
563 
564   for (size_t i = 0; i < kNumClients; i++) {
565     task_runner_.RunUntilCheckpoint(std::to_string(i));
566     ASSERT_TRUE(Mock::VerifyAndClearExpectations(cli[i].get()));
567   }
568 }
569 
570 // ---------------------------------
571 // Posix-only tests below this point
572 // ---------------------------------
573 
574 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
575 
576 // Tests the SockPeerCredMode::kIgnore logic.
TEST_F(UnixSocketTest,IgnorePeerCredentials)577 TEST_F(UnixSocketTest, IgnorePeerCredentials) {
578   auto srv =
579       UnixSocket::Listen(kTestSocket.name(), &event_listener_, &task_runner_,
580                          kTestSocket.family(), SockType::kStream);
581   ASSERT_TRUE(srv->is_listening());
582   auto cli1_connected = task_runner_.CreateCheckpoint("cli1_connected");
583   auto cli1 = UnixSocket::Connect(kTestSocket.name(), &event_listener_,
584                                   &task_runner_, kTestSocket.family(),
585                                   SockType::kStream, SockPeerCredMode::kIgnore);
586   EXPECT_CALL(event_listener_, OnConnect(cli1.get(), true))
587       .WillOnce(InvokeWithoutArgs(cli1_connected));
588 
589   auto cli2_connected = task_runner_.CreateCheckpoint("cli2_connected");
590   auto cli2 = UnixSocket::Connect(
591       kTestSocket.name(), &event_listener_, &task_runner_, kTestSocket.family(),
592       SockType::kStream, SockPeerCredMode::kReadOnConnect);
593   EXPECT_CALL(event_listener_, OnConnect(cli2.get(), true))
594       .WillOnce(InvokeWithoutArgs(cli2_connected));
595 
596   task_runner_.RunUntilCheckpoint("cli1_connected");
597   task_runner_.RunUntilCheckpoint("cli2_connected");
598 
599   ASSERT_EQ(cli1->peer_uid_posix(/*skip_check_for_testing=*/true), kInvalidUid);
600   ASSERT_EQ(cli2->peer_uid_posix(), geteuid());
601 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
602     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
603   ASSERT_EQ(cli1->peer_pid_linux(/*skip_check_for_testing=*/true), kInvalidPid);
604   ASSERT_EQ(cli2->peer_pid_linux(), getpid());
605 #endif
606 }
607 
608 // Checks that the peer_uid() is retained after the client disconnects. The IPC
609 // layer needs to rely on this to validate messages received immediately before
610 // a client disconnects.
TEST_F(UnixSocketTest,PeerCredentialsRetainedAfterDisconnect)611 TEST_F(UnixSocketTest, PeerCredentialsRetainedAfterDisconnect) {
612   auto srv =
613       UnixSocket::Listen(kTestSocket.name(), &event_listener_, &task_runner_,
614                          kTestSocket.family(), SockType::kStream);
615   ASSERT_TRUE(srv->is_listening());
616   UnixSocket* srv_client_conn = nullptr;
617   auto srv_connected = task_runner_.CreateCheckpoint("srv_connected");
618   EXPECT_CALL(event_listener_, OnNewIncomingConnection(srv.get(), _))
619       .WillOnce(Invoke([&srv_client_conn, srv_connected](UnixSocket*,
620                                                          UnixSocket* srv_conn) {
621         srv_client_conn = srv_conn;
622         EXPECT_EQ(geteuid(), static_cast<uint32_t>(srv_conn->peer_uid_posix()));
623 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
624     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
625         EXPECT_EQ(getpid(), static_cast<pid_t>(srv_conn->peer_pid_linux()));
626 #endif
627         srv_connected();
628       }));
629   auto cli_connected = task_runner_.CreateCheckpoint("cli_connected");
630   auto cli =
631       UnixSocket::Connect(kTestSocket.name(), &event_listener_, &task_runner_,
632                           kTestSocket.family(), SockType::kStream);
633   EXPECT_CALL(event_listener_, OnConnect(cli.get(), true))
634       .WillOnce(InvokeWithoutArgs(cli_connected));
635 
636   task_runner_.RunUntilCheckpoint("cli_connected");
637   task_runner_.RunUntilCheckpoint("srv_connected");
638   ASSERT_NE(nullptr, srv_client_conn);
639   ASSERT_TRUE(srv_client_conn->is_connected());
640 
641   auto cli_disconnected = task_runner_.CreateCheckpoint("cli_disconnected");
642   EXPECT_CALL(event_listener_, OnDisconnect(srv_client_conn))
643       .WillOnce(InvokeWithoutArgs(cli_disconnected));
644 
645   // TODO(primiano): when the a peer disconnects, the other end receives a
646   // spurious OnDataAvailable() that needs to be acked with a Receive() to read
647   // the EOF. See b/69536434.
648   EXPECT_CALL(event_listener_, OnDataAvailable(srv_client_conn))
649       .WillOnce(Invoke([](UnixSocket* sock) { sock->ReceiveString(); }));
650 
651   cli.reset();
652   task_runner_.RunUntilCheckpoint("cli_disconnected");
653   ASSERT_FALSE(srv_client_conn->is_connected());
654   EXPECT_EQ(geteuid(),
655             static_cast<uint32_t>(srv_client_conn->peer_uid_posix()));
656 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
657     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
658   EXPECT_EQ(getpid(), static_cast<pid_t>(srv_client_conn->peer_pid_linux()));
659 #endif
660 }
661 
TEST_F(UnixSocketTest,ClientAndServerExchangeFDs)662 TEST_F(UnixSocketTest, ClientAndServerExchangeFDs) {
663   static constexpr char cli_str[] = "cli>srv";
664   static constexpr char srv_str[] = "srv>cli";
665   auto srv =
666       UnixSocket::Listen(kTestSocket.name(), &event_listener_, &task_runner_,
667                          kTestSocket.family(), SockType::kStream);
668   ASSERT_TRUE(srv->is_listening());
669 
670   auto cli =
671       UnixSocket::Connect(kTestSocket.name(), &event_listener_, &task_runner_,
672                           kTestSocket.family(), SockType::kStream);
673   EXPECT_CALL(event_listener_, OnConnect(cli.get(), true));
674   auto cli_connected = task_runner_.CreateCheckpoint("cli_connected");
675   auto srv_disconnected = task_runner_.CreateCheckpoint("srv_disconnected");
676   EXPECT_CALL(event_listener_, OnNewIncomingConnection(srv.get(), _))
677       .WillOnce(Invoke([this, cli_connected, srv_disconnected](
678                            UnixSocket*, UnixSocket* srv_conn) {
679         EXPECT_CALL(event_listener_, OnDisconnect(srv_conn))
680             .WillOnce(InvokeWithoutArgs(srv_disconnected));
681         cli_connected();
682       }));
683   task_runner_.RunUntilCheckpoint("cli_connected");
684 
685   auto srv_conn = event_listener_.GetIncomingConnection();
686   ASSERT_TRUE(srv_conn);
687   ASSERT_TRUE(cli->is_connected());
688 
689   ScopedFile null_fd(base::OpenFile("/dev/null", O_RDONLY));
690   ScopedFile zero_fd(base::OpenFile("/dev/zero", O_RDONLY));
691 
692   auto cli_did_recv = task_runner_.CreateCheckpoint("cli_did_recv");
693   EXPECT_CALL(event_listener_, OnDataAvailable(cli.get()))
694       .WillRepeatedly(Invoke([cli_did_recv](UnixSocket* s) {
695         ScopedFile fd_buf[3];
696         char buf[sizeof(cli_str)];
697         if (!s->Receive(buf, sizeof(buf), fd_buf, ArraySize(fd_buf)))
698           return;
699         ASSERT_STREQ(srv_str, buf);
700         ASSERT_NE(*fd_buf[0], -1);
701         ASSERT_NE(*fd_buf[1], -1);
702         ASSERT_EQ(*fd_buf[2], -1);
703 
704         char rd_buf[1];
705         // /dev/null
706         ASSERT_EQ(read(*fd_buf[0], rd_buf, sizeof(rd_buf)), 0);
707         // /dev/zero
708         ASSERT_EQ(read(*fd_buf[1], rd_buf, sizeof(rd_buf)), 1);
709         cli_did_recv();
710       }));
711 
712   auto srv_did_recv = task_runner_.CreateCheckpoint("srv_did_recv");
713   EXPECT_CALL(event_listener_, OnDataAvailable(srv_conn.get()))
714       .WillRepeatedly(Invoke([srv_did_recv](UnixSocket* s) {
715         ScopedFile fd_buf[3];
716         char buf[sizeof(srv_str)];
717         if (!s->Receive(buf, sizeof(buf), fd_buf, ArraySize(fd_buf)))
718           return;
719         ASSERT_STREQ(cli_str, buf);
720         ASSERT_NE(*fd_buf[0], -1);
721         ASSERT_NE(*fd_buf[1], -1);
722         ASSERT_EQ(*fd_buf[2], -1);
723 
724         char rd_buf[1];
725         // /dev/null
726         ASSERT_EQ(read(*fd_buf[0], rd_buf, sizeof(rd_buf)), 0);
727         // /dev/zero
728         ASSERT_EQ(read(*fd_buf[1], rd_buf, sizeof(rd_buf)), 1);
729         srv_did_recv();
730       }));
731 
732   int buf_fd[2] = {null_fd.get(), zero_fd.get()};
733 
734   ASSERT_TRUE(
735       cli->Send(cli_str, sizeof(cli_str), buf_fd, base::ArraySize(buf_fd)));
736   ASSERT_TRUE(srv_conn->Send(srv_str, sizeof(srv_str), buf_fd,
737                              base::ArraySize(buf_fd)));
738   task_runner_.RunUntilCheckpoint("srv_did_recv");
739   task_runner_.RunUntilCheckpoint("cli_did_recv");
740 
741   auto cli_disconnected = task_runner_.CreateCheckpoint("cli_disconnected");
742   EXPECT_CALL(event_listener_, OnDisconnect(cli.get()))
743       .WillOnce(InvokeWithoutArgs(cli_disconnected));
744   cli->Shutdown(true);
745   srv->Shutdown(true);
746   task_runner_.RunUntilCheckpoint("srv_disconnected");
747   task_runner_.RunUntilCheckpoint("cli_disconnected");
748 }
749 
750 // Creates two processes. The server process creates a file and passes it over
751 // the socket to the client. Both processes mmap the file in shared mode and
752 // check that they see the same contents.
TEST_F(UnixSocketTest,SharedMemory)753 TEST_F(UnixSocketTest, SharedMemory) {
754   Pipe pipe = Pipe::Create();
755   pid_t pid = fork();
756   ASSERT_GE(pid, 0);
757   constexpr size_t kTmpSize = 4096;
758 
759   if (pid == 0) {
760     // Child process.
761     TempFile scoped_tmp = TempFile::CreateUnlinked();
762     int tmp_fd = scoped_tmp.fd();
763     ASSERT_FALSE(ftruncate(tmp_fd, kTmpSize));
764     char* mem = reinterpret_cast<char*>(
765         mmap(nullptr, kTmpSize, PROT_READ | PROT_WRITE, MAP_SHARED, tmp_fd, 0));
766     ASSERT_NE(nullptr, mem);
767     memcpy(mem, "shm rocks", 10);
768 
769     auto srv =
770         UnixSocket::Listen(kTestSocket.name(), &event_listener_, &task_runner_,
771                            kTestSocket.family(), SockType::kStream);
772     ASSERT_TRUE(srv->is_listening());
773     // Signal the other process that it can connect.
774     ASSERT_EQ(1, base::WriteAll(*pipe.wr, ".", 1));
775     auto checkpoint = task_runner_.CreateCheckpoint("change_seen_by_server");
776     EXPECT_CALL(event_listener_, OnNewIncomingConnection(srv.get(), _))
777         .WillOnce(Invoke(
778             [this, tmp_fd, checkpoint, mem](UnixSocket*, UnixSocket* new_conn) {
779               ASSERT_EQ(geteuid(),
780                         static_cast<uint32_t>(new_conn->peer_uid_posix()));
781               ASSERT_TRUE(new_conn->Send("txfd", 5, tmp_fd));
782               // Wait for the client to change this again.
783               EXPECT_CALL(event_listener_, OnDataAvailable(new_conn))
784                   .WillOnce(Invoke([checkpoint, mem](UnixSocket* s) {
785                     ASSERT_EQ("change notify", s->ReceiveString());
786                     ASSERT_STREQ("rock more", mem);
787                     checkpoint();
788                   }));
789             }));
790     task_runner_.RunUntilCheckpoint("change_seen_by_server");
791     ASSERT_TRUE(Mock::VerifyAndClearExpectations(&event_listener_));
792     _exit(0);
793   } else {
794     char sync_cmd = '\0';
795     ASSERT_EQ(1, PERFETTO_EINTR(read(*pipe.rd, &sync_cmd, 1)));
796     ASSERT_EQ('.', sync_cmd);
797     auto cli =
798         UnixSocket::Connect(kTestSocket.name(), &event_listener_, &task_runner_,
799                             kTestSocket.family(), SockType::kStream);
800     EXPECT_CALL(event_listener_, OnConnect(cli.get(), true));
801     auto checkpoint = task_runner_.CreateCheckpoint("change_seen_by_client");
802     EXPECT_CALL(event_listener_, OnDataAvailable(cli.get()))
803         .WillOnce(Invoke([checkpoint](UnixSocket* s) {
804           char msg[32];
805           ScopedFile fd;
806           ASSERT_EQ(5u, s->Receive(msg, sizeof(msg), &fd));
807           ASSERT_STREQ("txfd", msg);
808           ASSERT_TRUE(fd);
809           char* mem = reinterpret_cast<char*>(mmap(
810               nullptr, kTmpSize, PROT_READ | PROT_WRITE, MAP_SHARED, *fd, 0));
811           ASSERT_NE(nullptr, mem);
812           mem[9] = '\0';  // Just to get a clean error in case of test failure.
813           ASSERT_STREQ("shm rocks", mem);
814 
815           // Now change the shared memory and ping the other process.
816           memcpy(mem, "rock more", 10);
817           ASSERT_TRUE(s->SendStr("change notify"));
818           checkpoint();
819         }));
820     task_runner_.RunUntilCheckpoint("change_seen_by_client");
821     int st = 0;
822     PERFETTO_EINTR(waitpid(pid, &st, 0));
823     ASSERT_FALSE(WIFSIGNALED(st)) << "Server died with signal " << WTERMSIG(st);
824     EXPECT_TRUE(WIFEXITED(st));
825     ASSERT_EQ(0, WEXITSTATUS(st));
826   }
827 }
828 
TEST_F(UnixSocketTest,ShiftMsgHdrSendPartialFirst)829 TEST_F(UnixSocketTest, ShiftMsgHdrSendPartialFirst) {
830   // Send a part of the first iov, then send the rest.
831   struct iovec iov[2] = {};
832   char hello[] = "hello";
833   char world[] = "world";
834   iov[0].iov_base = &hello[0];
835   iov[0].iov_len = base::ArraySize(hello);
836 
837   iov[1].iov_base = &world[0];
838   iov[1].iov_len = base::ArraySize(world);
839 
840   struct msghdr hdr = {};
841   hdr.msg_iov = iov;
842   hdr.msg_iovlen = base::ArraySize(iov);
843 
844   UnixSocketRaw::ShiftMsgHdrPosix(1, &hdr);
845   EXPECT_NE(hdr.msg_iov, nullptr);
846   EXPECT_EQ(hdr.msg_iov[0].iov_base, &hello[1]);
847   EXPECT_EQ(hdr.msg_iov[1].iov_base, &world[0]);
848   EXPECT_EQ(static_cast<int>(hdr.msg_iovlen), 2);
849   EXPECT_STREQ(reinterpret_cast<char*>(hdr.msg_iov[0].iov_base), "ello");
850   EXPECT_EQ(iov[0].iov_len, base::ArraySize(hello) - 1);
851 
852   UnixSocketRaw::ShiftMsgHdrPosix(base::ArraySize(hello) - 1, &hdr);
853   EXPECT_EQ(hdr.msg_iov, &iov[1]);
854   EXPECT_EQ(static_cast<int>(hdr.msg_iovlen), 1);
855   EXPECT_STREQ(reinterpret_cast<char*>(hdr.msg_iov[0].iov_base), world);
856   EXPECT_EQ(hdr.msg_iov[0].iov_len, base::ArraySize(world));
857 
858   UnixSocketRaw::ShiftMsgHdrPosix(base::ArraySize(world), &hdr);
859   EXPECT_EQ(hdr.msg_iov, nullptr);
860   EXPECT_EQ(static_cast<int>(hdr.msg_iovlen), 0);
861 }
862 
TEST_F(UnixSocketTest,ShiftMsgHdrSendFirstAndPartial)863 TEST_F(UnixSocketTest, ShiftMsgHdrSendFirstAndPartial) {
864   // Send first iov and part of the second iov, then send the rest.
865   struct iovec iov[2] = {};
866   char hello[] = "hello";
867   char world[] = "world";
868   iov[0].iov_base = &hello[0];
869   iov[0].iov_len = base::ArraySize(hello);
870 
871   iov[1].iov_base = &world[0];
872   iov[1].iov_len = base::ArraySize(world);
873 
874   struct msghdr hdr = {};
875   hdr.msg_iov = iov;
876   hdr.msg_iovlen = base::ArraySize(iov);
877 
878   UnixSocketRaw::ShiftMsgHdrPosix(base::ArraySize(hello) + 1, &hdr);
879   EXPECT_NE(hdr.msg_iov, nullptr);
880   EXPECT_EQ(static_cast<int>(hdr.msg_iovlen), 1);
881   EXPECT_STREQ(reinterpret_cast<char*>(hdr.msg_iov[0].iov_base), "orld");
882   EXPECT_EQ(hdr.msg_iov[0].iov_len, base::ArraySize(world) - 1);
883 
884   UnixSocketRaw::ShiftMsgHdrPosix(base::ArraySize(world) - 1, &hdr);
885   EXPECT_EQ(hdr.msg_iov, nullptr);
886   EXPECT_EQ(static_cast<int>(hdr.msg_iovlen), 0);
887 }
888 
TEST_F(UnixSocketTest,ShiftMsgHdrSendEverything)889 TEST_F(UnixSocketTest, ShiftMsgHdrSendEverything) {
890   // Send everything at once.
891   struct iovec iov[2] = {};
892   char hello[] = "hello";
893   char world[] = "world";
894   iov[0].iov_base = &hello[0];
895   iov[0].iov_len = base::ArraySize(hello);
896 
897   iov[1].iov_base = &world[0];
898   iov[1].iov_len = base::ArraySize(world);
899 
900   struct msghdr hdr = {};
901   hdr.msg_iov = iov;
902   hdr.msg_iovlen = base::ArraySize(iov);
903 
904   UnixSocketRaw::ShiftMsgHdrPosix(
905       base::ArraySize(world) + base::ArraySize(hello), &hdr);
906   EXPECT_EQ(hdr.msg_iov, nullptr);
907   EXPECT_EQ(static_cast<int>(hdr.msg_iovlen), 0);
908 }
909 
910 // For use in PartialSendMsgAll template argument. Cannot be a lambda.
RollbackSigaction(const struct sigaction * act)911 int RollbackSigaction(const struct sigaction* act) {
912   return sigaction(SIGWINCH, act, nullptr);
913 }
914 
TEST_F(UnixSocketTest,PartialSendMsgAll)915 TEST_F(UnixSocketTest, PartialSendMsgAll) {
916   UnixSocketRaw send_sock;
917   UnixSocketRaw recv_sock;
918   std::tie(send_sock, recv_sock) =
919       UnixSocketRaw::CreatePairPosix(kTestSocket.family(), SockType::kStream);
920   ASSERT_TRUE(send_sock);
921   ASSERT_TRUE(recv_sock);
922 
923   // Set bufsize to minimum.
924   int bufsize = 1024;
925   ASSERT_EQ(setsockopt(send_sock.fd(), SOL_SOCKET, SO_SNDBUF, &bufsize,
926                        sizeof(bufsize)),
927             0);
928   ASSERT_EQ(setsockopt(recv_sock.fd(), SOL_SOCKET, SO_RCVBUF, &bufsize,
929                        sizeof(bufsize)),
930             0);
931 
932   // Send something larger than send + recv kernel buffers combined to make
933   // sendmsg block.
934   std::string send_buf(8192, '\0');
935   // Make MSAN happy.
936   for (size_t i = 0; i < send_buf.size(); ++i)
937     send_buf[i] = static_cast<char>(i % 256);
938   std::string recv_buf(send_buf.size(), '\0');
939 
940   // Need to install signal handler to cause the interrupt to happen.
941   // man 3 pthread_kill:
942   //   Signal dispositions are process-wide: if a signal handler is
943   //   installed, the handler will be invoked in the thread thread, but if
944   //   the disposition of the signal is "stop", "continue", or "terminate",
945   //   this action will affect the whole process.
946   struct sigaction oldact;
947   struct sigaction newact = {};
948   newact.sa_handler = [](int) {};
949   ASSERT_EQ(sigaction(SIGWINCH, &newact, &oldact), 0);
950   base::ScopedResource<const struct sigaction*, RollbackSigaction, nullptr>
951       rollback(&oldact);
952 
953   auto blocked_thread = pthread_self();
954   std::thread th([blocked_thread, &recv_sock, &recv_buf] {
955     ssize_t rd = PERFETTO_EINTR(read(recv_sock.fd(), &recv_buf[0], 1));
956     ASSERT_EQ(rd, 1);
957     // We are now sure the other thread is in sendmsg, interrupt send.
958     ASSERT_EQ(pthread_kill(blocked_thread, SIGWINCH), 0);
959     // Drain the socket to allow SendMsgAllPosix to succeed.
960     size_t offset = 1;
961     while (offset < recv_buf.size()) {
962       rd = PERFETTO_EINTR(
963           read(recv_sock.fd(), &recv_buf[offset], recv_buf.size() - offset));
964       ASSERT_GE(rd, 0);
965       offset += static_cast<size_t>(rd);
966     }
967   });
968 
969   // Test sending the send_buf in several chunks as an iov to exercise the
970   // more complicated code-paths of SendMsgAllPosix.
971   struct msghdr hdr = {};
972   struct iovec iov[4];
973   ASSERT_EQ(send_buf.size() % base::ArraySize(iov), 0u)
974       << "Cannot split buffer into even pieces.";
975   const size_t kChunkSize = send_buf.size() / base::ArraySize(iov);
976   for (size_t i = 0; i < base::ArraySize(iov); ++i) {
977     iov[i].iov_base = &send_buf[i * kChunkSize];
978     iov[i].iov_len = kChunkSize;
979   }
980   hdr.msg_iov = iov;
981   hdr.msg_iovlen = base::ArraySize(iov);
982 
983   ASSERT_EQ(send_sock.SendMsgAllPosix(&hdr),
984             static_cast<ssize_t>(send_buf.size()));
985   send_sock.Shutdown();
986   th.join();
987   // Make sure the re-entry logic was actually triggered.
988   ASSERT_EQ(hdr.msg_iov, nullptr);
989   ASSERT_EQ(memcmp(&send_buf[0], &recv_buf[0], send_buf.size()), 0);
990 }
991 
992 // Regression test for b/193234818. SO_SNDTIMEO is unreliable on most systems.
993 // It doesn't guarantee that the whole send() call blocks for at most X, as the
994 // kernel rearms the timeout if the send buffers frees up and allows a partial
995 // send. This test reproduces the issue 100% on Mac. Unfortunately on Linux the
996 // repro seem to happen only when a suspend happens in the middle.
TEST_F(UnixSocketTest,BlockingSendTimeout)997 TEST_F(UnixSocketTest, BlockingSendTimeout) {
998   TestTaskRunner ttr;
999   UnixSocketRaw send_sock;
1000   UnixSocketRaw recv_sock;
1001   std::tie(send_sock, recv_sock) =
1002       UnixSocketRaw::CreatePairPosix(kTestSocket.family(), SockType::kStream);
1003 
1004   auto blocking_send_done = ttr.CreateCheckpoint("blocking_send_done");
1005 
1006   std::thread tx_thread([&] {
1007     // Fill the tx buffer in non-blocking mode.
1008     send_sock.SetBlocking(false);
1009     char buf[1024 * 16]{};
1010     while (send_sock.Send(buf, sizeof(buf)) > 0) {
1011     }
1012 
1013     // Then do a blocking send. It should return a partial value within the tx
1014     // timeout.
1015     send_sock.SetBlocking(true);
1016     send_sock.SetTxTimeout(10);
1017     ASSERT_LT(send_sock.Send(buf, sizeof(buf)),
1018               static_cast<ssize_t>(sizeof(buf)));
1019     ttr.PostTask(blocking_send_done);
1020   });
1021 
1022   // This task needs to be slow enough so that doesn't unblock the send, but
1023   // fast enough so that within a blocking cycle, the send re-attempts and
1024   // re-arms the timeout.
1025   PeriodicTask read_slowly_task(&ttr);
1026   PeriodicTask::Args args;
1027   args.period_ms = 1;  // Read 1 byte every ms (1 KiB/s).
1028   args.task = [&] {
1029     char rxbuf[1]{};
1030     recv_sock.Receive(rxbuf, sizeof(rxbuf));
1031   };
1032   read_slowly_task.Start(args);
1033 
1034   ttr.RunUntilCheckpoint("blocking_send_done");
1035   read_slowly_task.Reset();
1036   tx_thread.join();
1037 }
1038 
1039 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
TEST_F(UnixSocketTest,SetsCloexec)1040 TEST_F(UnixSocketTest, SetsCloexec) {
1041   // CLOEXEC set when constructing sockets through helper:
1042   {
1043     auto raw = UnixSocketRaw::CreateMayFail(base::SockFamily::kUnix,
1044                                             SockType::kStream);
1045     int flags = fcntl(raw.fd(), F_GETFD, 0);
1046     EXPECT_TRUE(flags & FD_CLOEXEC);
1047   }
1048   // CLOEXEC set when creating a UnixSocketRaw out of an existing fd:
1049   {
1050     int fd = socket(AF_UNIX, SOCK_STREAM, 0);
1051     int flags = fcntl(fd, F_GETFD, 0);
1052     EXPECT_FALSE(flags & FD_CLOEXEC);
1053 
1054     auto raw = UnixSocketRaw(ScopedSocketHandle(fd), base::SockFamily::kUnix,
1055                              SockType::kStream);
1056     flags = fcntl(raw.fd(), F_GETFD, 0);
1057     EXPECT_TRUE(flags & FD_CLOEXEC);
1058   }
1059 }
1060 #endif  // !OS_FUCHSIA
1061 
1062 #endif  // !OS_WIN
1063 
1064 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
1065     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
1066     PERFETTO_BUILDFLAG(PERFETTO_OS_MAC)
1067 
1068 // Regression test for b/239725760.
TEST_F(UnixSocketTest,Sockaddr_FilesystemLinked)1069 TEST_F(UnixSocketTest, Sockaddr_FilesystemLinked) {
1070   TempDir tmp_dir = TempDir::Create();
1071   std::string sock_path = tmp_dir.path() + "/test.sock";
1072   auto srv = UnixSocket::Listen(sock_path, &event_listener_, &task_runner_,
1073                                 SockFamily::kUnix, SockType::kStream);
1074   ASSERT_TRUE(srv && srv->is_listening());
1075   ASSERT_TRUE(FileExists(sock_path));
1076 
1077   // Create a raw socket and manually connect to that (to avoid getting affected
1078   // by accidental future bugs in the logic that populates struct sockaddr_un).
1079   auto cli = UnixSocketRaw::CreateMayFail(SockFamily::kUnix, SockType::kStream);
1080   struct sockaddr_un addr {};
1081   addr.sun_family = AF_UNIX;
1082   StringCopy(addr.sun_path, sock_path.c_str(), sizeof(addr.sun_path));
1083   ASSERT_EQ(0, connect(cli.fd(), reinterpret_cast<struct sockaddr*>(&addr),
1084                        sizeof(addr)));
1085   cli.Shutdown();
1086   remove(sock_path.c_str());
1087 }
1088 #endif  // OS_LINUX || OS_ANDROID || OS_MAC
1089 
1090 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
1091     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
1092 // Regression test for b/239725760.
1093 // Abstract sockets are not supported on Mac OS.
TEST_F(UnixSocketTest,Sockaddr_AbstractUnix)1094 TEST_F(UnixSocketTest, Sockaddr_AbstractUnix) {
1095   StackString<128> sock_name("@perfetto_test_%d_%d", getpid(), rand() % 100000);
1096   auto srv =
1097       UnixSocket::Listen(sock_name.ToStdString(), &event_listener_,
1098                          &task_runner_, SockFamily::kUnix, SockType::kStream);
1099   ASSERT_TRUE(srv && srv->is_listening());
1100 
1101   auto cli = UnixSocketRaw::CreateMayFail(SockFamily::kUnix, SockType::kStream);
1102   struct sockaddr_un addr {};
1103   addr.sun_family = AF_UNIX;
1104   StringCopy(addr.sun_path, sock_name.c_str(), sizeof(addr.sun_path));
1105   addr.sun_path[0] = '\0';
1106   auto addr_len = static_cast<socklen_t>(
1107       __builtin_offsetof(sockaddr_un, sun_path) + sock_name.len());
1108   ASSERT_EQ(0, connect(cli.fd(), reinterpret_cast<struct sockaddr*>(&addr),
1109                        addr_len));
1110 }
1111 
TEST_F(UnixSocketTest,VSockStream)1112 TEST_F(UnixSocketTest, VSockStream) {
1113   SKIP_IF_VSOCK_LOOPBACK_NOT_SUPPORTED();
1114 
1115   // Set up the server. Use the loopback CID (1) and a random port number.
1116   auto srv = UnixSocket::Listen("vsock://1:-1", &event_listener_, &task_runner_,
1117                                 SockFamily::kVsock, SockType::kStream);
1118   ASSERT_TRUE(srv && srv->is_listening());
1119 
1120   std::unique_ptr<UnixSocket> prod;
1121   EXPECT_CALL(event_listener_, OnNewIncomingConnection(srv.get(), _))
1122       .WillOnce(Invoke([&](UnixSocket*, UnixSocket* s) {
1123         // OnDisconnect() might spuriously happen depending on the dtor order.
1124         EXPECT_CALL(event_listener_, OnDisconnect(s)).Times(AtLeast(0));
1125         EXPECT_CALL(event_listener_, OnDataAvailable(s))
1126             .WillRepeatedly(Invoke([](UnixSocket* prod_sock) {
1127               prod_sock->ReceiveString();  // Read connection EOF;
1128             }));
1129         ASSERT_TRUE(s->SendStr("welcome"));
1130       }));
1131 
1132   // Set up the client.
1133   prod =
1134       UnixSocket::Connect(srv->GetSockAddr(), &event_listener_, &task_runner_,
1135                           SockFamily::kVsock, SockType::kStream);
1136   auto checkpoint = task_runner_.CreateCheckpoint("prod_connected");
1137   EXPECT_CALL(event_listener_, OnDisconnect(prod.get())).Times(AtLeast(0));
1138   EXPECT_CALL(event_listener_, OnConnect(prod.get(), true));
1139   EXPECT_CALL(event_listener_, OnDataAvailable(prod.get()))
1140       .WillRepeatedly(Invoke([checkpoint](UnixSocket* s) {
1141         auto str = s->ReceiveString();
1142         if (str.empty())
1143           return;  // Connection EOF.
1144         ASSERT_EQ("welcome", str);
1145         checkpoint();
1146       }));
1147 
1148   task_runner_.RunUntilCheckpoint("prod_connected");
1149   ASSERT_TRUE(Mock::VerifyAndClearExpectations(prod.get()));
1150 }
1151 #endif  // OS_LINUX || OS_ANDROID
1152 
TEST_F(UnixSocketTest,GetSockFamily)1153 TEST_F(UnixSocketTest, GetSockFamily) {
1154   ASSERT_EQ(GetSockFamily(""), SockFamily::kUnspec);
1155   ASSERT_EQ(GetSockFamily("/path/to/sock"), SockFamily::kUnix);
1156   ASSERT_EQ(GetSockFamily("local_dir_sock"), SockFamily::kUnix);
1157   ASSERT_EQ(GetSockFamily("@abstract"), SockFamily::kUnix);
1158   ASSERT_EQ(GetSockFamily("0.0.0.0:80"), SockFamily::kInet);
1159   ASSERT_EQ(GetSockFamily("127.0.0.1:80"), SockFamily::kInet);
1160   ASSERT_EQ(GetSockFamily("[effe::acca]:1234"), SockFamily::kInet6);
1161   ASSERT_EQ(GetSockFamily("[::1]:123456"), SockFamily::kInet6);
1162 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
1163     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
1164   ASSERT_EQ(GetSockFamily("vsock://-1:10000"), SockFamily::kVsock);
1165 #endif
1166 }
1167 
TEST_F(UnixSocketTest,ShmemSupported)1168 TEST_F(UnixSocketTest, ShmemSupported) {
1169 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1170   ASSERT_EQ(SockShmemSupported(""), true);
1171 #else  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1172   ASSERT_EQ(SockShmemSupported(""), false);
1173   ASSERT_EQ(SockShmemSupported("/path/to/sock"), true);
1174   ASSERT_EQ(SockShmemSupported("local_dir_sock"), true);
1175   ASSERT_EQ(SockShmemSupported("@abstract"), true);
1176   ASSERT_EQ(SockShmemSupported("0.0.0.0:80"), false);
1177   ASSERT_EQ(SockShmemSupported("127.0.0.1:80"), false);
1178   ASSERT_EQ(SockShmemSupported("[effe::acca]:1234"), false);
1179   ASSERT_EQ(SockShmemSupported("[::1]:123456"), false);
1180 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
1181     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
1182   ASSERT_EQ(SockShmemSupported("vsock://-1:10000"), false);
1183 #endif
1184 #endif  // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1185 }
1186 
1187 }  // namespace
1188 }  // namespace base
1189 }  // namespace perfetto
1190