1 //===-- Socket.cpp ----------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/Host/Socket.h"
11 
12 #include "lldb/Core/Log.h"
13 #include "lldb/Core/RegularExpression.h"
14 #include "lldb/Host/Config.h"
15 #include "lldb/Host/Host.h"
16 #include "lldb/Host/SocketAddress.h"
17 #include "lldb/Host/StringConvert.h"
18 #include "lldb/Host/TimeValue.h"
19 #include "lldb/Host/common/TCPSocket.h"
20 #include "lldb/Host/common/UDPSocket.h"
21 
22 #ifndef LLDB_DISABLE_POSIX
23 #include "lldb/Host/posix/DomainSocket.h"
24 
25 #include <arpa/inet.h>
26 #include <netdb.h>
27 #include <netinet/in.h>
28 #include <netinet/tcp.h>
29 #include <sys/socket.h>
30 #include <sys/un.h>
31 #endif
32 
33 #ifdef __linux__
34 #include "lldb/Host/linux/AbstractSocket.h"
35 #endif
36 
37 #ifdef __ANDROID_NDK__
38 #include <linux/tcp.h>
39 #include <bits/error_constants.h>
40 #include <asm-generic/errno-base.h>
41 #include <errno.h>
42 #include <arpa/inet.h>
43 #if defined(ANDROID_ARM_BUILD_STATIC)
44 #include <unistd.h>
45 #include <sys/syscall.h>
46 #include <fcntl.h>
47 #endif // ANDROID_ARM_BUILD_STATIC
48 #endif // __ANDROID_NDK__
49 
50 using namespace lldb;
51 using namespace lldb_private;
52 
53 #if defined(_WIN32)
54 typedef const char * set_socket_option_arg_type;
55 typedef char * get_socket_option_arg_type;
56 const NativeSocket Socket::kInvalidSocketValue = INVALID_SOCKET;
57 #else // #if defined(_WIN32)
58 typedef const void * set_socket_option_arg_type;
59 typedef void * get_socket_option_arg_type;
60 const NativeSocket Socket::kInvalidSocketValue = -1;
61 #endif // #if defined(_WIN32)
62 
63 namespace {
64 
65 bool IsInterrupted()
66 {
67 #if defined(_WIN32)
68     return ::WSAGetLastError() == WSAEINTR;
69 #else
70     return errno == EINTR;
71 #endif
72 }
73 
74 }
75 
76 Socket::Socket(NativeSocket socket, SocketProtocol protocol, bool should_close)
77     : IOObject(eFDTypeSocket, should_close)
78     , m_protocol(protocol)
79     , m_socket(socket)
80 {
81 
82 }
83 
84 Socket::~Socket()
85 {
86     Close();
87 }
88 
89 Error Socket::TcpConnect(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&socket)
90 {
91     Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION));
92     if (log)
93         log->Printf ("Socket::%s (host/port = %s)", __FUNCTION__, host_and_port.data());
94 
95     Error error;
96     std::unique_ptr<TCPSocket> connect_socket(new TCPSocket(child_processes_inherit, error));
97     if (error.Fail())
98         return error;
99 
100     error = connect_socket->Connect(host_and_port);
101     if (error.Success())
102       socket = connect_socket.release();
103 
104     return error;
105 }
106 
107 Error
108 Socket::TcpListen (llvm::StringRef host_and_port,
109                    bool child_processes_inherit,
110                    Socket *&socket,
111                    Predicate<uint16_t>* predicate,
112                    int backlog)
113 {
114     Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
115     if (log)
116         log->Printf ("Socket::%s (%s)", __FUNCTION__, host_and_port.data());
117 
118     Error error;
119     std::string host_str;
120     std::string port_str;
121     int32_t port = INT32_MIN;
122     if (!DecodeHostAndPort (host_and_port, host_str, port_str, port, &error))
123         return error;
124 
125     std::unique_ptr<TCPSocket> listen_socket(new TCPSocket(child_processes_inherit, error));
126     if (error.Fail())
127         return error;
128 
129     error = listen_socket->Listen(host_and_port, backlog);
130     if (error.Success())
131     {
132         // We were asked to listen on port zero which means we
133         // must now read the actual port that was given to us
134         // as port zero is a special code for "find an open port
135         // for me".
136         if (port == 0)
137             port = listen_socket->GetLocalPortNumber();
138 
139         // Set the port predicate since when doing a listen://<host>:<port>
140         // it often needs to accept the incoming connection which is a blocking
141         // system call. Allowing access to the bound port using a predicate allows
142         // us to wait for the port predicate to be set to a non-zero value from
143         // another thread in an efficient manor.
144         if (predicate)
145             predicate->SetValue (port, eBroadcastAlways);
146         socket = listen_socket.release();
147     }
148 
149     return error;
150 }
151 
152 Error Socket::UdpConnect(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&send_socket, Socket *&recv_socket)
153 {
154     Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
155     if (log)
156         log->Printf ("Socket::%s (host/port = %s)", __FUNCTION__, host_and_port.data());
157 
158     return UDPSocket::Connect(host_and_port, child_processes_inherit, send_socket, recv_socket);
159 }
160 
161 Error Socket::UnixDomainConnect(llvm::StringRef name, bool child_processes_inherit, Socket *&socket)
162 {
163     Error error;
164 #ifndef LLDB_DISABLE_POSIX
165     std::unique_ptr<DomainSocket> connect_socket(new DomainSocket(child_processes_inherit, error));
166     if (error.Fail())
167         return error;
168 
169     error = connect_socket->Connect(name);
170     if (error.Success())
171       socket = connect_socket.release();
172 #else
173     error.SetErrorString("Unix domain sockets are not supported on this platform.");
174 #endif
175     return error;
176 }
177 
178 Error Socket::UnixDomainAccept(llvm::StringRef name, bool child_processes_inherit, Socket *&socket)
179 {
180     Error error;
181 #ifndef LLDB_DISABLE_POSIX
182     std::unique_ptr<DomainSocket> listen_socket(new DomainSocket(child_processes_inherit, error));
183     if (error.Fail())
184         return error;
185 
186     error = listen_socket->Listen(name, 5);
187     if (error.Fail())
188         return error;
189 
190     error = listen_socket->Accept(name, child_processes_inherit, socket);
191 #else
192     error.SetErrorString("Unix domain sockets are not supported on this platform.");
193 #endif
194     return error;
195 }
196 
197 Error
198 Socket::UnixAbstractConnect(llvm::StringRef name, bool child_processes_inherit, Socket *&socket)
199 {
200     Error error;
201 #ifdef __linux__
202     std::unique_ptr<Socket> connect_socket(new AbstractSocket(child_processes_inherit, error));
203     if (error.Fail())
204         return error;
205 
206     error = connect_socket->Connect(name);
207     if (error.Success())
208       socket = connect_socket.release();
209 #else
210     error.SetErrorString("Abstract domain sockets are not supported on this platform.");
211 #endif
212     return error;
213 }
214 
215 Error
216 Socket::UnixAbstractAccept(llvm::StringRef name, bool child_processes_inherit, Socket *&socket)
217 {
218     Error error;
219 #ifdef __linux__
220     std::unique_ptr<Socket> listen_socket(new AbstractSocket(child_processes_inherit, error));
221     if (error.Fail())
222         return error;
223 
224     error = listen_socket->Listen(name, 5);
225     if (error.Fail())
226         return error;
227 
228     error = listen_socket->Accept(name, child_processes_inherit, socket);
229 #else
230     error.SetErrorString("Abstract domain sockets are not supported on this platform.");
231 #endif
232     return error;
233 }
234 
235 bool
236 Socket::DecodeHostAndPort(llvm::StringRef host_and_port,
237                           std::string &host_str,
238                           std::string &port_str,
239                           int32_t& port,
240                           Error *error_ptr)
241 {
242     static RegularExpression g_regex ("([^:]+):([0-9]+)");
243     RegularExpression::Match regex_match(2);
244     if (g_regex.Execute (host_and_port.data(), &regex_match))
245     {
246         if (regex_match.GetMatchAtIndex (host_and_port.data(), 1, host_str) &&
247             regex_match.GetMatchAtIndex (host_and_port.data(), 2, port_str))
248         {
249             bool ok = false;
250             port = StringConvert::ToUInt32 (port_str.c_str(), UINT32_MAX, 10, &ok);
251             if (ok && port < UINT16_MAX)
252             {
253                 if (error_ptr)
254                     error_ptr->Clear();
255                 return true;
256             }
257             // port is too large
258             if (error_ptr)
259                 error_ptr->SetErrorStringWithFormat("invalid host:port specification: '%s'", host_and_port.data());
260             return false;
261         }
262     }
263 
264     // If this was unsuccessful, then check if it's simply a signed 32-bit integer, representing
265     // a port with an empty host.
266     host_str.clear();
267     port_str.clear();
268     bool ok = false;
269     port = StringConvert::ToUInt32 (host_and_port.data(), UINT32_MAX, 10, &ok);
270     if (ok && port < UINT16_MAX)
271     {
272         port_str = host_and_port;
273         if (error_ptr)
274             error_ptr->Clear();
275         return true;
276     }
277 
278     if (error_ptr)
279         error_ptr->SetErrorStringWithFormat("invalid host:port specification: '%s'", host_and_port.data());
280     return false;
281 }
282 
283 IOObject::WaitableHandle Socket::GetWaitableHandle()
284 {
285     // TODO: On Windows, use WSAEventSelect
286     return m_socket;
287 }
288 
289 Error Socket::Read (void *buf, size_t &num_bytes)
290 {
291     Error error;
292     int bytes_received = 0;
293     do
294     {
295         bytes_received = ::recv (m_socket, static_cast<char *>(buf), num_bytes, 0);
296     } while (bytes_received < 0 && IsInterrupted ());
297 
298     if (bytes_received < 0)
299     {
300         SetLastError (error);
301         num_bytes = 0;
302     }
303     else
304         num_bytes = bytes_received;
305 
306     Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION));
307     if (log)
308     {
309         log->Printf ("%p Socket::Read() (socket = %" PRIu64 ", src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64 " (error = %s)",
310                      static_cast<void*>(this),
311                      static_cast<uint64_t>(m_socket),
312                      buf,
313                      static_cast<uint64_t>(num_bytes),
314                      static_cast<int64_t>(bytes_received),
315                      error.AsCString());
316     }
317 
318     return error;
319 }
320 
321 Error Socket::Write (const void *buf, size_t &num_bytes)
322 {
323     Error error;
324     int bytes_sent = 0;
325     do
326     {
327         bytes_sent = Send(buf, num_bytes);
328     } while (bytes_sent < 0 && IsInterrupted ());
329 
330     if (bytes_sent < 0)
331     {
332         SetLastError (error);
333         num_bytes = 0;
334     }
335     else
336         num_bytes = bytes_sent;
337 
338     Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION));
339     if (log)
340     {
341         log->Printf ("%p Socket::Write() (socket = %" PRIu64 ", src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64 " (error = %s)",
342                         static_cast<void*>(this),
343                         static_cast<uint64_t>(m_socket),
344                         buf,
345                         static_cast<uint64_t>(num_bytes),
346                         static_cast<int64_t>(bytes_sent),
347                         error.AsCString());
348     }
349 
350     return error;
351 }
352 
353 Error Socket::PreDisconnect()
354 {
355     Error error;
356     return error;
357 }
358 
359 Error Socket::Close()
360 {
361     Error error;
362     if (!IsValid() || !m_should_close_fd)
363         return error;
364 
365     Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
366     if (log)
367         log->Printf ("%p Socket::Close (fd = %i)", static_cast<void*>(this), m_socket);
368 
369 #if defined(_WIN32)
370     bool success = !!closesocket(m_socket);
371 #else
372     bool success = !!::close (m_socket);
373 #endif
374     // A reference to a FD was passed in, set it to an invalid value
375     m_socket = kInvalidSocketValue;
376     if (!success)
377     {
378         SetLastError (error);
379     }
380 
381     return error;
382 }
383 
384 
385 int Socket::GetOption(int level, int option_name, int &option_value)
386 {
387     get_socket_option_arg_type option_value_p = reinterpret_cast<get_socket_option_arg_type>(&option_value);
388     socklen_t option_value_size = sizeof(int);
389     return ::getsockopt(m_socket, level, option_name, option_value_p, &option_value_size);
390 }
391 
392 int Socket::SetOption(int level, int option_name, int option_value)
393 {
394     set_socket_option_arg_type option_value_p = reinterpret_cast<get_socket_option_arg_type>(&option_value);
395     return ::setsockopt(m_socket, level, option_name, option_value_p, sizeof(option_value));
396 }
397 
398 size_t Socket::Send(const void *buf, const size_t num_bytes)
399 {
400     return ::send (m_socket, static_cast<const char *>(buf), num_bytes, 0);
401 }
402 
403 void Socket::SetLastError(Error &error)
404 {
405 #if defined(_WIN32)
406     error.SetError(::WSAGetLastError(), lldb::eErrorTypeWin32);
407 #else
408     error.SetErrorToErrno();
409 #endif
410 }
411 
412 NativeSocket
413 Socket::CreateSocket(const int domain,
414                      const int type,
415                      const int protocol,
416                      bool child_processes_inherit,
417                      Error& error)
418 {
419     error.Clear();
420     auto socketType = type;
421 #ifdef SOCK_CLOEXEC
422     if (!child_processes_inherit)
423         socketType |= SOCK_CLOEXEC;
424 #endif
425     auto sock = ::socket (domain, socketType, protocol);
426     if (sock == kInvalidSocketValue)
427         SetLastError(error);
428 
429     return sock;
430 }
431 
432 NativeSocket
433 Socket::AcceptSocket(NativeSocket sockfd,
434                      struct sockaddr *addr,
435                      socklen_t *addrlen,
436                      bool child_processes_inherit,
437                      Error& error)
438 {
439     error.Clear();
440 #if defined(ANDROID_ARM_BUILD_STATIC)
441     // Temporary workaround for statically linking Android lldb-server with the
442     // latest API.
443     int fd = syscall(__NR_accept, sockfd, addr, addrlen);
444     if (fd >= 0 && !child_processes_inherit)
445     {
446         int flags = ::fcntl(fd, F_GETFD);
447         if (flags != -1 && ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC) != -1)
448             return fd;
449         SetLastError(error);
450         close(fd);
451     }
452     return fd;
453 #elif defined(SOCK_CLOEXEC)
454     int flags = 0;
455     if (!child_processes_inherit) {
456         flags |= SOCK_CLOEXEC;
457     }
458 #if defined(__NetBSD__)
459     NativeSocket fd = ::paccept (sockfd, addr, addrlen, nullptr, flags);
460 #else
461     NativeSocket fd = ::accept4 (sockfd, addr, addrlen, flags);
462 #endif
463 #else
464     NativeSocket fd = ::accept (sockfd, addr, addrlen);
465 #endif
466     if (fd == kInvalidSocketValue)
467         SetLastError(error);
468     return fd;
469 }
470