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