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