IPC: Allow socket to be TCP, for Windows

This CL adds a constants which defines whether a
AF_UNIX or AF_INET socket should be used in the IPC
layer. This CL alone doesn't add the TCP support,
just prepares for it. It also fixes the test_socket
to support both TCP and AF_UNIX..
Also fix a minor compiler issue with MSVC recently
regressed by the introduction of __has_attribute.

Bug: 174454879
Change-Id: Ic5ab727d33aac1d17db0b675b9a44cb132fefffa
diff --git a/src/base/unix_socket_unittest.cc b/src/base/unix_socket_unittest.cc
index 0398608..9ef69c9 100644
--- a/src/base/unix_socket_unittest.cc
+++ b/src/base/unix_socket_unittest.cc
@@ -47,7 +47,7 @@
 using ::testing::InvokeWithoutArgs;
 using ::testing::Mock;
 
-constexpr char kSocketName[] = TEST_SOCK_NAME("unix_socket_unittest.sock");
+ipc::TestSocket kTestSocket{"unix_socket_unittest"};
 
 class MockEventListener : public UnixSocket::EventListener {
  public:
@@ -78,16 +78,17 @@
 
 class UnixSocketTest : public ::testing::Test {
  protected:
-  void SetUp() override { DESTROY_TEST_SOCK(kSocketName); }
-  void TearDown() override { DESTROY_TEST_SOCK(kSocketName); }
+  void SetUp() override { kTestSocket.Destroy(); }
+  void TearDown() override { kTestSocket.Destroy(); }
 
   TestTaskRunner task_runner_;
   MockEventListener event_listener_;
 };
 
 TEST_F(UnixSocketTest, ConnectionFailureIfUnreachable) {
-  auto cli = UnixSocket::Connect(kSocketName, &event_listener_, &task_runner_,
-                                 SockFamily::kUnix, SockType::kStream);
+  auto cli =
+      UnixSocket::Connect(kTestSocket.name(), &event_listener_, &task_runner_,
+                          kTestSocket.family(), SockType::kStream);
   ASSERT_FALSE(cli->is_connected());
   auto checkpoint = task_runner_.CreateCheckpoint("failure");
   EXPECT_CALL(event_listener_, OnConnect(cli.get(), false))
@@ -98,8 +99,9 @@
 // Both server and client should see an OnDisconnect() if the server drops
 // incoming connections immediately as they are created.
 TEST_F(UnixSocketTest, ConnectionImmediatelyDroppedByServer) {
-  auto srv = UnixSocket::Listen(kSocketName, &event_listener_, &task_runner_,
-                                SockFamily::kUnix, SockType::kStream);
+  auto srv =
+      UnixSocket::Listen(kTestSocket.name(), &event_listener_, &task_runner_,
+                         kTestSocket.family(), SockType::kStream);
   ASSERT_TRUE(srv->is_listening());
 
   // The server will immediately shutdown the connection upon
@@ -114,8 +116,9 @@
           }));
 
   auto checkpoint = task_runner_.CreateCheckpoint("cli_connected");
-  auto cli = UnixSocket::Connect(kSocketName, &event_listener_, &task_runner_,
-                                 SockFamily::kUnix, SockType::kStream);
+  auto cli =
+      UnixSocket::Connect(kTestSocket.name(), &event_listener_, &task_runner_,
+                          kTestSocket.family(), SockType::kStream);
   EXPECT_CALL(event_listener_, OnConnect(cli.get(), true))
       .WillOnce(InvokeWithoutArgs(checkpoint));
   task_runner_.RunUntilCheckpoint("cli_connected");
