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