Esempio n. 1
0
psckt_t *
psckt_connect(const char *addr, int port, void *ctx, psckt_cb_t *callback)
{
  int sfd;
  psckt_t *sock = p_malloc(sizeof(psckt_t));
  struct addrinfo *ai, *ailist = sock? psckt_get_ailist(addr, port, 0) : 0;
  if (!ailist) {
    if (sock) p_free(sock);
    return 0;
  }

  for (ai=ailist ; ai ; ai=ai->ai_next) {
    sfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
    if (sfd == -1) continue;
    if (connect(sfd, ai->ai_addr, ai->ai_addrlen) != -1) break;
    close(sfd);
  }
  if (!ai) {
    p_free(sock);
    sock = 0;
  }
  freeaddrinfo(ailist);
  if (!sock) return 0;

  sock->fd = sfd;
  sock->peer = p_strcpy(addr);
  return psckt_setup(sock, ctx, callback);
}
Esempio n. 2
0
psckt_t *
psckt_accept(psckt_t *listener, char **ppeer, void *ctx, psckt_cb_t *callback)
{
  struct sockaddr_storage sad;
  socklen_t lsad = sizeof(struct sockaddr_storage);
  struct sockaddr *psad = (struct sockaddr *)&sad;
  char host[NI_MAXHOST];
  psckt_t *sock = p_malloc(sizeof(psckt_t));
  int sfd, lfd = sock->fd;

  *ppeer = 0;
  if (listener->peer || !sock) {  /* listeners have no peer */
    if (sock) p_free(sock);
    return 0;
  }

  sfd = accept(listener->fd, psad, &lsad);
  if (sfd==-1 || getnameinfo(psad, lsad, host, NI_MAXHOST, 0, 0, 0)) {
    close(sfd);
    p_free(sock);
    return 0;
  }

  sock->fd = sfd;
  sock->peer = *ppeer = p_strcpy(host);
  return psckt_setup(sock, ctx, callback);
}
Esempio n. 3
0
psckt_t *
psckt_listen(int *pport, void *ctx, psckt_cb_t *callback)
{
  int lfd;
  int port = *pport;
  psckt_t *listener = p_malloc(sizeof(psckt_t));
  struct addrinfo *ai, *ailist = listener? psckt_get_ailist(0, port, 1) : 0;
  if (!ailist) {
    if (listener) p_free(listener);
    return 0;
  }

  for (ai=ailist ; ai ; ai=ai->ai_next) {
    lfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
    if (lfd == -1) continue;
    if (!bind(lfd, ai->ai_addr, ai->ai_addrlen)) break;
    close(lfd);
  }
  if (ailist) freeaddrinfo(ailist);
  if (lfd < 0) {
    p_free(listener);
    return 0;
  }

  if (port == 0) {
    struct sockaddr_storage sad;
    socklen_t lsad = sizeof(struct sockaddr_storage);
    struct sockaddr *psad = (struct sockaddr *)&sad;
    char sport[NI_MAXSERV];
    if (getsockname(lfd, psad, &lsad) ||
        getnameinfo(psad, lsad, 0, 0, sport, NI_MAXSERV, NI_NUMERICSERV)) {
      close(lfd);
      p_free(listener);
      return 0;
    }
    pport[0] = port = strtod(sport, 0);
  }

  if (listen(lfd, 10)) {
    close(lfd);
    p_free(listener);
    return 0;
  }
  listener->fd = lfd;
  listener->peer = 0;  /* listener has no peer, could usefully be port */
  return psckt_setup(listener, ctx, callback);
}
Esempio n. 4
0
psckt_t *
psckt_accept(psckt_t *listener, char **ppeer, void *ctx, psckt_cb_t *callback)
{
  struct sockaddr_storage sad;
  socklen_t lsad = sizeof(struct sockaddr_storage);
  struct sockaddr *psad = (struct sockaddr *)&sad;
  char host[NI_MAXHOST];
  psckt_t *sock = p_malloc(sizeof(psckt_t));
  SOCKET sfd, lfd = sock->fd;

  *ppeer = 0;
  if (listener->peer || !sock) {  /* listeners have no peer */
    if (sock) p_free(sock);
    return 0;
  }

  if (listener->callback && listener->waiting) {
    if (WaitForSingleObject(listener->ready, INFINITE) != WAIT_OBJECT_0)
      psckt_stop_thread(listener);
    listener->waiting = 0;
    if (listener->ready != INVALID_HANDLE_VALUE)
      ResetEvent(listener->ready);
  }

  sfd = accept(listener->fd, psad, &lsad);
  if (sfd==INVALID_SOCKET ||
      getnameinfo(psad, lsad, host, NI_MAXHOST, 0, 0, 0)) {
    closesocket(sfd);
    p_free(sock);
    return 0;
  }

  sock->fd = sfd;
  sock->peer = *ppeer = p_strcpy(host);
  return psckt_setup(sock, ctx, callback);
}