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