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; }
pn_socket_t pn_accept(pn_io_t *io, pn_socket_t listen_sock, char *name, size_t size) { struct sockaddr_in addr = {0}; addr.sin_family = AF_INET; socklen_t addrlen = sizeof(addr); iocpdesc_t *listend = pni_iocpdesc_map_get(io->iocp, listen_sock); pn_socket_t accept_sock; if (listend) accept_sock = pni_iocp_end_accept(listend, (struct sockaddr *) &addr, &addrlen, &io->wouldblock, io->error); else { // User supplied socket accept_sock = accept(listen_sock, (struct sockaddr *) &addr, &addrlen); if (accept_sock == INVALID_SOCKET) pni_win32_error(io->error, "sync accept", WSAGetLastError()); } if (accept_sock == INVALID_SOCKET) return accept_sock; int code = getnameinfo((struct sockaddr *) &addr, addrlen, io->host, NI_MAXHOST, io->serv, NI_MAXSERV, 0); if (code) code = getnameinfo((struct sockaddr *) &addr, addrlen, io->host, NI_MAXHOST, io->serv, NI_MAXSERV, NI_NUMERICHOST | NI_NUMERICSERV); if (code) { pn_error_format(io->error, PN_ERR, "getnameinfo: %s\n", gai_strerror(code)); pn_close(io, accept_sock); return INVALID_SOCKET; } else { pn_configure_sock(io, accept_sock); snprintf(name, size, "%s:%s", io->host, io->serv); if (listend) { pni_iocpdesc_start(pni_iocpdesc_map_get(io->iocp, accept_sock)); } return accept_sock; } }
pn_socket_t pn_connect(pn_io_t *io, const char *hostarg, const char *port) { // convert "0.0.0.0" to "127.0.0.1" on Windows for outgoing sockets const char *host = strcmp("0.0.0.0", hostarg) ? hostarg : "127.0.0.1"; 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", 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, "proton pni_create_socket", WSAGetLastError()); freeaddrinfo(addr); return INVALID_SOCKET; } ensure_unique(io, sock); pn_configure_sock(io, sock); if (io->iocp->selector) { return pni_iocp_begin_connect(io->iocp, sock, addr, io->error); } else { if (connect(sock, addr->ai_addr, addr->ai_addrlen) != 0) { if (WSAGetLastError() != WSAEWOULDBLOCK) { pni_win32_error(io->error, "connect", WSAGetLastError()); freeaddrinfo(addr); closesocket(sock); return INVALID_SOCKET; } } freeaddrinfo(addr); return sock; } }
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; } } }