BOOL netconn_close( netconn_t *conn ) { int res; if (conn->secure) { heap_free( conn->peek_msg_mem ); heap_free(conn->ssl_buf); heap_free(conn->extra_buf); DeleteSecurityContext(&conn->ssl_ctx); } res = closesocket( conn->socket ); release_host( conn->host ); heap_free(conn); if (res == -1) { set_last_error( sock_get_error( errno ) ); return FALSE; } return TRUE; }
netconn_t *netconn_create( hostdata_t *host, const struct sockaddr_storage *sockaddr, int timeout ) { netconn_t *conn; unsigned int addr_len; BOOL ret = FALSE; int res; ULONG state; conn = heap_alloc_zero(sizeof(*conn)); if (!conn) return NULL; conn->host = host; conn->sockaddr = *sockaddr; if ((conn->socket = socket( sockaddr->ss_family, SOCK_STREAM, 0 )) == -1) { WARN("unable to create socket (%s)\n", strerror(errno)); set_last_error( sock_get_error( errno ) ); heap_free(conn); return NULL; } switch (conn->sockaddr.ss_family) { case AF_INET: addr_len = sizeof(struct sockaddr_in); break; case AF_INET6: addr_len = sizeof(struct sockaddr_in6); break; default: assert(0); } if (timeout > 0) { state = 1; ioctlsocket( conn->socket, FIONBIO, &state ); } for (;;) { res = 0; if (connect( conn->socket, (const struct sockaddr *)&conn->sockaddr, addr_len ) < 0) { res = sock_get_error( errno ); if (res == WSAEWOULDBLOCK || res == WSAEINPROGRESS) { #ifdef __REACTOS__ /* ReactOS: use select instead of poll */ fd_set outfd; struct timeval tv; FD_ZERO(&outfd); FD_SET(conn->socket, &outfd); tv.tv_sec = 0; tv.tv_usec = timeout * 1000; for (;;) { res = 0; if (select( 0, NULL, &outfd, NULL, &tv ) > 0) #else struct pollfd pfd; pfd.fd = conn->socket; pfd.events = POLLOUT; for (;;) { res = 0; if (poll( &pfd, 1, timeout ) > 0) #endif { ret = TRUE; break; } else { res = sock_get_error( errno ); if (res != WSAEINTR) break; } } } if (res != WSAEINTR) break; } else { ret = TRUE; break; } } if (timeout > 0) { state = 0; ioctlsocket( conn->socket, FIONBIO, &state ); } if (!ret) { WARN("unable to connect to host (%d)\n", res); set_last_error( res ); netconn_close( conn ); return NULL; } return conn; } BOOL netconn_close( netconn_t *conn ) { int res; if (conn->secure) { heap_free( conn->peek_msg_mem ); heap_free(conn->ssl_buf); heap_free(conn->extra_buf); DeleteSecurityContext(&conn->ssl_ctx); } res = closesocket( conn->socket ); release_host( conn->host ); heap_free(conn); if (res == -1) { set_last_error( sock_get_error( errno ) ); return FALSE; } return TRUE; }