@@ -134,12 +137,14 @@
 }
 
 TEST_F(UnixSocketTest, ClientAndServerExchangeData) {
-  auto srv = UnixSocket::Listen(kSocketName, &event_listener_, &task_runner_,
-                                SockFamily::kUnix, SockType::kStream);
+  auto srv =
+      UnixSocket::Listen(kTestSocket.name(), &event_listener_, &task_runner_,
+                         kTestSocket.family(), SockType::kStream);
   ASSERT_TRUE(srv->is_listening());
 
-  auto cli = UnixSocket::Connect(kSocketName, &event_listener_, &task_runner_,
-                                 SockFamily::kUnix, SockType::kStream);
+  auto cli =
+      UnixSocket::Connect(kTestSocket.name(), &event_listener_, &task_runner_,
+                          kTestSocket.family(), SockType::kStream);
   auto cli_connected = task_runner_.CreateCheckpoint("cli_connected");
   EXPECT_CALL(event_listener_, OnConnect(cli.get(), true))
       .WillOnce(InvokeWithoutArgs(cli_connected));
@@ -196,16 +201,17 @@
 
 TEST_F(UnixSocketTest, ListenWithPassedSocketHandle) {
   auto sock_raw =
-      UnixSocketRaw::CreateMayFail(SockFamily::kUnix, SockType::kStream);
-  ASSERT_TRUE(sock_raw.Bind(kSocketName));
+      UnixSocketRaw::CreateMayFail(kTestSocket.family(), SockType::kStream);
+  ASSERT_TRUE(sock_raw.Bind(kTestSocket.name()));
   auto fd = sock_raw.ReleaseFd();
   auto srv = UnixSocket::Listen(std::move(fd), &event_listener_, &task_runner_,
-                                SockFamily::kUnix, SockType::kStream);
+                                kTestSocket.family(), SockType::kStream);
   ASSERT_TRUE(srv->is_listening());
 
   auto cli_connected = task_runner_.CreateCheckpoint("cli_connected");
-  auto cli = UnixSocket::Connect(kSocketName, &event_listener_, &task_runner_,
-                                 SockFamily::kUnix, SockType::kStream);
+  auto cli =
+      UnixSocket::Connect(kTestSocket.name(), &event_listener_, &task_runner_,
+                          kTestSocket.family(), SockType::kStream);
   EXPECT_CALL(event_listener_, OnConnect(cli.get(), true))
       .WillOnce(InvokeWithoutArgs(cli_connected));
   auto srv_connected = task_runner_.CreateCheckpoint("srv_connected");
@@ -231,8 +237,9 @@
 // Mostly a stress tests. Connects kNumClients clients to the same server and
 // tests that all can exchange data and can see the expected sequence of events.
 TEST_F(UnixSocketTest, SeveralClients) {
-  auto srv = UnixSocket::Listen(kSocketName, &event_listener_, &task_runner_,
-                                SockFamily::kUnix, SockType::kStream);
+  auto srv =
+      UnixSocket::Listen(kTestSocket.name(), &event_listener_, &task_runner_,
+                         kTestSocket.family(), SockType::kStream);
   ASSERT_TRUE(srv->is_listening());
   constexpr size_t kNumClients = 32;
   std::unique_ptr<UnixSocket> cli[kNumClients];
@@ -248,8 +255,9 @@
       }));
 
   for (size_t i = 0; i < kNumClients; i++) {
-    cli[i] = UnixSocket::Connect(kSocketName, &event_listener_, &task_runner_,
-                                 SockFamily::kUnix, SockType::kStream);
+    cli[i] =
+        UnixSocket::Connect(kTestSocket.name(), &event_listener_, &task_runner_,
+                            kTestSocket.family(), SockType::kStream);
     EXPECT_CALL(event_listener_, OnConnect(cli[i].get(), true))
         .WillOnce(Invoke([](UnixSocket* s, bool success) {
           ASSERT_TRUE(success);
@@ -270,42 +278,10 @@
   }
 }
 
-// Tests the SockPeerCredMode::kIgnore logic.
-TEST_F(UnixSocketTest, IgnorePeerCredentials) {
-  auto srv = UnixSocket::Listen(kSocketName, &event_listener_, &task_runner_,
-                                SockFamily::kUnix, SockType::kStream);
-  ASSERT_TRUE(srv->is_listening());
-  auto cli1_connected = task_runner_.CreateCheckpoint("cli1_connected");
-  auto cli1 = UnixSocket::Connect(kSocketName, &event_listener_, &task_runner_,
-                                  SockFamily::kUnix, SockType::kStream,
-                                  SockPeerCredMode::kIgnore);
-  EXPECT_CALL(event_listener_, OnConnect(cli1.get(), true))
-      .WillOnce(InvokeWithoutArgs(cli1_connected));
-
-  auto cli2_connected = task_runner_.CreateCheckpoint("cli2_connected");
-  auto cli2 = UnixSocket::Connect(kSocketName, &event_listener_, &task_runner_,
-                                  SockFamily::kUnix, SockType::kStream,
-                                  SockPeerCredMode::kReadOnConnect);
-  EXPECT_CALL(event_listener_, OnConnect(cli2.get(), true))
-      .WillOnce(InvokeWithoutArgs(cli2_connected));
-
-  task_runner_.RunUntilCheckpoint("cli1_connected");
-  task_runner_.RunUntilCheckpoint("cli2_connected");
-
-#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
-  ASSERT_EQ(cli1->peer_uid_posix(/*skip_check_for_testing=*/true), kInvalidUid);
-  ASSERT_EQ(cli2->peer_uid_posix(), geteuid());
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
-    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
-  ASSERT_EQ(cli1->peer_pid_linux(/*skip_check_for_testing=*/true), kInvalidPid);
-  ASSERT_EQ(cli2->peer_pid_linux(), getpid());
-#endif
-#endif
-}
-
 TEST_F(UnixSocketTest, BlockingSend) {
-  auto srv = UnixSocket::Listen(kSocketName, &event_listener_, &task_runner_,
-                                SockFamily::kUnix, SockType::kStream);
+  auto srv =
+      UnixSocket::Listen(kTestSocket.name(), &event_listener_, &task_runner_,
+                         kTestSocket.family(), SockType::kStream);
   ASSERT_TRUE(srv->is_listening());
 
   auto all_frames_done = task_runner_.CreateCheckpoint("all_frames_done");
@@ -332,8 +308,9 @@
   std::thread tx_thread([] {
     TestTaskRunner tx_task_runner;
     MockEventListener tx_events;
-    auto cli = UnixSocket::Connect(kSocketName, &tx_events, &tx_task_runner,
-                                   SockFamily::kUnix, SockType::kStream);
+    auto cli =
+        UnixSocket::Connect(kTestSocket.name(), &tx_events, &tx_task_runner,
+                            kTestSocket.family(), SockType::kStream);
 
     auto cli_connected = tx_task_runner.CreateCheckpoint("cli_connected");
     EXPECT_CALL(tx_events, OnConnect(cli.get(), true))
@@ -358,8 +335,9 @@
 // sender is in the middle of a large send(), the socket should gracefully give
 // up (i.e. Shutdown()) but not crash.
 TEST_F(UnixSocketTest, ReceiverDisconnectsDuringSend) {
-  auto srv = UnixSocket::Listen(kSocketName, &event_listener_, &task_runner_,
-                                SockFamily::kUnix, SockType::kStream);
+  auto srv =
+      UnixSocket::Listen(kTestSocket.name(), &event_listener_, &task_runner_,
+                         kTestSocket.family(), SockType::kStream);
   ASSERT_TRUE(srv->is_listening());
   static constexpr int kTimeoutMs = 30000;
 
@@ -380,8 +358,9 @@
   std::thread tx_thread([] {
     TestTaskRunner tx_task_runner;
     MockEventListener tx_events;
-    auto cli = UnixSocket::Connect(kSocketName, &tx_events, &tx_task_runner,
-                                   SockFamily::kUnix, SockType::kStream);
+    auto cli =
+        UnixSocket::Connect(kTestSocket.name(), &tx_events, &tx_task_runner,
+                            kTestSocket.family(), SockType::kStream);
 
     auto cli_connected = tx_task_runner.CreateCheckpoint("cli_connected");
     EXPECT_CALL(tx_events, OnConnect(cli.get(), true))
@@ -403,8 +382,9 @@
 }
 
 TEST_F(UnixSocketTest, ReleaseSocket) {
-  auto srv = UnixSocket::Listen(kSocketName, &event_listener_, &task_runner_,
-                                SockFamily::kUnix, SockType::kStream);
+  auto srv =
+      UnixSocket::Listen(kTestSocket.name(), &event_listener_, &task_runner_,
+                         kTestSocket.family(), SockType::kStream);
   ASSERT_TRUE(srv->is_listening());
   auto srv_connected = task_runner_.CreateCheckpoint("srv_connected");
   UnixSocket* peer = nullptr;
@@ -415,8 +395,9 @@
             srv_connected();
           }));
 
-  auto cli = UnixSocket::Connect(kSocketName, &event_listener_, &task_runner_,
-                                 SockFamily::kUnix, SockType::kStream);
+  auto cli =
+      UnixSocket::Connect(kTestSocket.name(), &event_listener_, &task_runner_,
+                          kTestSocket.family(), SockType::kStream);
   auto cli_connected = task_runner_.CreateCheckpoint("cli_connected");
   EXPECT_CALL(event_listener_, OnConnect(cli.get(), true))
       .WillOnce(InvokeWithoutArgs(cli_connected));
@@ -494,12 +475,46 @@
 // ---------------------------------
 
 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+// Tests the SockPeerCredMode::kIgnore logic.
+TEST_F(UnixSocketTest, IgnorePeerCredentials) {
+  auto srv =
+      UnixSocket::Listen(kTestSocket.name(), &event_listener_, &task_runner_,
+                         kTestSocket.family(), SockType::kStream);
+  ASSERT_TRUE(srv->is_listening());
+  auto cli1_connected = task_runner_.CreateCheckpoint("cli1_connected");
+  auto cli1 = UnixSocket::Connect(kTestSocket.name(), &event_listener_,
+                                  &task_runner_, kTestSocket.family(),
+                                  SockType::kStream, SockPeerCredMode::kIgnore);
+  EXPECT_CALL(event_listener_, OnConnect(cli1.get(), true))
+      .WillOnce(InvokeWithoutArgs(cli1_connected));
+
+  auto cli2_connected = task_runner_.CreateCheckpoint("cli2_connected");
+  auto cli2 = UnixSocket::Connect(
+      kTestSocket.name(), &event_listener_, &task_runner_, kTestSocket.family(),
+      SockType::kStream, SockPeerCredMode::kReadOnConnect);
+  EXPECT_CALL(event_listener_, OnConnect(cli2.get(), true))
+      .WillOnce(InvokeWithoutArgs(cli2_connected));
+
+  task_runner_.RunUntilCheckpoint("cli1_connected");
+  task_runner_.RunUntilCheckpoint("cli2_connected");
+
+  ASSERT_EQ(cli1->peer_uid_posix(/*skip_check_for_testing=*/true), kInvalidUid);
+  ASSERT_EQ(cli2->peer_uid_posix(), geteuid());
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  ASSERT_EQ(cli1->peer_pid_linux(/*skip_check_for_testing=*/true), kInvalidPid);
+  ASSERT_EQ(cli2->peer_pid_linux(), getpid());
+#endif
+}
+
 // Checks that the peer_uid() is retained after the client disconnects. The IPC
 // layer needs to rely on this to validate messages received immediately before
 // a client disconnects.
 TEST_F(UnixSocketTest, PeerCredentialsRetainedAfterDisconnect) {
-  auto srv = UnixSocket::Listen(kSocketName, &event_listener_, &task_runner_,
-                                SockFamily::kUnix, SockType::kStream);
+  auto srv =
+      UnixSocket::Listen(kTestSocket.name(), &event_listener_, &task_runner_,
+                         kTestSocket.family(), SockType::kStream);
   ASSERT_TRUE(srv->is_listening());
   UnixSocket* srv_client_conn = nullptr;
   auto srv_connected = task_runner_.CreateCheckpoint("srv_connected");
@@ -515,8 +530,9 @@
         srv_connected();
       }));
   auto cli_connected = task_runner_.CreateCheckpoint("cli_connected");
-  auto cli = UnixSocket::Connect(kSocketName, &event_listener_, &task_runner_,
-                                 SockFamily::kUnix, SockType::kStream);
+  auto cli =
+      UnixSocket::Connect(kTestSocket.name(), &event_listener_, &task_runner_,
+                          kTestSocket.family(), SockType::kStream);
   EXPECT_CALL(event_listener_, OnConnect(cli.get(), true))
       .WillOnce(InvokeWithoutArgs(cli_connected));
 
@@ -549,12 +565,14 @@
 TEST_F(UnixSocketTest, ClientAndServerExchangeFDs) {
   static constexpr char cli_str[] = "cli>srv";
   static constexpr char srv_str[] = "srv>cli";
-  auto srv = UnixSocket::Listen(kSocketName, &event_listener_, &task_runner_,
-                                SockFamily::kUnix, SockType::kStream);
+  auto srv =
+      UnixSocket::Listen(kTestSocket.name(), &event_listener_, &task_runner_,
+                         kTestSocket.family(), SockType::kStream);
   ASSERT_TRUE(srv->is_listening());
 
-  auto cli = UnixSocket::Connect(kSocketName, &event_listener_, &task_runner_,
-                                 SockFamily::kUnix, SockType::kStream);
+  auto cli =
+      UnixSocket::Connect(kTestSocket.name(), &event_listener_, &task_runner_,
+                          kTestSocket.family(), SockType::kStream);
   EXPECT_CALL(event_listener_, OnConnect(cli.get(), true));
   auto cli_connected = task_runner_.CreateCheckpoint("cli_connected");
   auto srv_disconnected = task_runner_.CreateCheckpoint("srv_disconnected");
@@ -651,8 +669,9 @@
     ASSERT_NE(nullptr, mem);
     memcpy(mem, "shm rocks", 10);
 
-    auto srv = UnixSocket::Listen(kSocketName, &event_listener_, &task_runner_,
-                                  SockFamily::kUnix, SockType::kStream);
+    auto srv =
+        UnixSocket::Listen(kTestSocket.name(), &event_listener_, &task_runner_,
+                           kTestSocket.family(), SockType::kStream);
     ASSERT_TRUE(srv->is_listening());
     // Signal the other process that it can connect.
     ASSERT_EQ(1, base::WriteAll(*pipe.wr, ".", 1));
@@ -678,8 +697,9 @@
     char sync_cmd = '\0';
     ASSERT_EQ(1, PERFETTO_EINTR(read(*pipe.rd, &sync_cmd, 1)));
     ASSERT_EQ('.', sync_cmd);
-    auto cli = UnixSocket::Connect(kSocketName, &event_listener_, &task_runner_,
-                                   SockFamily::kUnix, SockType::kStream);
+    auto cli =
+        UnixSocket::Connect(kTestSocket.name(), &event_listener_, &task_runner_,
+                            kTestSocket.family(), SockType::kStream);
     EXPECT_CALL(event_listener_, OnConnect(cli.get(), true));
     auto checkpoint = task_runner_.CreateCheckpoint("change_seen_by_client");
     EXPECT_CALL(event_listener_, OnDataAvailable(cli.get()))
@@ -799,7 +819,7 @@
   UnixSocketRaw send_sock;
   UnixSocketRaw recv_sock;
   std::tie(send_sock, recv_sock) =
-      UnixSocketRaw::CreatePairPosix(SockFamily::kUnix, SockType::kStream);
+      UnixSocketRaw::CreatePairPosix(kTestSocket.family(), SockType::kStream);
   ASSERT_TRUE(send_sock);
   ASSERT_TRUE(recv_sock);
 
diff --git a/src/ipc/client_impl.cc b/src/ipc/client_impl.cc
index c27bf37..1b475be 100644
--- a/src/ipc/client_impl.cc
+++ b/src/ipc/client_impl.cc
@@ -36,6 +36,11 @@
 namespace perfetto {
 namespace ipc {
 
+namespace {
+constexpr base::SockFamily kClientSockFamily =
+    kUseTCPSocket ? base::SockFamily::kInet : base::SockFamily::kUnix;
+}  // namespace
+
 // static
 std::unique_ptr<Client> Client::CreateInstance(ConnArgs conn_args,
                                                base::TaskRunner* task_runner) {
@@ -53,9 +58,8 @@
     // Create the client using a connected socket. This code path will never hit
     // OnConnect().
     sock_ = base::UnixSocket::AdoptConnected(
-        std::move(conn_args.socket_fd), this, task_runner_,
-        base::SockFamily::kUnix, base::SockType::kStream,
-        base::SockPeerCredMode::kIgnore);
+        std::move(conn_args.socket_fd), this, task_runner_, kClientSockFamily,
+        base::SockType::kStream, base::SockPeerCredMode::kIgnore);
   } else {
     // Connect using the socket name.
     TryConnect();
@@ -71,9 +75,9 @@
 
 void ClientImpl::TryConnect() {
   PERFETTO_DCHECK(socket_name_);
-  sock_ = base::UnixSocket::Connect(
-      socket_name_, this, task_runner_, base::SockFamily::kUnix,
-      base::SockType::kStream, base::SockPeerCredMode::kIgnore);
+  sock_ = base::UnixSocket::Connect(socket_name_, this, task_runner_,
+                                    kClientSockFamily, base::SockType::kStream,
+                                    base::SockPeerCredMode::kIgnore);
 }
 
 void ClientImpl::BindService(base::WeakPtr<ServiceProxy> service_proxy) {
diff --git a/src/ipc/client_impl_unittest.cc b/src/ipc/client_impl_unittest.cc
index c482e1e..0a31a8c 100644
--- a/src/ipc/client_impl_unittest.cc
+++ b/src/ipc/client_impl_unittest.cc
@@ -45,7 +45,7 @@
 using ::testing::Invoke;
 using ::testing::Mock;
 
-constexpr char kSockName[] = TEST_SOCK_NAME("client_impl_unittest");
+ipc::TestSocket kTestSocket{"client_impl_unittest"};
 
 // A fake ServiceProxy. This fakes the client-side class that would be
 // auto-generated from .proto-files.
@@ -78,8 +78,8 @@
   MOCK_METHOD0(OnDisconnect, void());
 };
 
-// A fake host implementation. Listens on |kSockName| and replies to IPC
-// metohds like a real one.
+// A fake host implementation. Listens on |kTestSocket.name()| and replies to
+// IPC metohds like a real one.
 class FakeHost : public base::UnixSocket::EventListener {
  public:
   struct FakeMethod {
@@ -104,13 +104,13 @@
   };  // FakeService.
 
   explicit FakeHost(base::TaskRunner* task_runner) {
-    DESTROY_TEST_SOCK(kSockName);
-    listening_sock = base::UnixSocket::Listen(kSockName, this, task_runner,
-                                              base::SockFamily::kUnix,
-                                              base::SockType::kStream);
+    kTestSocket.Destroy();
+    listening_sock =
+        base::UnixSocket::Listen(kTestSocket.name(), this, task_runner,
+                                 kTestSocket.family(), base::SockType::kStream);
     EXPECT_TRUE(listening_sock->is_listening());
   }
-  ~FakeHost() override { DESTROY_TEST_SOCK(kSockName); }
+  ~FakeHost() override { kTestSocket.Destroy(); }
 
   FakeService* AddFakeService(const std::string& name) {
     auto it_and_inserted =
@@ -204,7 +204,7 @@
   void SetUp() override {
     task_runner_.reset(new base::TestTaskRunner());
     host_.reset(new FakeHost(task_runner_.get()));
-    cli_ = Client::CreateInstance({kSockName, /*retry=*/false},
+    cli_ = Client::CreateInstance({kTestSocket.name(), /*retry=*/false},
                                   task_runner_.get());
   }
 
@@ -579,10 +579,9 @@
 }
 
 TEST_F(ClientImplTest, HostConnectionFailure) {
-  constexpr char kNonexistentSockName[] =
-      TEST_SOCK_NAME("client_impl_unittest_nonexistent");
+  ipc::TestSocket kNonexistentSock{"client_impl_unittest_nonexistent"};
   std::unique_ptr<Client> client = Client::CreateInstance(
-      {kNonexistentSockName, /*retry=*/false}, task_runner_.get());
+      {kNonexistentSock.name(), /*retry=*/false}, task_runner_.get());
 
   // Connect a client to a non-existent socket, which will always fail. The
   // client will notify the proxy of disconnection.
diff --git a/src/ipc/host_impl.cc b/src/ipc/host_impl.cc
index 7ca6914..d0f370c 100644
--- a/src/ipc/host_impl.cc
+++ b/src/ipc/host_impl.cc
@@ -34,6 +34,10 @@
 namespace ipc {
 
 namespace {
+
+constexpr base::SockFamily kHostSockFamily =
+    kUseTCPSocket ? base::SockFamily::kInet : base::SockFamily::kUnix;
+
 uid_t GetPosixPeerUid(base::UnixSocket* sock) {
 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
   base::ignore_result(sock);
@@ -43,6 +47,7 @@
   return sock->peer_uid_posix();
 #endif
 }
+
 }  // namespace
 
 // static
@@ -69,16 +74,14 @@
     : task_runner_(task_runner), weak_ptr_factory_(this) {
   PERFETTO_DCHECK_THREAD(thread_checker_);
   sock_ = base::UnixSocket::Listen(std::move(socket_fd), this, task_runner_,
-                                   base::SockFamily::kUnix,
-                                   base::SockType::kStream);
+                                   kHostSockFamily, base::SockType::kStream);
 }
 
 HostImpl::HostImpl(const char* socket_name, base::TaskRunner* task_runner)
     : task_runner_(task_runner), weak_ptr_factory_(this) {
   PERFETTO_DCHECK_THREAD(thread_checker_);
   sock_ = base::UnixSocket::Listen(socket_name, this, task_runner_,
-                                   base::SockFamily::kUnix,
-                                   base::SockType::kStream);
+                                   kHostSockFamily, base::SockType::kStream);
   if (!sock_) {
     PERFETTO_PLOG("Failed to create %s", socket_name);
   }
diff --git a/src/ipc/host_impl_unittest.cc b/src/ipc/host_impl_unittest.cc
index 13147a7..a04ff22 100644
--- a/src/ipc/host_impl_unittest.cc
+++ b/src/ipc/host_impl_unittest.cc
@@ -44,7 +44,7 @@
 using ::testing::InvokeWithoutArgs;
 using ::testing::Return;
 
-constexpr char kSockName[] = TEST_SOCK_NAME("host_impl_unittest.sock");
+ipc::TestSocket kTestSocket{"host_impl_unittest"};
 
 // RequestProto and ReplyProto are defined in client_unittest_messages.proto.
 
@@ -90,8 +90,8 @@
   MOCK_METHOD0(OnRequestError, void());
 
   explicit FakeClient(base::TaskRunner* task_runner) {
-    sock_ = base::UnixSocket::Connect(kSockName, this, task_runner,
-                                      base::SockFamily::kUnix,
+    sock_ = base::UnixSocket::Connect(kTestSocket.name(), this, task_runner,
+                                      kTestSocket.family(),
                                       base::SockType::kStream);
   }
 
@@ -168,9 +168,10 @@
 class HostImplTest : public ::testing::Test {
  public:
   void SetUp() override {
-    DESTROY_TEST_SOCK(kSockName);
+    kTestSocket.Destroy();
     task_runner_.reset(new base::TestTaskRunner());
-    Host* host = Host::CreateInstance(kSockName, task_runner_.get()).release();
+    Host* host =
+        Host::CreateInstance(kTestSocket.name(), task_runner_.get()).release();
     ASSERT_NE(nullptr, host);
     host_.reset(static_cast<HostImpl*>(host));
     cli_.reset(new FakeClient(task_runner_.get()));
@@ -185,7 +186,7 @@
     host_.reset();
     task_runner_->RunUntilIdle();
     task_runner_.reset();
-    DESTROY_TEST_SOCK(kSockName);
+    kTestSocket.Destroy();
   }
 
   // ::testing::StrictMock<MockEventListener> proxy_events_;
diff --git a/src/ipc/test/ipc_integrationtest.cc b/src/ipc/test/ipc_integrationtest.cc
index b2f5bc5..b1b0631 100644
--- a/src/ipc/test/ipc_integrationtest.cc
+++ b/src/ipc/test/ipc_integrationtest.cc
@@ -37,7 +37,7 @@
 
 using namespace ::ipc_test::gen;
 
-constexpr char kSockName[] = TEST_SOCK_NAME("ipc_integrationtest");
+::perfetto::ipc::TestSocket kTestSocket{"ipc_integrationtest"};
 
 class MockEventListener : public ServiceProxy::EventListener {
  public:
@@ -64,15 +64,16 @@
 
 class IPCIntegrationTest : public ::testing::Test {
  protected:
-  void SetUp() override { DESTROY_TEST_SOCK(kSockName); }
-  void TearDown() override { DESTROY_TEST_SOCK(kSockName); }
+  void SetUp() override { kTestSocket.Destroy(); }
+  void TearDown() override { kTestSocket.Destroy(); }
 
   perfetto::base::TestTaskRunner task_runner_;
   MockEventListener svc_proxy_events_;
 };
 
 TEST_F(IPCIntegrationTest, SayHelloWaveGoodbye) {
-  std::unique_ptr<Host> host = Host::CreateInstance(kSockName, &task_runner_);
+  std::unique_ptr<Host> host =
+      Host::CreateInstance(kTestSocket.name(), &task_runner_);
   ASSERT_TRUE(host);
 
   MockGreeterService* svc = new MockGreeterService();
@@ -80,8 +81,8 @@
 
   auto on_connect = task_runner_.CreateCheckpoint("on_connect");
   EXPECT_CALL(svc_proxy_events_, OnConnect()).WillOnce(Invoke(on_connect));
-  std::unique_ptr<Client> cli =
-      Client::CreateInstance({kSockName, /*retry=*/false}, &task_runner_);
+  std::unique_ptr<Client> cli = Client::CreateInstance(
+      {kTestSocket.name(), /*retry=*/false}, &task_runner_);
   std::unique_ptr<GreeterProxy> svc_proxy(new GreeterProxy(&svc_proxy_events_));
   cli->BindService(svc_proxy->GetWeakPtr());
   task_runner_.RunUntilCheckpoint("on_connect");
diff --git a/src/ipc/test/test_socket.h b/src/ipc/test/test_socket.h
index f68ef4b..e55a8df 100644
--- a/src/ipc/test/test_socket.h
+++ b/src/ipc/test/test_socket.h
@@ -17,17 +17,69 @@
 #ifndef SRC_IPC_TEST_TEST_SOCKET_H_
 #define SRC_IPC_TEST_TEST_SOCKET_H_
 
-#include "perfetto/base/build_config.h"
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdio.h>
 
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
-#define TEST_SOCK_NAME(x) "@" x
-#define DESTROY_TEST_SOCK(x) \
-  do {                       \
-  } while (0)
+#include "perfetto/base/build_config.h"
+#include "perfetto/ext/base/unix_socket.h"
+
+namespace perfetto {
+namespace ipc {
+
+struct TestSocket {
+  explicit constexpr TestSocket(const char* test_name)
+      : test_name_(test_name) {}
+
+  const char* test_name_;
+  char buf_[64]{};
+
+  // Inline to avoid multiple definition linker warnings (and avoid a .cc file).
+  inline base::SockFamily family();
+  inline const char* name();
+  inline void Destroy();
+};
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+const char* TestSocket::name() {
+  uint64_t hash = 5381;
+  for (const char* c = test_name_; *c; c++)
+    hash = 33 * hash + static_cast<uint64_t>(*c);
+  snprintf(buf_, sizeof(buf_), "127.0.0.1:%" PRIu64, 40000 + (hash % 20000));
+  return buf_;
+}
+base::SockFamily TestSocket::family() {
+  return base::SockFamily::kInet;
+}
+void TestSocket::Destroy() {}
+
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+
+const char* TestSocket::name() {
+  snprintf(buf_, sizeof(buf_), "@%s", test_name_);
+  return buf_;
+}
+base::SockFamily TestSocket::family() {
+  return base::SockFamily::kUnix;
+}
+void TestSocket::Destroy() {}
+
 #else
-#include <unistd.h>
-#define TEST_SOCK_NAME(x) "/tmp/" x ".sock"
-#define DESTROY_TEST_SOCK(x) unlink(x)
+
+const char* TestSocket::name() {
+  snprintf(buf_, sizeof(buf_), "/tmp/%s.sock", test_name_);
+  return buf_;
+}
+base::SockFamily TestSocket::family() {
+  return base::SockFamily::kUnix;
+}
+void TestSocket::Destroy() {
+  remove(name());
+}
 #endif
 
+}  // namespace ipc
+}  // namespace perfetto
+
 #endif  // SRC_IPC_TEST_TEST_SOCKET_H_
diff --git a/src/trace_processor/importers/proto/proto_trace_parser.cc b/src/trace_processor/importers/proto/proto_trace_parser.cc
index 96c3833..6543be2 100644
--- a/src/trace_processor/importers/proto/proto_trace_parser.cc
+++ b/src/trace_processor/importers/proto/proto_trace_parser.cc
@@ -469,7 +469,7 @@
   // requiring stack samples, then this would still count as an error.
   // For now, use an invalid callsite id.
   if (!cs_id) {
-    cs_id = base::make_optional<CallsiteId>(-1u);
+    cs_id = base::make_optional<CallsiteId>(static_cast<uint32_t>(-1));
   }
 
   UniqueTid utid =
diff --git a/src/tracing/ipc/default_socket.cc b/src/tracing/ipc/default_socket.cc
index 255af8d..3ad5cee 100644
--- a/src/tracing/ipc/default_socket.cc
+++ b/src/tracing/ipc/default_socket.cc
@@ -62,7 +62,9 @@
 const char* GetProducerSocket() {
   const char* name = getenv("PERFETTO_PRODUCER_SOCK_NAME");
   if (name == nullptr) {
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    name = "127.0.0.1:32278";
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
     name = "/dev/socket/traced_producer";
 #else
     // Use /run/perfetto if it exists. Then fallback to /tmp.
@@ -78,7 +80,9 @@
 const char* GetConsumerSocket() {
   const char* name = getenv("PERFETTO_CONSUMER_SOCK_NAME");
   if (name == nullptr) {
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    name = "127.0.0.1:32279";
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
     name = "/dev/socket/traced_consumer";
 #else
     // Use /run/perfetto if it exists. Then fallback to /tmp.
diff --git a/src/tracing/test/tracing_integration_test.cc b/src/tracing/test/tracing_integration_test.cc
index 1fd624b..3fc8d4b 100644
--- a/src/tracing/test/tracing_integration_test.cc
+++ b/src/tracing/test/tracing_integration_test.cc
@@ -48,8 +48,8 @@
 using testing::Invoke;
 using testing::InvokeWithoutArgs;
 
-constexpr char kProducerSockName[] = TEST_SOCK_NAME("tracing_test-producer");
-constexpr char kConsumerSockName[] = TEST_SOCK_NAME("tracing_test-consumer");
+ipc::TestSocket kProducerSock{"tracing_test-producer"};
+ipc::TestSocket kConsumerSock{"tracing_test-consumer"};
 
 // TODO(rsavitski): consider using src/tracing/test/mock_producer.h.
 class MockProducer : public Producer {
@@ -118,17 +118,17 @@
 class TracingIntegrationTest : public ::testing::Test {
  public:
   void SetUp() override {
-    DESTROY_TEST_SOCK(kProducerSockName);
-    DESTROY_TEST_SOCK(kConsumerSockName);
+    kProducerSock.Destroy();
+    kConsumerSock.Destroy();
     task_runner_.reset(new base::TestTaskRunner());
 
     // Create the service host.
     svc_ = ServiceIPCHost::CreateInstance(task_runner_.get());
-    svc_->Start(kProducerSockName, kConsumerSockName);
+    svc_->Start(kProducerSock.name(), kConsumerSock.name());
 
     // Create and connect a Producer.
     producer_endpoint_ = ProducerIPCClient::Connect(
-        kProducerSockName, &producer_, "perfetto.mock_producer",
+        kProducerSock.name(), &producer_, "perfetto.mock_producer",
         task_runner_.get(), GetProducerSMBScrapingMode());
     auto on_producer_connect =
         task_runner_->CreateCheckpoint("on_producer_connect");
@@ -142,7 +142,7 @@
 
     // Create and connect a Consumer.
     consumer_endpoint_ = ConsumerIPCClient::Connect(
-        kConsumerSockName, &consumer_, task_runner_.get());
+        kConsumerSock.name(), &consumer_, task_runner_.get());
     auto on_consumer_connect =
         task_runner_->CreateCheckpoint("on_consumer_connect");
     EXPECT_CALL(consumer_, OnConnect()).WillOnce(Invoke(on_consumer_connect));
@@ -174,8 +174,8 @@
     ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(&consumer_));
 
     task_runner_.reset();
-    DESTROY_TEST_SOCK(kProducerSockName);
-    DESTROY_TEST_SOCK(kConsumerSockName);
+    kProducerSock.Destroy();
+    kConsumerSock.Destroy();
   }
 
   virtual TracingService::ProducerSMBScrapingMode GetProducerSMBScrapingMode() {