1dda28197Spatrick //===-- Socket.cpp --------------------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick
9061da546Spatrick #include "lldb/Host/Socket.h"
10061da546Spatrick
11061da546Spatrick #include "lldb/Host/Config.h"
12061da546Spatrick #include "lldb/Host/Host.h"
13061da546Spatrick #include "lldb/Host/SocketAddress.h"
14061da546Spatrick #include "lldb/Host/common/TCPSocket.h"
15061da546Spatrick #include "lldb/Host/common/UDPSocket.h"
16*f6aab3d8Srobert #include "lldb/Utility/LLDBLog.h"
17061da546Spatrick #include "lldb/Utility/Log.h"
18061da546Spatrick
19061da546Spatrick #include "llvm/ADT/STLExtras.h"
20061da546Spatrick #include "llvm/Support/Errno.h"
21061da546Spatrick #include "llvm/Support/Error.h"
22*f6aab3d8Srobert #include "llvm/Support/Regex.h"
23061da546Spatrick #include "llvm/Support/WindowsError.h"
24061da546Spatrick
25061da546Spatrick #if LLDB_ENABLE_POSIX
26061da546Spatrick #include "lldb/Host/posix/DomainSocket.h"
27061da546Spatrick
28061da546Spatrick #include <arpa/inet.h>
29061da546Spatrick #include <netdb.h>
30061da546Spatrick #include <netinet/in.h>
31061da546Spatrick #include <netinet/tcp.h>
32061da546Spatrick #include <sys/socket.h>
33061da546Spatrick #include <sys/un.h>
34061da546Spatrick #include <unistd.h>
35061da546Spatrick #endif
36061da546Spatrick
37061da546Spatrick #ifdef __linux__
38061da546Spatrick #include "lldb/Host/linux/AbstractSocket.h"
39061da546Spatrick #endif
40061da546Spatrick
41061da546Spatrick #ifdef __ANDROID__
42061da546Spatrick #include <arpa/inet.h>
43061da546Spatrick #include <asm-generic/errno-base.h>
44be691f3bSpatrick #include <cerrno>
45061da546Spatrick #include <fcntl.h>
46be691f3bSpatrick #include <linux/tcp.h>
47061da546Spatrick #include <sys/syscall.h>
48061da546Spatrick #include <unistd.h>
49061da546Spatrick #endif // __ANDROID__
50061da546Spatrick
51061da546Spatrick using namespace lldb;
52061da546Spatrick using namespace lldb_private;
53061da546Spatrick
54061da546Spatrick #if defined(_WIN32)
55061da546Spatrick typedef const char *set_socket_option_arg_type;
56061da546Spatrick typedef char *get_socket_option_arg_type;
57061da546Spatrick const NativeSocket Socket::kInvalidSocketValue = INVALID_SOCKET;
58061da546Spatrick #else // #if defined(_WIN32)
59061da546Spatrick typedef const void *set_socket_option_arg_type;
60061da546Spatrick typedef void *get_socket_option_arg_type;
61061da546Spatrick const NativeSocket Socket::kInvalidSocketValue = -1;
62061da546Spatrick #endif // #if defined(_WIN32)
63061da546Spatrick
IsInterrupted()64*f6aab3d8Srobert static bool IsInterrupted() {
65061da546Spatrick #if defined(_WIN32)
66061da546Spatrick return ::WSAGetLastError() == WSAEINTR;
67061da546Spatrick #else
68061da546Spatrick return errno == EINTR;
69061da546Spatrick #endif
70061da546Spatrick }
71061da546Spatrick
Socket(SocketProtocol protocol,bool should_close,bool child_processes_inherit)72061da546Spatrick Socket::Socket(SocketProtocol protocol, bool should_close,
73061da546Spatrick bool child_processes_inherit)
74061da546Spatrick : IOObject(eFDTypeSocket), m_protocol(protocol),
75061da546Spatrick m_socket(kInvalidSocketValue),
76061da546Spatrick m_child_processes_inherit(child_processes_inherit),
77061da546Spatrick m_should_close_fd(should_close) {}
78061da546Spatrick
~Socket()79061da546Spatrick Socket::~Socket() { Close(); }
80061da546Spatrick
Initialize()81061da546Spatrick llvm::Error Socket::Initialize() {
82061da546Spatrick #if defined(_WIN32)
83061da546Spatrick auto wVersion = WINSOCK_VERSION;
84061da546Spatrick WSADATA wsaData;
85061da546Spatrick int err = ::WSAStartup(wVersion, &wsaData);
86061da546Spatrick if (err == 0) {
87061da546Spatrick if (wsaData.wVersion < wVersion) {
88061da546Spatrick WSACleanup();
89061da546Spatrick return llvm::make_error<llvm::StringError>(
90061da546Spatrick "WSASock version is not expected.", llvm::inconvertibleErrorCode());
91061da546Spatrick }
92061da546Spatrick } else {
93061da546Spatrick return llvm::errorCodeToError(llvm::mapWindowsError(::WSAGetLastError()));
94061da546Spatrick }
95061da546Spatrick #endif
96061da546Spatrick
97061da546Spatrick return llvm::Error::success();
98061da546Spatrick }
99061da546Spatrick
Terminate()100061da546Spatrick void Socket::Terminate() {
101061da546Spatrick #if defined(_WIN32)
102061da546Spatrick ::WSACleanup();
103061da546Spatrick #endif
104061da546Spatrick }
105061da546Spatrick
Create(const SocketProtocol protocol,bool child_processes_inherit,Status & error)106061da546Spatrick std::unique_ptr<Socket> Socket::Create(const SocketProtocol protocol,
107061da546Spatrick bool child_processes_inherit,
108061da546Spatrick Status &error) {
109061da546Spatrick error.Clear();
110061da546Spatrick
111061da546Spatrick std::unique_ptr<Socket> socket_up;
112061da546Spatrick switch (protocol) {
113061da546Spatrick case ProtocolTcp:
114061da546Spatrick socket_up =
115061da546Spatrick std::make_unique<TCPSocket>(true, child_processes_inherit);
116061da546Spatrick break;
117061da546Spatrick case ProtocolUdp:
118061da546Spatrick socket_up =
119061da546Spatrick std::make_unique<UDPSocket>(true, child_processes_inherit);
120061da546Spatrick break;
121061da546Spatrick case ProtocolUnixDomain:
122061da546Spatrick #if LLDB_ENABLE_POSIX
123061da546Spatrick socket_up =
124061da546Spatrick std::make_unique<DomainSocket>(true, child_processes_inherit);
125061da546Spatrick #else
126061da546Spatrick error.SetErrorString(
127061da546Spatrick "Unix domain sockets are not supported on this platform.");
128061da546Spatrick #endif
129061da546Spatrick break;
130061da546Spatrick case ProtocolUnixAbstract:
131061da546Spatrick #ifdef __linux__
132061da546Spatrick socket_up =
133061da546Spatrick std::make_unique<AbstractSocket>(child_processes_inherit);
134061da546Spatrick #else
135061da546Spatrick error.SetErrorString(
136061da546Spatrick "Abstract domain sockets are not supported on this platform.");
137061da546Spatrick #endif
138061da546Spatrick break;
139061da546Spatrick }
140061da546Spatrick
141061da546Spatrick if (error.Fail())
142061da546Spatrick socket_up.reset();
143061da546Spatrick
144061da546Spatrick return socket_up;
145061da546Spatrick }
146061da546Spatrick
147dda28197Spatrick llvm::Expected<std::unique_ptr<Socket>>
TcpConnect(llvm::StringRef host_and_port,bool child_processes_inherit)148dda28197Spatrick Socket::TcpConnect(llvm::StringRef host_and_port,
149dda28197Spatrick bool child_processes_inherit) {
150*f6aab3d8Srobert Log *log = GetLog(LLDBLog::Connection);
151dda28197Spatrick LLDB_LOG(log, "host_and_port = {0}", host_and_port);
152061da546Spatrick
153061da546Spatrick Status error;
154061da546Spatrick std::unique_ptr<Socket> connect_socket(
155061da546Spatrick Create(ProtocolTcp, child_processes_inherit, error));
156061da546Spatrick if (error.Fail())
157dda28197Spatrick return error.ToError();
158061da546Spatrick
159061da546Spatrick error = connect_socket->Connect(host_and_port);
160061da546Spatrick if (error.Success())
161dda28197Spatrick return std::move(connect_socket);
162061da546Spatrick
163dda28197Spatrick return error.ToError();
164061da546Spatrick }
165061da546Spatrick
166dda28197Spatrick llvm::Expected<std::unique_ptr<TCPSocket>>
TcpListen(llvm::StringRef host_and_port,bool child_processes_inherit,int backlog)167dda28197Spatrick Socket::TcpListen(llvm::StringRef host_and_port, bool child_processes_inherit,
168*f6aab3d8Srobert int backlog) {
169*f6aab3d8Srobert Log *log = GetLog(LLDBLog::Connection);
170dda28197Spatrick LLDB_LOG(log, "host_and_port = {0}", host_and_port);
171061da546Spatrick
172061da546Spatrick std::unique_ptr<TCPSocket> listen_socket(
173061da546Spatrick new TCPSocket(true, child_processes_inherit));
174061da546Spatrick
175*f6aab3d8Srobert Status error = listen_socket->Listen(host_and_port, backlog);
176dda28197Spatrick if (error.Fail())
177dda28197Spatrick return error.ToError();
178dda28197Spatrick
179dda28197Spatrick return std::move(listen_socket);
180061da546Spatrick }
181061da546Spatrick
182dda28197Spatrick llvm::Expected<std::unique_ptr<UDPSocket>>
UdpConnect(llvm::StringRef host_and_port,bool child_processes_inherit)183dda28197Spatrick Socket::UdpConnect(llvm::StringRef host_and_port,
184dda28197Spatrick bool child_processes_inherit) {
185dda28197Spatrick return UDPSocket::Connect(host_and_port, child_processes_inherit);
186061da546Spatrick }
187061da546Spatrick
DecodeHostAndPort(llvm::StringRef host_and_port)188*f6aab3d8Srobert llvm::Expected<Socket::HostAndPort> Socket::DecodeHostAndPort(llvm::StringRef host_and_port) {
189*f6aab3d8Srobert static llvm::Regex g_regex("([^:]+|\\[[0-9a-fA-F:]+.*\\]):([0-9]+)");
190*f6aab3d8Srobert HostAndPort ret;
191061da546Spatrick llvm::SmallVector<llvm::StringRef, 3> matches;
192*f6aab3d8Srobert if (g_regex.match(host_and_port, &matches)) {
193*f6aab3d8Srobert ret.hostname = matches[1].str();
194061da546Spatrick // IPv6 addresses are wrapped in [] when specified with ports
195*f6aab3d8Srobert if (ret.hostname.front() == '[' && ret.hostname.back() == ']')
196*f6aab3d8Srobert ret.hostname = ret.hostname.substr(1, ret.hostname.size() - 2);
197*f6aab3d8Srobert if (to_integer(matches[2], ret.port, 10))
198*f6aab3d8Srobert return ret;
199*f6aab3d8Srobert } else {
200*f6aab3d8Srobert // If this was unsuccessful, then check if it's simply an unsigned 16-bit
201061da546Spatrick // integer, representing a port with an empty host.
202*f6aab3d8Srobert if (to_integer(host_and_port, ret.port, 10))
203*f6aab3d8Srobert return ret;
204061da546Spatrick }
205061da546Spatrick
206*f6aab3d8Srobert return llvm::createStringError(llvm::inconvertibleErrorCode(),
207*f6aab3d8Srobert "invalid host:port specification: '%s'",
208061da546Spatrick host_and_port.str().c_str());
209061da546Spatrick }
210061da546Spatrick
GetWaitableHandle()211061da546Spatrick IOObject::WaitableHandle Socket::GetWaitableHandle() {
212061da546Spatrick // TODO: On Windows, use WSAEventSelect
213061da546Spatrick return m_socket;
214061da546Spatrick }
215061da546Spatrick
Read(void * buf,size_t & num_bytes)216061da546Spatrick Status Socket::Read(void *buf, size_t &num_bytes) {
217061da546Spatrick Status error;
218061da546Spatrick int bytes_received = 0;
219061da546Spatrick do {
220061da546Spatrick bytes_received = ::recv(m_socket, static_cast<char *>(buf), num_bytes, 0);
221061da546Spatrick } while (bytes_received < 0 && IsInterrupted());
222061da546Spatrick
223061da546Spatrick if (bytes_received < 0) {
224061da546Spatrick SetLastError(error);
225061da546Spatrick num_bytes = 0;
226061da546Spatrick } else
227061da546Spatrick num_bytes = bytes_received;
228061da546Spatrick
229*f6aab3d8Srobert Log *log = GetLog(LLDBLog::Communication);
230061da546Spatrick if (log) {
231061da546Spatrick LLDB_LOGF(log,
232061da546Spatrick "%p Socket::Read() (socket = %" PRIu64
233061da546Spatrick ", src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64
234061da546Spatrick " (error = %s)",
235061da546Spatrick static_cast<void *>(this), static_cast<uint64_t>(m_socket), buf,
236061da546Spatrick static_cast<uint64_t>(num_bytes),
237061da546Spatrick static_cast<int64_t>(bytes_received), error.AsCString());
238061da546Spatrick }
239061da546Spatrick
240061da546Spatrick return error;
241061da546Spatrick }
242061da546Spatrick
Write(const void * buf,size_t & num_bytes)243061da546Spatrick Status Socket::Write(const void *buf, size_t &num_bytes) {
244061da546Spatrick const size_t src_len = num_bytes;
245061da546Spatrick Status error;
246061da546Spatrick int bytes_sent = 0;
247061da546Spatrick do {
248061da546Spatrick bytes_sent = Send(buf, num_bytes);
249061da546Spatrick } while (bytes_sent < 0 && IsInterrupted());
250061da546Spatrick
251061da546Spatrick if (bytes_sent < 0) {
252061da546Spatrick SetLastError(error);
253061da546Spatrick num_bytes = 0;
254061da546Spatrick } else
255061da546Spatrick num_bytes = bytes_sent;
256061da546Spatrick
257*f6aab3d8Srobert Log *log = GetLog(LLDBLog::Communication);
258061da546Spatrick if (log) {
259061da546Spatrick LLDB_LOGF(log,
260061da546Spatrick "%p Socket::Write() (socket = %" PRIu64
261061da546Spatrick ", src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64
262061da546Spatrick " (error = %s)",
263061da546Spatrick static_cast<void *>(this), static_cast<uint64_t>(m_socket), buf,
264061da546Spatrick static_cast<uint64_t>(src_len),
265061da546Spatrick static_cast<int64_t>(bytes_sent), error.AsCString());
266061da546Spatrick }
267061da546Spatrick
268061da546Spatrick return error;
269061da546Spatrick }
270061da546Spatrick
PreDisconnect()271061da546Spatrick Status Socket::PreDisconnect() {
272061da546Spatrick Status error;
273061da546Spatrick return error;
274061da546Spatrick }
275061da546Spatrick
Close()276061da546Spatrick Status Socket::Close() {
277061da546Spatrick Status error;
278061da546Spatrick if (!IsValid() || !m_should_close_fd)
279061da546Spatrick return error;
280061da546Spatrick
281*f6aab3d8Srobert Log *log = GetLog(LLDBLog::Connection);
282061da546Spatrick LLDB_LOGF(log, "%p Socket::Close (fd = %" PRIu64 ")",
283061da546Spatrick static_cast<void *>(this), static_cast<uint64_t>(m_socket));
284061da546Spatrick
285061da546Spatrick #if defined(_WIN32)
286*f6aab3d8Srobert bool success = closesocket(m_socket) == 0;
287061da546Spatrick #else
288*f6aab3d8Srobert bool success = ::close(m_socket) == 0;
289061da546Spatrick #endif
290061da546Spatrick // A reference to a FD was passed in, set it to an invalid value
291061da546Spatrick m_socket = kInvalidSocketValue;
292061da546Spatrick if (!success) {
293061da546Spatrick SetLastError(error);
294061da546Spatrick }
295061da546Spatrick
296061da546Spatrick return error;
297061da546Spatrick }
298061da546Spatrick
GetOption(int level,int option_name,int & option_value)299061da546Spatrick int Socket::GetOption(int level, int option_name, int &option_value) {
300061da546Spatrick get_socket_option_arg_type option_value_p =
301061da546Spatrick reinterpret_cast<get_socket_option_arg_type>(&option_value);
302061da546Spatrick socklen_t option_value_size = sizeof(int);
303061da546Spatrick return ::getsockopt(m_socket, level, option_name, option_value_p,
304061da546Spatrick &option_value_size);
305061da546Spatrick }
306061da546Spatrick
SetOption(int level,int option_name,int option_value)307061da546Spatrick int Socket::SetOption(int level, int option_name, int option_value) {
308061da546Spatrick set_socket_option_arg_type option_value_p =
309061da546Spatrick reinterpret_cast<get_socket_option_arg_type>(&option_value);
310061da546Spatrick return ::setsockopt(m_socket, level, option_name, option_value_p,
311061da546Spatrick sizeof(option_value));
312061da546Spatrick }
313061da546Spatrick
Send(const void * buf,const size_t num_bytes)314061da546Spatrick size_t Socket::Send(const void *buf, const size_t num_bytes) {
315061da546Spatrick return ::send(m_socket, static_cast<const char *>(buf), num_bytes, 0);
316061da546Spatrick }
317061da546Spatrick
SetLastError(Status & error)318061da546Spatrick void Socket::SetLastError(Status &error) {
319061da546Spatrick #if defined(_WIN32)
320061da546Spatrick error.SetError(::WSAGetLastError(), lldb::eErrorTypeWin32);
321061da546Spatrick #else
322061da546Spatrick error.SetErrorToErrno();
323061da546Spatrick #endif
324061da546Spatrick }
325061da546Spatrick
CreateSocket(const int domain,const int type,const int protocol,bool child_processes_inherit,Status & error)326061da546Spatrick NativeSocket Socket::CreateSocket(const int domain, const int type,
327061da546Spatrick const int protocol,
328061da546Spatrick bool child_processes_inherit, Status &error) {
329061da546Spatrick error.Clear();
330061da546Spatrick auto socket_type = type;
331061da546Spatrick #ifdef SOCK_CLOEXEC
332061da546Spatrick if (!child_processes_inherit)
333061da546Spatrick socket_type |= SOCK_CLOEXEC;
334061da546Spatrick #endif
335061da546Spatrick auto sock = ::socket(domain, socket_type, protocol);
336061da546Spatrick if (sock == kInvalidSocketValue)
337061da546Spatrick SetLastError(error);
338061da546Spatrick
339061da546Spatrick return sock;
340061da546Spatrick }
341061da546Spatrick
AcceptSocket(NativeSocket sockfd,struct sockaddr * addr,socklen_t * addrlen,bool child_processes_inherit,Status & error)342061da546Spatrick NativeSocket Socket::AcceptSocket(NativeSocket sockfd, struct sockaddr *addr,
343061da546Spatrick socklen_t *addrlen,
344061da546Spatrick bool child_processes_inherit, Status &error) {
345061da546Spatrick error.Clear();
346061da546Spatrick #if defined(ANDROID_USE_ACCEPT_WORKAROUND)
347061da546Spatrick // Hack:
348061da546Spatrick // This enables static linking lldb-server to an API 21 libc, but still
349061da546Spatrick // having it run on older devices. It is necessary because API 21 libc's
350061da546Spatrick // implementation of accept() uses the accept4 syscall(), which is not
351061da546Spatrick // available in older kernels. Using an older libc would fix this issue, but
352061da546Spatrick // introduce other ones, as the old libraries were quite buggy.
353061da546Spatrick int fd = syscall(__NR_accept, sockfd, addr, addrlen);
354061da546Spatrick if (fd >= 0 && !child_processes_inherit) {
355061da546Spatrick int flags = ::fcntl(fd, F_GETFD);
356061da546Spatrick if (flags != -1 && ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC) != -1)
357061da546Spatrick return fd;
358061da546Spatrick SetLastError(error);
359061da546Spatrick close(fd);
360061da546Spatrick }
361061da546Spatrick return fd;
362061da546Spatrick #elif defined(SOCK_CLOEXEC) && defined(HAVE_ACCEPT4)
363061da546Spatrick int flags = 0;
364061da546Spatrick if (!child_processes_inherit) {
365061da546Spatrick flags |= SOCK_CLOEXEC;
366061da546Spatrick }
367061da546Spatrick NativeSocket fd = llvm::sys::RetryAfterSignal(
368061da546Spatrick static_cast<NativeSocket>(-1), ::accept4, sockfd, addr, addrlen, flags);
369061da546Spatrick #else
370061da546Spatrick NativeSocket fd = llvm::sys::RetryAfterSignal(
371061da546Spatrick static_cast<NativeSocket>(-1), ::accept, sockfd, addr, addrlen);
372061da546Spatrick #endif
373061da546Spatrick if (fd == kInvalidSocketValue)
374061da546Spatrick SetLastError(error);
375061da546Spatrick return fd;
376061da546Spatrick }
377*f6aab3d8Srobert
operator <<(llvm::raw_ostream & OS,const Socket::HostAndPort & HP)378*f6aab3d8Srobert llvm::raw_ostream &lldb_private::operator<<(llvm::raw_ostream &OS,
379*f6aab3d8Srobert const Socket::HostAndPort &HP) {
380*f6aab3d8Srobert return OS << '[' << HP.hostname << ']' << ':' << HP.port;
381*f6aab3d8Srobert }
382