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