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/FileSystem.h"
16 #include "lldb/Host/Host.h"
17 #include "lldb/Host/SocketAddress.h"
18 #include "lldb/Host/StringConvert.h"
19 #include "lldb/Host/TimeValue.h"
20 
21 #ifdef __ANDROID_NDK__
22 #include <linux/tcp.h>
23 #include <bits/error_constants.h>
24 #include <asm-generic/errno-base.h>
25 #include <errno.h>
26 #include <arpa/inet.h>
27 #if defined(ANDROID_ARM_BUILD_STATIC)
28 #include <unistd.h>
29 #include <sys/syscall.h>
30 #include <fcntl.h>
31 #endif // ANDROID_ARM_BUILD_STATIC
32 #endif // __ANDROID_NDK__
33 
34 #ifndef LLDB_DISABLE_POSIX
35 #include <arpa/inet.h>
36 #include <netdb.h>
37 #include <netinet/in.h>
38 #include <netinet/tcp.h>
39 #include <sys/socket.h>
40 #include <sys/un.h>
41 #endif
42 
43 using namespace lldb;
44 using namespace lldb_private;
45 
46 #if defined(_WIN32)
47 typedef const char * set_socket_option_arg_type;
48 typedef char * get_socket_option_arg_type;
49 const NativeSocket Socket::kInvalidSocketValue = INVALID_SOCKET;
50 #else // #if defined(_WIN32)
51 typedef const void * set_socket_option_arg_type;
52 typedef void * get_socket_option_arg_type;
53 const NativeSocket Socket::kInvalidSocketValue = -1;
54 #endif // #if defined(_WIN32)
55 
56 #ifdef __ANDROID__
57 // Android does not have SUN_LEN
58 #ifndef SUN_LEN
59 #define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) + strlen((ptr)->sun_path))
60 #endif
61 #endif // #ifdef __ANDROID__
62 
63 namespace {
64 
65 NativeSocket CreateSocket(const int domain, const int type, const int protocol, bool child_processes_inherit)
66 {
67     auto socketType = type;
68 #ifdef SOCK_CLOEXEC
69     if (!child_processes_inherit) {
70         socketType |= SOCK_CLOEXEC;
71     }
72 #endif
73     return ::socket (domain, socketType, protocol);
74 }
75 
76 NativeSocket Accept(NativeSocket sockfd, struct sockaddr *addr, socklen_t *addrlen, bool child_processes_inherit)
77 {
78 #if defined(ANDROID_ARM_BUILD_STATIC)
79 	// Temporary workaround for statically linking Android lldb-server with the
80 	// latest API.
81 	int fd = syscall(__NR_accept, sockfd, addr, addrlen);
82 	if (fd >= 0 && !child_processes_inherit)
83 	{
84 		int flags = ::fcntl(fd, F_GETFD);
85 		if (flags == -1)
86 			return -1;
87 		if (::fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
88 			return -1;
89 	}
90 	return fd;
91 #elif defined(SOCK_CLOEXEC)
92     int flags = 0;
93     if (!child_processes_inherit) {
94         flags |= SOCK_CLOEXEC;
95     }
96     return ::accept4 (sockfd, addr, addrlen, flags);
97 #else
98     return ::accept (sockfd, addr, addrlen);
99 #endif
100 }
101 
102 void SetLastError(Error &error)
103 {
104 #if defined(_WIN32)
105     error.SetError(::WSAGetLastError(), lldb::eErrorTypeWin32);
106 #else
107     error.SetErrorToErrno();
108 #endif
109 }
110 
111 bool IsInterrupted()
112 {
113 #if defined(_WIN32)
114     return ::WSAGetLastError() == WSAEINTR;
115 #else
116     return errno == EINTR;
117 #endif
118 }
119 
120 }
121 
122 Socket::Socket(NativeSocket socket, SocketProtocol protocol, bool should_close)
123     : IOObject(eFDTypeSocket, should_close)
124     , m_protocol(protocol)
125     , m_socket(socket)
126 {
127 
128 }
129 
130 Socket::~Socket()
131 {
132     Close();
133 }
134 
135 Error Socket::TcpConnect(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&socket)
136 {
137     // Store the result in a unique_ptr in case we error out, the memory will get correctly freed.
138     std::unique_ptr<Socket> final_socket;
139     NativeSocket sock = kInvalidSocketValue;
140     Error error;
141 
142     Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_HOST));
143     if (log)
144         log->Printf ("Socket::TcpConnect (host/port = %s)", host_and_port.data());
145 
146     std::string host_str;
147     std::string port_str;
148     int32_t port = INT32_MIN;
149     if (!DecodeHostAndPort (host_and_port, host_str, port_str, port, &error))
150         return error;
151 
152     // Create the socket
153     sock = CreateSocket (AF_INET, SOCK_STREAM, IPPROTO_TCP, child_processes_inherit);
154     if (sock == kInvalidSocketValue)
155     {
156         SetLastError (error);
157         return error;
158     }
159 
160     // Since they both refer to the same socket descriptor, arbitrarily choose the send socket to
161     // be the owner.
162     final_socket.reset(new Socket(sock, ProtocolTcp, true));
163 
164     // Enable local address reuse
165     final_socket->SetOption(SOL_SOCKET, SO_REUSEADDR, 1);
166 
167     struct sockaddr_in sa;
168     ::memset (&sa, 0, sizeof (sa));
169     sa.sin_family = AF_INET;
170     sa.sin_port = htons (port);
171 
172     int inet_pton_result = ::inet_pton (AF_INET, host_str.c_str(), &sa.sin_addr);
173 
174     if (inet_pton_result <= 0)
175     {
176         struct hostent *host_entry = gethostbyname (host_str.c_str());
177         if (host_entry)
178             host_str = ::inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list);
179         inet_pton_result = ::inet_pton (AF_INET, host_str.c_str(), &sa.sin_addr);
180         if (inet_pton_result <= 0)
181         {
182             if (inet_pton_result == -1)
183                 SetLastError(error);
184             else
185                 error.SetErrorStringWithFormat("invalid host string: '%s'", host_str.c_str());
186 
187             return error;
188         }
189     }
190 
191     if (-1 == ::connect (sock, (const struct sockaddr *)&sa, sizeof(sa)))
192     {
193         SetLastError (error);
194         return error;
195     }
196 
197     // Keep our TCP packets coming without any delays.
198     final_socket->SetOption(IPPROTO_TCP, TCP_NODELAY, 1);
199     error.Clear();
200     socket = final_socket.release();
201     return error;
202 }
203 
204 Error Socket::TcpListen(
205     llvm::StringRef host_and_port,
206     bool child_processes_inherit,
207     Socket *&socket,
208     Predicate<uint16_t>* predicate,
209     int backlog)
210 {
211     std::unique_ptr<Socket> listen_socket;
212     NativeSocket listen_sock = kInvalidSocketValue;
213     Error error;
214 
215     const sa_family_t family = AF_INET;
216     const int socktype = SOCK_STREAM;
217     const int protocol = IPPROTO_TCP;
218     listen_sock = ::CreateSocket (family, socktype, protocol, child_processes_inherit);
219     if (listen_sock == kInvalidSocketValue)
220     {
221         SetLastError (error);
222         return error;
223     }
224 
225     listen_socket.reset(new Socket(listen_sock, ProtocolTcp, true));
226 
227     // enable local address reuse
228     listen_socket->SetOption(SOL_SOCKET, SO_REUSEADDR, 1);
229 
230     Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
231     if (log)
232         log->Printf ("Socket::TcpListen (%s)", host_and_port.data());
233 
234     std::string host_str;
235     std::string port_str;
236     int32_t port = INT32_MIN;
237     if (!DecodeHostAndPort (host_and_port, host_str, port_str, port, &error))
238         return error;
239 
240     SocketAddress anyaddr;
241     if (anyaddr.SetToAnyAddress (family, port))
242     {
243         int err = ::bind (listen_sock, anyaddr, anyaddr.GetLength());
244         if (err == -1)
245         {
246             SetLastError (error);
247             return error;
248         }
249 
250         err = ::listen (listen_sock, backlog);
251         if (err == -1)
252         {
253             SetLastError (error);
254             return error;
255         }
256 
257         // We were asked to listen on port zero which means we
258         // must now read the actual port that was given to us
259         // as port zero is a special code for "find an open port
260         // for me".
261         if (port == 0)
262             port = listen_socket->GetLocalPortNumber();
263 
264         // Set the port predicate since when doing a listen://<host>:<port>
265         // it often needs to accept the incoming connection which is a blocking
266         // system call. Allowing access to the bound port using a predicate allows
267         // us to wait for the port predicate to be set to a non-zero value from
268         // another thread in an efficient manor.
269         if (predicate)
270             predicate->SetValue (port, eBroadcastAlways);
271 
272         socket = listen_socket.release();
273     }
274 
275     return error;
276 }
277 
278 Error Socket::BlockingAccept(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&socket)
279 {
280     Error error;
281     std::string host_str;
282     std::string port_str;
283     int32_t port;
284     if (!DecodeHostAndPort(host_and_port, host_str, port_str, port, &error))
285         return error;
286 
287     const sa_family_t family = AF_INET;
288     const int socktype = SOCK_STREAM;
289     const int protocol = IPPROTO_TCP;
290     SocketAddress listen_addr;
291     if (host_str.empty())
292         listen_addr.SetToLocalhost(family, port);
293     else if (host_str.compare("*") == 0)
294         listen_addr.SetToAnyAddress(family, port);
295     else
296     {
297         if (!listen_addr.getaddrinfo(host_str.c_str(), port_str.c_str(), family, socktype, protocol))
298         {
299             error.SetErrorStringWithFormat("unable to resolve hostname '%s'", host_str.c_str());
300             return error;
301         }
302     }
303 
304     bool accept_connection = false;
305     std::unique_ptr<Socket> accepted_socket;
306 
307     // Loop until we are happy with our connection
308     while (!accept_connection)
309     {
310         struct sockaddr_in accept_addr;
311         ::memset (&accept_addr, 0, sizeof accept_addr);
312 #if !(defined (__linux__) || defined(_WIN32))
313         accept_addr.sin_len = sizeof accept_addr;
314 #endif
315         socklen_t accept_addr_len = sizeof accept_addr;
316 
317         int sock = Accept (this->GetNativeSocket(),
318                            (struct sockaddr *)&accept_addr,
319                            &accept_addr_len,
320                            child_processes_inherit);
321 
322         if (sock == kInvalidSocketValue)
323         {
324             SetLastError (error);
325             break;
326         }
327 
328         bool is_same_addr = true;
329 #if !(defined(__linux__) || (defined(_WIN32)))
330         is_same_addr = (accept_addr_len == listen_addr.sockaddr_in().sin_len);
331 #endif
332         if (is_same_addr)
333             is_same_addr = (accept_addr.sin_addr.s_addr == listen_addr.sockaddr_in().sin_addr.s_addr);
334 
335         if (is_same_addr || (listen_addr.sockaddr_in().sin_addr.s_addr == INADDR_ANY))
336         {
337             accept_connection = true;
338             // Since both sockets have the same descriptor, arbitrarily choose the send
339             // socket to be the owner.
340             accepted_socket.reset(new Socket(sock, ProtocolTcp, true));
341         }
342         else
343         {
344             const uint8_t *accept_ip = (const uint8_t *)&accept_addr.sin_addr.s_addr;
345             const uint8_t *listen_ip = (const uint8_t *)&listen_addr.sockaddr_in().sin_addr.s_addr;
346             ::fprintf (stderr, "error: rejecting incoming connection from %u.%u.%u.%u (expecting %u.%u.%u.%u)\n",
347                         accept_ip[0], accept_ip[1], accept_ip[2], accept_ip[3],
348                         listen_ip[0], listen_ip[1], listen_ip[2], listen_ip[3]);
349             accepted_socket.reset();
350         }
351     }
352 
353     if (!accepted_socket)
354         return error;
355 
356     // Keep our TCP packets coming without any delays.
357     accepted_socket->SetOption (IPPROTO_TCP, TCP_NODELAY, 1);
358     error.Clear();
359     socket = accepted_socket.release();
360     return error;
361 
362 }
363 
364 Error Socket::UdpConnect(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&send_socket, Socket *&recv_socket)
365 {
366     std::unique_ptr<Socket> final_send_socket;
367     std::unique_ptr<Socket> final_recv_socket;
368     NativeSocket final_send_fd = kInvalidSocketValue;
369     NativeSocket final_recv_fd = kInvalidSocketValue;
370 
371     Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
372     if (log)
373         log->Printf ("Socket::UdpConnect (host/port = %s)", host_and_port.data());
374 
375     Error error;
376     std::string host_str;
377     std::string port_str;
378     int32_t port = INT32_MIN;
379     if (!DecodeHostAndPort (host_and_port, host_str, port_str, port, &error))
380         return error;
381 
382     // Setup the receiving end of the UDP connection on this localhost
383     // on port zero. After we bind to port zero we can read the port.
384     final_recv_fd = ::CreateSocket (AF_INET, SOCK_DGRAM, 0, child_processes_inherit);
385     if (final_recv_fd == kInvalidSocketValue)
386     {
387         // Socket creation failed...
388         SetLastError (error);
389     }
390     else
391     {
392         final_recv_socket.reset(new Socket(final_recv_fd, ProtocolUdp, true));
393 
394         // Socket was created, now lets bind to the requested port
395         SocketAddress addr;
396         addr.SetToAnyAddress (AF_INET, 0);
397 
398         if (::bind (final_recv_fd, addr, addr.GetLength()) == -1)
399         {
400             // Bind failed...
401             SetLastError (error);
402         }
403     }
404 
405     assert(error.Fail() == !(final_recv_socket && final_recv_socket->IsValid()));
406     if (error.Fail())
407         return error;
408 
409     // At this point we have setup the receive port, now we need to
410     // setup the UDP send socket
411 
412     struct addrinfo hints;
413     struct addrinfo *service_info_list = NULL;
414 
415     ::memset (&hints, 0, sizeof(hints));
416     hints.ai_family = AF_INET;
417     hints.ai_socktype = SOCK_DGRAM;
418     int err = ::getaddrinfo (host_str.c_str(), port_str.c_str(), &hints, &service_info_list);
419     if (err != 0)
420     {
421         error.SetErrorStringWithFormat("getaddrinfo(%s, %s, &hints, &info) returned error %i (%s)",
422                                        host_str.c_str(),
423                                        port_str.c_str(),
424                                        err,
425                                        gai_strerror(err));
426         return error;
427     }
428 
429     for (struct addrinfo *service_info_ptr = service_info_list;
430          service_info_ptr != NULL;
431          service_info_ptr = service_info_ptr->ai_next)
432     {
433         final_send_fd = ::CreateSocket (service_info_ptr->ai_family,
434                                         service_info_ptr->ai_socktype,
435                                         service_info_ptr->ai_protocol,
436                                         child_processes_inherit);
437 
438         if (final_send_fd != kInvalidSocketValue)
439         {
440             final_send_socket.reset(new Socket(final_send_fd, ProtocolUdp, true));
441             final_send_socket->m_udp_send_sockaddr = service_info_ptr;
442             break;
443         }
444         else
445             continue;
446     }
447 
448     :: freeaddrinfo (service_info_list);
449 
450     if (final_send_fd == kInvalidSocketValue)
451     {
452         SetLastError (error);
453         return error;
454     }
455 
456     send_socket = final_send_socket.release();
457     recv_socket = final_recv_socket.release();
458     error.Clear();
459     return error;
460 }
461 
462 Error Socket::UnixDomainConnect(llvm::StringRef name, bool child_processes_inherit, Socket *&socket)
463 {
464     Error error;
465 #ifndef LLDB_DISABLE_POSIX
466     std::unique_ptr<Socket> final_socket;
467 
468     // Open the socket that was passed in as an option
469     struct sockaddr_un saddr_un;
470     int fd = ::CreateSocket (AF_UNIX, SOCK_STREAM, 0, child_processes_inherit);
471     if (fd == kInvalidSocketValue)
472     {
473         SetLastError (error);
474         return error;
475     }
476 
477     final_socket.reset(new Socket(fd, ProtocolUnixDomain, true));
478 
479     saddr_un.sun_family = AF_UNIX;
480     ::strncpy(saddr_un.sun_path, name.data(), sizeof(saddr_un.sun_path) - 1);
481     saddr_un.sun_path[sizeof(saddr_un.sun_path) - 1] = '\0';
482 #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__)
483     saddr_un.sun_len = SUN_LEN (&saddr_un);
484 #endif
485 
486     if (::connect (fd, (struct sockaddr *)&saddr_un, SUN_LEN (&saddr_un)) < 0)
487     {
488         SetLastError (error);
489         return error;
490     }
491 
492     socket = final_socket.release();
493 #else
494     error.SetErrorString("Unix domain sockets are not supported on this platform.");
495 #endif
496     return error;
497 }
498 
499 Error Socket::UnixDomainAccept(llvm::StringRef name, bool child_processes_inherit, Socket *&socket)
500 {
501     Error error;
502 #ifndef LLDB_DISABLE_POSIX
503     struct sockaddr_un saddr_un;
504     std::unique_ptr<Socket> listen_socket;
505     std::unique_ptr<Socket> final_socket;
506     NativeSocket listen_fd = kInvalidSocketValue;
507     NativeSocket socket_fd = kInvalidSocketValue;
508 
509     listen_fd = ::CreateSocket (AF_UNIX, SOCK_STREAM, 0, child_processes_inherit);
510     if (listen_fd == kInvalidSocketValue)
511     {
512         SetLastError (error);
513         return error;
514     }
515 
516     listen_socket.reset(new Socket(listen_fd, ProtocolUnixDomain, true));
517 
518     saddr_un.sun_family = AF_UNIX;
519     ::strncpy(saddr_un.sun_path, name.data(), sizeof(saddr_un.sun_path) - 1);
520     saddr_un.sun_path[sizeof(saddr_un.sun_path) - 1] = '\0';
521 #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__)
522     saddr_un.sun_len = SUN_LEN (&saddr_un);
523 #endif
524 
525     FileSystem::Unlink(FileSpec{name, true});
526     bool success = false;
527     if (::bind (listen_fd, (struct sockaddr *)&saddr_un, SUN_LEN (&saddr_un)) == 0)
528     {
529         if (::listen (listen_fd, 5) == 0)
530         {
531             socket_fd = Accept (listen_fd, NULL, 0, child_processes_inherit);
532             if (socket_fd > 0)
533             {
534                 final_socket.reset(new Socket(socket_fd, ProtocolUnixDomain, true));
535                 success = true;
536             }
537         }
538     }
539 
540     if (!success)
541     {
542         SetLastError (error);
543         return error;
544     }
545     // We are done with the listen port
546     listen_socket.reset();
547 
548     socket = final_socket.release();
549 #else
550     error.SetErrorString("Unix domain sockets are not supported on this platform.");
551 #endif
552     return error;
553 }
554 
555 bool
556 Socket::DecodeHostAndPort(llvm::StringRef host_and_port,
557                           std::string &host_str,
558                           std::string &port_str,
559                           int32_t& port,
560                           Error *error_ptr)
561 {
562     static RegularExpression g_regex ("([^:]+):([0-9]+)");
563     RegularExpression::Match regex_match(2);
564     if (g_regex.Execute (host_and_port.data(), &regex_match))
565     {
566         if (regex_match.GetMatchAtIndex (host_and_port.data(), 1, host_str) &&
567             regex_match.GetMatchAtIndex (host_and_port.data(), 2, port_str))
568         {
569             bool ok = false;
570             port = StringConvert::ToUInt32 (port_str.c_str(), UINT32_MAX, 10, &ok);
571             if (ok && port < UINT16_MAX)
572             {
573                 if (error_ptr)
574                     error_ptr->Clear();
575                 return true;
576             }
577             // port is too large
578             if (error_ptr)
579                 error_ptr->SetErrorStringWithFormat("invalid host:port specification: '%s'", host_and_port.data());
580             return false;
581         }
582     }
583 
584     // If this was unsuccessful, then check if it's simply a signed 32-bit integer, representing
585     // a port with an empty host.
586     host_str.clear();
587     port_str.clear();
588     bool ok = false;
589     port = StringConvert::ToUInt32 (host_and_port.data(), UINT32_MAX, 10, &ok);
590     if (ok && port < UINT16_MAX)
591     {
592         port_str = host_and_port;
593         if (error_ptr)
594             error_ptr->Clear();
595         return true;
596     }
597 
598     if (error_ptr)
599         error_ptr->SetErrorStringWithFormat("invalid host:port specification: '%s'", host_and_port.data());
600     return false;
601 }
602 
603 IOObject::WaitableHandle Socket::GetWaitableHandle()
604 {
605     // TODO: On Windows, use WSAEventSelect
606     return m_socket;
607 }
608 
609 Error Socket::Read (void *buf, size_t &num_bytes)
610 {
611     Error error;
612     int bytes_received = 0;
613     do
614     {
615         bytes_received = ::recv (m_socket, static_cast<char *>(buf), num_bytes, 0);
616     } while (bytes_received < 0 && IsInterrupted ());
617 
618     if (bytes_received < 0)
619     {
620         SetLastError (error);
621         num_bytes = 0;
622     }
623     else
624         num_bytes = bytes_received;
625 
626     Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_COMMUNICATION));
627     if (log)
628     {
629         log->Printf ("%p Socket::Read() (socket = %" PRIu64 ", src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64 " (error = %s)",
630                      static_cast<void*>(this),
631                      static_cast<uint64_t>(m_socket),
632                      buf,
633                      static_cast<uint64_t>(num_bytes),
634                      static_cast<int64_t>(bytes_received),
635                      error.AsCString());
636     }
637 
638     return error;
639 }
640 
641 Error Socket::Write (const void *buf, size_t &num_bytes)
642 {
643     Error error;
644     int bytes_sent = 0;
645     do
646     {
647         if (m_protocol == ProtocolUdp)
648         {
649             bytes_sent = ::sendto (m_socket,
650                                     static_cast<const char*>(buf),
651                                     num_bytes,
652                                     0,
653                                     m_udp_send_sockaddr,
654                                     m_udp_send_sockaddr.GetLength());
655         }
656         else
657             bytes_sent = ::send (m_socket, static_cast<const char *>(buf), num_bytes, 0);
658     } while (bytes_sent < 0 && IsInterrupted ());
659 
660     if (bytes_sent < 0)
661     {
662         SetLastError (error);
663         num_bytes = 0;
664     }
665     else
666         num_bytes = bytes_sent;
667 
668     Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_HOST));
669     if (log)
670     {
671         log->Printf ("%p Socket::Write() (socket = %" PRIu64 ", src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64 " (error = %s)",
672                         static_cast<void*>(this),
673                         static_cast<uint64_t>(m_socket),
674                         buf,
675                         static_cast<uint64_t>(num_bytes),
676                         static_cast<int64_t>(bytes_sent),
677                         error.AsCString());
678     }
679 
680     return error;
681 }
682 
683 Error Socket::PreDisconnect()
684 {
685     Error error;
686     return error;
687 }
688 
689 Error Socket::Close()
690 {
691     Error error;
692     if (!IsValid() || !m_should_close_fd)
693         return error;
694 
695     Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
696     if (log)
697         log->Printf ("%p Socket::Close (fd = %i)", static_cast<void*>(this), m_socket);
698 
699 #if defined(_WIN32)
700     bool success = !!closesocket(m_socket);
701 #else
702     bool success = !!::close (m_socket);
703 #endif
704     // A reference to a FD was passed in, set it to an invalid value
705     m_socket = kInvalidSocketValue;
706     if (!success)
707     {
708         SetLastError (error);
709     }
710 
711     return error;
712 }
713 
714 
715 int Socket::GetOption(int level, int option_name, int &option_value)
716 {
717     get_socket_option_arg_type option_value_p = reinterpret_cast<get_socket_option_arg_type>(&option_value);
718     socklen_t option_value_size = sizeof(int);
719 	return ::getsockopt(m_socket, level, option_name, option_value_p, &option_value_size);
720 }
721 
722 int Socket::SetOption(int level, int option_name, int option_value)
723 {
724     set_socket_option_arg_type option_value_p = reinterpret_cast<get_socket_option_arg_type>(&option_value);
725 	return ::setsockopt(m_socket, level, option_name, option_value_p, sizeof(option_value));
726 }
727 
728 uint16_t Socket::GetLocalPortNumber(const NativeSocket& socket)
729 {
730     // We bound to port zero, so we need to figure out which port we actually bound to
731     if (socket != kInvalidSocketValue)
732     {
733         SocketAddress sock_addr;
734         socklen_t sock_addr_len = sock_addr.GetMaxLength ();
735         if (::getsockname (socket, sock_addr, &sock_addr_len) == 0)
736             return sock_addr.GetPort ();
737     }
738     return 0;
739 }
740 
741 // Return the port number that is being used by the socket.
742 uint16_t Socket::GetLocalPortNumber() const
743 {
744     return GetLocalPortNumber (m_socket);
745 }
746 
747 std::string  Socket::GetLocalIPAddress () const
748 {
749     // We bound to port zero, so we need to figure out which port we actually bound to
750     if (m_socket != kInvalidSocketValue)
751     {
752         SocketAddress sock_addr;
753         socklen_t sock_addr_len = sock_addr.GetMaxLength ();
754         if (::getsockname (m_socket, sock_addr, &sock_addr_len) == 0)
755             return sock_addr.GetIPAddress ();
756     }
757     return "";
758 }
759 
760 uint16_t Socket::GetRemotePortNumber () const
761 {
762     if (m_socket != kInvalidSocketValue)
763     {
764         SocketAddress sock_addr;
765         socklen_t sock_addr_len = sock_addr.GetMaxLength ();
766         if (::getpeername (m_socket, sock_addr, &sock_addr_len) == 0)
767             return sock_addr.GetPort ();
768     }
769     return 0;
770 }
771 
772 std::string Socket::GetRemoteIPAddress () const
773 {
774     // We bound to port zero, so we need to figure out which port we actually bound to
775     if (m_socket != kInvalidSocketValue)
776     {
777         SocketAddress sock_addr;
778         socklen_t sock_addr_len = sock_addr.GetMaxLength ();
779         if (::getpeername (m_socket, sock_addr, &sock_addr_len) == 0)
780             return sock_addr.GetIPAddress ();
781     }
782     return "";
783 }
784 
785 
786