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