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