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