예제 #1
0
ContactUser *ContactsManager::createContactRequest(const QString &contactid, const QString &nickname,
                                                   const QString &myNickname, const QString &message)
{
    QString hostname = ContactIDValidator::hostnameFromID(contactid);
    if (hostname.isEmpty() || lookupHostname(contactid) || lookupNickname(nickname))
    {
        return 0;
    }

    bool b = blockSignals(true);
    ContactUser *user = addContact(nickname);
    blockSignals(b);
    if (!user)
        return user;
    user->setHostname(ContactIDValidator::hostnameFromID(contactid));

    OutgoingContactRequest::createNewRequest(user, myNickname, message);

    /* Signal deferred from addContact to avoid changing the status immediately */
    Q_ASSERT(user->status() == ContactUser::RequestPending);
    emit contactAdded(user);
    return user;
}
예제 #2
0
int XDebugServer::createSocket(const char* hostname, int port) {
  // Grab the address info
  sockaddr sa;
  sockaddr_in address;
  memset(&address, 0, sizeof(address));
  address.sin_family = AF_INET;
  address.sin_port = htons((unsigned short) port);
  lookupHostname(hostname, address.sin_addr);

  // Create the socket
  auto const sockfd = socket(address.sin_family, SOCK_STREAM, 0);
  if (sockfd == -1) {
    log("create_debugger_socket(\"%s\", %d) socket: %s\n",
        hostname, port, folly::errnoStr(errno).c_str());
    return -1;
  }

  // Put socket in non-blocking mode so we can use poll() for timeouts.
  fcntl(sockfd, F_SETFL, O_NONBLOCK);

  // Do the connect.
  auto const status = connect(sockfd, (sockaddr*)(&address), sizeof(address));
  if (status < 0) {
    if (errno != EINPROGRESS) {
      return -1;
    }

    double timeout_sec = XDEBUG_GLOBAL(RemoteTimeout);

    // Loop until request has completed or there is an error.
    while (true) {
      pollfd pollfd;
      pollfd.fd = sockfd;
      pollfd.events = POLLIN | POLLOUT;
      pollfd.revents = 0;

      // Wait for a socket event.
      auto const status = poll(&pollfd, 1, (int)(timeout_sec * 1000.0));

      // Timeout.
      if (status == 0) return -2;
      // Error.
      if (status == -1) return -1;

      // Error or hang-up.
      if ((pollfd.revents & POLLERR) || (pollfd.revents & POLLHUP)) return -1;

      // Success.
      if ((pollfd.revents & POLLIN) || (pollfd.revents & POLLOUT)) break;
    }

    // Ensure we're actually connected.
    socklen_t sa_size = sizeof(sa);
    if (getpeername(sockfd, &sa, &sa_size) == -1) {
      return -1;
    }
  }

  // Reset the socket to non-blocking mode and setup socket options
  fcntl(sockfd, F_SETFL, 0);
  long optval = 1;
  setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(optval));
  return sockfd;
}
예제 #3
0
int XDebugServer::createSocket(const char* hostname, int port) {
  // Grab the address info
  struct sockaddr sa;
  struct sockaddr_in address;
  memset(&address, 0, sizeof(address));
  address.sin_family = AF_INET;
  address.sin_port = htons((unsigned short) port);
  lookupHostname(hostname, address.sin_addr);

  // Create the socket
  int sockfd = socket(address.sin_family, SOCK_STREAM, 0);
  if (sockfd == -1) {
    printf("create_debugger_socket(\"%s\", %d) socket: %s\n",
           hostname, port, strerror(errno));
    return -1;
  }

  // Put socket in non-blocking mode so we can use select for timeouts
  struct timeval timeout;
  double timeout_sec = XDEBUG_GLOBAL(RemoteTimeout);
  timeout.tv_sec = (int) timeout_sec;
  timeout.tv_usec = (timeout_sec - (double) timeout.tv_sec) * 1.0e6;
  fcntl(sockfd, F_SETFL, O_NONBLOCK);

  // Do the connect
  int status = connect(sockfd, (struct sockaddr*) &address, sizeof(address));
  if (status < 0) {
    if (errno != EINPROGRESS) {
      return -1;
    }

    // Loop until request has completed or there is an error
    while (true) {
      fd_set rset, wset, eset;
      FD_ZERO(&rset);
      FD_SET(sockfd, &rset);
      FD_ZERO(&wset);
      FD_SET(sockfd, &wset);
      FD_ZERO(&eset);
      FD_SET(sockfd, &eset);

      // Wait for a socket event. If we continue due to a timeout, return -2
      // If we exited due to an error, return -1. If the descriptor is ready,
      // we're done.
      if (select(sockfd + 1, &rset, &wset, &eset, &timeout) == 0) {
        return -2;
      } else if (FD_ISSET(sockfd, &eset)) {
        return -1;
      } else if (FD_ISSET(sockfd, &wset) || FD_ISSET(sockfd, &rset)) {
        break;
      }
    }

    // Ensure we're actually connected
    socklen_t sa_size = sizeof(sa);
    if (getpeername(sockfd, &sa, &sa_size) == -1) {
      return -1;
    }
  }

  // Reset the socket to non-blocking mode and setup socket options
  fcntl(sockfd, F_SETFL, 0);
  long optval = 1;
  setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(optval));
  return sockfd;
}