ConnectionFileDescriptor.cpp revision 2f28ece553d2ef0d7b3e8d1419020591ec3818f9
1//===-- ConnectionFileDescriptor.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/Core/ConnectionFileDescriptor.h"
11
12// C Includes
13#include <errno.h>
14#include <fcntl.h>
15#include <arpa/inet.h>
16#include <netdb.h>
17#include <netinet/in.h>
18#include <netinet/tcp.h>
19#include <sys/socket.h>
20#include <sys/un.h>
21#include <sys/types.h>
22#include <string.h>
23#include <stdlib.h>
24
25// C++ Includes
26// Other libraries and framework includes
27// Project includes
28#include "lldb/lldb-private-log.h"
29#include "lldb/Interpreter/Args.h"
30#include "lldb/Core/Communication.h"
31#include "lldb/Core/Log.h"
32#include "lldb/Core/RegularExpression.h"
33#include "lldb/Core/Timer.h"
34
35using namespace lldb;
36using namespace lldb_private;
37
38static bool
39DecodeHostAndPort (const char *host_and_port,
40                   std::string &host_str,
41                   std::string &port_str,
42                   int32_t& port,
43                   Error *error_ptr)
44{
45    RegularExpression regex ("([^:]+):([0-9]+)");
46    if (regex.Execute (host_and_port, 2))
47    {
48        if (regex.GetMatchAtIndex (host_and_port, 1, host_str) &&
49            regex.GetMatchAtIndex (host_and_port, 2, port_str))
50        {
51            port = Args::StringToSInt32 (port_str.c_str(), INT32_MIN);
52            if (port != INT32_MIN)
53            {
54                if (error_ptr)
55                    error_ptr->Clear();
56                return true;
57            }
58        }
59    }
60    host_str.clear();
61    port_str.clear();
62    port = INT32_MIN;
63    if (error_ptr)
64        error_ptr->SetErrorStringWithFormat("invalid host:port specification: '%s'", host_and_port);
65    return false;
66}
67
68ConnectionFileDescriptor::ConnectionFileDescriptor () :
69    Connection(),
70    m_fd_send (-1),
71    m_fd_recv (-1),
72    m_fd_send_type (eFDTypeFile),
73    m_fd_recv_type (eFDTypeFile),
74    m_udp_send_sockaddr (),
75    m_should_close_fd (false),
76    m_socket_timeout_usec(0)
77{
78    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION |  LIBLLDB_LOG_OBJECT));
79    if (log)
80        log->Printf ("%p ConnectionFileDescriptor::ConnectionFileDescriptor ()", this);
81}
82
83ConnectionFileDescriptor::ConnectionFileDescriptor (int fd, bool owns_fd) :
84    Connection(),
85    m_fd_send (fd),
86    m_fd_recv (fd),
87    m_fd_send_type (eFDTypeFile),
88    m_fd_recv_type (eFDTypeFile),
89    m_udp_send_sockaddr (),
90    m_should_close_fd (owns_fd),
91    m_socket_timeout_usec(0)
92{
93    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION |  LIBLLDB_LOG_OBJECT));
94    if (log)
95        log->Printf ("%p ConnectionFileDescriptor::ConnectionFileDescriptor (fd = %i, owns_fd = %i)", this, fd, owns_fd);
96}
97
98
99ConnectionFileDescriptor::~ConnectionFileDescriptor ()
100{
101    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION |  LIBLLDB_LOG_OBJECT));
102    if (log)
103        log->Printf ("%p ConnectionFileDescriptor::~ConnectionFileDescriptor ()", this);
104    Disconnect (NULL);
105}
106
107bool
108ConnectionFileDescriptor::IsConnected () const
109{
110    return m_fd_send >= 0 || m_fd_recv >= 0;
111}
112
113ConnectionStatus
114ConnectionFileDescriptor::Connect (const char *s, Error *error_ptr)
115{
116    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
117    if (log)
118        log->Printf ("%p ConnectionFileDescriptor::Connect (url = '%s')", this, s);
119
120    if (s && s[0])
121    {
122        char *end = NULL;
123        if (strstr(s, "listen://"))
124        {
125            // listen://HOST:PORT
126            unsigned long listen_port = ::strtoul(s + strlen("listen://"), &end, 0);
127            return SocketListen (listen_port, error_ptr);
128        }
129        else if (strstr(s, "unix-accept://"))
130        {
131            // unix://SOCKNAME
132            return NamedSocketAccept (s + strlen("unix-accept://"), error_ptr);
133        }
134        else if (strstr(s, "connect://"))
135        {
136            return ConnectTCP (s + strlen("connect://"), error_ptr);
137        }
138        else if (strstr(s, "tcp-connect://"))
139        {
140            return ConnectTCP (s + strlen("tcp-connect://"), error_ptr);
141        }
142        else if (strstr(s, "udp://"))
143        {
144            return ConnectUDP (s + strlen("udp://"), error_ptr);
145        }
146        else if (strstr(s, "fd://"))
147        {
148            // Just passing a native file descriptor within this current process
149            // that is already opened (possibly from a service or other source).
150            s += strlen ("fd://");
151            bool success = false;
152            m_fd_send = m_fd_recv = Args::StringToSInt32 (s, -1, 0, &success);
153
154            if (success)
155            {
156                // We have what looks to be a valid file descriptor, but we
157                // should make it is. We currently are doing this by trying to
158                // get the flags from the file descriptor and making sure it
159                // isn't a bad fd.
160                errno = 0;
161                int flags = ::fcntl (m_fd_send, F_GETFL, 0);
162                if (flags == -1 || errno == EBADF)
163                {
164                    if (error_ptr)
165                        error_ptr->SetErrorStringWithFormat ("stale file descriptor: %s", s);
166                    m_fd_send = m_fd_recv = -1;
167                    return eConnectionStatusError;
168                }
169                else
170                {
171                    // Try and get a socket option from this file descriptor to
172                    // see if this is a socket and set m_is_socket accordingly.
173                    int resuse;
174                    bool is_socket = GetSocketOption (m_fd_send, SOL_SOCKET, SO_REUSEADDR, resuse) == 0;
175                    if (is_socket)
176                        m_fd_send_type = m_fd_recv_type = eFDTypeSocket;
177                    m_should_close_fd = true;
178                    return eConnectionStatusSuccess;
179                }
180            }
181
182            if (error_ptr)
183                error_ptr->SetErrorStringWithFormat ("invalid file descriptor: \"fd://%s\"", s);
184            m_fd_send = m_fd_recv = -1;
185            return eConnectionStatusError;
186        }
187        else if (strstr(s, "file://"))
188        {
189            // file:///PATH
190            const char *path = s + strlen("file://");
191            do
192            {
193                m_fd_send = m_fd_recv = ::open (path, O_RDWR);
194            } while (m_fd_send == -1 && errno == EINTR);
195            if (m_fd_send == -1)
196            {
197                if (error_ptr)
198                    error_ptr->SetErrorToErrno();
199                return eConnectionStatusError;
200            }
201
202            int flags = ::fcntl (m_fd_send, F_GETFL, 0);
203            if (flags >= 0)
204            {
205                if ((flags & O_NONBLOCK) == 0)
206                {
207                    flags |= O_NONBLOCK;
208                    ::fcntl (m_fd_send, F_SETFL, flags);
209                }
210            }
211            m_should_close_fd = true;
212            return eConnectionStatusSuccess;
213        }
214        if (error_ptr)
215            error_ptr->SetErrorStringWithFormat ("unsupported connection URL: '%s'", s);
216        return eConnectionStatusError;
217    }
218    if (error_ptr)
219        error_ptr->SetErrorString("invalid connect arguments");
220    return eConnectionStatusError;
221}
222
223ConnectionStatus
224ConnectionFileDescriptor::Disconnect (Error *error_ptr)
225{
226    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
227    if (log)
228        log->Printf ("%p ConnectionFileDescriptor::Disconnect ()", this);
229    if (m_should_close_fd == false)
230    {
231        m_fd_send = m_fd_recv = -1;
232        return eConnectionStatusSuccess;
233    }
234    ConnectionStatus status = eConnectionStatusSuccess;
235    if (m_fd_send == m_fd_recv)
236    {
237        // Both file descriptors are the same, only close one
238        status = Close (m_fd_send, error_ptr);
239        m_fd_recv = -1;
240    }
241    else
242    {
243        // File descriptors are the different, close both if needed
244        if (m_fd_send >= 0)
245            status = Close (m_fd_send, error_ptr);
246        if (m_fd_recv >= 0)
247        {
248            ConnectionStatus recv_status = Close (m_fd_recv, error_ptr);
249            if (status == eConnectionStatusSuccess)
250                status = recv_status;
251        }
252    }
253    return status;
254}
255
256size_t
257ConnectionFileDescriptor::Read (void *dst,
258                                size_t dst_len,
259                                uint32_t timeout_usec,
260                                ConnectionStatus &status,
261                                Error *error_ptr)
262{
263    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
264    if (log)
265        log->Printf ("%p ConnectionFileDescriptor::Read () ::read (fd = %i, dst = %p, dst_len = %zu)...",
266                     this, m_fd_recv, dst, dst_len);
267
268    ssize_t bytes_read = 0;
269
270    switch (m_fd_recv_type)
271    {
272    case eFDTypeFile:       // Other FD requireing read/write
273        status = BytesAvailable (timeout_usec, error_ptr);
274        if (status == eConnectionStatusSuccess)
275        {
276            do
277            {
278                bytes_read = ::read (m_fd_recv, dst, dst_len);
279            } while (bytes_read < 0 && errno == EINTR);
280        }
281        break;
282
283    case eFDTypeSocket:     // Socket requiring send/recv
284        if (SetSocketReceiveTimeout (timeout_usec))
285        {
286            status = eConnectionStatusSuccess;
287            do
288            {
289                bytes_read = ::recv (m_fd_recv, dst, dst_len, 0);
290            } while (bytes_read < 0 && errno == EINTR);
291        }
292        break;
293
294    case eFDTypeSocketUDP:  // Unconnected UDP socket requiring sendto/recvfrom
295        if (SetSocketReceiveTimeout (timeout_usec))
296        {
297            status = eConnectionStatusSuccess;
298            SocketAddress from (m_udp_send_sockaddr);
299            socklen_t from_len = m_udp_send_sockaddr.GetLength();
300            do
301            {
302                bytes_read = ::recvfrom (m_fd_recv, dst, dst_len, 0, (struct sockaddr *)&from, &from_len);
303            } while (bytes_read < 0 && errno == EINTR);
304        }
305        break;
306    }
307
308    if (status != eConnectionStatusSuccess)
309        return 0;
310
311    Error error;
312    if (bytes_read == 0)
313    {
314        error.Clear(); // End-of-file.  Do not automatically close; pass along for the end-of-file handlers.
315        status = eConnectionStatusEndOfFile;
316    }
317    else if (bytes_read < 0)
318    {
319        error.SetErrorToErrno();
320    }
321    else
322    {
323        error.Clear();
324    }
325
326    if (log)
327        log->Printf ("%p ConnectionFileDescriptor::Read () ::read (fd = %i, dst = %p, dst_len = %zu) => %zi, error = %s",
328                     this,
329                     m_fd_recv,
330                     dst,
331                     dst_len,
332                     bytes_read,
333                     error.AsCString());
334
335    if (error_ptr)
336        *error_ptr = error;
337
338    if (error.Fail())
339    {
340        uint32_t error_value = error.GetError();
341        switch (error_value)
342        {
343        case EAGAIN:    // The file was marked for non-blocking I/O, and no data were ready to be read.
344            if (m_fd_recv_type == eFDTypeSocket || m_fd_recv_type == eFDTypeSocketUDP)
345                status = eConnectionStatusTimedOut;
346            else
347                status = eConnectionStatusSuccess;
348            return 0;
349
350        case EFAULT:    // Buf points outside the allocated address space.
351        case EINTR:     // A read from a slow device was interrupted before any data arrived by the delivery of a signal.
352        case EINVAL:    // The pointer associated with fildes was negative.
353        case EIO:       // An I/O error occurred while reading from the file system.
354                        // The process group is orphaned.
355                        // The file is a regular file, nbyte is greater than 0,
356                        // the starting position is before the end-of-file, and
357                        // the starting position is greater than or equal to the
358                        // offset maximum established for the open file
359                        // descriptor associated with fildes.
360        case EISDIR:    // An attempt is made to read a directory.
361        case ENOBUFS:   // An attempt to allocate a memory buffer fails.
362        case ENOMEM:    // Insufficient memory is available.
363            status = eConnectionStatusError;
364            break;  // Break to close....
365
366        case ENOENT:    // no such file or directory
367        case EBADF:     // fildes is not a valid file or socket descriptor open for reading.
368        case ENXIO:     // An action is requested of a device that does not exist..
369                        // A requested action cannot be performed by the device.
370        case ECONNRESET:// The connection is closed by the peer during a read attempt on a socket.
371        case ENOTCONN:  // A read is attempted on an unconnected socket.
372            status = eConnectionStatusLostConnection;
373            break;  // Break to close....
374
375        case ETIMEDOUT: // A transmission timeout occurs during a read attempt on a socket.
376            status = eConnectionStatusTimedOut;
377            return 0;
378        }
379
380        Disconnect (NULL);
381        return 0;
382    }
383    return bytes_read;
384}
385
386size_t
387ConnectionFileDescriptor::Write (const void *src, size_t src_len, ConnectionStatus &status, Error *error_ptr)
388{
389    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
390    if (log)
391        log->Printf ("%p ConnectionFileDescriptor::Write (src = %p, src_len = %zu)", this, src, src_len);
392
393    if (!IsConnected ())
394    {
395        if (error_ptr)
396            error_ptr->SetErrorString("not connected");
397        status = eConnectionStatusNoConnection;
398        return 0;
399    }
400
401
402    Error error;
403
404    ssize_t bytes_sent = 0;
405
406    switch (m_fd_send_type)
407    {
408        case eFDTypeFile:       // Other FD requireing read/write
409            do
410            {
411                bytes_sent = ::write (m_fd_send, src, src_len);
412            } while (bytes_sent < 0 && errno == EINTR);
413            break;
414
415        case eFDTypeSocket:     // Socket requiring send/recv
416            do
417            {
418                bytes_sent = ::send (m_fd_send, src, src_len, 0);
419            } while (bytes_sent < 0 && errno == EINTR);
420            break;
421
422        case eFDTypeSocketUDP:  // Unconnected UDP socket requiring sendto/recvfrom
423            assert (m_udp_send_sockaddr.GetFamily() != 0);
424            do
425            {
426                bytes_sent = ::sendto (m_fd_send,
427                                       src,
428                                       src_len,
429                                       0,
430                                       m_udp_send_sockaddr,
431                                       m_udp_send_sockaddr.GetLength());
432            } while (bytes_sent < 0 && errno == EINTR);
433            break;
434    }
435
436    if (bytes_sent < 0)
437        error.SetErrorToErrno ();
438    else
439        error.Clear ();
440
441    if (log)
442    {
443        switch (m_fd_send_type)
444        {
445            case eFDTypeFile:       // Other FD requireing read/write
446                log->Printf ("%p ConnectionFileDescriptor::Write()  ::write (fd = %i, src = %p, src_len = %zu) => %zi (error = %s)",
447                             this,
448                             m_fd_send,
449                             src,
450                             src_len,
451                             bytes_sent,
452                             error.AsCString());
453                break;
454
455            case eFDTypeSocket:     // Socket requiring send/recv
456                log->Printf ("%p ConnectionFileDescriptor::Write()  ::send (socket = %i, src = %p, src_len = %zu, flags = 0) => %zi (error = %s)",
457                             this,
458                             m_fd_send,
459                             src,
460                             src_len,
461                             bytes_sent,
462                             error.AsCString());
463                break;
464
465            case eFDTypeSocketUDP:  // Unconnected UDP socket requiring sendto/recvfrom
466                log->Printf ("%p ConnectionFileDescriptor::Write()  ::sendto (socket = %i, src = %p, src_len = %zu, flags = 0) => %zi (error = %s)",
467                             this,
468                             m_fd_send,
469                             src,
470                             src_len,
471                             bytes_sent,
472                             error.AsCString());
473                break;
474        }
475    }
476
477    if (error_ptr)
478        *error_ptr = error;
479
480    if (error.Fail())
481    {
482        switch (error.GetError())
483        {
484        case EAGAIN:
485        case EINTR:
486            status = eConnectionStatusSuccess;
487            return 0;
488
489        case ECONNRESET:// The connection is closed by the peer during a read attempt on a socket.
490        case ENOTCONN:  // A read is attempted on an unconnected socket.
491            status = eConnectionStatusLostConnection;
492            break;  // Break to close....
493
494        default:
495            status = eConnectionStatusError;
496            break;  // Break to close....
497        }
498
499        Disconnect (NULL);
500        return 0;
501    }
502
503    status = eConnectionStatusSuccess;
504    return bytes_sent;
505}
506
507ConnectionStatus
508ConnectionFileDescriptor::BytesAvailable (uint32_t timeout_usec, Error *error_ptr)
509{
510    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
511    if (log)
512        log->Printf("%p ConnectionFileDescriptor::BytesAvailable (timeout_usec = %u)", this, timeout_usec);
513    struct timeval *tv_ptr;
514    struct timeval tv;
515    if (timeout_usec == UINT32_MAX)
516    {
517        // Infinite wait...
518        tv_ptr = NULL;
519    }
520    else
521    {
522        TimeValue time_value;
523        time_value.OffsetWithMicroSeconds (timeout_usec);
524        tv = time_value.GetAsTimeVal();
525        tv_ptr = &tv;
526    }
527
528    while (IsConnected())
529    {
530        fd_set read_fds;
531        FD_ZERO (&read_fds);
532        FD_SET (m_fd_recv, &read_fds);
533        int nfds = m_fd_recv + 1;
534
535        Error error;
536
537
538        if (log)
539            log->Printf("%p ConnectionFileDescriptor::BytesAvailable()  ::select (nfds = %i, fd = %i, NULL, NULL, timeout = %p)...",
540                        this, nfds, m_fd_recv, tv_ptr);
541
542        const int num_set_fds = ::select (nfds, &read_fds, NULL, NULL, tv_ptr);
543        if (num_set_fds < 0)
544            error.SetErrorToErrno();
545        else
546            error.Clear();
547
548        if (log)
549            log->Printf("%p ConnectionFileDescriptor::BytesAvailable()  ::select (nfds = %i, fd = %i, NULL, NULL, timeout = %p) => %d, error = %s",
550                        this, nfds, m_fd_recv, tv_ptr, num_set_fds, error.AsCString());
551
552        if (error_ptr)
553            *error_ptr = error;
554
555        if (error.Fail())
556        {
557            switch (error.GetError())
558            {
559            case EBADF:     // One of the descriptor sets specified an invalid descriptor.
560                return eConnectionStatusLostConnection;
561
562            case EINVAL:    // The specified time limit is invalid. One of its components is negative or too large.
563            default:        // Other unknown error
564                return eConnectionStatusError;
565
566            case EAGAIN:    // The kernel was (perhaps temporarily) unable to
567                            // allocate the requested number of file descriptors,
568                            // or we have non-blocking IO
569            case EINTR:     // A signal was delivered before the time limit
570                            // expired and before any of the selected events
571                            // occurred.
572                break;      // Lets keep reading to until we timeout
573            }
574        }
575        else if (num_set_fds == 0)
576        {
577            return eConnectionStatusTimedOut;
578        }
579        else if (num_set_fds > 0)
580        {
581            return eConnectionStatusSuccess;
582        }
583    }
584
585    if (error_ptr)
586        error_ptr->SetErrorString("not connected");
587    return eConnectionStatusLostConnection;
588}
589
590ConnectionStatus
591ConnectionFileDescriptor::Close (int& fd, Error *error_ptr)
592{
593    if (error_ptr)
594        error_ptr->Clear();
595    bool success = true;
596    if (fd >= 0)
597    {
598        LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
599        if (log)
600            log->Printf ("%p ConnectionFileDescriptor::Close (fd = %i)", this,fd);
601
602        success = ::close (fd) == 0;
603        if (!success && error_ptr)
604        {
605            // Only set the error if we have been asked to since something else
606            // might have caused us to try and shut down the connection and may
607            // have already set the error.
608            error_ptr->SetErrorToErrno();
609        }
610        fd = -1;
611    }
612    m_fd_send_type = m_fd_recv_type = eFDTypeFile;
613    if (success)
614        return eConnectionStatusSuccess;
615    else
616        return eConnectionStatusError;
617}
618
619ConnectionStatus
620ConnectionFileDescriptor::NamedSocketAccept (const char *socket_name, Error *error_ptr)
621{
622    ConnectionStatus result = eConnectionStatusError;
623    struct sockaddr_un saddr_un;
624
625    m_fd_send_type = m_fd_recv_type = eFDTypeSocket;
626
627    int listen_socket = ::socket (AF_UNIX, SOCK_STREAM, 0);
628    if (listen_socket == -1)
629    {
630        if (error_ptr)
631            error_ptr->SetErrorToErrno();
632        return eConnectionStatusError;
633    }
634
635    saddr_un.sun_family = AF_UNIX;
636    ::strncpy(saddr_un.sun_path, socket_name, sizeof(saddr_un.sun_path) - 1);
637    saddr_un.sun_path[sizeof(saddr_un.sun_path) - 1] = '\0';
638#if defined(__APPLE__) || defined(__FreeBSD__)
639    saddr_un.sun_len = SUN_LEN (&saddr_un);
640#endif
641
642    if (::bind (listen_socket, (struct sockaddr *)&saddr_un, SUN_LEN (&saddr_un)) == 0)
643    {
644        if (::listen (listen_socket, 5) == 0)
645        {
646            m_fd_send = m_fd_recv = ::accept (listen_socket, NULL, 0);
647            if (m_fd_send > 0)
648            {
649                m_should_close_fd = true;
650
651                if (error_ptr)
652                    error_ptr->Clear();
653                result = eConnectionStatusSuccess;
654            }
655        }
656    }
657
658    if (result != eConnectionStatusSuccess)
659    {
660        if (error_ptr)
661            error_ptr->SetErrorToErrno();
662    }
663    // We are done with the listen port
664    Close (listen_socket, NULL);
665    return result;
666}
667
668ConnectionStatus
669ConnectionFileDescriptor::NamedSocketConnect (const char *socket_name, Error *error_ptr)
670{
671    Disconnect (NULL);
672    m_fd_send_type = m_fd_recv_type = eFDTypeSocket;
673
674    // Open the socket that was passed in as an option
675    struct sockaddr_un saddr_un;
676    m_fd_send = m_fd_recv = ::socket (AF_UNIX, SOCK_STREAM, 0);
677    if (m_fd_send == -1)
678    {
679        if (error_ptr)
680            error_ptr->SetErrorToErrno();
681        return eConnectionStatusError;
682    }
683
684    saddr_un.sun_family = AF_UNIX;
685    ::strncpy(saddr_un.sun_path, socket_name, sizeof(saddr_un.sun_path) - 1);
686    saddr_un.sun_path[sizeof(saddr_un.sun_path) - 1] = '\0';
687#if defined(__APPLE__) || defined(__FreeBSD__)
688    saddr_un.sun_len = SUN_LEN (&saddr_un);
689#endif
690
691    if (::connect (m_fd_send, (struct sockaddr *)&saddr_un, SUN_LEN (&saddr_un)) < 0)
692    {
693        if (error_ptr)
694            error_ptr->SetErrorToErrno();
695        Disconnect (NULL);
696        return eConnectionStatusError;
697    }
698    if (error_ptr)
699        error_ptr->Clear();
700    return eConnectionStatusSuccess;
701}
702
703ConnectionStatus
704ConnectionFileDescriptor::SocketListen (uint16_t listen_port_num, Error *error_ptr)
705{
706    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
707    if (log)
708        log->Printf ("%p ConnectionFileDescriptor::SocketListen (port = %i)", this, listen_port_num);
709
710    Disconnect (NULL);
711    m_fd_send_type = m_fd_recv_type = eFDTypeSocket;
712    int listen_port = ::socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
713    if (listen_port == -1)
714    {
715        if (error_ptr)
716            error_ptr->SetErrorToErrno();
717        return eConnectionStatusError;
718    }
719
720    // enable local address reuse
721    SetSocketOption (listen_port, SOL_SOCKET, SO_REUSEADDR, 1);
722
723    SocketAddress localhost;
724    if (localhost.SetToLocalhost (AF_INET, listen_port_num))
725    {
726        int err = ::bind (listen_port, localhost, localhost.GetLength());
727        if (err == -1)
728        {
729            if (error_ptr)
730                error_ptr->SetErrorToErrno();
731            Close (listen_port, NULL);
732            return eConnectionStatusError;
733        }
734
735        err = ::listen (listen_port, 1);
736        if (err == -1)
737        {
738            if (error_ptr)
739                error_ptr->SetErrorToErrno();
740            Close (listen_port, NULL);
741            return eConnectionStatusError;
742        }
743
744        m_fd_send = m_fd_recv = ::accept (listen_port, NULL, 0);
745        if (m_fd_send == -1)
746        {
747            if (error_ptr)
748                error_ptr->SetErrorToErrno();
749            Close (listen_port, NULL);
750            return eConnectionStatusError;
751        }
752    }
753
754    // We are done with the listen port
755    Close (listen_port, NULL);
756
757    m_should_close_fd = true;
758
759    // Keep our TCP packets coming without any delays.
760    SetSocketOption (m_fd_send, IPPROTO_TCP, TCP_NODELAY, 1);
761    if (error_ptr)
762        error_ptr->Clear();
763    return eConnectionStatusSuccess;
764}
765
766ConnectionStatus
767ConnectionFileDescriptor::ConnectTCP (const char *host_and_port, Error *error_ptr)
768{
769    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
770    if (log)
771        log->Printf ("%p ConnectionFileDescriptor::ConnectTCP (host/port = %s)", this, host_and_port);
772    Disconnect (NULL);
773
774    m_fd_send_type = m_fd_recv_type = eFDTypeSocket;
775    std::string host_str;
776    std::string port_str;
777    int32_t port = INT32_MIN;
778    if (!DecodeHostAndPort (host_and_port, host_str, port_str, port, error_ptr))
779        return eConnectionStatusError;
780
781    // Create the socket
782    m_fd_send = m_fd_recv = ::socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
783    if (m_fd_send == -1)
784    {
785        if (error_ptr)
786            error_ptr->SetErrorToErrno();
787        return eConnectionStatusError;
788    }
789
790    m_should_close_fd = true;
791
792    // Enable local address reuse
793    SetSocketOption (m_fd_send, SOL_SOCKET, SO_REUSEADDR, 1);
794
795    struct sockaddr_in sa;
796    ::memset (&sa, 0, sizeof (sa));
797    sa.sin_family = AF_INET;
798    sa.sin_port = htons (port);
799
800    int inet_pton_result = ::inet_pton (AF_INET, host_str.c_str(), &sa.sin_addr);
801
802    if (inet_pton_result <= 0)
803    {
804        struct hostent *host_entry = gethostbyname (host_str.c_str());
805        if (host_entry)
806            host_str = ::inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list);
807        inet_pton_result = ::inet_pton (AF_INET, host_str.c_str(), &sa.sin_addr);
808        if (inet_pton_result <= 0)
809        {
810
811            if (error_ptr)
812            {
813                if (inet_pton_result == -1)
814                    error_ptr->SetErrorToErrno();
815                else
816                    error_ptr->SetErrorStringWithFormat("invalid host string: '%s'", host_str.c_str());
817            }
818            Disconnect (NULL);
819
820            return eConnectionStatusError;
821        }
822    }
823
824    if (-1 == ::connect (m_fd_send, (const struct sockaddr *)&sa, sizeof(sa)))
825    {
826        if (error_ptr)
827            error_ptr->SetErrorToErrno();
828        Disconnect (NULL);
829
830        return eConnectionStatusError;
831    }
832
833    // Keep our TCP packets coming without any delays.
834    SetSocketOption (m_fd_send, IPPROTO_TCP, TCP_NODELAY, 1);
835    if (error_ptr)
836        error_ptr->Clear();
837    return eConnectionStatusSuccess;
838}
839
840ConnectionStatus
841ConnectionFileDescriptor::ConnectUDP (const char *host_and_port, Error *error_ptr)
842{
843    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
844    if (log)
845        log->Printf ("%p ConnectionFileDescriptor::ConnectUDP (host/port = %s)", this, host_and_port);
846    Disconnect (NULL);
847
848    m_fd_send_type = m_fd_recv_type = eFDTypeSocketUDP;
849
850    std::string host_str;
851    std::string port_str;
852    int32_t port = INT32_MIN;
853    if (!DecodeHostAndPort (host_and_port, host_str, port_str, port, error_ptr))
854        return eConnectionStatusError;
855
856    // Setup the receiving end of the UDP connection on this localhost
857    // on port zero. After we bind to port zero we can read the port.
858    m_fd_recv = ::socket (AF_INET, SOCK_DGRAM, 0);
859    if (m_fd_recv == -1)
860    {
861        // Socket creation failed...
862        if (error_ptr)
863            error_ptr->SetErrorToErrno();
864    }
865    else
866    {
867        // Socket was created, now lets bind to the requested port
868        SocketAddress addr;
869        addr.SetToLocalhost (AF_INET, 0);
870
871        if (::bind (m_fd_recv, addr, addr.GetLength()) == -1)
872        {
873            // Bind failed...
874            if (error_ptr)
875                error_ptr->SetErrorToErrno();
876            Disconnect (NULL);
877        }
878    }
879
880    if (m_fd_recv == -1)
881        return eConnectionStatusError;
882
883    // At this point we have setup the recieve port, now we need to
884    // setup the UDP send socket
885
886    struct addrinfo hints;
887    struct addrinfo *service_info_list = NULL;
888
889    ::memset (&hints, 0, sizeof(hints));
890    hints.ai_family = AF_INET;
891    hints.ai_socktype = SOCK_DGRAM;
892    int err = ::getaddrinfo (host_str.c_str(), port_str.c_str(), &hints, &service_info_list);
893    if (err != 0)
894    {
895        if (error_ptr)
896            error_ptr->SetErrorStringWithFormat("getaddrinfo(%s, %s, &hints, &info) returned error %i (%s)",
897                                                host_str.c_str(),
898                                                port_str.c_str(),
899                                                err,
900                                                gai_strerror(err));
901        Disconnect (NULL);
902        return eConnectionStatusError;
903    }
904
905    for (struct addrinfo *service_info_ptr = service_info_list;
906         service_info_ptr != NULL;
907         service_info_ptr = service_info_ptr->ai_next)
908    {
909        m_fd_send = ::socket (service_info_ptr->ai_family,
910                              service_info_ptr->ai_socktype,
911                              service_info_ptr->ai_protocol);
912
913        if (m_fd_send != -1)
914        {
915            m_udp_send_sockaddr = service_info_ptr;
916            break;
917        }
918        else
919            continue;
920    }
921
922    :: freeaddrinfo (service_info_list);
923
924    if (m_fd_send == -1)
925    {
926        Disconnect (NULL);
927        return eConnectionStatusError;
928    }
929
930    if (error_ptr)
931        error_ptr->Clear();
932
933    m_should_close_fd = true;
934    return eConnectionStatusSuccess;
935}
936
937#if defined(__MINGW32__) || defined(__MINGW64__)
938typedef const char * set_socket_option_arg_type;
939typedef char * get_socket_option_arg_type;
940#else // #if defined(__MINGW32__) || defined(__MINGW64__)
941typedef const void * set_socket_option_arg_type;
942typedef void * get_socket_option_arg_type;
943#endif // #if defined(__MINGW32__) || defined(__MINGW64__)
944
945int
946ConnectionFileDescriptor::GetSocketOption(int fd, int level, int option_name, int &option_value)
947{
948    get_socket_option_arg_type option_value_p = static_cast<get_socket_option_arg_type>(&option_value);
949    socklen_t option_value_size = sizeof(int);
950	return ::getsockopt(fd, level, option_name, option_value_p, &option_value_size);
951}
952
953int
954ConnectionFileDescriptor::SetSocketOption(int fd, int level, int option_name, int option_value)
955{
956    set_socket_option_arg_type option_value_p = static_cast<get_socket_option_arg_type>(&option_value);
957	return ::setsockopt(fd, level, option_name, option_value_p, sizeof(option_value));
958}
959
960bool
961ConnectionFileDescriptor::SetSocketReceiveTimeout (uint32_t timeout_usec)
962{
963    switch (m_fd_recv_type)
964    {
965        case eFDTypeFile:       // Other FD requireing read/write
966            break;
967
968        case eFDTypeSocket:     // Socket requiring send/recv
969        case eFDTypeSocketUDP:  // Unconnected UDP socket requiring sendto/recvfrom
970        {
971            // Check in case timeout for m_fd has already been set to this value
972            if (timeout_usec == m_socket_timeout_usec)
973                return true;
974            //printf ("ConnectionFileDescriptor::SetSocketReceiveTimeout (timeout_usec = %u)\n", timeout_usec);
975
976            struct timeval timeout;
977            timeout.tv_sec = timeout_usec / TimeValue::MicroSecPerSec;
978            timeout.tv_usec = timeout_usec % TimeValue::MicroSecPerSec;
979            if (::setsockopt (m_fd_recv, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) == 0)
980            {
981                m_socket_timeout_usec = timeout_usec;
982                return true;
983            }
984        }
985    }
986    return false;
987}
988
989in_port_t
990ConnectionFileDescriptor::GetSocketPort (int fd)
991{
992    // We bound to port zero, so we need to figure out which port we actually bound to
993    SocketAddress sock_addr;
994    socklen_t sock_addr_len = sock_addr.GetMaxLength ();
995    if (::getsockname (fd, sock_addr, &sock_addr_len) == 0)
996        return sock_addr.GetPort ();
997
998    return 0;
999}
1000
1001// If the read file descriptor is a socket, then return
1002// the port number that is being used by the socket.
1003in_port_t
1004ConnectionFileDescriptor::GetReadPort () const
1005{
1006    return ConnectionFileDescriptor::GetSocketPort (m_fd_recv);
1007}
1008
1009// If the write file descriptor is a socket, then return
1010// the port number that is being used by the socket.
1011in_port_t
1012ConnectionFileDescriptor::GetWritePort () const
1013{
1014    return ConnectionFileDescriptor::GetSocketPort (m_fd_send);
1015}
1016
1017
1018