Exemple #1
0
static void pn_configure_sock(pn_io_t *io, pn_socket_t sock) {
  // this would be nice, but doesn't appear to exist on linux
  /*
  int set = 1;
  if (!setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int))) {
    pn_i_error_from_errno(io->error, "setsockopt");
  };
  */

  int flags = fcntl(sock, F_GETFL);
  flags |= O_NONBLOCK;

  if (fcntl(sock, F_SETFL, flags) < 0) {
    pn_i_error_from_errno(io->error, "fcntl");
  }

  //
  // Disable the Nagle algorithm on TCP connections.
  //
  // Note:  It would be more correct for the "level" argument to be SOL_TCP.  However, there
  //        are portability issues with this macro so we use IPPROTO_TCP instead.
  //
  int tcp_nodelay = 1;
  if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void*) &tcp_nodelay, sizeof(tcp_nodelay)) < 0) {
    pn_i_error_from_errno(io->error, "setsockopt");
  }
}
Exemple #2
0
pn_socket_t pn_connect(pn_io_t *io, const char *host, const char *port)
{
  struct addrinfo *addr;
  int code = getaddrinfo(host, port, NULL, &addr);
  if (code) {
    pn_error_format(io->error, PN_ERR, "getaddrinfo(%s, %s): %s", host, port, gai_strerror(code));
    return PN_INVALID_SOCKET;
  }

  pn_socket_t sock = pn_create_socket(addr->ai_family);
  if (sock == PN_INVALID_SOCKET) {
    pn_i_error_from_errno(io->error, "pn_create_socket");
    return PN_INVALID_SOCKET;
  }

  pn_configure_sock(io, sock);

  if (connect(sock, addr->ai_addr, addr->ai_addrlen) == -1) {
    if (errno != EINPROGRESS) {
      pn_i_error_from_errno(io->error, "connect");
      freeaddrinfo(addr);
      close(sock);
      return PN_INVALID_SOCKET;
    }
  }

  freeaddrinfo(addr);

  return sock;
}
Exemple #3
0
int pn_pipe(pn_io_t *io, pn_socket_t *dest)
{
  int n = pipe(dest);
  if (n) {
    pn_i_error_from_errno(io->error, "pipe");
  }

  return n;
}
Exemple #4
0
pn_socket_t pn_listen(pn_io_t *io, const char *host, const char *port)
{
  struct addrinfo *addr;
  int code = getaddrinfo(host, port, NULL, &addr);
  if (code) {
    pn_error_format(io->error, PN_ERR, "getaddrinfo(%s, %s): %s\n", host, port, gai_strerror(code));
    return PN_INVALID_SOCKET;
  }

  pn_socket_t sock = pn_create_socket(addr->ai_family);
  if (sock == PN_INVALID_SOCKET) {
    pn_i_error_from_errno(io->error, "pn_create_socket");
    return PN_INVALID_SOCKET;
  }

  int optval = 1;
  if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1) {
    pn_i_error_from_errno(io->error, "setsockopt");
    close(sock);
    return PN_INVALID_SOCKET;
  }

  if (bind(sock, addr->ai_addr, addr->ai_addrlen) == -1) {
    pn_i_error_from_errno(io->error, "bind");
    freeaddrinfo(addr);
    close(sock);
    return PN_INVALID_SOCKET;
  }

  freeaddrinfo(addr);

  if (listen(sock, 50) == -1) {
    pn_i_error_from_errno(io->error, "listen");
    close(sock);
    return PN_INVALID_SOCKET;
  }

  return sock;
}
Exemple #5
0
pn_socket_t pn_listen(pn_io_t *io, const char *host, const char *port)
{
  struct addrinfo *addr;
  int code = getaddrinfo(host, amqp_service(port), NULL, &addr);
  if (code) {
    pn_error_format(io->error, PN_ERR, "getaddrinfo(%s, %s): %s\n", host, port, gai_strerror(code));
    return INVALID_SOCKET;
  }

  pn_socket_t sock = pni_create_socket(addr->ai_family);
  if (sock == INVALID_SOCKET) {
    pni_win32_error(io->error, "pni_create_socket", WSAGetLastError());
    return INVALID_SOCKET;
  }
  ensure_unique(io, sock);

  bool optval = 1;
  if (setsockopt(sock, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (const char *) &optval,
                 sizeof(optval)) == -1) {
    pni_win32_error(io->error, "setsockopt", WSAGetLastError());
    closesocket(sock);
    return INVALID_SOCKET;
  }

  if (bind(sock, addr->ai_addr, addr->ai_addrlen) == -1) {
    pni_win32_error(io->error, "bind", WSAGetLastError());
    freeaddrinfo(addr);
    closesocket(sock);
    return INVALID_SOCKET;
  }
  freeaddrinfo(addr);

  if (listen(sock, 50) == -1) {
    pni_win32_error(io->error, "listen", WSAGetLastError());
    closesocket(sock);
    return INVALID_SOCKET;
  }

  if (io->iocp->selector) {
    iocpdesc_t *iocpd = pni_iocpdesc_create(io->iocp, sock, false);
    if (!iocpd) {
      pn_i_error_from_errno(io->error, "register");
      closesocket(sock);
      return INVALID_SOCKET;
    }
    pni_iocpdesc_start(iocpd);
  }

  return sock;
}
Exemple #6
0
pn_socket_t pn_accept(pn_io_t *io, pn_socket_t socket, char *name, size_t size)
{
  struct sockaddr_in addr = {0};
  addr.sin_family = AF_UNSPEC;
  socklen_t addrlen = sizeof(addr);
  pn_socket_t sock = accept(socket, (struct sockaddr *) &addr, &addrlen);
  if (sock == PN_INVALID_SOCKET) {
    pn_i_error_from_errno(io->error, "accept");
    return sock;
  } else {
    int code;
    if ((code = getnameinfo((struct sockaddr *) &addr, addrlen, io->host, MAX_HOST, io->serv, MAX_SERV, 0))) {
      pn_error_format(io->error, PN_ERR, "getnameinfo: %s\n", gai_strerror(code));
      if (close(sock) == -1)
        pn_i_error_from_errno(io->error, "close");
      return PN_INVALID_SOCKET;
    } else {
      pn_configure_sock(io, sock);
      snprintf(name, size, "%s:%s", io->host, io->serv);
      return sock;
    }
  }
}