1275072Semaste//===-- Socket.cpp ----------------------------------------------*- C++ -*-===//
2275072Semaste//
3275072Semaste//                     The LLVM Compiler Infrastructure
4275072Semaste//
5275072Semaste// This file is distributed under the University of Illinois Open Source
6275072Semaste// License. See LICENSE.TXT for details.
7275072Semaste//
8275072Semaste//===----------------------------------------------------------------------===//
9275072Semaste
10275072Semaste#include "lldb/Host/Socket.h"
11275072Semaste
12275072Semaste#include "lldb/Core/Log.h"
13275072Semaste#include "lldb/Core/RegularExpression.h"
14275072Semaste#include "lldb/Host/Config.h"
15275072Semaste#include "lldb/Host/Host.h"
16275072Semaste#include "lldb/Host/SocketAddress.h"
17288943Sdim#include "lldb/Host/StringConvert.h"
18275072Semaste#include "lldb/Host/TimeValue.h"
19296417Sdim#include "lldb/Host/common/TCPSocket.h"
20296417Sdim#include "lldb/Host/common/UDPSocket.h"
21275072Semaste
22296417Sdim#ifndef LLDB_DISABLE_POSIX
23296417Sdim#include "lldb/Host/posix/DomainSocket.h"
24280031Sdim
25275072Semaste#include <arpa/inet.h>
26275072Semaste#include <netdb.h>
27275072Semaste#include <netinet/in.h>
28275072Semaste#include <netinet/tcp.h>
29275072Semaste#include <sys/socket.h>
30275072Semaste#include <sys/un.h>
31275072Semaste#endif
32275072Semaste
33296417Sdim#ifdef __linux__
34296417Sdim#include "lldb/Host/linux/AbstractSocket.h"
35296417Sdim#endif
36296417Sdim
37296417Sdim#ifdef __ANDROID_NDK__
38296417Sdim#include <linux/tcp.h>
39296417Sdim#include <bits/error_constants.h>
40296417Sdim#include <asm-generic/errno-base.h>
41296417Sdim#include <errno.h>
42296417Sdim#include <arpa/inet.h>
43296417Sdim#if defined(ANDROID_ARM_BUILD_STATIC) || defined(ANDROID_MIPS_BUILD_STATIC)
44296417Sdim#include <unistd.h>
45296417Sdim#include <sys/syscall.h>
46296417Sdim#include <fcntl.h>
47296417Sdim#endif // ANDROID_ARM_BUILD_STATIC || ANDROID_MIPS_BUILD_STATIC
48296417Sdim#endif // __ANDROID_NDK__
49296417Sdim
50275072Semasteusing namespace lldb;
51275072Semasteusing namespace lldb_private;
52275072Semaste
53275072Semaste#if defined(_WIN32)
54275072Semastetypedef const char * set_socket_option_arg_type;
55275072Semastetypedef char * get_socket_option_arg_type;
56275072Semasteconst NativeSocket Socket::kInvalidSocketValue = INVALID_SOCKET;
57275072Semaste#else // #if defined(_WIN32)
58275072Semastetypedef const void * set_socket_option_arg_type;
59275072Semastetypedef void * get_socket_option_arg_type;
60275072Semasteconst NativeSocket Socket::kInvalidSocketValue = -1;
61275072Semaste#endif // #if defined(_WIN32)
62275072Semaste
63280031Sdimnamespace {
64280031Sdim
65288943Sdimbool IsInterrupted()
66288943Sdim{
67288943Sdim#if defined(_WIN32)
68288943Sdim    return ::WSAGetLastError() == WSAEINTR;
69288943Sdim#else
70288943Sdim    return errno == EINTR;
71288943Sdim#endif
72288943Sdim}
73288943Sdim
74288943Sdim}
75288943Sdim
76275072SemasteSocket::Socket(NativeSocket socket, SocketProtocol protocol, bool should_close)
77275072Semaste    : IOObject(eFDTypeSocket, should_close)
78275072Semaste    , m_protocol(protocol)
79275072Semaste    , m_socket(socket)
80275072Semaste{
81275072Semaste
82275072Semaste}
83275072Semaste
84275072SemasteSocket::~Socket()
85275072Semaste{
86275072Semaste    Close();
87275072Semaste}
88275072Semaste
89296417Sdimstd::unique_ptr<Socket> Socket::Create(const SocketProtocol protocol, bool child_processes_inherit, Error &error)
90275072Semaste{
91296417Sdim    error.Clear();
92275072Semaste
93296417Sdim    std::unique_ptr<Socket> socket_up;
94296417Sdim    switch (protocol)
95275072Semaste    {
96296417Sdim    case ProtocolTcp:
97296417Sdim        socket_up.reset(new TCPSocket(child_processes_inherit, error));
98296417Sdim        break;
99296417Sdim    case ProtocolUdp:
100296417Sdim        socket_up.reset(new UDPSocket(child_processes_inherit, error));
101296417Sdim        break;
102296417Sdim    case ProtocolUnixDomain:
103296417Sdim#ifndef LLDB_DISABLE_POSIX
104296417Sdim        socket_up.reset(new DomainSocket(child_processes_inherit, error));
105296417Sdim#else
106296417Sdim        error.SetErrorString("Unix domain sockets are not supported on this platform.");
107296417Sdim#endif
108296417Sdim        break;
109296417Sdim    case ProtocolUnixAbstract:
110296417Sdim#ifdef __linux__
111296417Sdim        socket_up.reset(new AbstractSocket(child_processes_inherit, error));
112296417Sdim#else
113296417Sdim        error.SetErrorString("Abstract domain sockets are not supported on this platform.");
114296417Sdim#endif
115296417Sdim        break;
116275072Semaste    }
117275072Semaste
118296417Sdim    if (error.Fail())
119296417Sdim        socket_up.reset();
120275072Semaste
121296417Sdim    return socket_up;
122296417Sdim}
123275072Semaste
124296417SdimError Socket::TcpConnect(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&socket)
125296417Sdim{
126296417Sdim    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION));
127296417Sdim    if (log)
128296417Sdim        log->Printf ("Socket::%s (host/port = %s)", __FUNCTION__, host_and_port.data());
129275072Semaste
130296417Sdim    Error error;
131296417Sdim    std::unique_ptr<Socket> connect_socket(Create(ProtocolTcp, child_processes_inherit, error));
132296417Sdim    if (error.Fail())
133296417Sdim        return error;
134275072Semaste
135296417Sdim    error = connect_socket->Connect(host_and_port);
136296417Sdim    if (error.Success())
137296417Sdim      socket = connect_socket.release();
138275072Semaste
139275072Semaste    return error;
140275072Semaste}
141275072Semaste
142296417SdimError
143296417SdimSocket::TcpListen (llvm::StringRef host_and_port,
144296417Sdim                   bool child_processes_inherit,
145296417Sdim                   Socket *&socket,
146296417Sdim                   Predicate<uint16_t>* predicate,
147296417Sdim                   int backlog)
148275072Semaste{
149275072Semaste    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
150275072Semaste    if (log)
151296417Sdim        log->Printf ("Socket::%s (%s)", __FUNCTION__, host_and_port.data());
152275072Semaste
153296417Sdim    Error error;
154275072Semaste    std::string host_str;
155275072Semaste    std::string port_str;
156275072Semaste    int32_t port = INT32_MIN;
157275072Semaste    if (!DecodeHostAndPort (host_and_port, host_str, port_str, port, &error))
158275072Semaste        return error;
159275072Semaste
160296417Sdim    std::unique_ptr<TCPSocket> listen_socket(new TCPSocket(child_processes_inherit, error));
161296417Sdim    if (error.Fail())
162296417Sdim        return error;
163296417Sdim
164296417Sdim    error = listen_socket->Listen(host_and_port, backlog);
165296417Sdim    if (error.Success())
166275072Semaste    {
167275072Semaste        // We were asked to listen on port zero which means we
168275072Semaste        // must now read the actual port that was given to us
169275072Semaste        // as port zero is a special code for "find an open port
170275072Semaste        // for me".
171275072Semaste        if (port == 0)
172288943Sdim            port = listen_socket->GetLocalPortNumber();
173275072Semaste
174275072Semaste        // Set the port predicate since when doing a listen://<host>:<port>
175275072Semaste        // it often needs to accept the incoming connection which is a blocking
176275072Semaste        // system call. Allowing access to the bound port using a predicate allows
177275072Semaste        // us to wait for the port predicate to be set to a non-zero value from
178275072Semaste        // another thread in an efficient manor.
179275072Semaste        if (predicate)
180288943Sdim            predicate->SetValue (port, eBroadcastAlways);
181275072Semaste        socket = listen_socket.release();
182275072Semaste    }
183275072Semaste
184275072Semaste    return error;
185275072Semaste}
186275072Semaste
187296417SdimError Socket::UdpConnect(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&send_socket, Socket *&recv_socket)
188275072Semaste{
189296417Sdim    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
190296417Sdim    if (log)
191296417Sdim        log->Printf ("Socket::%s (host/port = %s)", __FUNCTION__, host_and_port.data());
192296417Sdim
193296417Sdim    return UDPSocket::Connect(host_and_port, child_processes_inherit, send_socket, recv_socket);
194296417Sdim}
195296417Sdim
196296417SdimError Socket::UnixDomainConnect(llvm::StringRef name, bool child_processes_inherit, Socket *&socket)
197296417Sdim{
198275072Semaste    Error error;
199296417Sdim    std::unique_ptr<Socket> connect_socket(Create(ProtocolUnixDomain, child_processes_inherit, error));
200296417Sdim    if (error.Fail())
201275072Semaste        return error;
202275072Semaste
203296417Sdim    error = connect_socket->Connect(name);
204296417Sdim    if (error.Success())
205296417Sdim      socket = connect_socket.release();
206275072Semaste
207275072Semaste    return error;
208275072Semaste}
209275072Semaste
210296417SdimError Socket::UnixDomainAccept(llvm::StringRef name, bool child_processes_inherit, Socket *&socket)
211275072Semaste{
212275072Semaste    Error error;
213296417Sdim    std::unique_ptr<Socket> listen_socket(Create(ProtocolUnixDomain, child_processes_inherit, error));
214296417Sdim    if (error.Fail())
215275072Semaste        return error;
216275072Semaste
217296417Sdim    error = listen_socket->Listen(name, 5);
218275072Semaste    if (error.Fail())
219275072Semaste        return error;
220275072Semaste
221296417Sdim    error = listen_socket->Accept(name, child_processes_inherit, socket);
222275072Semaste    return error;
223275072Semaste}
224275072Semaste
225296417SdimError
226296417SdimSocket::UnixAbstractConnect(llvm::StringRef name, bool child_processes_inherit, Socket *&socket)
227275072Semaste{
228275072Semaste    Error error;
229296417Sdim    std::unique_ptr<Socket> connect_socket(Create(ProtocolUnixAbstract, child_processes_inherit, error));
230296417Sdim    if (error.Fail())
231275072Semaste        return error;
232275072Semaste
233296417Sdim    error = connect_socket->Connect(name);
234296417Sdim    if (error.Success())
235296417Sdim      socket = connect_socket.release();
236275072Semaste    return error;
237275072Semaste}
238275072Semaste
239296417SdimError
240296417SdimSocket::UnixAbstractAccept(llvm::StringRef name, bool child_processes_inherit, Socket *&socket)
241275072Semaste{
242275072Semaste    Error error;
243296417Sdim    std::unique_ptr<Socket> listen_socket(Create(ProtocolUnixAbstract,child_processes_inherit, error));
244296417Sdim    if (error.Fail())
245275072Semaste        return error;
246275072Semaste
247296417Sdim    error = listen_socket->Listen(name, 5);
248296417Sdim    if (error.Fail())
249275072Semaste        return error;
250275072Semaste
251296417Sdim    error = listen_socket->Accept(name, child_processes_inherit, socket);
252275072Semaste    return error;
253275072Semaste}
254275072Semaste
255275072Semastebool
256275072SemasteSocket::DecodeHostAndPort(llvm::StringRef host_and_port,
257275072Semaste                          std::string &host_str,
258275072Semaste                          std::string &port_str,
259275072Semaste                          int32_t& port,
260275072Semaste                          Error *error_ptr)
261275072Semaste{
262275072Semaste    static RegularExpression g_regex ("([^:]+):([0-9]+)");
263275072Semaste    RegularExpression::Match regex_match(2);
264275072Semaste    if (g_regex.Execute (host_and_port.data(), &regex_match))
265275072Semaste    {
266275072Semaste        if (regex_match.GetMatchAtIndex (host_and_port.data(), 1, host_str) &&
267275072Semaste            regex_match.GetMatchAtIndex (host_and_port.data(), 2, port_str))
268275072Semaste        {
269288943Sdim            bool ok = false;
270288943Sdim            port = StringConvert::ToUInt32 (port_str.c_str(), UINT32_MAX, 10, &ok);
271288943Sdim            if (ok && port < UINT16_MAX)
272275072Semaste            {
273275072Semaste                if (error_ptr)
274275072Semaste                    error_ptr->Clear();
275275072Semaste                return true;
276275072Semaste            }
277288943Sdim            // port is too large
278288943Sdim            if (error_ptr)
279288943Sdim                error_ptr->SetErrorStringWithFormat("invalid host:port specification: '%s'", host_and_port.data());
280288943Sdim            return false;
281275072Semaste        }
282275072Semaste    }
283275072Semaste
284275072Semaste    // If this was unsuccessful, then check if it's simply a signed 32-bit integer, representing
285275072Semaste    // a port with an empty host.
286275072Semaste    host_str.clear();
287275072Semaste    port_str.clear();
288288943Sdim    bool ok = false;
289288943Sdim    port = StringConvert::ToUInt32 (host_and_port.data(), UINT32_MAX, 10, &ok);
290288943Sdim    if (ok && port < UINT16_MAX)
291275072Semaste    {
292275072Semaste        port_str = host_and_port;
293288943Sdim        if (error_ptr)
294288943Sdim            error_ptr->Clear();
295275072Semaste        return true;
296275072Semaste    }
297275072Semaste
298275072Semaste    if (error_ptr)
299275072Semaste        error_ptr->SetErrorStringWithFormat("invalid host:port specification: '%s'", host_and_port.data());
300275072Semaste    return false;
301275072Semaste}
302275072Semaste
303275072SemasteIOObject::WaitableHandle Socket::GetWaitableHandle()
304275072Semaste{
305275072Semaste    // TODO: On Windows, use WSAEventSelect
306275072Semaste    return m_socket;
307275072Semaste}
308275072Semaste
309275072SemasteError Socket::Read (void *buf, size_t &num_bytes)
310275072Semaste{
311275072Semaste    Error error;
312275072Semaste    int bytes_received = 0;
313275072Semaste    do
314275072Semaste    {
315275072Semaste        bytes_received = ::recv (m_socket, static_cast<char *>(buf), num_bytes, 0);
316288943Sdim    } while (bytes_received < 0 && IsInterrupted ());
317275072Semaste
318275072Semaste    if (bytes_received < 0)
319275072Semaste    {
320288943Sdim        SetLastError (error);
321275072Semaste        num_bytes = 0;
322275072Semaste    }
323275072Semaste    else
324275072Semaste        num_bytes = bytes_received;
325275072Semaste
326296417Sdim    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION));
327275072Semaste    if (log)
328275072Semaste    {
329275072Semaste        log->Printf ("%p Socket::Read() (socket = %" PRIu64 ", src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64 " (error = %s)",
330275072Semaste                     static_cast<void*>(this),
331275072Semaste                     static_cast<uint64_t>(m_socket),
332275072Semaste                     buf,
333275072Semaste                     static_cast<uint64_t>(num_bytes),
334275072Semaste                     static_cast<int64_t>(bytes_received),
335275072Semaste                     error.AsCString());
336275072Semaste    }
337275072Semaste
338275072Semaste    return error;
339275072Semaste}
340275072Semaste
341275072SemasteError Socket::Write (const void *buf, size_t &num_bytes)
342275072Semaste{
343275072Semaste    Error error;
344275072Semaste    int bytes_sent = 0;
345275072Semaste    do
346275072Semaste    {
347296417Sdim        bytes_sent = Send(buf, num_bytes);
348288943Sdim    } while (bytes_sent < 0 && IsInterrupted ());
349275072Semaste
350275072Semaste    if (bytes_sent < 0)
351275072Semaste    {
352288943Sdim        SetLastError (error);
353275072Semaste        num_bytes = 0;
354275072Semaste    }
355275072Semaste    else
356275072Semaste        num_bytes = bytes_sent;
357275072Semaste
358296417Sdim    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION));
359275072Semaste    if (log)
360275072Semaste    {
361275072Semaste        log->Printf ("%p Socket::Write() (socket = %" PRIu64 ", src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64 " (error = %s)",
362275072Semaste                        static_cast<void*>(this),
363275072Semaste                        static_cast<uint64_t>(m_socket),
364275072Semaste                        buf,
365275072Semaste                        static_cast<uint64_t>(num_bytes),
366275072Semaste                        static_cast<int64_t>(bytes_sent),
367275072Semaste                        error.AsCString());
368275072Semaste    }
369275072Semaste
370275072Semaste    return error;
371275072Semaste}
372275072Semaste
373275072SemasteError Socket::PreDisconnect()
374275072Semaste{
375275072Semaste    Error error;
376275072Semaste    return error;
377275072Semaste}
378275072Semaste
379275072SemasteError Socket::Close()
380275072Semaste{
381275072Semaste    Error error;
382275072Semaste    if (!IsValid() || !m_should_close_fd)
383275072Semaste        return error;
384275072Semaste
385275072Semaste    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
386275072Semaste    if (log)
387275072Semaste        log->Printf ("%p Socket::Close (fd = %i)", static_cast<void*>(this), m_socket);
388275072Semaste
389275072Semaste#if defined(_WIN32)
390275072Semaste    bool success = !!closesocket(m_socket);
391275072Semaste#else
392275072Semaste    bool success = !!::close (m_socket);
393275072Semaste#endif
394275072Semaste    // A reference to a FD was passed in, set it to an invalid value
395275072Semaste    m_socket = kInvalidSocketValue;
396275072Semaste    if (!success)
397275072Semaste    {
398288943Sdim        SetLastError (error);
399275072Semaste    }
400275072Semaste
401275072Semaste    return error;
402275072Semaste}
403275072Semaste
404275072Semaste
405275072Semasteint Socket::GetOption(int level, int option_name, int &option_value)
406275072Semaste{
407275072Semaste    get_socket_option_arg_type option_value_p = reinterpret_cast<get_socket_option_arg_type>(&option_value);
408275072Semaste    socklen_t option_value_size = sizeof(int);
409296417Sdim    return ::getsockopt(m_socket, level, option_name, option_value_p, &option_value_size);
410275072Semaste}
411275072Semaste
412275072Semasteint Socket::SetOption(int level, int option_name, int option_value)
413275072Semaste{
414275072Semaste    set_socket_option_arg_type option_value_p = reinterpret_cast<get_socket_option_arg_type>(&option_value);
415296417Sdim    return ::setsockopt(m_socket, level, option_name, option_value_p, sizeof(option_value));
416275072Semaste}
417275072Semaste
418296417Sdimsize_t Socket::Send(const void *buf, const size_t num_bytes)
419275072Semaste{
420296417Sdim    return ::send (m_socket, static_cast<const char *>(buf), num_bytes, 0);
421275072Semaste}
422275072Semaste
423296417Sdimvoid Socket::SetLastError(Error &error)
424275072Semaste{
425296417Sdim#if defined(_WIN32)
426296417Sdim    error.SetError(::WSAGetLastError(), lldb::eErrorTypeWin32);
427296417Sdim#else
428296417Sdim    error.SetErrorToErrno();
429296417Sdim#endif
430275072Semaste}
431288943Sdim
432296417SdimNativeSocket
433296417SdimSocket::CreateSocket(const int domain,
434296417Sdim                     const int type,
435296417Sdim                     const int protocol,
436296417Sdim                     bool child_processes_inherit,
437296417Sdim                     Error& error)
438288943Sdim{
439296417Sdim    error.Clear();
440296417Sdim    auto socketType = type;
441296417Sdim#ifdef SOCK_CLOEXEC
442296417Sdim    if (!child_processes_inherit)
443296417Sdim        socketType |= SOCK_CLOEXEC;
444296417Sdim#endif
445296417Sdim    auto sock = ::socket (domain, socketType, protocol);
446296417Sdim    if (sock == kInvalidSocketValue)
447296417Sdim        SetLastError(error);
448288943Sdim
449296417Sdim    return sock;
450288943Sdim}
451288943Sdim
452296417SdimNativeSocket
453296417SdimSocket::AcceptSocket(NativeSocket sockfd,
454296417Sdim                     struct sockaddr *addr,
455296417Sdim                     socklen_t *addrlen,
456296417Sdim                     bool child_processes_inherit,
457296417Sdim                     Error& error)
458288943Sdim{
459296417Sdim    error.Clear();
460296417Sdim#if defined(ANDROID_ARM_BUILD_STATIC) || defined(ANDROID_MIPS_BUILD_STATIC)
461296417Sdim    // Temporary workaround for statically linking Android lldb-server with the
462296417Sdim    // latest API.
463296417Sdim    int fd = syscall(__NR_accept, sockfd, addr, addrlen);
464296417Sdim    if (fd >= 0 && !child_processes_inherit)
465288943Sdim    {
466296417Sdim        int flags = ::fcntl(fd, F_GETFD);
467296417Sdim        if (flags != -1 && ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC) != -1)
468296417Sdim            return fd;
469296417Sdim        SetLastError(error);
470296417Sdim        close(fd);
471288943Sdim    }
472296417Sdim    return fd;
473296417Sdim#elif defined(SOCK_CLOEXEC)
474296417Sdim    int flags = 0;
475296417Sdim    if (!child_processes_inherit) {
476296417Sdim        flags |= SOCK_CLOEXEC;
477296417Sdim    }
478296417Sdim#if defined(__NetBSD__)
479296417Sdim    NativeSocket fd = ::paccept (sockfd, addr, addrlen, nullptr, flags);
480296417Sdim#else
481296417Sdim    NativeSocket fd = ::accept4 (sockfd, addr, addrlen, flags);
482296417Sdim#endif
483296417Sdim#else
484296417Sdim    NativeSocket fd = ::accept (sockfd, addr, addrlen);
485296417Sdim#endif
486296417Sdim    if (fd == kInvalidSocketValue)
487296417Sdim        SetLastError(error);
488296417Sdim    return fd;
489288943Sdim}
490