ConnectionFileDescriptor.cpp revision aa119ddd6de5a572175d56dd033181a1f3dd19f6
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 Mutex::Locker locker (m_mutex); 238 LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); 239 if (log) 240 log->Printf ("%p ConnectionFileDescriptor::Disconnect ()", this); 241 if (m_should_close_fd == false) 242 { 243 m_fd_send = m_fd_recv = -1; 244 return eConnectionStatusSuccess; 245 } 246 ConnectionStatus status = eConnectionStatusSuccess; 247 if (m_fd_send == m_fd_recv) 248 { 249 // Both file descriptors are the same, only close one 250 status = Close (m_fd_send, error_ptr); 251 m_fd_recv = -1; 252 } 253 else 254 { 255 // File descriptors are the different, close both if needed 256 if (m_fd_send >= 0) 257 status = Close (m_fd_send, error_ptr); 258 if (m_fd_recv >= 0) 259 { 260 ConnectionStatus recv_status = Close (m_fd_recv, error_ptr); 261 if (status == eConnectionStatusSuccess) 262 status = recv_status; 263 } 264 } 265 return status; 266} 267 268size_t 269ConnectionFileDescriptor::Read (void *dst, 270 size_t dst_len, 271 uint32_t timeout_usec, 272 ConnectionStatus &status, 273 Error *error_ptr) 274{ 275 LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); 276 if (log) 277 log->Printf ("%p ConnectionFileDescriptor::Read () ::read (fd = %i, dst = %p, dst_len = %zu)...", 278 this, m_fd_recv, dst, dst_len); 279 280 ssize_t bytes_read = 0; 281 282 switch (m_fd_recv_type) 283 { 284 case eFDTypeFile: // Other FD requireing read/write 285 status = BytesAvailable (timeout_usec, error_ptr); 286 if (status == eConnectionStatusSuccess) 287 { 288 do 289 { 290 bytes_read = ::read (m_fd_recv, dst, dst_len); 291 } while (bytes_read < 0 && errno == EINTR); 292 } 293 break; 294 295 case eFDTypeSocket: // Socket requiring send/recv 296 if (SetSocketReceiveTimeout (timeout_usec)) 297 { 298 status = eConnectionStatusSuccess; 299 do 300 { 301 bytes_read = ::recv (m_fd_recv, dst, dst_len, 0); 302 } while (bytes_read < 0 && errno == EINTR); 303 } 304 break; 305 306 case eFDTypeSocketUDP: // Unconnected UDP socket requiring sendto/recvfrom 307 if (SetSocketReceiveTimeout (timeout_usec)) 308 { 309 status = eConnectionStatusSuccess; 310 SocketAddress from (m_udp_send_sockaddr); 311 socklen_t from_len = m_udp_send_sockaddr.GetLength(); 312 do 313 { 314 bytes_read = ::recvfrom (m_fd_recv, dst, dst_len, 0, (struct sockaddr *)&from, &from_len); 315 } while (bytes_read < 0 && errno == EINTR); 316 } 317 break; 318 } 319 320 if (status != eConnectionStatusSuccess) 321 return 0; 322 323 Error error; 324 if (bytes_read == 0) 325 { 326 error.Clear(); // End-of-file. Do not automatically close; pass along for the end-of-file handlers. 327 status = eConnectionStatusEndOfFile; 328 } 329 else if (bytes_read < 0) 330 { 331 error.SetErrorToErrno(); 332 } 333 else 334 { 335 error.Clear(); 336 } 337 338 if (log) 339 log->Printf ("%p ConnectionFileDescriptor::Read () ::read (fd = %i, dst = %p, dst_len = %zu) => %zi, error = %s", 340 this, 341 m_fd_recv, 342 dst, 343 dst_len, 344 bytes_read, 345 error.AsCString()); 346 347 if (error_ptr) 348 *error_ptr = error; 349 350 if (error.Fail()) 351 { 352 uint32_t error_value = error.GetError(); 353 switch (error_value) 354 { 355 case EAGAIN: // The file was marked for non-blocking I/O, and no data were ready to be read. 356 if (m_fd_recv_type == eFDTypeSocket || m_fd_recv_type == eFDTypeSocketUDP) 357 status = eConnectionStatusTimedOut; 358 else 359 status = eConnectionStatusSuccess; 360 return 0; 361 362 case EFAULT: // Buf points outside the allocated address space. 363 case EINTR: // A read from a slow device was interrupted before any data arrived by the delivery of a signal. 364 case EINVAL: // The pointer associated with fildes was negative. 365 case EIO: // An I/O error occurred while reading from the file system. 366 // The process group is orphaned. 367 // The file is a regular file, nbyte is greater than 0, 368 // the starting position is before the end-of-file, and 369 // the starting position is greater than or equal to the 370 // offset maximum established for the open file 371 // descriptor associated with fildes. 372 case EISDIR: // An attempt is made to read a directory. 373 case ENOBUFS: // An attempt to allocate a memory buffer fails. 374 case ENOMEM: // Insufficient memory is available. 375 status = eConnectionStatusError; 376 break; // Break to close.... 377 378 case ENOENT: // no such file or directory 379 case EBADF: // fildes is not a valid file or socket descriptor open for reading. 380 case ENXIO: // An action is requested of a device that does not exist.. 381 // A requested action cannot be performed by the device. 382 case ECONNRESET:// The connection is closed by the peer during a read attempt on a socket. 383 case ENOTCONN: // A read is attempted on an unconnected socket. 384 status = eConnectionStatusLostConnection; 385 break; // Break to close.... 386 387 case ETIMEDOUT: // A transmission timeout occurs during a read attempt on a socket. 388 status = eConnectionStatusTimedOut; 389 return 0; 390 } 391 392 Disconnect (NULL); 393 return 0; 394 } 395 return bytes_read; 396} 397 398size_t 399ConnectionFileDescriptor::Write (const void *src, size_t src_len, ConnectionStatus &status, Error *error_ptr) 400{ 401 LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); 402 if (log) 403 log->Printf ("%p ConnectionFileDescriptor::Write (src = %p, src_len = %zu)", this, src, src_len); 404 405 if (!IsConnected ()) 406 { 407 if (error_ptr) 408 error_ptr->SetErrorString("not connected"); 409 status = eConnectionStatusNoConnection; 410 return 0; 411 } 412 413 414 Error error; 415 416 ssize_t bytes_sent = 0; 417 418 switch (m_fd_send_type) 419 { 420 case eFDTypeFile: // Other FD requireing read/write 421 do 422 { 423 bytes_sent = ::write (m_fd_send, src, src_len); 424 } while (bytes_sent < 0 && errno == EINTR); 425 break; 426 427 case eFDTypeSocket: // Socket requiring send/recv 428 do 429 { 430 bytes_sent = ::send (m_fd_send, src, src_len, 0); 431 } while (bytes_sent < 0 && errno == EINTR); 432 break; 433 434 case eFDTypeSocketUDP: // Unconnected UDP socket requiring sendto/recvfrom 435 assert (m_udp_send_sockaddr.GetFamily() != 0); 436 do 437 { 438 bytes_sent = ::sendto (m_fd_send, 439 src, 440 src_len, 441 0, 442 m_udp_send_sockaddr, 443 m_udp_send_sockaddr.GetLength()); 444 } while (bytes_sent < 0 && errno == EINTR); 445 break; 446 } 447 448 if (bytes_sent < 0) 449 error.SetErrorToErrno (); 450 else 451 error.Clear (); 452 453 if (log) 454 { 455 switch (m_fd_send_type) 456 { 457 case eFDTypeFile: // Other FD requireing read/write 458 log->Printf ("%p ConnectionFileDescriptor::Write() ::write (fd = %i, src = %p, src_len = %zu) => %zi (error = %s)", 459 this, 460 m_fd_send, 461 src, 462 src_len, 463 bytes_sent, 464 error.AsCString()); 465 break; 466 467 case eFDTypeSocket: // Socket requiring send/recv 468 log->Printf ("%p ConnectionFileDescriptor::Write() ::send (socket = %i, src = %p, src_len = %zu, flags = 0) => %zi (error = %s)", 469 this, 470 m_fd_send, 471 src, 472 src_len, 473 bytes_sent, 474 error.AsCString()); 475 break; 476 477 case eFDTypeSocketUDP: // Unconnected UDP socket requiring sendto/recvfrom 478 log->Printf ("%p ConnectionFileDescriptor::Write() ::sendto (socket = %i, src = %p, src_len = %zu, flags = 0) => %zi (error = %s)", 479 this, 480 m_fd_send, 481 src, 482 src_len, 483 bytes_sent, 484 error.AsCString()); 485 break; 486 } 487 } 488 489 if (error_ptr) 490 *error_ptr = error; 491 492 if (error.Fail()) 493 { 494 switch (error.GetError()) 495 { 496 case EAGAIN: 497 case EINTR: 498 status = eConnectionStatusSuccess; 499 return 0; 500 501 case ECONNRESET:// The connection is closed by the peer during a read attempt on a socket. 502 case ENOTCONN: // A read is attempted on an unconnected socket. 503 status = eConnectionStatusLostConnection; 504 break; // Break to close.... 505 506 default: 507 status = eConnectionStatusError; 508 break; // Break to close.... 509 } 510 511 Disconnect (NULL); 512 return 0; 513 } 514 515 status = eConnectionStatusSuccess; 516 return bytes_sent; 517} 518 519ConnectionStatus 520ConnectionFileDescriptor::BytesAvailable (uint32_t timeout_usec, Error *error_ptr) 521{ 522 LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); 523 if (log) 524 log->Printf("%p ConnectionFileDescriptor::BytesAvailable (timeout_usec = %u)", this, timeout_usec); 525 struct timeval *tv_ptr; 526 struct timeval tv; 527 if (timeout_usec == UINT32_MAX) 528 { 529 // Infinite wait... 530 tv_ptr = NULL; 531 } 532 else 533 { 534 TimeValue time_value; 535 time_value.OffsetWithMicroSeconds (timeout_usec); 536 tv = time_value.GetAsTimeVal(); 537 tv_ptr = &tv; 538 } 539 540 while (IsConnected()) 541 { 542 fd_set read_fds; 543 FD_ZERO (&read_fds); 544 FD_SET (m_fd_recv, &read_fds); 545 int nfds = m_fd_recv + 1; 546 547 Error error; 548 549 550 if (log) 551 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds = %i, fd = %i, NULL, NULL, timeout = %p)...", 552 this, nfds, m_fd_recv, tv_ptr); 553 554 const int num_set_fds = ::select (nfds, &read_fds, NULL, NULL, tv_ptr); 555 if (num_set_fds < 0) 556 error.SetErrorToErrno(); 557 else 558 error.Clear(); 559 560 if (log) 561 log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds = %i, fd = %i, NULL, NULL, timeout = %p) => %d, error = %s", 562 this, nfds, m_fd_recv, tv_ptr, num_set_fds, error.AsCString()); 563 564 if (error_ptr) 565 *error_ptr = error; 566 567 if (error.Fail()) 568 { 569 switch (error.GetError()) 570 { 571 case EBADF: // One of the descriptor sets specified an invalid descriptor. 572 return eConnectionStatusLostConnection; 573 574 case EINVAL: // The specified time limit is invalid. One of its components is negative or too large. 575 default: // Other unknown error 576 return eConnectionStatusError; 577 578 case EAGAIN: // The kernel was (perhaps temporarily) unable to 579 // allocate the requested number of file descriptors, 580 // or we have non-blocking IO 581 case EINTR: // A signal was delivered before the time limit 582 // expired and before any of the selected events 583 // occurred. 584 break; // Lets keep reading to until we timeout 585 } 586 } 587 else if (num_set_fds == 0) 588 { 589 return eConnectionStatusTimedOut; 590 } 591 else if (num_set_fds > 0) 592 { 593 return eConnectionStatusSuccess; 594 } 595 } 596 597 if (error_ptr) 598 error_ptr->SetErrorString("not connected"); 599 return eConnectionStatusLostConnection; 600} 601 602ConnectionStatus 603ConnectionFileDescriptor::Close (int& fd, Error *error_ptr) 604{ 605 Mutex::Locker locker (m_mutex); 606 if (error_ptr) 607 error_ptr->Clear(); 608 bool success = true; 609 if (fd >= 0) 610 { 611 LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); 612 if (log) 613 log->Printf ("%p ConnectionFileDescriptor::Close (fd = %i)", this,fd); 614 615 success = ::close (fd) == 0; 616 if (!success && error_ptr) 617 { 618 // Only set the error if we have been asked to since something else 619 // might have caused us to try and shut down the connection and may 620 // have already set the error. 621 error_ptr->SetErrorToErrno(); 622 } 623 fd = -1; 624 } 625 m_fd_send_type = m_fd_recv_type = eFDTypeFile; 626 if (success) 627 return eConnectionStatusSuccess; 628 else 629 return eConnectionStatusError; 630} 631 632ConnectionStatus 633ConnectionFileDescriptor::NamedSocketAccept (const char *socket_name, Error *error_ptr) 634{ 635 ConnectionStatus result = eConnectionStatusError; 636 struct sockaddr_un saddr_un; 637 638 m_fd_send_type = m_fd_recv_type = eFDTypeSocket; 639 640 int listen_socket = ::socket (AF_UNIX, SOCK_STREAM, 0); 641 if (listen_socket == -1) 642 { 643 if (error_ptr) 644 error_ptr->SetErrorToErrno(); 645 return eConnectionStatusError; 646 } 647 648 saddr_un.sun_family = AF_UNIX; 649 ::strncpy(saddr_un.sun_path, socket_name, sizeof(saddr_un.sun_path) - 1); 650 saddr_un.sun_path[sizeof(saddr_un.sun_path) - 1] = '\0'; 651#if defined(__APPLE__) || defined(__FreeBSD__) 652 saddr_un.sun_len = SUN_LEN (&saddr_un); 653#endif 654 655 if (::bind (listen_socket, (struct sockaddr *)&saddr_un, SUN_LEN (&saddr_un)) == 0) 656 { 657 if (::listen (listen_socket, 5) == 0) 658 { 659 m_fd_send = m_fd_recv = ::accept (listen_socket, NULL, 0); 660 if (m_fd_send > 0) 661 { 662 m_should_close_fd = true; 663 664 if (error_ptr) 665 error_ptr->Clear(); 666 result = eConnectionStatusSuccess; 667 } 668 } 669 } 670 671 if (result != eConnectionStatusSuccess) 672 { 673 if (error_ptr) 674 error_ptr->SetErrorToErrno(); 675 } 676 // We are done with the listen port 677 Close (listen_socket, NULL); 678 return result; 679} 680 681ConnectionStatus 682ConnectionFileDescriptor::NamedSocketConnect (const char *socket_name, Error *error_ptr) 683{ 684 Disconnect (NULL); 685 m_fd_send_type = m_fd_recv_type = eFDTypeSocket; 686 687 // Open the socket that was passed in as an option 688 struct sockaddr_un saddr_un; 689 m_fd_send = m_fd_recv = ::socket (AF_UNIX, SOCK_STREAM, 0); 690 if (m_fd_send == -1) 691 { 692 if (error_ptr) 693 error_ptr->SetErrorToErrno(); 694 return eConnectionStatusError; 695 } 696 697 saddr_un.sun_family = AF_UNIX; 698 ::strncpy(saddr_un.sun_path, socket_name, sizeof(saddr_un.sun_path) - 1); 699 saddr_un.sun_path[sizeof(saddr_un.sun_path) - 1] = '\0'; 700#if defined(__APPLE__) || defined(__FreeBSD__) 701 saddr_un.sun_len = SUN_LEN (&saddr_un); 702#endif 703 704 if (::connect (m_fd_send, (struct sockaddr *)&saddr_un, SUN_LEN (&saddr_un)) < 0) 705 { 706 if (error_ptr) 707 error_ptr->SetErrorToErrno(); 708 Disconnect (NULL); 709 return eConnectionStatusError; 710 } 711 if (error_ptr) 712 error_ptr->Clear(); 713 return eConnectionStatusSuccess; 714} 715 716ConnectionStatus 717ConnectionFileDescriptor::SocketListen (uint16_t listen_port_num, Error *error_ptr) 718{ 719 LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); 720 if (log) 721 log->Printf ("%p ConnectionFileDescriptor::SocketListen (port = %i)", this, listen_port_num); 722 723 Disconnect (NULL); 724 m_fd_send_type = m_fd_recv_type = eFDTypeSocket; 725 int listen_port = ::socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); 726 if (listen_port == -1) 727 { 728 if (error_ptr) 729 error_ptr->SetErrorToErrno(); 730 return eConnectionStatusError; 731 } 732 733 // enable local address reuse 734 SetSocketOption (listen_port, SOL_SOCKET, SO_REUSEADDR, 1); 735 736 SocketAddress localhost; 737 if (localhost.SetToLocalhost (AF_INET, listen_port_num)) 738 { 739 int err = ::bind (listen_port, localhost, localhost.GetLength()); 740 if (err == -1) 741 { 742 if (error_ptr) 743 error_ptr->SetErrorToErrno(); 744 Close (listen_port, NULL); 745 return eConnectionStatusError; 746 } 747 748 err = ::listen (listen_port, 1); 749 if (err == -1) 750 { 751 if (error_ptr) 752 error_ptr->SetErrorToErrno(); 753 Close (listen_port, NULL); 754 return eConnectionStatusError; 755 } 756 757 m_fd_send = m_fd_recv = ::accept (listen_port, NULL, 0); 758 if (m_fd_send == -1) 759 { 760 if (error_ptr) 761 error_ptr->SetErrorToErrno(); 762 Close (listen_port, NULL); 763 return eConnectionStatusError; 764 } 765 } 766 767 // We are done with the listen port 768 Close (listen_port, NULL); 769 770 m_should_close_fd = true; 771 772 // Keep our TCP packets coming without any delays. 773 SetSocketOption (m_fd_send, IPPROTO_TCP, TCP_NODELAY, 1); 774 if (error_ptr) 775 error_ptr->Clear(); 776 return eConnectionStatusSuccess; 777} 778 779ConnectionStatus 780ConnectionFileDescriptor::ConnectTCP (const char *host_and_port, Error *error_ptr) 781{ 782 LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); 783 if (log) 784 log->Printf ("%p ConnectionFileDescriptor::ConnectTCP (host/port = %s)", this, host_and_port); 785 Disconnect (NULL); 786 787 m_fd_send_type = m_fd_recv_type = eFDTypeSocket; 788 std::string host_str; 789 std::string port_str; 790 int32_t port = INT32_MIN; 791 if (!DecodeHostAndPort (host_and_port, host_str, port_str, port, error_ptr)) 792 return eConnectionStatusError; 793 794 // Create the socket 795 m_fd_send = m_fd_recv = ::socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); 796 if (m_fd_send == -1) 797 { 798 if (error_ptr) 799 error_ptr->SetErrorToErrno(); 800 return eConnectionStatusError; 801 } 802 803 m_should_close_fd = true; 804 805 // Enable local address reuse 806 SetSocketOption (m_fd_send, SOL_SOCKET, SO_REUSEADDR, 1); 807 808 struct sockaddr_in sa; 809 ::memset (&sa, 0, sizeof (sa)); 810 sa.sin_family = AF_INET; 811 sa.sin_port = htons (port); 812 813 int inet_pton_result = ::inet_pton (AF_INET, host_str.c_str(), &sa.sin_addr); 814 815 if (inet_pton_result <= 0) 816 { 817 struct hostent *host_entry = gethostbyname (host_str.c_str()); 818 if (host_entry) 819 host_str = ::inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list); 820 inet_pton_result = ::inet_pton (AF_INET, host_str.c_str(), &sa.sin_addr); 821 if (inet_pton_result <= 0) 822 { 823 824 if (error_ptr) 825 { 826 if (inet_pton_result == -1) 827 error_ptr->SetErrorToErrno(); 828 else 829 error_ptr->SetErrorStringWithFormat("invalid host string: '%s'", host_str.c_str()); 830 } 831 Disconnect (NULL); 832 833 return eConnectionStatusError; 834 } 835 } 836 837 if (-1 == ::connect (m_fd_send, (const struct sockaddr *)&sa, sizeof(sa))) 838 { 839 if (error_ptr) 840 error_ptr->SetErrorToErrno(); 841 Disconnect (NULL); 842 843 return eConnectionStatusError; 844 } 845 846 // Keep our TCP packets coming without any delays. 847 SetSocketOption (m_fd_send, IPPROTO_TCP, TCP_NODELAY, 1); 848 if (error_ptr) 849 error_ptr->Clear(); 850 return eConnectionStatusSuccess; 851} 852 853ConnectionStatus 854ConnectionFileDescriptor::ConnectUDP (const char *host_and_port, Error *error_ptr) 855{ 856 LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION)); 857 if (log) 858 log->Printf ("%p ConnectionFileDescriptor::ConnectUDP (host/port = %s)", this, host_and_port); 859 Disconnect (NULL); 860 861 m_fd_send_type = m_fd_recv_type = eFDTypeSocketUDP; 862 863 std::string host_str; 864 std::string port_str; 865 int32_t port = INT32_MIN; 866 if (!DecodeHostAndPort (host_and_port, host_str, port_str, port, error_ptr)) 867 return eConnectionStatusError; 868 869 // Setup the receiving end of the UDP connection on this localhost 870 // on port zero. After we bind to port zero we can read the port. 871 m_fd_recv = ::socket (AF_INET, SOCK_DGRAM, 0); 872 if (m_fd_recv == -1) 873 { 874 // Socket creation failed... 875 if (error_ptr) 876 error_ptr->SetErrorToErrno(); 877 } 878 else 879 { 880 // Socket was created, now lets bind to the requested port 881 SocketAddress addr; 882 addr.SetToLocalhost (AF_INET, 0); 883 884 if (::bind (m_fd_recv, addr, addr.GetLength()) == -1) 885 { 886 // Bind failed... 887 if (error_ptr) 888 error_ptr->SetErrorToErrno(); 889 Disconnect (NULL); 890 } 891 } 892 893 if (m_fd_recv == -1) 894 return eConnectionStatusError; 895 896 // At this point we have setup the recieve port, now we need to 897 // setup the UDP send socket 898 899 struct addrinfo hints; 900 struct addrinfo *service_info_list = NULL; 901 902 ::memset (&hints, 0, sizeof(hints)); 903 hints.ai_family = AF_INET; 904 hints.ai_socktype = SOCK_DGRAM; 905 int err = ::getaddrinfo (host_str.c_str(), port_str.c_str(), &hints, &service_info_list); 906 if (err != 0) 907 { 908 if (error_ptr) 909 error_ptr->SetErrorStringWithFormat("getaddrinfo(%s, %s, &hints, &info) returned error %i (%s)", 910 host_str.c_str(), 911 port_str.c_str(), 912 err, 913 gai_strerror(err)); 914 Disconnect (NULL); 915 return eConnectionStatusError; 916 } 917 918 for (struct addrinfo *service_info_ptr = service_info_list; 919 service_info_ptr != NULL; 920 service_info_ptr = service_info_ptr->ai_next) 921 { 922 m_fd_send = ::socket (service_info_ptr->ai_family, 923 service_info_ptr->ai_socktype, 924 service_info_ptr->ai_protocol); 925 926 if (m_fd_send != -1) 927 { 928 m_udp_send_sockaddr = service_info_ptr; 929 break; 930 } 931 else 932 continue; 933 } 934 935 :: freeaddrinfo (service_info_list); 936 937 if (m_fd_send == -1) 938 { 939 Disconnect (NULL); 940 return eConnectionStatusError; 941 } 942 943 if (error_ptr) 944 error_ptr->Clear(); 945 946 m_should_close_fd = true; 947 return eConnectionStatusSuccess; 948} 949 950#if defined(__MINGW32__) || defined(__MINGW64__) 951typedef const char * set_socket_option_arg_type; 952typedef char * get_socket_option_arg_type; 953#else // #if defined(__MINGW32__) || defined(__MINGW64__) 954typedef const void * set_socket_option_arg_type; 955typedef void * get_socket_option_arg_type; 956#endif // #if defined(__MINGW32__) || defined(__MINGW64__) 957 958int 959ConnectionFileDescriptor::GetSocketOption(int fd, int level, int option_name, int &option_value) 960{ 961 get_socket_option_arg_type option_value_p = static_cast<get_socket_option_arg_type>(&option_value); 962 socklen_t option_value_size = sizeof(int); 963 return ::getsockopt(fd, level, option_name, option_value_p, &option_value_size); 964} 965 966int 967ConnectionFileDescriptor::SetSocketOption(int fd, int level, int option_name, int option_value) 968{ 969 set_socket_option_arg_type option_value_p = static_cast<get_socket_option_arg_type>(&option_value); 970 return ::setsockopt(fd, level, option_name, option_value_p, sizeof(option_value)); 971} 972 973bool 974ConnectionFileDescriptor::SetSocketReceiveTimeout (uint32_t timeout_usec) 975{ 976 switch (m_fd_recv_type) 977 { 978 case eFDTypeFile: // Other FD requireing read/write 979 break; 980 981 case eFDTypeSocket: // Socket requiring send/recv 982 case eFDTypeSocketUDP: // Unconnected UDP socket requiring sendto/recvfrom 983 { 984 // Check in case timeout for m_fd has already been set to this value 985 if (timeout_usec == m_socket_timeout_usec) 986 return true; 987 //printf ("ConnectionFileDescriptor::SetSocketReceiveTimeout (timeout_usec = %u)\n", timeout_usec); 988 989 struct timeval timeout; 990 if (timeout_usec == UINT32_MAX) 991 { 992 timeout.tv_sec = 0; 993 timeout.tv_usec = 0; 994 } 995 else if (timeout_usec == 0) 996 { 997 // Sending in zero does an infinite timeout, so set this as low 998 // as we can go to get an effective zero timeout... 999 timeout.tv_sec = 0; 1000 timeout.tv_usec = 1; 1001 } 1002 else 1003 { 1004 timeout.tv_sec = timeout_usec / TimeValue::MicroSecPerSec; 1005 timeout.tv_usec = timeout_usec % TimeValue::MicroSecPerSec; 1006 } 1007 if (::setsockopt (m_fd_recv, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) == 0) 1008 { 1009 m_socket_timeout_usec = timeout_usec; 1010 return true; 1011 } 1012 } 1013 } 1014 return false; 1015} 1016 1017in_port_t 1018ConnectionFileDescriptor::GetSocketPort (int fd) 1019{ 1020 // We bound to port zero, so we need to figure out which port we actually bound to 1021 SocketAddress sock_addr; 1022 socklen_t sock_addr_len = sock_addr.GetMaxLength (); 1023 if (::getsockname (fd, sock_addr, &sock_addr_len) == 0) 1024 return sock_addr.GetPort (); 1025 1026 return 0; 1027} 1028 1029// If the read file descriptor is a socket, then return 1030// the port number that is being used by the socket. 1031in_port_t 1032ConnectionFileDescriptor::GetReadPort () const 1033{ 1034 return ConnectionFileDescriptor::GetSocketPort (m_fd_recv); 1035} 1036 1037// If the write file descriptor is a socket, then return 1038// the port number that is being used by the socket. 1039in_port_t 1040ConnectionFileDescriptor::GetWritePort () const 1041{ 1042 return ConnectionFileDescriptor::GetSocketPort (m_fd_send); 1043} 1044 1045 1046