1275072Semaste//===-- Socket.cpp ----------------------------------------------*- C++ -*-===// 2275072Semaste// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6275072Semaste// 7275072Semaste//===----------------------------------------------------------------------===// 8275072Semaste 9275072Semaste#include "lldb/Host/Socket.h" 10275072Semaste 11275072Semaste#include "lldb/Host/Config.h" 12275072Semaste#include "lldb/Host/Host.h" 13275072Semaste#include "lldb/Host/SocketAddress.h" 14288943Sdim#include "lldb/Host/StringConvert.h" 15296417Sdim#include "lldb/Host/common/TCPSocket.h" 16296417Sdim#include "lldb/Host/common/UDPSocket.h" 17321369Sdim#include "lldb/Utility/Log.h" 18321369Sdim#include "lldb/Utility/RegularExpression.h" 19275072Semaste 20321369Sdim#include "llvm/ADT/STLExtras.h" 21353358Sdim#include "llvm/Support/Errno.h" 22353358Sdim#include "llvm/Support/Error.h" 23353358Sdim#include "llvm/Support/WindowsError.h" 24321369Sdim 25360784Sdim#if LLDB_ENABLE_POSIX 26296417Sdim#include "lldb/Host/posix/DomainSocket.h" 27280031Sdim 28275072Semaste#include <arpa/inet.h> 29275072Semaste#include <netdb.h> 30275072Semaste#include <netinet/in.h> 31275072Semaste#include <netinet/tcp.h> 32275072Semaste#include <sys/socket.h> 33275072Semaste#include <sys/un.h> 34321369Sdim#include <unistd.h> 35275072Semaste#endif 36275072Semaste 37296417Sdim#ifdef __linux__ 38296417Sdim#include "lldb/Host/linux/AbstractSocket.h" 39296417Sdim#endif 40296417Sdim 41314564Sdim#ifdef __ANDROID__ 42314564Sdim#include <arpa/inet.h> 43296417Sdim#include <asm-generic/errno-base.h> 44296417Sdim#include <errno.h> 45314564Sdim#include <linux/tcp.h> 46314564Sdim#include <fcntl.h> 47314564Sdim#include <sys/syscall.h> 48296417Sdim#include <unistd.h> 49314564Sdim#endif // __ANDROID__ 50296417Sdim 51275072Semasteusing namespace lldb; 52275072Semasteusing namespace lldb_private; 53275072Semaste 54275072Semaste#if defined(_WIN32) 55314564Sdimtypedef const char *set_socket_option_arg_type; 56314564Sdimtypedef char *get_socket_option_arg_type; 57275072Semasteconst NativeSocket Socket::kInvalidSocketValue = INVALID_SOCKET; 58314564Sdim#else // #if defined(_WIN32) 59314564Sdimtypedef const void *set_socket_option_arg_type; 60314564Sdimtypedef void *get_socket_option_arg_type; 61275072Semasteconst NativeSocket Socket::kInvalidSocketValue = -1; 62275072Semaste#endif // #if defined(_WIN32) 63275072Semaste 64280031Sdimnamespace { 65280031Sdim 66314564Sdimbool IsInterrupted() { 67288943Sdim#if defined(_WIN32) 68314564Sdim return ::WSAGetLastError() == WSAEINTR; 69288943Sdim#else 70314564Sdim return errno == EINTR; 71288943Sdim#endif 72288943Sdim} 73288943Sdim} 74288943Sdim 75321369SdimSocket::Socket(SocketProtocol protocol, bool should_close, 76321369Sdim bool child_processes_inherit) 77360784Sdim : IOObject(eFDTypeSocket), m_protocol(protocol), 78321369Sdim m_socket(kInvalidSocketValue), 79360784Sdim m_child_processes_inherit(child_processes_inherit), 80360784Sdim m_should_close_fd(should_close) {} 81275072Semaste 82314564SdimSocket::~Socket() { Close(); } 83275072Semaste 84353358Sdimllvm::Error Socket::Initialize() { 85353358Sdim#if defined(_WIN32) 86353358Sdim auto wVersion = WINSOCK_VERSION; 87353358Sdim WSADATA wsaData; 88353358Sdim int err = ::WSAStartup(wVersion, &wsaData); 89353358Sdim if (err == 0) { 90353358Sdim if (wsaData.wVersion < wVersion) { 91353358Sdim WSACleanup(); 92353358Sdim return llvm::make_error<llvm::StringError>( 93353358Sdim "WSASock version is not expected.", llvm::inconvertibleErrorCode()); 94353358Sdim } 95353358Sdim } else { 96353358Sdim return llvm::errorCodeToError(llvm::mapWindowsError(::WSAGetLastError())); 97353358Sdim } 98353358Sdim#endif 99353358Sdim 100353358Sdim return llvm::Error::success(); 101353358Sdim} 102353358Sdim 103353358Sdimvoid Socket::Terminate() { 104353358Sdim#if defined(_WIN32) 105353358Sdim ::WSACleanup(); 106353358Sdim#endif 107353358Sdim} 108353358Sdim 109314564Sdimstd::unique_ptr<Socket> Socket::Create(const SocketProtocol protocol, 110314564Sdim bool child_processes_inherit, 111321369Sdim Status &error) { 112314564Sdim error.Clear(); 113275072Semaste 114314564Sdim std::unique_ptr<Socket> socket_up; 115314564Sdim switch (protocol) { 116314564Sdim case ProtocolTcp: 117321369Sdim socket_up = 118360784Sdim std::make_unique<TCPSocket>(true, child_processes_inherit); 119314564Sdim break; 120314564Sdim case ProtocolUdp: 121321369Sdim socket_up = 122360784Sdim std::make_unique<UDPSocket>(true, child_processes_inherit); 123314564Sdim break; 124314564Sdim case ProtocolUnixDomain: 125360784Sdim#if LLDB_ENABLE_POSIX 126321369Sdim socket_up = 127360784Sdim std::make_unique<DomainSocket>(true, child_processes_inherit); 128296417Sdim#else 129314564Sdim error.SetErrorString( 130314564Sdim "Unix domain sockets are not supported on this platform."); 131296417Sdim#endif 132314564Sdim break; 133314564Sdim case ProtocolUnixAbstract: 134296417Sdim#ifdef __linux__ 135321369Sdim socket_up = 136360784Sdim std::make_unique<AbstractSocket>(child_processes_inherit); 137296417Sdim#else 138314564Sdim error.SetErrorString( 139314564Sdim "Abstract domain sockets are not supported on this platform."); 140296417Sdim#endif 141314564Sdim break; 142314564Sdim } 143275072Semaste 144314564Sdim if (error.Fail()) 145314564Sdim socket_up.reset(); 146275072Semaste 147314564Sdim return socket_up; 148296417Sdim} 149275072Semaste 150321369SdimStatus Socket::TcpConnect(llvm::StringRef host_and_port, 151321369Sdim bool child_processes_inherit, Socket *&socket) { 152314564Sdim Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_COMMUNICATION)); 153360784Sdim LLDB_LOGF(log, "Socket::%s (host/port = %s)", __FUNCTION__, 154360784Sdim host_and_port.str().c_str()); 155275072Semaste 156321369Sdim Status error; 157314564Sdim std::unique_ptr<Socket> connect_socket( 158314564Sdim Create(ProtocolTcp, child_processes_inherit, error)); 159314564Sdim if (error.Fail()) 160314564Sdim return error; 161275072Semaste 162314564Sdim error = connect_socket->Connect(host_and_port); 163314564Sdim if (error.Success()) 164314564Sdim socket = connect_socket.release(); 165275072Semaste 166314564Sdim return error; 167275072Semaste} 168275072Semaste 169321369SdimStatus Socket::TcpListen(llvm::StringRef host_and_port, 170321369Sdim bool child_processes_inherit, Socket *&socket, 171321369Sdim Predicate<uint16_t> *predicate, int backlog) { 172314564Sdim Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); 173360784Sdim LLDB_LOGF(log, "Socket::%s (%s)", __FUNCTION__, host_and_port.str().c_str()); 174275072Semaste 175321369Sdim Status error; 176314564Sdim std::string host_str; 177314564Sdim std::string port_str; 178314564Sdim int32_t port = INT32_MIN; 179314564Sdim if (!DecodeHostAndPort(host_and_port, host_str, port_str, port, &error)) 180314564Sdim return error; 181275072Semaste 182314564Sdim std::unique_ptr<TCPSocket> listen_socket( 183321369Sdim new TCPSocket(true, child_processes_inherit)); 184314564Sdim if (error.Fail()) 185314564Sdim return error; 186296417Sdim 187314564Sdim error = listen_socket->Listen(host_and_port, backlog); 188314564Sdim if (error.Success()) { 189341825Sdim // We were asked to listen on port zero which means we must now read the 190341825Sdim // actual port that was given to us as port zero is a special code for 191341825Sdim // "find an open port for me". 192314564Sdim if (port == 0) 193314564Sdim port = listen_socket->GetLocalPortNumber(); 194275072Semaste 195341825Sdim // Set the port predicate since when doing a listen://<host>:<port> it 196341825Sdim // often needs to accept the incoming connection which is a blocking system 197341825Sdim // call. Allowing access to the bound port using a predicate allows us to 198341825Sdim // wait for the port predicate to be set to a non-zero value from another 199341825Sdim // thread in an efficient manor. 200314564Sdim if (predicate) 201314564Sdim predicate->SetValue(port, eBroadcastAlways); 202314564Sdim socket = listen_socket.release(); 203314564Sdim } 204275072Semaste 205314564Sdim return error; 206275072Semaste} 207275072Semaste 208321369SdimStatus Socket::UdpConnect(llvm::StringRef host_and_port, 209321369Sdim bool child_processes_inherit, Socket *&socket) { 210314564Sdim Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); 211360784Sdim LLDB_LOGF(log, "Socket::%s (host/port = %s)", __FUNCTION__, 212360784Sdim host_and_port.str().c_str()); 213296417Sdim 214321369Sdim return UDPSocket::Connect(host_and_port, child_processes_inherit, socket); 215296417Sdim} 216296417Sdim 217321369SdimStatus Socket::UnixDomainConnect(llvm::StringRef name, 218321369Sdim bool child_processes_inherit, 219321369Sdim Socket *&socket) { 220321369Sdim Status error; 221314564Sdim std::unique_ptr<Socket> connect_socket( 222314564Sdim Create(ProtocolUnixDomain, child_processes_inherit, error)); 223314564Sdim if (error.Fail()) 224314564Sdim return error; 225275072Semaste 226314564Sdim error = connect_socket->Connect(name); 227314564Sdim if (error.Success()) 228314564Sdim socket = connect_socket.release(); 229275072Semaste 230314564Sdim return error; 231275072Semaste} 232275072Semaste 233321369SdimStatus Socket::UnixDomainAccept(llvm::StringRef name, 234321369Sdim bool child_processes_inherit, Socket *&socket) { 235321369Sdim Status error; 236314564Sdim std::unique_ptr<Socket> listen_socket( 237314564Sdim Create(ProtocolUnixDomain, child_processes_inherit, error)); 238314564Sdim if (error.Fail()) 239314564Sdim return error; 240275072Semaste 241314564Sdim error = listen_socket->Listen(name, 5); 242314564Sdim if (error.Fail()) 243314564Sdim return error; 244275072Semaste 245321369Sdim error = listen_socket->Accept(socket); 246314564Sdim return error; 247275072Semaste} 248275072Semaste 249321369SdimStatus Socket::UnixAbstractConnect(llvm::StringRef name, 250321369Sdim bool child_processes_inherit, 251321369Sdim Socket *&socket) { 252321369Sdim Status error; 253314564Sdim std::unique_ptr<Socket> connect_socket( 254314564Sdim Create(ProtocolUnixAbstract, child_processes_inherit, error)); 255314564Sdim if (error.Fail()) 256314564Sdim return error; 257275072Semaste 258314564Sdim error = connect_socket->Connect(name); 259314564Sdim if (error.Success()) 260314564Sdim socket = connect_socket.release(); 261314564Sdim return error; 262275072Semaste} 263275072Semaste 264321369SdimStatus Socket::UnixAbstractAccept(llvm::StringRef name, 265321369Sdim bool child_processes_inherit, 266321369Sdim Socket *&socket) { 267321369Sdim Status error; 268314564Sdim std::unique_ptr<Socket> listen_socket( 269314564Sdim Create(ProtocolUnixAbstract, child_processes_inherit, error)); 270314564Sdim if (error.Fail()) 271314564Sdim return error; 272275072Semaste 273314564Sdim error = listen_socket->Listen(name, 5); 274314564Sdim if (error.Fail()) 275314564Sdim return error; 276275072Semaste 277321369Sdim error = listen_socket->Accept(socket); 278314564Sdim return error; 279275072Semaste} 280275072Semaste 281314564Sdimbool Socket::DecodeHostAndPort(llvm::StringRef host_and_port, 282314564Sdim std::string &host_str, std::string &port_str, 283321369Sdim int32_t &port, Status *error_ptr) { 284321369Sdim static RegularExpression g_regex( 285321369Sdim llvm::StringRef("([^:]+|\\[[0-9a-fA-F:]+.*\\]):([0-9]+)")); 286360784Sdim llvm::SmallVector<llvm::StringRef, 3> matches; 287360784Sdim if (g_regex.Execute(host_and_port, &matches)) { 288360784Sdim host_str = matches[1].str(); 289360784Sdim port_str = matches[2].str(); 290360784Sdim // IPv6 addresses are wrapped in [] when specified with ports 291360784Sdim if (host_str.front() == '[' && host_str.back() == ']') 292360784Sdim host_str = host_str.substr(1, host_str.size() - 2); 293360784Sdim bool ok = false; 294360784Sdim port = StringConvert::ToUInt32(port_str.c_str(), UINT32_MAX, 10, &ok); 295360784Sdim if (ok && port <= UINT16_MAX) { 296314564Sdim if (error_ptr) 297360784Sdim error_ptr->Clear(); 298360784Sdim return true; 299275072Semaste } 300360784Sdim // port is too large 301360784Sdim if (error_ptr) 302360784Sdim error_ptr->SetErrorStringWithFormat( 303360784Sdim "invalid host:port specification: '%s'", host_and_port.str().c_str()); 304360784Sdim return false; 305314564Sdim } 306275072Semaste 307314564Sdim // If this was unsuccessful, then check if it's simply a signed 32-bit 308341825Sdim // integer, representing a port with an empty host. 309314564Sdim host_str.clear(); 310314564Sdim port_str.clear(); 311353358Sdim if (to_integer(host_and_port, port, 10) && port < UINT16_MAX) { 312314564Sdim port_str = host_and_port; 313275072Semaste if (error_ptr) 314314564Sdim error_ptr->Clear(); 315314564Sdim return true; 316314564Sdim } 317314564Sdim 318314564Sdim if (error_ptr) 319314564Sdim error_ptr->SetErrorStringWithFormat("invalid host:port specification: '%s'", 320353358Sdim host_and_port.str().c_str()); 321314564Sdim return false; 322275072Semaste} 323275072Semaste 324314564SdimIOObject::WaitableHandle Socket::GetWaitableHandle() { 325314564Sdim // TODO: On Windows, use WSAEventSelect 326314564Sdim return m_socket; 327275072Semaste} 328275072Semaste 329321369SdimStatus Socket::Read(void *buf, size_t &num_bytes) { 330321369Sdim Status error; 331314564Sdim int bytes_received = 0; 332314564Sdim do { 333314564Sdim bytes_received = ::recv(m_socket, static_cast<char *>(buf), num_bytes, 0); 334314564Sdim } while (bytes_received < 0 && IsInterrupted()); 335275072Semaste 336314564Sdim if (bytes_received < 0) { 337314564Sdim SetLastError(error); 338314564Sdim num_bytes = 0; 339314564Sdim } else 340314564Sdim num_bytes = bytes_received; 341275072Semaste 342314564Sdim Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_COMMUNICATION)); 343314564Sdim if (log) { 344360784Sdim LLDB_LOGF(log, 345360784Sdim "%p Socket::Read() (socket = %" PRIu64 346360784Sdim ", src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64 347360784Sdim " (error = %s)", 348360784Sdim static_cast<void *>(this), static_cast<uint64_t>(m_socket), buf, 349360784Sdim static_cast<uint64_t>(num_bytes), 350360784Sdim static_cast<int64_t>(bytes_received), error.AsCString()); 351314564Sdim } 352275072Semaste 353314564Sdim return error; 354275072Semaste} 355275072Semaste 356321369SdimStatus Socket::Write(const void *buf, size_t &num_bytes) { 357360784Sdim const size_t src_len = num_bytes; 358321369Sdim Status error; 359314564Sdim int bytes_sent = 0; 360314564Sdim do { 361314564Sdim bytes_sent = Send(buf, num_bytes); 362314564Sdim } while (bytes_sent < 0 && IsInterrupted()); 363275072Semaste 364314564Sdim if (bytes_sent < 0) { 365314564Sdim SetLastError(error); 366314564Sdim num_bytes = 0; 367314564Sdim } else 368314564Sdim num_bytes = bytes_sent; 369275072Semaste 370314564Sdim Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_COMMUNICATION)); 371314564Sdim if (log) { 372360784Sdim LLDB_LOGF(log, 373360784Sdim "%p Socket::Write() (socket = %" PRIu64 374360784Sdim ", src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64 375360784Sdim " (error = %s)", 376360784Sdim static_cast<void *>(this), static_cast<uint64_t>(m_socket), buf, 377360784Sdim static_cast<uint64_t>(src_len), 378360784Sdim static_cast<int64_t>(bytes_sent), error.AsCString()); 379314564Sdim } 380275072Semaste 381314564Sdim return error; 382275072Semaste} 383275072Semaste 384321369SdimStatus Socket::PreDisconnect() { 385321369Sdim Status error; 386314564Sdim return error; 387275072Semaste} 388275072Semaste 389321369SdimStatus Socket::Close() { 390321369Sdim Status error; 391314564Sdim if (!IsValid() || !m_should_close_fd) 392314564Sdim return error; 393275072Semaste 394314564Sdim Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); 395360784Sdim LLDB_LOGF(log, "%p Socket::Close (fd = %" PRIu64 ")", 396360784Sdim static_cast<void *>(this), static_cast<uint64_t>(m_socket)); 397275072Semaste 398275072Semaste#if defined(_WIN32) 399314564Sdim bool success = !!closesocket(m_socket); 400275072Semaste#else 401314564Sdim bool success = !!::close(m_socket); 402275072Semaste#endif 403314564Sdim // A reference to a FD was passed in, set it to an invalid value 404314564Sdim m_socket = kInvalidSocketValue; 405314564Sdim if (!success) { 406314564Sdim SetLastError(error); 407314564Sdim } 408275072Semaste 409314564Sdim return error; 410275072Semaste} 411275072Semaste 412314564Sdimint Socket::GetOption(int level, int option_name, int &option_value) { 413314564Sdim get_socket_option_arg_type option_value_p = 414314564Sdim reinterpret_cast<get_socket_option_arg_type>(&option_value); 415314564Sdim socklen_t option_value_size = sizeof(int); 416314564Sdim return ::getsockopt(m_socket, level, option_name, option_value_p, 417314564Sdim &option_value_size); 418275072Semaste} 419275072Semaste 420314564Sdimint Socket::SetOption(int level, int option_name, int option_value) { 421314564Sdim set_socket_option_arg_type option_value_p = 422314564Sdim reinterpret_cast<get_socket_option_arg_type>(&option_value); 423314564Sdim return ::setsockopt(m_socket, level, option_name, option_value_p, 424314564Sdim sizeof(option_value)); 425275072Semaste} 426275072Semaste 427314564Sdimsize_t Socket::Send(const void *buf, const size_t num_bytes) { 428314564Sdim return ::send(m_socket, static_cast<const char *>(buf), num_bytes, 0); 429275072Semaste} 430275072Semaste 431321369Sdimvoid Socket::SetLastError(Status &error) { 432296417Sdim#if defined(_WIN32) 433314564Sdim error.SetError(::WSAGetLastError(), lldb::eErrorTypeWin32); 434296417Sdim#else 435314564Sdim error.SetErrorToErrno(); 436296417Sdim#endif 437275072Semaste} 438288943Sdim 439314564SdimNativeSocket Socket::CreateSocket(const int domain, const int type, 440314564Sdim const int protocol, 441321369Sdim bool child_processes_inherit, Status &error) { 442314564Sdim error.Clear(); 443321369Sdim auto socket_type = type; 444296417Sdim#ifdef SOCK_CLOEXEC 445314564Sdim if (!child_processes_inherit) 446321369Sdim socket_type |= SOCK_CLOEXEC; 447296417Sdim#endif 448321369Sdim auto sock = ::socket(domain, socket_type, protocol); 449314564Sdim if (sock == kInvalidSocketValue) 450314564Sdim SetLastError(error); 451288943Sdim 452314564Sdim return sock; 453288943Sdim} 454288943Sdim 455314564SdimNativeSocket Socket::AcceptSocket(NativeSocket sockfd, struct sockaddr *addr, 456314564Sdim socklen_t *addrlen, 457321369Sdim bool child_processes_inherit, Status &error) { 458314564Sdim error.Clear(); 459321369Sdim#if defined(ANDROID_USE_ACCEPT_WORKAROUND) 460321369Sdim // Hack: 461341825Sdim // This enables static linking lldb-server to an API 21 libc, but still 462341825Sdim // having it run on older devices. It is necessary because API 21 libc's 463321369Sdim // implementation of accept() uses the accept4 syscall(), which is not 464321369Sdim // available in older kernels. Using an older libc would fix this issue, but 465321369Sdim // introduce other ones, as the old libraries were quite buggy. 466314564Sdim int fd = syscall(__NR_accept, sockfd, addr, addrlen); 467314564Sdim if (fd >= 0 && !child_processes_inherit) { 468314564Sdim int flags = ::fcntl(fd, F_GETFD); 469314564Sdim if (flags != -1 && ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC) != -1) 470314564Sdim return fd; 471314564Sdim SetLastError(error); 472314564Sdim close(fd); 473314564Sdim } 474314564Sdim return fd; 475327952Sdim#elif defined(SOCK_CLOEXEC) && defined(HAVE_ACCEPT4) 476314564Sdim int flags = 0; 477314564Sdim if (!child_processes_inherit) { 478314564Sdim flags |= SOCK_CLOEXEC; 479314564Sdim } 480360784Sdim NativeSocket fd = llvm::sys::RetryAfterSignal( 481360784Sdim static_cast<NativeSocket>(-1), ::accept4, sockfd, addr, addrlen, flags); 482296417Sdim#else 483360784Sdim NativeSocket fd = llvm::sys::RetryAfterSignal( 484360784Sdim static_cast<NativeSocket>(-1), ::accept, sockfd, addr, addrlen); 485296417Sdim#endif 486314564Sdim if (fd == kInvalidSocketValue) 487314564Sdim SetLastError(error); 488314564Sdim return fd; 489288943Sdim} 490