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