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 #ifndef INCLUDE_PERFETTO_EXT_BASE_UNIX_SOCKET_H_ 18 #define INCLUDE_PERFETTO_EXT_BASE_UNIX_SOCKET_H_ 19 20 #include <stdint.h> 21 #include <sys/types.h> 22 23 #include <memory> 24 #include <string> 25 #include <utility> 26 27 #include "perfetto/base/build_config.h" 28 #include "perfetto/base/export.h" 29 #include "perfetto/base/logging.h" 30 #include "perfetto/ext/base/scoped_file.h" 31 #include "perfetto/ext/base/utils.h" 32 #include "perfetto/ext/base/weak_ptr.h" 33 34 struct msghdr; 35 36 namespace perfetto { 37 namespace base { 38 39 // Define the SocketHandle and ScopedSocketHandle types. 40 // On POSIX OSes, a SocketHandle is really just an int (a file descriptor). 41 // On Windows, sockets are have their own type (SOCKET) which is neither a 42 // HANDLE nor an int. However Windows SOCKET(s) can have a event HANDLE attached 43 // to them (which in Perfetto is a PlatformHandle), and that can be used in 44 // WaitForMultipleObjects, hence in base::TaskRunner.AddFileDescriptorWatch(). 45 46 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) 47 // uintptr_t really reads as SOCKET here (Windows headers typedef to that). 48 // As usual we don't just use SOCKET here to avoid leaking Windows.h includes 49 // in our headers. 50 using SocketHandle = uintptr_t; // SOCKET 51 int CloseSocket(SocketHandle); // A wrapper around ::closesocket(). 52 using ScopedSocketHandle = 53 ScopedResource<SocketHandle, CloseSocket, static_cast<SocketHandle>(-1)>; 54 #else 55 using SocketHandle = int; 56 using ScopedSocketHandle = ScopedFile; 57 #endif 58 59 class TaskRunner; 60 61 // Use arbitrarily high values to avoid that some code accidentally ends up 62 // assuming that these enum values match the sysroot's SOCK_xxx defines rather 63 // than using GetSockType() / GetSockFamily(). 64 enum class SockType { kStream = 100, kDgram, kSeqPacket }; 65 enum class SockFamily { kUnix = 200, kInet, kInet6 }; 66 67 // Controls the getsockopt(SO_PEERCRED) behavior, which allows to obtain the 68 // peer credentials. 69 enum class SockPeerCredMode { 70 // Obtain the peer credentials immediately after connection and cache them. 71 kReadOnConnect = 0, 72 73 // Don't read peer credentials at all. Calls to peer_uid()/peer_pid() will 74 // hit a DCHECK and return kInvalidUid/Pid in release builds. 75 kIgnore = 1, 76 77 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) || \ 78 PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA) 79 kDefault = kIgnore, 80 #else 81 kDefault = kReadOnConnect, 82 #endif 83 }; 84 85 // UnixSocketRaw is a basic wrapper around sockets. It exposes wrapper 86 // methods that take care of most common pitfalls (e.g., marking fd as 87 // O_CLOEXEC, avoiding SIGPIPE, properly handling partial writes). It is used as 88 // a building block for the more sophisticated UnixSocket class which depends 89 // on base::TaskRunner. 90 class UnixSocketRaw { 91 public: 92 // Creates a new unconnected unix socket. 93 static UnixSocketRaw CreateMayFail(SockFamily family, SockType type); 94 95 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) 96 // Crates a pair of connected sockets. 97 static std::pair<UnixSocketRaw, UnixSocketRaw> CreatePairPosix(SockFamily, 98 SockType); 99 #endif 100 101 // Creates an uninitialized unix socket. 102 UnixSocketRaw(); 103 104 // Creates a unix socket adopting an existing file descriptor. This is 105 // typically used to inherit fds from init via environment variables. 106 UnixSocketRaw(ScopedSocketHandle, SockFamily, SockType); 107 108 ~UnixSocketRaw() = default; 109 UnixSocketRaw(UnixSocketRaw&&) noexcept = default; 110 UnixSocketRaw& operator=(UnixSocketRaw&&) = default; 111 112 bool Bind(const std::string& socket_name); 113 bool Listen(); 114 bool Connect(const std::string& socket_name); 115 bool SetTxTimeout(uint32_t timeout_ms); 116 bool SetRxTimeout(uint32_t timeout_ms); 117 void Shutdown(); 118 void SetBlocking(bool); 119 void DcheckIsBlocking(bool expected) const; // No-op on release and Win. 120 void SetRetainOnExec(bool retain); type()121 SockType type() const { return type_; } family()122 SockFamily family() const { return family_; } fd()123 SocketHandle fd() const { return *fd_; } 124 explicit operator bool() const { return !!fd_; } 125 126 // This is the handle that passed to TaskRunner.AddFileDescriptorWatch(). 127 // On UNIX this is just the socket FD. On Windows, we need to create a 128 // dedicated event object. watch_handle()129 PlatformHandle watch_handle() const { 130 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) 131 return *event_handle_; 132 #else 133 return *fd_; 134 #endif 135 } 136 ReleaseFd()137 ScopedSocketHandle ReleaseFd() { return std::move(fd_); } 138 139 // |send_fds| and |num_fds| are ignored on Windows. 140 ssize_t Send(const void* msg, 141 size_t len, 142 const int* send_fds = nullptr, 143 size_t num_fds = 0); 144 SendStr(const std::string & str)145 ssize_t SendStr(const std::string& str) { 146 return Send(str.data(), str.size()); 147 } 148 149 // |fd_vec| and |max_files| are ignored on Windows. 150 ssize_t Receive(void* msg, 151 size_t len, 152 ScopedFile* fd_vec = nullptr, 153 size_t max_files = 0); 154 155 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) 156 // UNIX-specific helpers to deal with SCM_RIGHTS. 157 158 // Re-enter sendmsg until all the data has been sent or an error occurs. 159 // TODO(fmayer): Figure out how to do timeouts here for heapprofd. 160 ssize_t SendMsgAllPosix(struct msghdr* msg); 161 162 // Exposed for testing only. 163 // Update msghdr so subsequent sendmsg will send data that remains after n 164 // bytes have already been sent. 165 static void ShiftMsgHdrPosix(size_t n, struct msghdr* msg); 166 #endif 167 168 private: 169 UnixSocketRaw(SockFamily, SockType); 170 171 UnixSocketRaw(const UnixSocketRaw&) = delete; 172 UnixSocketRaw& operator=(const UnixSocketRaw&) = delete; 173 174 ScopedSocketHandle fd_; 175 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) 176 ScopedPlatformHandle event_handle_; 177 #endif 178 SockFamily family_ = SockFamily::kUnix; 179 SockType type_ = SockType::kStream; 180 uint32_t tx_timeout_ms_ = 0; 181 }; 182 183 // A non-blocking UNIX domain socket. Allows also to transfer file descriptors. 184 // None of the methods in this class are blocking. 185 // The main design goal is making strong guarantees on the EventListener 186 // callbacks, in order to avoid ending in some undefined state. 187 // In case of any error it will aggressively just shut down the socket and 188 // notify the failure with OnConnect(false) or OnDisconnect() depending on the 189 // state of the socket (see below). 190 // EventListener callbacks stop happening as soon as the instance is destroyed. 191 // 192 // Lifecycle of a client socket: 193 // 194 // Connect() 195 // | 196 // +------------------+------------------+ 197 // | (success) | (failure or Shutdown()) 198 // V V 199 // OnConnect(true) OnConnect(false) 200 // | 201 // V 202 // OnDataAvailable() 203 // | 204 // V 205 // OnDisconnect() (failure or shutdown) 206 // 207 // 208 // Lifecycle of a server socket: 209 // 210 // Listen() --> returns false in case of errors. 211 // | 212 // V 213 // OnNewIncomingConnection(new_socket) 214 // 215 // (|new_socket| inherits the same EventListener) 216 // | 217 // V 218 // OnDataAvailable() 219 // | (failure or Shutdown()) 220 // V 221 // OnDisconnect() 222 class PERFETTO_EXPORT_COMPONENT UnixSocket { 223 public: 224 class EventListener { 225 public: 226 EventListener() = default; 227 virtual ~EventListener(); 228 229 EventListener(const EventListener&) = delete; 230 EventListener& operator=(const EventListener&) = delete; 231 232 EventListener(EventListener&&) noexcept = default; 233 EventListener& operator=(EventListener&&) noexcept = default; 234 235 // After Listen(). 236 // |self| may be null if the connection was not accepted via a listen 237 // socket. 238 virtual void OnNewIncomingConnection( 239 UnixSocket* self, 240 std::unique_ptr<UnixSocket> new_connection); 241 242 // After Connect(), whether successful or not. 243 virtual void OnConnect(UnixSocket* self, bool connected); 244 245 // After a successful Connect() or OnNewIncomingConnection(). Either the 246 // other endpoint did disconnect or some other error happened. 247 virtual void OnDisconnect(UnixSocket* self); 248 249 // Whenever there is data available to Receive(). Note that spurious FD 250 // watch events are possible, so it is possible that Receive() soon after 251 // OnDataAvailable() returns 0 (just ignore those). 252 virtual void OnDataAvailable(UnixSocket* self); 253 }; 254 255 enum class State { 256 kDisconnected = 0, // Failed connection, peer disconnection or Shutdown(). 257 kConnecting, // Soon after Connect(), before it either succeeds or fails. 258 kConnected, // After a successful Connect(). 259 kListening // After Listen(), until Shutdown(). 260 }; 261 262 // Creates a socket and starts listening. If SockFamily::kUnix and 263 // |socket_name| starts with a '@', an abstract UNIX dmoain socket will be 264 // created instead of a filesystem-linked UNIX socket (Linux/Android only). 265 // If SockFamily::kInet, |socket_name| is host:port (e.g., "1.2.3.4:8000"). 266 // If SockFamily::kInet6, |socket_name| is [host]:port (e.g., "[::1]:8000"). 267 // Returns nullptr if the socket creation or bind fails. If listening fails, 268 // (e.g. if another socket with the same name is already listening) the 269 // returned socket will have is_listening() == false. 270 static std::unique_ptr<UnixSocket> Listen(const std::string& socket_name, 271 EventListener*, 272 TaskRunner*, 273 SockFamily, 274 SockType); 275 276 // Attaches to a pre-existing socket. The socket must have been created in 277 // SOCK_STREAM mode and the caller must have called bind() on it. 278 static std::unique_ptr<UnixSocket> Listen(ScopedSocketHandle, 279 EventListener*, 280 TaskRunner*, 281 SockFamily, 282 SockType); 283 284 // Creates a Unix domain socket and connects to the listening endpoint. 285 // Returns always an instance. EventListener::OnConnect(bool success) will 286 // be called always, whether the connection succeeded or not. 287 static std::unique_ptr<UnixSocket> Connect( 288 const std::string& socket_name, 289 EventListener*, 290 TaskRunner*, 291 SockFamily, 292 SockType, 293 SockPeerCredMode = SockPeerCredMode::kDefault); 294 295 // Constructs a UnixSocket using the given connected socket. 296 static std::unique_ptr<UnixSocket> AdoptConnected( 297 ScopedSocketHandle, 298 EventListener*, 299 TaskRunner*, 300 SockFamily, 301 SockType, 302 SockPeerCredMode = SockPeerCredMode::kDefault); 303 304 UnixSocket(const UnixSocket&) = delete; 305 UnixSocket& operator=(const UnixSocket&) = delete; 306 // Cannot be easily moved because of tasks from the FileDescriptorWatch. 307 UnixSocket(UnixSocket&&) = delete; 308 UnixSocket& operator=(UnixSocket&&) = delete; 309 310 // This class gives the hard guarantee that no callback is called on the 311 // passed EventListener immediately after the object has been destroyed. 312 // Any queued callback will be silently dropped. 313 ~UnixSocket(); 314 315 // Shuts down the current connection, if any. If the socket was Listen()-ing, 316 // stops listening. The socket goes back to kNotInitialized state, so it can 317 // be reused with Listen() or Connect(). 318 void Shutdown(bool notify); 319 SetTxTimeout(uint32_t timeout_ms)320 void SetTxTimeout(uint32_t timeout_ms) { 321 PERFETTO_CHECK(sock_raw_.SetTxTimeout(timeout_ms)); 322 } SetRxTimeout(uint32_t timeout_ms)323 void SetRxTimeout(uint32_t timeout_ms) { 324 PERFETTO_CHECK(sock_raw_.SetRxTimeout(timeout_ms)); 325 } 326 // Returns true is the message was queued, false if there was no space in the 327 // output buffer, in which case the client should retry or give up. 328 // If any other error happens the socket will be shutdown and 329 // EventListener::OnDisconnect() will be called. 330 // If the socket is not connected, Send() will just return false. 331 // Does not append a null string terminator to msg in any case. 332 bool Send(const void* msg, size_t len, const int* send_fds, size_t num_fds); 333 334 inline bool Send(const void* msg, size_t len, int send_fd = -1) { 335 if (send_fd != -1) 336 return Send(msg, len, &send_fd, 1); 337 return Send(msg, len, nullptr, 0); 338 } 339 SendStr(const std::string & msg)340 inline bool SendStr(const std::string& msg) { 341 return Send(msg.data(), msg.size(), -1); 342 } 343 344 // Returns the number of bytes (<= |len|) written in |msg| or 0 if there 345 // is no data in the buffer to read or an error occurs (in which case a 346 // EventListener::OnDisconnect() will follow). 347 // If the ScopedFile pointer is not null and a FD is received, it moves the 348 // received FD into that. If a FD is received but the ScopedFile pointer is 349 // null, the FD will be automatically closed. 350 size_t Receive(void* msg, size_t len, ScopedFile*, size_t max_files = 1); 351 Receive(void * msg,size_t len)352 inline size_t Receive(void* msg, size_t len) { 353 return Receive(msg, len, nullptr, 0); 354 } 355 356 // Only for tests. This is slower than Receive() as it requires a heap 357 // allocation and a copy for the std::string. Guarantees that the returned 358 // string is null terminated even if the underlying message sent by the peer 359 // is not. 360 std::string ReceiveString(size_t max_length = 1024); 361 is_connected()362 bool is_connected() const { return state_ == State::kConnected; } is_listening()363 bool is_listening() const { return state_ == State::kListening; } fd()364 SocketHandle fd() const { return sock_raw_.fd(); } 365 366 // User ID of the peer, as returned by the kernel. If the client disconnects 367 // and the socket goes into the kDisconnected state, it retains the uid of 368 // the last peer. 369 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \ 370 !PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA) 371 uid_t peer_uid_posix(bool skip_check_for_testing = false) const { 372 PERFETTO_DCHECK((!is_listening() && peer_uid_ != kInvalidUid) || 373 skip_check_for_testing); 374 375 return peer_uid_; 376 } 377 #endif 378 379 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \ 380 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) 381 // Process ID of the peer, as returned by the kernel. If the client 382 // disconnects and the socket goes into the kDisconnected state, it 383 // retains the pid of the last peer. 384 // 385 // This is only available on Linux / Android. 386 pid_t peer_pid_linux(bool skip_check_for_testing = false) const { 387 PERFETTO_DCHECK((!is_listening() && peer_pid_ != kInvalidPid) || 388 skip_check_for_testing); 389 return peer_pid_; 390 } 391 #endif 392 393 // This makes the UnixSocket unusable. 394 UnixSocketRaw ReleaseSocket(); 395 396 private: 397 UnixSocket(EventListener*, 398 TaskRunner*, 399 SockFamily, 400 SockType, 401 SockPeerCredMode); 402 UnixSocket(EventListener*, 403 TaskRunner*, 404 ScopedSocketHandle, 405 State, 406 SockFamily, 407 SockType, 408 SockPeerCredMode); 409 410 // Called once by the corresponding public static factory methods. 411 void DoConnect(const std::string& socket_name); 412 413 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) 414 void ReadPeerCredentialsPosix(); 415 #endif 416 417 void OnEvent(); 418 void NotifyConnectionState(bool success); 419 420 UnixSocketRaw sock_raw_; 421 State state_ = State::kDisconnected; 422 SockPeerCredMode peer_cred_mode_ = SockPeerCredMode::kDefault; 423 424 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \ 425 !PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA) 426 uid_t peer_uid_ = kInvalidUid; 427 #endif 428 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \ 429 PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) 430 pid_t peer_pid_ = kInvalidPid; 431 #endif 432 EventListener* const event_listener_; 433 TaskRunner* const task_runner_; 434 WeakPtrFactory<UnixSocket> weak_ptr_factory_; // Keep last. 435 }; 436 437 } // namespace base 438 } // namespace perfetto 439 440 #endif // INCLUDE_PERFETTO_EXT_BASE_UNIX_SOCKET_H_ 441