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 #if defined(__APPLE__)
11 // Enable this special support for Apple builds where we can have unlimited
12 // select bounds. We tried switching to poll() and kqueue and we were panicing
13 // the kernel, so we have to stick with select for now.
14 #define _DARWIN_UNLIMITED_SELECT
15 #endif
16
17 #include "lldb/Core/ConnectionFileDescriptor.h"
18
19 // C Includes
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <arpa/inet.h>
23 #include <netdb.h>
24 #include <netinet/in.h>
25 #include <netinet/tcp.h>
26 #include <sys/socket.h>
27 #include <sys/un.h>
28 #include <termios.h>
29 #include <sys/types.h>
30 #include <string.h>
31 #include <stdlib.h>
32 #include <unistd.h>
33
34 // C++ Includes
35 // Other libraries and framework includes
36 #if defined(__APPLE__)
37 #include "llvm/ADT/SmallVector.h"
38 #endif
39 // Project includes
40 #include "lldb/lldb-private-log.h"
41 #include "lldb/Interpreter/Args.h"
42 #include "lldb/Core/Communication.h"
43 #include "lldb/Core/Log.h"
44 #include "lldb/Core/RegularExpression.h"
45 #include "lldb/Core/Timer.h"
46
47 using namespace lldb;
48 using namespace lldb_private;
49
50 static bool
DecodeHostAndPort(const char * host_and_port,std::string & host_str,std::string & port_str,int32_t & port,Error * error_ptr)51 DecodeHostAndPort (const char *host_and_port,
52 std::string &host_str,
53 std::string &port_str,
54 int32_t& port,
55 Error *error_ptr)
56 {
57 static RegularExpression g_regex ("([^:]+):([0-9]+)");
58 RegularExpression::Match regex_match(2);
59 if (g_regex.Execute (host_and_port, ®ex_match))
60 {
61 if (regex_match.GetMatchAtIndex (host_and_port, 1, host_str) &&
62 regex_match.GetMatchAtIndex (host_and_port, 2, port_str))
63 {
64 port = Args::StringToSInt32 (port_str.c_str(), INT32_MIN);
65 if (port != INT32_MIN)
66 {
67 if (error_ptr)
68 error_ptr->Clear();
69 return true;
70 }
71 }
72 }
73 host_str.clear();
74 port_str.clear();
75 port = INT32_MIN;
76 if (error_ptr)
77 error_ptr->SetErrorStringWithFormat("invalid host:port specification: '%s'", host_and_port);
78 return false;
79 }
80
ConnectionFileDescriptor()81 ConnectionFileDescriptor::ConnectionFileDescriptor () :
82 Connection(),
83 m_fd_send (-1),
84 m_fd_recv (-1),
85 m_fd_send_type (eFDTypeFile),
86 m_fd_recv_type (eFDTypeFile),
87 m_udp_send_sockaddr (),
88 m_should_close_fd (false),
89 m_socket_timeout_usec(0),
90 m_pipe_read(-1),
91 m_pipe_write(-1),
92 m_mutex (Mutex::eMutexTypeRecursive),
93 m_shutting_down (false)
94 {
95 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT));
96 if (log)
97 log->Printf ("%p ConnectionFileDescriptor::ConnectionFileDescriptor ()", this);
98 }
99
ConnectionFileDescriptor(int fd,bool owns_fd)100 ConnectionFileDescriptor::ConnectionFileDescriptor (int fd, bool owns_fd) :
101 Connection(),
102 m_fd_send (fd),
103 m_fd_recv (fd),
104 m_fd_send_type (eFDTypeFile),
105 m_fd_recv_type (eFDTypeFile),
106 m_udp_send_sockaddr (),
107 m_should_close_fd (owns_fd),
108 m_socket_timeout_usec(0),
109 m_pipe_read(-1),
110 m_pipe_write(-1),
111 m_mutex (Mutex::eMutexTypeRecursive),
112 m_shutting_down (false)
113 {
114 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT));
115 if (log)
116 log->Printf ("%p ConnectionFileDescriptor::ConnectionFileDescriptor (fd = %i, owns_fd = %i)", this, fd, owns_fd);
117 OpenCommandPipe ();
118 }
119
120
~ConnectionFileDescriptor()121 ConnectionFileDescriptor::~ConnectionFileDescriptor ()
122 {
123 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION | LIBLLDB_LOG_OBJECT));
124 if (log)
125 log->Printf ("%p ConnectionFileDescriptor::~ConnectionFileDescriptor ()", this);
126 Disconnect (NULL);
127 CloseCommandPipe ();
128 }
129
130 void
OpenCommandPipe()131 ConnectionFileDescriptor::OpenCommandPipe ()
132 {
133 CloseCommandPipe();
134
135 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
136 // Make the command file descriptor here:
137 int filedes[2];
138 int result = pipe (filedes);
139 if (result != 0)
140 {
141 if (log)
142 log->Printf ("%p ConnectionFileDescriptor::ConnectionFileDescriptor () - could not make pipe: %s",
143 this,
144 strerror(errno));
145 }
146 else
147 {
148 m_pipe_read = filedes[0];
149 m_pipe_write = filedes[1];
150 }
151 }
152
153 void
CloseCommandPipe()154 ConnectionFileDescriptor::CloseCommandPipe ()
155 {
156 if (m_pipe_read != -1)
157 {
158 close (m_pipe_read);
159 m_pipe_read = -1;
160 }
161
162 if (m_pipe_write != -1)
163 {
164 close (m_pipe_write);
165 m_pipe_write = -1;
166 }
167 }
168
169 bool
IsConnected() const170 ConnectionFileDescriptor::IsConnected () const
171 {
172 return m_fd_send >= 0 || m_fd_recv >= 0;
173 }
174
175 ConnectionStatus
Connect(const char * s,Error * error_ptr)176 ConnectionFileDescriptor::Connect (const char *s, Error *error_ptr)
177 {
178 Mutex::Locker locker (m_mutex);
179 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
180 if (log)
181 log->Printf ("%p ConnectionFileDescriptor::Connect (url = '%s')", this, s);
182
183 OpenCommandPipe();
184
185 if (s && s[0])
186 {
187 char *end = NULL;
188 if (strstr(s, "listen://"))
189 {
190 // listen://HOST:PORT
191 unsigned long listen_port = ::strtoul(s + strlen("listen://"), &end, 0);
192 return SocketListen (listen_port, error_ptr);
193 }
194 else if (strstr(s, "unix-accept://"))
195 {
196 // unix://SOCKNAME
197 return NamedSocketAccept (s + strlen("unix-accept://"), error_ptr);
198 }
199 else if (strstr(s, "connect://"))
200 {
201 return ConnectTCP (s + strlen("connect://"), error_ptr);
202 }
203 else if (strstr(s, "tcp-connect://"))
204 {
205 return ConnectTCP (s + strlen("tcp-connect://"), error_ptr);
206 }
207 else if (strstr(s, "udp://"))
208 {
209 return ConnectUDP (s + strlen("udp://"), error_ptr);
210 }
211 else if (strstr(s, "fd://"))
212 {
213 // Just passing a native file descriptor within this current process
214 // that is already opened (possibly from a service or other source).
215 s += strlen ("fd://");
216 bool success = false;
217 m_fd_send = m_fd_recv = Args::StringToSInt32 (s, -1, 0, &success);
218
219 if (success)
220 {
221 // We have what looks to be a valid file descriptor, but we
222 // should make sure it is. We currently are doing this by trying to
223 // get the flags from the file descriptor and making sure it
224 // isn't a bad fd.
225 errno = 0;
226 int flags = ::fcntl (m_fd_send, F_GETFL, 0);
227 if (flags == -1 || errno == EBADF)
228 {
229 if (error_ptr)
230 error_ptr->SetErrorStringWithFormat ("stale file descriptor: %s", s);
231 m_fd_send = m_fd_recv = -1;
232 return eConnectionStatusError;
233 }
234 else
235 {
236 // Try and get a socket option from this file descriptor to
237 // see if this is a socket and set m_is_socket accordingly.
238 int resuse;
239 bool is_socket = GetSocketOption (m_fd_send, SOL_SOCKET, SO_REUSEADDR, resuse) == 0;
240 if (is_socket)
241 m_fd_send_type = m_fd_recv_type = eFDTypeSocket;
242 // Don't take ownership of a file descriptor that gets passed
243 // to us since someone else opened the file descriptor and
244 // handed it to us.
245 // TODO: Since are using a URL to open connection we should
246 // eventually parse options using the web standard where we
247 // have "fd://123?opt1=value;opt2=value" and we can have an
248 // option be "owns=1" or "owns=0" or something like this to
249 // allow us to specify this. For now, we assume we must
250 // assume we don't own it.
251 m_should_close_fd = false;
252 return eConnectionStatusSuccess;
253 }
254 }
255
256 if (error_ptr)
257 error_ptr->SetErrorStringWithFormat ("invalid file descriptor: \"fd://%s\"", s);
258 m_fd_send = m_fd_recv = -1;
259 return eConnectionStatusError;
260 }
261 else if (strstr(s, "file://"))
262 {
263 // file:///PATH
264 const char *path = s + strlen("file://");
265 do
266 {
267 m_fd_send = m_fd_recv = ::open (path, O_RDWR);
268 } while (m_fd_send == -1 && errno == EINTR);
269 if (m_fd_send == -1)
270 {
271 if (error_ptr)
272 error_ptr->SetErrorToErrno();
273 return eConnectionStatusError;
274 }
275
276 if (::isatty(m_fd_send))
277 {
278 // Set up serial terminal emulation
279 struct termios options;
280 ::tcgetattr (m_fd_send, &options);
281
282 // Set port speed to maximum
283 ::cfsetospeed (&options, B115200);
284 ::cfsetispeed (&options, B115200);
285
286 // Raw input, disable echo and signals
287 options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
288
289 // Make sure only one character is needed to return from a read
290 options.c_cc[VMIN] = 1;
291 options.c_cc[VTIME] = 0;
292
293 ::tcsetattr (m_fd_send, TCSANOW, &options);
294 }
295
296 int flags = ::fcntl (m_fd_send, F_GETFL, 0);
297 if (flags >= 0)
298 {
299 if ((flags & O_NONBLOCK) == 0)
300 {
301 flags |= O_NONBLOCK;
302 ::fcntl (m_fd_send, F_SETFL, flags);
303 }
304 }
305 m_should_close_fd = true;
306 return eConnectionStatusSuccess;
307 }
308 if (error_ptr)
309 error_ptr->SetErrorStringWithFormat ("unsupported connection URL: '%s'", s);
310 return eConnectionStatusError;
311 }
312 if (error_ptr)
313 error_ptr->SetErrorString("invalid connect arguments");
314 return eConnectionStatusError;
315 }
316
317 ConnectionStatus
Disconnect(Error * error_ptr)318 ConnectionFileDescriptor::Disconnect (Error *error_ptr)
319 {
320 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
321 if (log)
322 log->Printf ("%p ConnectionFileDescriptor::Disconnect ()", this);
323
324 ConnectionStatus status = eConnectionStatusSuccess;
325
326 if (m_fd_send < 0 && m_fd_recv < 0)
327 {
328 if (log)
329 log->Printf ("%p ConnectionFileDescriptor::Disconnect(): Nothing to disconnect", this);
330 return eConnectionStatusSuccess;
331 }
332
333 // Try to get the ConnectionFileDescriptor's mutex. If we fail, that is quite likely
334 // because somebody is doing a blocking read on our file descriptor. If that's the case,
335 // then send the "q" char to the command file channel so the read will wake up and the connection
336 // will then know to shut down.
337
338 m_shutting_down = true;
339
340 Mutex::Locker locker;
341 bool got_lock= locker.TryLock (m_mutex);
342
343 if (!got_lock)
344 {
345 if (m_pipe_write != -1 )
346 {
347 write (m_pipe_write, "q", 1);
348 close (m_pipe_write);
349 m_pipe_write = -1;
350 }
351 locker.Lock (m_mutex);
352 }
353
354 if (m_should_close_fd == true)
355 {
356 if (m_fd_send == m_fd_recv)
357 {
358 status = Close (m_fd_send, error_ptr);
359 }
360 else
361 {
362 // File descriptors are the different, close both if needed
363 if (m_fd_send >= 0)
364 status = Close (m_fd_send, error_ptr);
365 if (m_fd_recv >= 0)
366 {
367 ConnectionStatus recv_status = Close (m_fd_recv, error_ptr);
368 if (status == eConnectionStatusSuccess)
369 status = recv_status;
370 }
371 }
372 }
373
374 // Now set all our descriptors to invalid values.
375
376 m_fd_send = m_fd_recv = -1;
377
378 if (status != eConnectionStatusSuccess)
379 {
380
381 return status;
382 }
383
384 m_shutting_down = false;
385 return eConnectionStatusSuccess;
386 }
387
388 size_t
Read(void * dst,size_t dst_len,uint32_t timeout_usec,ConnectionStatus & status,Error * error_ptr)389 ConnectionFileDescriptor::Read (void *dst,
390 size_t dst_len,
391 uint32_t timeout_usec,
392 ConnectionStatus &status,
393 Error *error_ptr)
394 {
395 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
396 if (log)
397 log->Printf ("%p ConnectionFileDescriptor::Read () ::read (fd = %i, dst = %p, dst_len = %" PRIu64 ")...",
398 this, m_fd_recv, dst, (uint64_t)dst_len);
399
400 Mutex::Locker locker;
401 bool got_lock = locker.TryLock (m_mutex);
402 if (!got_lock)
403 {
404 if (log)
405 log->Printf ("%p ConnectionFileDescriptor::Read () failed to get the connection lock.",
406 this);
407 if (error_ptr)
408 error_ptr->SetErrorString ("failed to get the connection lock for read.");
409
410 status = eConnectionStatusTimedOut;
411 return 0;
412 }
413 else if (m_shutting_down)
414 return eConnectionStatusError;
415
416 ssize_t bytes_read = 0;
417
418 status = BytesAvailable (timeout_usec, error_ptr);
419 if (status == eConnectionStatusSuccess)
420 {
421 do
422 {
423 bytes_read = ::read (m_fd_recv, dst, dst_len);
424 } while (bytes_read < 0 && errno == EINTR);
425 }
426
427 if (status != eConnectionStatusSuccess)
428 return 0;
429
430 Error error;
431 if (bytes_read == 0)
432 {
433 error.Clear(); // End-of-file. Do not automatically close; pass along for the end-of-file handlers.
434 status = eConnectionStatusEndOfFile;
435 }
436 else if (bytes_read < 0)
437 {
438 error.SetErrorToErrno();
439 }
440 else
441 {
442 error.Clear();
443 }
444
445 if (log)
446 log->Printf ("%p ConnectionFileDescriptor::Read () ::read (fd = %i, dst = %p, dst_len = %" PRIu64 ") => %" PRIi64 ", error = %s",
447 this,
448 m_fd_recv,
449 dst,
450 (uint64_t)dst_len,
451 (int64_t)bytes_read,
452 error.AsCString());
453
454 if (error_ptr)
455 *error_ptr = error;
456
457 if (error.Fail())
458 {
459 uint32_t error_value = error.GetError();
460 switch (error_value)
461 {
462 case EAGAIN: // The file was marked for non-blocking I/O, and no data were ready to be read.
463 if (m_fd_recv_type == eFDTypeSocket || m_fd_recv_type == eFDTypeSocketUDP)
464 status = eConnectionStatusTimedOut;
465 else
466 status = eConnectionStatusSuccess;
467 return 0;
468
469 case EFAULT: // Buf points outside the allocated address space.
470 case EINTR: // A read from a slow device was interrupted before any data arrived by the delivery of a signal.
471 case EINVAL: // The pointer associated with fildes was negative.
472 case EIO: // An I/O error occurred while reading from the file system.
473 // The process group is orphaned.
474 // The file is a regular file, nbyte is greater than 0,
475 // the starting position is before the end-of-file, and
476 // the starting position is greater than or equal to the
477 // offset maximum established for the open file
478 // descriptor associated with fildes.
479 case EISDIR: // An attempt is made to read a directory.
480 case ENOBUFS: // An attempt to allocate a memory buffer fails.
481 case ENOMEM: // Insufficient memory is available.
482 status = eConnectionStatusError;
483 break; // Break to close....
484
485 case ENOENT: // no such file or directory
486 case EBADF: // fildes is not a valid file or socket descriptor open for reading.
487 case ENXIO: // An action is requested of a device that does not exist..
488 // A requested action cannot be performed by the device.
489 case ECONNRESET:// The connection is closed by the peer during a read attempt on a socket.
490 case ENOTCONN: // A read is attempted on an unconnected socket.
491 status = eConnectionStatusLostConnection;
492 break; // Break to close....
493
494 case ETIMEDOUT: // A transmission timeout occurs during a read attempt on a socket.
495 status = eConnectionStatusTimedOut;
496 return 0;
497 }
498
499 return 0;
500 }
501 return bytes_read;
502 }
503
504 size_t
Write(const void * src,size_t src_len,ConnectionStatus & status,Error * error_ptr)505 ConnectionFileDescriptor::Write (const void *src, size_t src_len, ConnectionStatus &status, Error *error_ptr)
506 {
507 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
508 if (log)
509 log->Printf ("%p ConnectionFileDescriptor::Write (src = %p, src_len = %" PRIu64 ")", this, src, (uint64_t)src_len);
510
511 if (!IsConnected ())
512 {
513 if (error_ptr)
514 error_ptr->SetErrorString("not connected");
515 status = eConnectionStatusNoConnection;
516 return 0;
517 }
518
519
520 Error error;
521
522 ssize_t bytes_sent = 0;
523
524 switch (m_fd_send_type)
525 {
526 case eFDTypeFile: // Other FD requireing read/write
527 do
528 {
529 bytes_sent = ::write (m_fd_send, src, src_len);
530 } while (bytes_sent < 0 && errno == EINTR);
531 break;
532
533 case eFDTypeSocket: // Socket requiring send/recv
534 do
535 {
536 bytes_sent = ::send (m_fd_send, src, src_len, 0);
537 } while (bytes_sent < 0 && errno == EINTR);
538 break;
539
540 case eFDTypeSocketUDP: // Unconnected UDP socket requiring sendto/recvfrom
541 assert (m_udp_send_sockaddr.GetFamily() != 0);
542 do
543 {
544 bytes_sent = ::sendto (m_fd_send,
545 src,
546 src_len,
547 0,
548 m_udp_send_sockaddr,
549 m_udp_send_sockaddr.GetLength());
550 } while (bytes_sent < 0 && errno == EINTR);
551 break;
552 }
553
554 if (bytes_sent < 0)
555 error.SetErrorToErrno ();
556 else
557 error.Clear ();
558
559 if (log)
560 {
561 switch (m_fd_send_type)
562 {
563 case eFDTypeFile: // Other FD requireing read/write
564 log->Printf ("%p ConnectionFileDescriptor::Write() ::write (fd = %i, src = %p, src_len = %" PRIu64 ") => %" PRIi64 " (error = %s)",
565 this,
566 m_fd_send,
567 src,
568 (uint64_t)src_len,
569 (int64_t)bytes_sent,
570 error.AsCString());
571 break;
572
573 case eFDTypeSocket: // Socket requiring send/recv
574 log->Printf ("%p ConnectionFileDescriptor::Write() ::send (socket = %i, src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64 " (error = %s)",
575 this,
576 m_fd_send,
577 src,
578 (uint64_t)src_len,
579 (int64_t)bytes_sent,
580 error.AsCString());
581 break;
582
583 case eFDTypeSocketUDP: // Unconnected UDP socket requiring sendto/recvfrom
584 log->Printf ("%p ConnectionFileDescriptor::Write() ::sendto (socket = %i, src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64 " (error = %s)",
585 this,
586 m_fd_send,
587 src,
588 (uint64_t)src_len,
589 (int64_t)bytes_sent,
590 error.AsCString());
591 break;
592 }
593 }
594
595 if (error_ptr)
596 *error_ptr = error;
597
598 if (error.Fail())
599 {
600 switch (error.GetError())
601 {
602 case EAGAIN:
603 case EINTR:
604 status = eConnectionStatusSuccess;
605 return 0;
606
607 case ECONNRESET:// The connection is closed by the peer during a read attempt on a socket.
608 case ENOTCONN: // A read is attempted on an unconnected socket.
609 status = eConnectionStatusLostConnection;
610 break; // Break to close....
611
612 default:
613 status = eConnectionStatusError;
614 break; // Break to close....
615 }
616
617 return 0;
618 }
619
620 status = eConnectionStatusSuccess;
621 return bytes_sent;
622 }
623
624
625
626 #if defined(__APPLE__)
627
628 // This ConnectionFileDescriptor::BytesAvailable() uses select().
629 //
630 // PROS:
631 // - select is consistent across most unix platforms
632 // - this Apple specific version allows for unlimited fds in the fd_sets by
633 // setting the _DARWIN_UNLIMITED_SELECT define prior to including the
634 // required header files.
635
636 // CONS:
637 // - Darwin only
638
639 ConnectionStatus
BytesAvailable(uint32_t timeout_usec,Error * error_ptr)640 ConnectionFileDescriptor::BytesAvailable (uint32_t timeout_usec, Error *error_ptr)
641 {
642 // Don't need to take the mutex here separately since we are only called from Read. If we
643 // ever get used more generally we will need to lock here as well.
644
645 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
646 if (log)
647 log->Printf("%p ConnectionFileDescriptor::BytesAvailable (timeout_usec = %u)", this, timeout_usec);
648 struct timeval *tv_ptr;
649 struct timeval tv;
650 if (timeout_usec == UINT32_MAX)
651 {
652 // Infinite wait...
653 tv_ptr = NULL;
654 }
655 else
656 {
657 TimeValue time_value;
658 time_value.OffsetWithMicroSeconds (timeout_usec);
659 tv = time_value.GetAsTimeVal();
660 tv_ptr = &tv;
661 }
662
663 // Make a copy of the file descriptors to make sure we don't
664 // have another thread change these values out from under us
665 // and cause problems in the loop below where like in FS_SET()
666 const int data_fd = m_fd_recv;
667 const int pipe_fd = m_pipe_read;
668
669 if (data_fd >= 0)
670 {
671 const bool have_pipe_fd = pipe_fd >= 0;
672
673 while (data_fd == m_fd_recv)
674 {
675 const int nfds = std::max<int>(data_fd, pipe_fd) + 1;
676 llvm::SmallVector<fd_set, 1> read_fds;
677 read_fds.resize((nfds/FD_SETSIZE) + 1);
678 for (size_t i=0; i<read_fds.size(); ++i)
679 FD_ZERO (&read_fds[i]);
680 // FD_SET doesn't bounds check, it just happily walks off the end
681 // but we have taken care of making the extra storage with our
682 // SmallVector of fd_set objects
683 FD_SET (data_fd, read_fds.data());
684 if (have_pipe_fd)
685 FD_SET (pipe_fd, read_fds.data());
686
687 Error error;
688
689 if (log)
690 {
691 if (have_pipe_fd)
692 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i, %i}, NULL, NULL, timeout=%p)...",
693 this, nfds, data_fd, pipe_fd, tv_ptr);
694 else
695 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i}, NULL, NULL, timeout=%p)...",
696 this, nfds, data_fd, tv_ptr);
697 }
698
699 const int num_set_fds = ::select (nfds, read_fds.data(), NULL, NULL, tv_ptr);
700 if (num_set_fds < 0)
701 error.SetErrorToErrno();
702 else
703 error.Clear();
704
705 if (log)
706 {
707 if (have_pipe_fd)
708 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i, %i}, NULL, NULL, timeout=%p) => %d, error = %s",
709 this, nfds, data_fd, pipe_fd, tv_ptr, num_set_fds, error.AsCString());
710 else
711 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i}, NULL, NULL, timeout=%p) => %d, error = %s",
712 this, nfds, data_fd, tv_ptr, num_set_fds, error.AsCString());
713 }
714
715 if (error_ptr)
716 *error_ptr = error;
717
718 if (error.Fail())
719 {
720 switch (error.GetError())
721 {
722 case EBADF: // One of the descriptor sets specified an invalid descriptor.
723 return eConnectionStatusLostConnection;
724
725 case EINVAL: // The specified time limit is invalid. One of its components is negative or too large.
726 default: // Other unknown error
727 return eConnectionStatusError;
728
729 case EAGAIN: // The kernel was (perhaps temporarily) unable to
730 // allocate the requested number of file descriptors,
731 // or we have non-blocking IO
732 case EINTR: // A signal was delivered before the time limit
733 // expired and before any of the selected events
734 // occurred.
735 break; // Lets keep reading to until we timeout
736 }
737 }
738 else if (num_set_fds == 0)
739 {
740 return eConnectionStatusTimedOut;
741 }
742 else if (num_set_fds > 0)
743 {
744 // FD_ISSET is happy to deal with a something larger than
745 // a single fd_set.
746 if (FD_ISSET(data_fd, read_fds.data()))
747 return eConnectionStatusSuccess;
748 if (have_pipe_fd && FD_ISSET(pipe_fd, read_fds.data()))
749 {
750 // We got a command to exit. Read the data from that pipe:
751 char buffer[16];
752 ssize_t bytes_read;
753
754 do
755 {
756 bytes_read = ::read (pipe_fd, buffer, sizeof(buffer));
757 } while (bytes_read < 0 && errno == EINTR);
758 assert (bytes_read == 1 && buffer[0] == 'q');
759
760 if (log)
761 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() got data: %*s from the command channel.",
762 this, (int) bytes_read, buffer);
763
764 return eConnectionStatusEndOfFile;
765 }
766 }
767 }
768 }
769
770 if (error_ptr)
771 error_ptr->SetErrorString("not connected");
772 return eConnectionStatusLostConnection;
773 }
774
775 #else
776
777 // This ConnectionFileDescriptor::BytesAvailable() uses select().
778 //
779 // PROS:
780 // - select is consistent across most unix platforms
781 // CONS:
782 // - only supports file descriptors up to FD_SETSIZE. This implementation
783 // will assert if it runs into that hard limit to let users know that
784 // another ConnectionFileDescriptor::BytesAvailable() should be used
785 // or a new version of ConnectionFileDescriptor::BytesAvailable() should
786 // be written for the system that is running into the limitations. MacOSX
787 // uses kqueues, and there is a poll() based implementation below.
788
789 ConnectionStatus
BytesAvailable(uint32_t timeout_usec,Error * error_ptr)790 ConnectionFileDescriptor::BytesAvailable (uint32_t timeout_usec, Error *error_ptr)
791 {
792 // Don't need to take the mutex here separately since we are only called from Read. If we
793 // ever get used more generally we will need to lock here as well.
794
795 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
796 if (log)
797 log->Printf("%p ConnectionFileDescriptor::BytesAvailable (timeout_usec = %u)", this, timeout_usec);
798 struct timeval *tv_ptr;
799 struct timeval tv;
800 if (timeout_usec == UINT32_MAX)
801 {
802 // Infinite wait...
803 tv_ptr = NULL;
804 }
805 else
806 {
807 TimeValue time_value;
808 time_value.OffsetWithMicroSeconds (timeout_usec);
809 tv = time_value.GetAsTimeVal();
810 tv_ptr = &tv;
811 }
812
813 // Make a copy of the file descriptors to make sure we don't
814 // have another thread change these values out from under us
815 // and cause problems in the loop below where like in FS_SET()
816 const int data_fd = m_fd_recv;
817 const int pipe_fd = m_pipe_read;
818
819 if (data_fd >= 0)
820 {
821 // If this assert fires off on MacOSX, we will need to switch to using
822 // libdispatch to read from file descriptors because poll() is causing
823 // kernel panics and if we exceed FD_SETSIZE we will have no choice...
824 assert (data_fd < FD_SETSIZE);
825
826 const bool have_pipe_fd = pipe_fd >= 0;
827
828 if (have_pipe_fd)
829 {
830 assert (pipe_fd < FD_SETSIZE);
831 }
832
833 while (data_fd == m_fd_recv)
834 {
835 fd_set read_fds;
836 FD_ZERO (&read_fds);
837 FD_SET (data_fd, &read_fds);
838 if (have_pipe_fd)
839 FD_SET (pipe_fd, &read_fds);
840
841 const int nfds = std::max<int>(data_fd, pipe_fd) + 1;
842
843 Error error;
844
845 if (log)
846 {
847 if (have_pipe_fd)
848 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i, %i}, NULL, NULL, timeout=%p)...",
849 this, nfds, data_fd, pipe_fd, tv_ptr);
850 else
851 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i}, NULL, NULL, timeout=%p)...",
852 this, nfds, data_fd, tv_ptr);
853 }
854
855 const int num_set_fds = ::select (nfds, &read_fds, NULL, NULL, tv_ptr);
856 if (num_set_fds < 0)
857 error.SetErrorToErrno();
858 else
859 error.Clear();
860
861 if (log)
862 {
863 if (have_pipe_fd)
864 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i, %i}, NULL, NULL, timeout=%p) => %d, error = %s",
865 this, nfds, data_fd, pipe_fd, tv_ptr, num_set_fds, error.AsCString());
866 else
867 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i}, NULL, NULL, timeout=%p) => %d, error = %s",
868 this, nfds, data_fd, tv_ptr, num_set_fds, error.AsCString());
869 }
870
871 if (error_ptr)
872 *error_ptr = error;
873
874 if (error.Fail())
875 {
876 switch (error.GetError())
877 {
878 case EBADF: // One of the descriptor sets specified an invalid descriptor.
879 return eConnectionStatusLostConnection;
880
881 case EINVAL: // The specified time limit is invalid. One of its components is negative or too large.
882 default: // Other unknown error
883 return eConnectionStatusError;
884
885 case EAGAIN: // The kernel was (perhaps temporarily) unable to
886 // allocate the requested number of file descriptors,
887 // or we have non-blocking IO
888 case EINTR: // A signal was delivered before the time limit
889 // expired and before any of the selected events
890 // occurred.
891 break; // Lets keep reading to until we timeout
892 }
893 }
894 else if (num_set_fds == 0)
895 {
896 return eConnectionStatusTimedOut;
897 }
898 else if (num_set_fds > 0)
899 {
900 if (FD_ISSET(data_fd, &read_fds))
901 return eConnectionStatusSuccess;
902 if (have_pipe_fd && FD_ISSET(pipe_fd, &read_fds))
903 {
904 // We got a command to exit. Read the data from that pipe:
905 char buffer[16];
906 ssize_t bytes_read;
907
908 do
909 {
910 bytes_read = ::read (pipe_fd, buffer, sizeof(buffer));
911 } while (bytes_read < 0 && errno == EINTR);
912 assert (bytes_read == 1 && buffer[0] == 'q');
913
914 if (log)
915 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() got data: %*s from the command channel.",
916 this, (int) bytes_read, buffer);
917
918 return eConnectionStatusEndOfFile;
919 }
920 }
921 }
922 }
923
924 if (error_ptr)
925 error_ptr->SetErrorString("not connected");
926 return eConnectionStatusLostConnection;
927 }
928
929 #endif
930
931 #if 0
932 #include <poll.h>
933
934 // This ConnectionFileDescriptor::BytesAvailable() uses poll(). poll() should NOT
935 // be used on MacOSX as it has all sorts of restrictions on the types of file descriptors
936 // that it doesn't support.
937 //
938 // There may be some systems that properly support poll() that could use this
939 // implementation. I will let each system opt into this on their own.
940 //
941 // PROS:
942 // - no restrictions on the fd value that is used
943 // CONS:
944 // - varies wildly from platform to platform in its implementation restrictions
945
946 ConnectionStatus
947 ConnectionFileDescriptor::BytesAvailable (uint32_t timeout_usec, Error *error_ptr)
948 {
949 // Don't need to take the mutex here separately since we are only called from Read. If we
950 // ever get used more generally we will need to lock here as well.
951
952 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
953 if (log)
954 log->Printf("%p ConnectionFileDescriptor::BytesAvailable (timeout_usec = %u)", this, timeout_usec);
955 int timeout_msec = 0;
956 if (timeout_usec == UINT32_MAX)
957 {
958 // Infinite wait...
959 timeout_msec = -1;
960 }
961 else if (timeout_usec == 0)
962 {
963 // Return immediately, don't wait
964 timeout_msec = 0;
965 }
966 else
967 {
968 // Convert usec to msec
969 timeout_msec = (timeout_usec + 999) / 1000;
970 }
971
972 // Make a copy of the file descriptors to make sure we don't
973 // have another thread change these values out from under us
974 // and cause problems in the loop below where like in FS_SET()
975 const int data_fd = m_fd_recv;
976 const int pipe_fd = m_pipe_read;
977
978 // Make sure the file descriptor can be used with select as it
979 // must be in range
980 if (data_fd >= 0)
981 {
982 const bool have_pipe_fd = pipe_fd >= 0;
983 struct pollfd fds[2] =
984 {
985 { data_fd, POLLIN, 0 },
986 { pipe_fd, POLLIN, 0 }
987 };
988 const int nfds = have_pipe_fd ? 2 : 1;
989 Error error;
990 while (data_fd == m_fd_recv)
991 {
992 const int num_set_fds = ::poll (fds, nfds, timeout_msec);
993
994 if (num_set_fds < 0)
995 error.SetErrorToErrno();
996 else
997 error.Clear();
998
999 if (error_ptr)
1000 *error_ptr = error;
1001
1002 if (log)
1003 {
1004 if (have_pipe_fd)
1005 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::poll (fds={{%i,POLLIN},{%i,POLLIN}}, nfds=%i, timeout_ms=%i) => %d, error = %s\n",
1006 this,
1007 data_fd,
1008 pipe_fd,
1009 nfds,
1010 timeout_msec,
1011 num_set_fds,
1012 error.AsCString());
1013 else
1014 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::poll (fds={{%i,POLLIN}}, nfds=%i, timeout_ms=%i) => %d, error = %s\n",
1015 this,
1016 data_fd,
1017 nfds,
1018 timeout_msec,
1019 num_set_fds,
1020 error.AsCString());
1021 }
1022
1023 if (error.Fail())
1024 {
1025 switch (error.GetError())
1026 {
1027 case EBADF: // One of the descriptor sets specified an invalid descriptor.
1028 return eConnectionStatusLostConnection;
1029
1030 case EINVAL: // The specified time limit is invalid. One of its components is negative or too large.
1031 default: // Other unknown error
1032 return eConnectionStatusError;
1033
1034 case EAGAIN: // The kernel was (perhaps temporarily) unable to
1035 // allocate the requested number of file descriptors,
1036 // or we have non-blocking IO
1037 case EINTR: // A signal was delivered before the time limit
1038 // expired and before any of the selected events
1039 // occurred.
1040 break; // Lets keep reading to until we timeout
1041 }
1042 }
1043 else if (num_set_fds == 0)
1044 {
1045 return eConnectionStatusTimedOut;
1046 }
1047 else if (num_set_fds > 0)
1048 {
1049 if (fds[0].revents & POLLIN)
1050 return eConnectionStatusSuccess;
1051 if (fds[1].revents & POLLIN)
1052 {
1053 // We got a command to exit. Read the data from that pipe:
1054 char buffer[16];
1055 ssize_t bytes_read;
1056
1057 do
1058 {
1059 bytes_read = ::read (pipe_fd, buffer, sizeof(buffer));
1060 } while (bytes_read < 0 && errno == EINTR);
1061 assert (bytes_read == 1 && buffer[0] == 'q');
1062
1063 if (log)
1064 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() got data: %*s from the command channel.",
1065 this, (int) bytes_read, buffer);
1066
1067 return eConnectionStatusEndOfFile;
1068 }
1069 }
1070 }
1071 }
1072 if (error_ptr)
1073 error_ptr->SetErrorString("not connected");
1074 return eConnectionStatusLostConnection;
1075 }
1076
1077 #endif
1078
1079 ConnectionStatus
Close(int & fd,Error * error_ptr)1080 ConnectionFileDescriptor::Close (int& fd, Error *error_ptr)
1081 {
1082 if (error_ptr)
1083 error_ptr->Clear();
1084 bool success = true;
1085 // Avoid taking a lock if we can
1086 if (fd >= 0)
1087 {
1088 Mutex::Locker locker (m_mutex);
1089 // Check the FD after the lock is taken to ensure only one thread
1090 // can get into the close scope below
1091 if (fd >= 0)
1092 {
1093 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
1094 if (log)
1095 log->Printf ("%p ConnectionFileDescriptor::Close (fd = %i)", this,fd);
1096
1097 success = ::close (fd) == 0;
1098 // A reference to a FD was passed in, set it to an invalid value
1099 fd = -1;
1100 if (!success && error_ptr)
1101 {
1102 // Only set the error if we have been asked to since something else
1103 // might have caused us to try and shut down the connection and may
1104 // have already set the error.
1105 error_ptr->SetErrorToErrno();
1106 }
1107 }
1108 }
1109 if (success)
1110 return eConnectionStatusSuccess;
1111 else
1112 return eConnectionStatusError;
1113 }
1114
1115 ConnectionStatus
NamedSocketAccept(const char * socket_name,Error * error_ptr)1116 ConnectionFileDescriptor::NamedSocketAccept (const char *socket_name, Error *error_ptr)
1117 {
1118 ConnectionStatus result = eConnectionStatusError;
1119 struct sockaddr_un saddr_un;
1120
1121 m_fd_send_type = m_fd_recv_type = eFDTypeSocket;
1122
1123 int listen_socket = ::socket (AF_UNIX, SOCK_STREAM, 0);
1124 if (listen_socket == -1)
1125 {
1126 if (error_ptr)
1127 error_ptr->SetErrorToErrno();
1128 return eConnectionStatusError;
1129 }
1130
1131 saddr_un.sun_family = AF_UNIX;
1132 ::strncpy(saddr_un.sun_path, socket_name, sizeof(saddr_un.sun_path) - 1);
1133 saddr_un.sun_path[sizeof(saddr_un.sun_path) - 1] = '\0';
1134 #if defined(__APPLE__) || defined(__FreeBSD__)
1135 saddr_un.sun_len = SUN_LEN (&saddr_un);
1136 #endif
1137
1138 if (::bind (listen_socket, (struct sockaddr *)&saddr_un, SUN_LEN (&saddr_un)) == 0)
1139 {
1140 if (::listen (listen_socket, 5) == 0)
1141 {
1142 m_fd_send = m_fd_recv = ::accept (listen_socket, NULL, 0);
1143 if (m_fd_send > 0)
1144 {
1145 m_should_close_fd = true;
1146
1147 if (error_ptr)
1148 error_ptr->Clear();
1149 result = eConnectionStatusSuccess;
1150 }
1151 }
1152 }
1153
1154 if (result != eConnectionStatusSuccess)
1155 {
1156 if (error_ptr)
1157 error_ptr->SetErrorToErrno();
1158 }
1159 // We are done with the listen port
1160 Close (listen_socket, NULL);
1161 return result;
1162 }
1163
1164 ConnectionStatus
NamedSocketConnect(const char * socket_name,Error * error_ptr)1165 ConnectionFileDescriptor::NamedSocketConnect (const char *socket_name, Error *error_ptr)
1166 {
1167 Disconnect (NULL);
1168 m_fd_send_type = m_fd_recv_type = eFDTypeSocket;
1169
1170 // Open the socket that was passed in as an option
1171 struct sockaddr_un saddr_un;
1172 m_fd_send = m_fd_recv = ::socket (AF_UNIX, SOCK_STREAM, 0);
1173 if (m_fd_send == -1)
1174 {
1175 if (error_ptr)
1176 error_ptr->SetErrorToErrno();
1177 return eConnectionStatusError;
1178 }
1179
1180 saddr_un.sun_family = AF_UNIX;
1181 ::strncpy(saddr_un.sun_path, socket_name, sizeof(saddr_un.sun_path) - 1);
1182 saddr_un.sun_path[sizeof(saddr_un.sun_path) - 1] = '\0';
1183 #if defined(__APPLE__) || defined(__FreeBSD__)
1184 saddr_un.sun_len = SUN_LEN (&saddr_un);
1185 #endif
1186
1187 if (::connect (m_fd_send, (struct sockaddr *)&saddr_un, SUN_LEN (&saddr_un)) < 0)
1188 {
1189 if (error_ptr)
1190 error_ptr->SetErrorToErrno();
1191 Disconnect (NULL);
1192 return eConnectionStatusError;
1193 }
1194 if (error_ptr)
1195 error_ptr->Clear();
1196 return eConnectionStatusSuccess;
1197 }
1198
1199 ConnectionStatus
SocketListen(uint16_t listen_port_num,Error * error_ptr)1200 ConnectionFileDescriptor::SocketListen (uint16_t listen_port_num, Error *error_ptr)
1201 {
1202 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
1203 if (log)
1204 log->Printf ("%p ConnectionFileDescriptor::SocketListen (port = %i)", this, listen_port_num);
1205
1206 Disconnect (NULL);
1207 m_fd_send_type = m_fd_recv_type = eFDTypeSocket;
1208 int listen_port = ::socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
1209 if (listen_port == -1)
1210 {
1211 if (error_ptr)
1212 error_ptr->SetErrorToErrno();
1213 return eConnectionStatusError;
1214 }
1215
1216 // enable local address reuse
1217 SetSocketOption (listen_port, SOL_SOCKET, SO_REUSEADDR, 1);
1218
1219 SocketAddress localhost;
1220 if (localhost.SetToLocalhost (AF_INET, listen_port_num))
1221 {
1222 int err = ::bind (listen_port, localhost, localhost.GetLength());
1223 if (err == -1)
1224 {
1225 if (error_ptr)
1226 error_ptr->SetErrorToErrno();
1227 Close (listen_port, NULL);
1228 return eConnectionStatusError;
1229 }
1230
1231 err = ::listen (listen_port, 1);
1232 if (err == -1)
1233 {
1234 if (error_ptr)
1235 error_ptr->SetErrorToErrno();
1236 Close (listen_port, NULL);
1237 return eConnectionStatusError;
1238 }
1239
1240 m_fd_send = m_fd_recv = ::accept (listen_port, NULL, 0);
1241 if (m_fd_send == -1)
1242 {
1243 if (error_ptr)
1244 error_ptr->SetErrorToErrno();
1245 Close (listen_port, NULL);
1246 return eConnectionStatusError;
1247 }
1248 }
1249
1250 // We are done with the listen port
1251 Close (listen_port, NULL);
1252
1253 m_should_close_fd = true;
1254
1255 // Keep our TCP packets coming without any delays.
1256 SetSocketOption (m_fd_send, IPPROTO_TCP, TCP_NODELAY, 1);
1257 if (error_ptr)
1258 error_ptr->Clear();
1259 return eConnectionStatusSuccess;
1260 }
1261
1262 ConnectionStatus
ConnectTCP(const char * host_and_port,Error * error_ptr)1263 ConnectionFileDescriptor::ConnectTCP (const char *host_and_port, Error *error_ptr)
1264 {
1265 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
1266 if (log)
1267 log->Printf ("%p ConnectionFileDescriptor::ConnectTCP (host/port = %s)", this, host_and_port);
1268 Disconnect (NULL);
1269
1270 m_fd_send_type = m_fd_recv_type = eFDTypeSocket;
1271 std::string host_str;
1272 std::string port_str;
1273 int32_t port = INT32_MIN;
1274 if (!DecodeHostAndPort (host_and_port, host_str, port_str, port, error_ptr))
1275 return eConnectionStatusError;
1276
1277 // Create the socket
1278 m_fd_send = m_fd_recv = ::socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
1279 if (m_fd_send == -1)
1280 {
1281 if (error_ptr)
1282 error_ptr->SetErrorToErrno();
1283 return eConnectionStatusError;
1284 }
1285
1286 m_should_close_fd = true;
1287
1288 // Enable local address reuse
1289 SetSocketOption (m_fd_send, SOL_SOCKET, SO_REUSEADDR, 1);
1290
1291 struct sockaddr_in sa;
1292 ::memset (&sa, 0, sizeof (sa));
1293 sa.sin_family = AF_INET;
1294 sa.sin_port = htons (port);
1295
1296 int inet_pton_result = ::inet_pton (AF_INET, host_str.c_str(), &sa.sin_addr);
1297
1298 if (inet_pton_result <= 0)
1299 {
1300 struct hostent *host_entry = gethostbyname (host_str.c_str());
1301 if (host_entry)
1302 host_str = ::inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list);
1303 inet_pton_result = ::inet_pton (AF_INET, host_str.c_str(), &sa.sin_addr);
1304 if (inet_pton_result <= 0)
1305 {
1306
1307 if (error_ptr)
1308 {
1309 if (inet_pton_result == -1)
1310 error_ptr->SetErrorToErrno();
1311 else
1312 error_ptr->SetErrorStringWithFormat("invalid host string: '%s'", host_str.c_str());
1313 }
1314 Disconnect (NULL);
1315
1316 return eConnectionStatusError;
1317 }
1318 }
1319
1320 if (-1 == ::connect (m_fd_send, (const struct sockaddr *)&sa, sizeof(sa)))
1321 {
1322 if (error_ptr)
1323 error_ptr->SetErrorToErrno();
1324 Disconnect (NULL);
1325
1326 return eConnectionStatusError;
1327 }
1328
1329 // Keep our TCP packets coming without any delays.
1330 SetSocketOption (m_fd_send, IPPROTO_TCP, TCP_NODELAY, 1);
1331 if (error_ptr)
1332 error_ptr->Clear();
1333 return eConnectionStatusSuccess;
1334 }
1335
1336 ConnectionStatus
ConnectUDP(const char * host_and_port,Error * error_ptr)1337 ConnectionFileDescriptor::ConnectUDP (const char *host_and_port, Error *error_ptr)
1338 {
1339 Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
1340 if (log)
1341 log->Printf ("%p ConnectionFileDescriptor::ConnectUDP (host/port = %s)", this, host_and_port);
1342 Disconnect (NULL);
1343
1344 m_fd_send_type = m_fd_recv_type = eFDTypeSocketUDP;
1345
1346 std::string host_str;
1347 std::string port_str;
1348 int32_t port = INT32_MIN;
1349 if (!DecodeHostAndPort (host_and_port, host_str, port_str, port, error_ptr))
1350 return eConnectionStatusError;
1351
1352 // Setup the receiving end of the UDP connection on this localhost
1353 // on port zero. After we bind to port zero we can read the port.
1354 m_fd_recv = ::socket (AF_INET, SOCK_DGRAM, 0);
1355 if (m_fd_recv == -1)
1356 {
1357 // Socket creation failed...
1358 if (error_ptr)
1359 error_ptr->SetErrorToErrno();
1360 }
1361 else
1362 {
1363 // Socket was created, now lets bind to the requested port
1364 SocketAddress addr;
1365 addr.SetToLocalhost (AF_INET, 0);
1366
1367 if (::bind (m_fd_recv, addr, addr.GetLength()) == -1)
1368 {
1369 // Bind failed...
1370 if (error_ptr)
1371 error_ptr->SetErrorToErrno();
1372 Disconnect (NULL);
1373 }
1374 }
1375
1376 if (m_fd_recv == -1)
1377 return eConnectionStatusError;
1378
1379 // At this point we have setup the recieve port, now we need to
1380 // setup the UDP send socket
1381
1382 struct addrinfo hints;
1383 struct addrinfo *service_info_list = NULL;
1384
1385 ::memset (&hints, 0, sizeof(hints));
1386 hints.ai_family = AF_INET;
1387 hints.ai_socktype = SOCK_DGRAM;
1388 int err = ::getaddrinfo (host_str.c_str(), port_str.c_str(), &hints, &service_info_list);
1389 if (err != 0)
1390 {
1391 if (error_ptr)
1392 error_ptr->SetErrorStringWithFormat("getaddrinfo(%s, %s, &hints, &info) returned error %i (%s)",
1393 host_str.c_str(),
1394 port_str.c_str(),
1395 err,
1396 gai_strerror(err));
1397 Disconnect (NULL);
1398 return eConnectionStatusError;
1399 }
1400
1401 for (struct addrinfo *service_info_ptr = service_info_list;
1402 service_info_ptr != NULL;
1403 service_info_ptr = service_info_ptr->ai_next)
1404 {
1405 m_fd_send = ::socket (service_info_ptr->ai_family,
1406 service_info_ptr->ai_socktype,
1407 service_info_ptr->ai_protocol);
1408
1409 if (m_fd_send != -1)
1410 {
1411 m_udp_send_sockaddr = service_info_ptr;
1412 break;
1413 }
1414 else
1415 continue;
1416 }
1417
1418 :: freeaddrinfo (service_info_list);
1419
1420 if (m_fd_send == -1)
1421 {
1422 Disconnect (NULL);
1423 return eConnectionStatusError;
1424 }
1425
1426 if (error_ptr)
1427 error_ptr->Clear();
1428
1429 m_should_close_fd = true;
1430 return eConnectionStatusSuccess;
1431 }
1432
1433 #if defined(__MINGW32__) || defined(__MINGW64__)
1434 typedef const char * set_socket_option_arg_type;
1435 typedef char * get_socket_option_arg_type;
1436 #else // #if defined(__MINGW32__) || defined(__MINGW64__)
1437 typedef const void * set_socket_option_arg_type;
1438 typedef void * get_socket_option_arg_type;
1439 #endif // #if defined(__MINGW32__) || defined(__MINGW64__)
1440
1441 int
GetSocketOption(int fd,int level,int option_name,int & option_value)1442 ConnectionFileDescriptor::GetSocketOption(int fd, int level, int option_name, int &option_value)
1443 {
1444 get_socket_option_arg_type option_value_p = static_cast<get_socket_option_arg_type>(&option_value);
1445 socklen_t option_value_size = sizeof(int);
1446 return ::getsockopt(fd, level, option_name, option_value_p, &option_value_size);
1447 }
1448
1449 int
SetSocketOption(int fd,int level,int option_name,int option_value)1450 ConnectionFileDescriptor::SetSocketOption(int fd, int level, int option_name, int option_value)
1451 {
1452 set_socket_option_arg_type option_value_p = static_cast<get_socket_option_arg_type>(&option_value);
1453 return ::setsockopt(fd, level, option_name, option_value_p, sizeof(option_value));
1454 }
1455
1456 bool
SetSocketReceiveTimeout(uint32_t timeout_usec)1457 ConnectionFileDescriptor::SetSocketReceiveTimeout (uint32_t timeout_usec)
1458 {
1459 switch (m_fd_recv_type)
1460 {
1461 case eFDTypeFile: // Other FD requireing read/write
1462 break;
1463
1464 case eFDTypeSocket: // Socket requiring send/recv
1465 case eFDTypeSocketUDP: // Unconnected UDP socket requiring sendto/recvfrom
1466 {
1467 // Check in case timeout for m_fd has already been set to this value
1468 if (timeout_usec == m_socket_timeout_usec)
1469 return true;
1470 //printf ("ConnectionFileDescriptor::SetSocketReceiveTimeout (timeout_usec = %u)\n", timeout_usec);
1471
1472 struct timeval timeout;
1473 if (timeout_usec == UINT32_MAX)
1474 {
1475 timeout.tv_sec = 0;
1476 timeout.tv_usec = 0;
1477 }
1478 else if (timeout_usec == 0)
1479 {
1480 // Sending in zero does an infinite timeout, so set this as low
1481 // as we can go to get an effective zero timeout...
1482 timeout.tv_sec = 0;
1483 timeout.tv_usec = 1;
1484 }
1485 else
1486 {
1487 timeout.tv_sec = timeout_usec / TimeValue::MicroSecPerSec;
1488 timeout.tv_usec = timeout_usec % TimeValue::MicroSecPerSec;
1489 }
1490 if (::setsockopt (m_fd_recv, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) == 0)
1491 {
1492 m_socket_timeout_usec = timeout_usec;
1493 return true;
1494 }
1495 }
1496 }
1497 return false;
1498 }
1499
1500 in_port_t
GetSocketPort(int fd)1501 ConnectionFileDescriptor::GetSocketPort (int fd)
1502 {
1503 // We bound to port zero, so we need to figure out which port we actually bound to
1504 SocketAddress sock_addr;
1505 socklen_t sock_addr_len = sock_addr.GetMaxLength ();
1506 if (::getsockname (fd, sock_addr, &sock_addr_len) == 0)
1507 return sock_addr.GetPort ();
1508
1509 return 0;
1510 }
1511
1512 // If the read file descriptor is a socket, then return
1513 // the port number that is being used by the socket.
1514 in_port_t
GetReadPort() const1515 ConnectionFileDescriptor::GetReadPort () const
1516 {
1517 return ConnectionFileDescriptor::GetSocketPort (m_fd_recv);
1518 }
1519
1520 // If the write file descriptor is a socket, then return
1521 // the port number that is being used by the socket.
1522 in_port_t
GetWritePort() const1523 ConnectionFileDescriptor::GetWritePort () const
1524 {
1525 return ConnectionFileDescriptor::GetSocketPort (m_fd_send);
1526 }
1527
1528
1529