Пример #1
0
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;
}
Пример #2
0
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;
}