コード例 #1
0
ファイル: net.c プロジェクト: Strongc/reactos
BOOL netconn_connect( netconn_t *conn, const struct sockaddr *sockaddr, unsigned int addr_len, int timeout )
{
    BOOL ret = FALSE;
    int res = 0;
    ULONG state;

    if (timeout > 0)
    {
        state = 1;
        ioctlsocket( conn->socket, FIONBIO, &state );
    }
    if (connect( conn->socket, 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;

            if (select( 0, NULL, &outfd, NULL, &tv ) > 0)
#else
            struct pollfd pfd;

            pfd.fd = conn->socket;
            pfd.events = POLLOUT;
            if (poll( &pfd, 1, timeout ) > 0)
#endif
                ret = TRUE;
            else
                res = sock_get_error( errno );
        }
    }
    else
        ret = TRUE;
    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 );
    }
    return ret;
}
コード例 #2
0
ファイル: netconnection.c プロジェクト: klickverbot/wine
/******************************************************************************
 * NETCON_recv
 * Basically calls 'recv()' unless we should use SSL
 * number of chars received is put in *recvd
 */
DWORD NETCON_recv(netconn_t *connection, void *buf, size_t len, int flags,
		int *recvd /* out */)
{
    *recvd = 0;
    if (!len)
        return ERROR_SUCCESS;
    if (!connection->useSSL)
    {
	*recvd = recv(connection->socketFD, buf, len, flags);
	return *recvd == -1 ? sock_get_error(errno) :  ERROR_SUCCESS;
    }
    else
    {
#ifdef SONAME_LIBSSL
        if(!connection->ssl_s) {
            FIXME("not connected\n");
            return ERROR_NOT_SUPPORTED;
        }
	*recvd = pSSL_read(connection->ssl_s, buf, len);

        /* Check if EOF was received */
        if(!*recvd && (pSSL_get_error(connection->ssl_s, *recvd)==SSL_ERROR_ZERO_RETURN
                    || pSSL_get_error(connection->ssl_s, *recvd)==SSL_ERROR_SYSCALL))
            return ERROR_SUCCESS;

        return *recvd > 0 ? ERROR_SUCCESS : ERROR_INTERNET_CONNECTION_ABORTED;
#else
	return ERROR_NOT_SUPPORTED;
#endif
    }
}
コード例 #3
0
ファイル: netconnection.c プロジェクト: klickverbot/wine
/******************************************************************************
 * NETCON_send
 * Basically calls 'send()' unless we should use SSL
 * number of chars send is put in *sent
 */
DWORD NETCON_send(netconn_t *connection, const void *msg, size_t len, int flags,
		int *sent /* out */)
{
    if (!connection->useSSL)
    {
	*sent = send(connection->socketFD, msg, len, flags);
	if (*sent == -1)
	    return sock_get_error(errno);
        return ERROR_SUCCESS;
    }
    else
    {
#ifdef SONAME_LIBSSL
        if(!connection->ssl_s) {
            FIXME("not connected\n");
            return ERROR_NOT_SUPPORTED;
        }
	if (flags)
            FIXME("SSL_write doesn't support any flags (%08x)\n", flags);
	*sent = pSSL_write(connection->ssl_s, msg, len);
	if (*sent < 1 && len)
	    return ERROR_INTERNET_CONNECTION_ABORTED;
        return ERROR_SUCCESS;
#else
	return ERROR_NOT_SUPPORTED;
#endif
    }
}
コード例 #4
0
ファイル: net.c プロジェクト: Strongc/reactos
BOOL netconn_close( netconn_t *conn )
{
    int res;

    if (conn->secure)
    {
        heap_free( conn->peek_msg_mem );
        conn->peek_msg_mem = NULL;
        conn->peek_msg = NULL;
        conn->peek_len = 0;
        heap_free(conn->ssl_buf);
        conn->ssl_buf = NULL;
        heap_free(conn->extra_buf);
        conn->extra_buf = NULL;
        conn->extra_len = 0;
        DeleteSecurityContext(&conn->ssl_ctx);
        conn->secure = FALSE;
    }
    res = closesocket( conn->socket );
    conn->socket = -1;
    if (res == -1)
    {
        set_last_error( sock_get_error( errno ) );
        return FALSE;
    }
    return TRUE;
}
コード例 #5
0
ファイル: netconnection.c プロジェクト: NVIDIA/winex_lgpl
DWORD NETCON_set_timeout(netconn_t *connection, BOOL send, DWORD value)
{
    int result;
    struct timeval tv;

    /* value is in milliseconds, convert to struct timeval */
    if (value == INFINITE)
    {
        tv.tv_sec = 0;
        tv.tv_usec = 0;
    }
    else
    {
        tv.tv_sec = value / 1000;
        tv.tv_usec = (value % 1000) * 1000;
    }
    result = setsockopt(connection->socket, SOL_SOCKET,
                        send ? SO_SNDTIMEO : SO_RCVTIMEO, (void*)&tv,
                        sizeof(tv));
    if (result == -1)
    {
        WARN("setsockopt failed (%s)\n", strerror(errno));
        return sock_get_error(errno);
    }
    return ERROR_SUCCESS;
}
コード例 #6
0
ファイル: netconnection.c プロジェクト: WASSUM/longene_travel
/******************************************************************************
 * NETCON_send
 * Basically calls 'send()' unless we should use SSL
 * number of chars send is put in *sent
 */
BOOL NETCON_send(WININET_NETCONNECTION *connection, const void *msg, size_t len, int flags,
		int *sent /* out */)
{
    if (!NETCON_connected(connection)) return FALSE;
    if (!connection->useSSL)
    {
	*sent = send(connection->socketFD, msg, len, flags);
	if (*sent == -1)
	{
	    INTERNET_SetLastError(sock_get_error(errno));
	    return FALSE;
	}
        return TRUE;
    }
    else
    {
#ifdef SONAME_LIBSSL
	if (flags)
            FIXME("SSL_write doesn't support any flags (%08x)\n", flags);
	*sent = pSSL_write(connection->ssl_s, msg, len);
	if (*sent < 1 && len)
	    return FALSE;
        return TRUE;
#else
	return FALSE;
#endif
    }
}
コード例 #7
0
ファイル: sock.c プロジェクト: DeltaYang/wine
/* wake anybody waiting on the socket event or send the associated message */
static void sock_wake_up( struct sock *sock )
{
    unsigned int events = sock->pmask & sock->mask;
    int i;

    if ( !events ) return;

    if (sock->event)
    {
        if (debug_level) fprintf(stderr, "signalling events %x ptr %p\n", events, sock->event );
        set_event( sock->event );
    }
    if (sock->window)
    {
        if (debug_level) fprintf(stderr, "signalling events %x win %08x\n", events, sock->window );
        for (i = 0; i < FD_MAX_EVENTS; i++)
        {
            int event = event_bitorder[i];
            if (sock->pmask & (1 << event))
            {
                lparam_t lparam = (1 << event) | (sock_get_error(sock->errors[event]) << 16);
                post_message( sock->window, sock->message, sock->wparam, lparam );
            }
        }
        sock->pmask = 0;
        sock_reselect( sock );
    }
}
コード例 #8
0
ファイル: net.c プロジェクト: Strongc/reactos
BOOL netconn_send( netconn_t *conn, const void *msg, size_t len, int *sent )
{
    if (!netconn_connected( conn )) return FALSE;
    if (conn->secure)
    {
        const BYTE *ptr = msg;
        size_t chunk_size;

        *sent = 0;

        while(len) {
            chunk_size = min(len, conn->ssl_sizes.cbMaximumMessage);
            if(!send_ssl_chunk(conn, ptr, chunk_size))
                return FALSE;

            *sent += chunk_size;
            ptr += chunk_size;
            len -= chunk_size;
        }

        return TRUE;
    }
    if ((*sent = sock_send( conn->socket, msg, len, 0 )) == -1)
    {
        set_last_error( sock_get_error( errno ) );
        return FALSE;
    }
    return TRUE;
}
コード例 #9
0
ファイル: netconnection.c プロジェクト: NVIDIA/winex_lgpl
/******************************************************************************
 * NETCON_send
 * Basically calls 'send()' unless we should use SSL
 * number of chars send is put in *sent
 */
DWORD NETCON_send(netconn_t *connection, const void *msg, size_t len, int flags,
		int *sent /* out */)
{
    if(!connection->secure)
    {
	*sent = sock_send(connection->socket, msg, len, flags);
	if (*sent == -1)
	    return sock_get_error(errno);
        return ERROR_SUCCESS;
    }
    else
    {
        const BYTE *ptr = msg;
        size_t chunk_size;

        *sent = 0;

        while(len) {
            chunk_size = min(len, connection->ssl_sizes.cbMaximumMessage);
            if(!send_ssl_chunk(connection, ptr, chunk_size))
                return ERROR_INTERNET_SECURITY_CHANNEL_ERROR;

            *sent += chunk_size;
            ptr += chunk_size;
            len -= chunk_size;
        }

        return ERROR_SUCCESS;
    }
}
コード例 #10
0
ファイル: netconnection.c プロジェクト: WASSUM/longene_travel
DWORD NETCON_set_timeout(WININET_NETCONNECTION *connection, BOOL send, int value)
{
    int result;
    struct timeval tv;

    /* FIXME: we should probably store the timeout in the connection to set
     * when we do connect */
    if (!NETCON_connected(connection))
        return ERROR_SUCCESS;

    /* value is in milliseconds, convert to struct timeval */
    tv.tv_sec = value / 1000;
    tv.tv_usec = (value % 1000) * 1000;

    result = setsockopt(connection->socketFD, SOL_SOCKET,
                        send ? SO_SNDTIMEO : SO_RCVTIMEO, &tv,
                        sizeof(tv));

    if (result == -1)
    {
        WARN("setsockopt failed (%s)\n", strerror(errno));
        return sock_get_error(errno);
    }

    return ERROR_SUCCESS;
}
コード例 #11
0
ファイル: net.c プロジェクト: mikekap/wine
BOOL netconn_close( netconn_t *conn )
{
    int res;

#ifdef SONAME_LIBSSL
    if (conn->secure)
    {
        heap_free( conn->peek_msg_mem );
        conn->peek_msg_mem = NULL;
        conn->peek_msg = NULL;
        conn->peek_len = 0;

        pSSL_shutdown( conn->ssl_conn );
        pSSL_free( conn->ssl_conn );

        conn->ssl_conn = NULL;
        conn->secure = FALSE;
    }
#endif
    res = closesocket( conn->socket );
    conn->socket = -1;
    if (res == -1)
    {
        set_last_error( sock_get_error( errno ) );
        return FALSE;
    }
    return TRUE;
}
コード例 #12
0
ファイル: netconnection.c プロジェクト: WASSUM/longene_travel
/******************************************************************************
 * NETCON_close
 * Basically calls 'close()' unless we should use SSL
 */
BOOL NETCON_close(WININET_NETCONNECTION *connection)
{
    int result;

    if (!NETCON_connected(connection)) return FALSE;

#ifdef SONAME_LIBSSL
    if (connection->useSSL)
    {
        HeapFree(GetProcessHeap(),0,connection->peek_msg_mem);
        connection->peek_msg = NULL;
        connection->peek_msg_mem = NULL;
        connection->peek_len = 0;

        pSSL_shutdown(connection->ssl_s);
        pSSL_free(connection->ssl_s);
        connection->ssl_s = NULL;

        connection->useSSL = FALSE;
    }
#endif

    result = closesocket(connection->socketFD);
    connection->socketFD = -1;

    if (result == -1)
    {
        INTERNET_SetLastError(sock_get_error(errno));
        return FALSE;
    }
    return TRUE;
}
コード例 #13
0
ファイル: netconnection.c プロジェクト: NVIDIA/winex_lgpl
static DWORD create_netconn_socket(server_t *server, netconn_t *netconn, DWORD timeout)
{
    int result;
    ULONG flag;

    assert(server->addr_len);
    result = netconn->socket = socket(server->addr.ss_family, SOCK_STREAM, 0);
    if(result != -1) {
        flag = 1;
        ioctlsocket(netconn->socket, FIONBIO, &flag);
        result = connect(netconn->socket, (struct sockaddr*)&server->addr, server->addr_len);
        if(result == -1)
        {
            if (sock_get_error(errno) == WSAEINPROGRESS) {
                struct pollfd pfd;
                int res;

                pfd.fd = netconn->socket;
                pfd.events = POLLOUT;
                res = poll(&pfd, 1, timeout);
                if (!res)
                {
                    closesocket(netconn->socket);
                    netconn->socket = -1;
                    return ERROR_INTERNET_CANNOT_CONNECT;
                }
                else if (res > 0)
                {
                    int err;
                    socklen_t len = sizeof(err);
                    if (!getsockopt(netconn->socket, SOL_SOCKET, SO_ERROR, (void *)&err, &len) && !err)
                        result = 0;
                }
            }
        }
        if(result == -1)
        {
            closesocket(netconn->socket);
            netconn->socket = -1;
        }
        else {
            flag = 0;
            ioctlsocket(netconn->socket, FIONBIO, &flag);
        }
    }
    if(result == -1)
        return ERROR_INTERNET_CANNOT_CONNECT;

#ifdef TCP_NODELAY
    flag = 1;
    result = setsockopt(netconn->socket, IPPROTO_TCP, TCP_NODELAY, (void*)&flag, sizeof(flag));
    if(result < 0)
        WARN("setsockopt(TCP_NODELAY) failed\n");
#endif

    return ERROR_SUCCESS;
}
コード例 #14
0
ファイル: net.c プロジェクト: Strongc/reactos
BOOL netconn_recv( netconn_t *conn, void *buf, size_t len, int flags, int *recvd )
{
    *recvd = 0;
    if (!netconn_connected( conn )) return FALSE;
    if (!len) return TRUE;

    if (conn->secure)
    {
        SIZE_T size, cread;
        BOOL res, eof;

        if (conn->peek_msg)
        {
            *recvd = min( len, conn->peek_len );
            memcpy( buf, conn->peek_msg, *recvd );
            conn->peek_len -= *recvd;
            conn->peek_msg += *recvd;

            if (conn->peek_len == 0)
            {
                heap_free( conn->peek_msg_mem );
                conn->peek_msg_mem = NULL;
                conn->peek_msg = NULL;
            }
            /* check if we have enough data from the peek buffer */
            if (!(flags & MSG_WAITALL) || *recvd == len) return TRUE;
        }
        size = *recvd;

        do {
            res = read_ssl_chunk(conn, (BYTE*)buf+size, len-size, &cread, &eof);
            if(!res) {
                WARN("read_ssl_chunk failed\n");
                if(!size)
                    return FALSE;
                break;
            }

            if(eof) {
                TRACE("EOF\n");
                break;
            }

            size += cread;
        } while(!size || ((flags & MSG_WAITALL) && size < len));

        TRACE("received %ld bytes\n", size);
        *recvd = size;
        return TRUE;
    }
    if ((*recvd = sock_recv( conn->socket, buf, len, flags )) == -1)
    {
        set_last_error( sock_get_error( errno ) );
        return FALSE;
    }
    return TRUE;
}
コード例 #15
0
ファイル: net.c プロジェクト: HBelusca/NasuTek-Odyssey
BOOL netconn_connect( netconn_t *conn, const struct sockaddr *sockaddr, unsigned int addr_len, int timeout )
{
    BOOL ret = FALSE;
    int res = 0, state;

    if (timeout > 0)
    {
        state = 1;
        ioctlsocket( conn->socket, FIONBIO, &state );
    }
    if (connect( conn->socket, sockaddr, addr_len ) < 0)
    {
        res = sock_get_error( errno );
        if (res == WSAEWOULDBLOCK || res == WSAEINPROGRESS)
        {
            fd_set outfd;
            struct timeval tv;

            FD_ZERO(&outfd);
            FD_SET(conn->socket, &outfd);

            tv.tv_sec = 0;
            tv.tv_usec = timeout * 1000;

            if (select( 0, NULL, &outfd, NULL, &tv ) > 0)
                ret = TRUE;
            else
                res = sock_get_error( errno );
        }
    }
    else
        ret = TRUE;
    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 );
    }
    return ret;
}
コード例 #16
0
BOOL netconn_connect( netconn_t *conn, const struct sockaddr *sockaddr, unsigned int addr_len )
{
    if (connect( conn->socket, sockaddr, addr_len ) == -1)
    {
        WARN("unable to connect to host (%s)\n", strerror(errno));
        set_last_error( sock_get_error( errno ) );
        return FALSE;
    }
    return TRUE;
}
コード例 #17
0
ファイル: net.c プロジェクト: mikekap/wine
BOOL netconn_create( netconn_t *conn, int domain, int type, int protocol )
{
    if ((conn->socket = socket( domain, type, protocol )) == -1)
    {
        WARN("unable to create socket (%s)\n", strerror(errno));
        set_last_error( sock_get_error( errno ) );
        return FALSE;
    }
    return TRUE;
}
コード例 #18
0
ファイル: net.c プロジェクト: mikekap/wine
BOOL netconn_connect( netconn_t *conn, const struct sockaddr *sockaddr, unsigned int addr_len, int timeout )
{
    BOOL ret = FALSE;
    int res = 0, state;

    if (timeout > 0)
    {
        state = 1;
        ioctlsocket( conn->socket, FIONBIO, &state );
    }
    if (connect( conn->socket, sockaddr, addr_len ) < 0)
    {
        res = sock_get_error( errno );
        if (res == WSAEWOULDBLOCK || res == WSAEINPROGRESS)
        {
            struct pollfd pfd;

            pfd.fd = conn->socket;
            pfd.events = POLLOUT;
            if (poll( &pfd, 1, timeout ) > 0)
                ret = TRUE;
            else
                res = sock_get_error( errno );
        }
    }
    else
        ret = TRUE;
    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 );
    }
    return ret;
}
コード例 #19
0
DWORD create_netconn(BOOL useSSL, server_t *server, DWORD security_flags, netconn_t **ret)
{
    netconn_t *netconn;
    int result, flag;

    if(useSSL) {
        DWORD res;

        TRACE("using SSL connection\n");

        EnterCriticalSection(&init_ssl_cs);
        res = init_openssl();
        LeaveCriticalSection(&init_ssl_cs);
        if(res != ERROR_SUCCESS)
            return res;
    }

    netconn = heap_alloc_zero(sizeof(*netconn));
    if(!netconn)
        return ERROR_OUTOFMEMORY;

    netconn->useSSL = useSSL;
    netconn->socketFD = -1;
    netconn->security_flags = security_flags;
    list_init(&netconn->pool_entry);

    assert(server->addr_len);
    result = netconn->socketFD = socket(server->addr.ss_family, SOCK_STREAM, 0);
    if(result != -1) {
        result = connect(netconn->socketFD, (struct sockaddr*)&server->addr, server->addr_len);
        if(result == -1)
            closesocket(netconn->socketFD);
    }
    if(result == -1) {
        heap_free(netconn);
        return sock_get_error(errno);
    }

#ifdef TCP_NODELAY
    flag = 1;
    result = setsockopt(netconn->socketFD, IPPROTO_TCP, TCP_NODELAY, (void*)&flag, sizeof(flag));
    if(result < 0)
        WARN("setsockopt(TCP_NODELAY) failed\n");
#endif

    server_addref(server);
    netconn->server = server;

    *ret = netconn;
    return ERROR_SUCCESS;
}
コード例 #20
0
ファイル: net.c プロジェクト: Strongc/reactos
DWORD netconn_set_timeout( netconn_t *netconn, BOOL send, int value )
{
    struct timeval tv;

    /* value is in milliseconds, convert to struct timeval */
    tv.tv_sec = value / 1000;
    tv.tv_usec = (value % 1000) * 1000;

    if (setsockopt( netconn->socket, SOL_SOCKET, send ? SO_SNDTIMEO : SO_RCVTIMEO, (void*)&tv, sizeof(tv) ) == -1)
    {
        WARN("setsockopt failed (%s)\n", strerror( errno ));
        return sock_get_error( errno );
    }
    return ERROR_SUCCESS;
}
コード例 #21
0
ファイル: netconnection.c プロジェクト: WASSUM/longene_travel
/******************************************************************************
 * NETCON_create
 * Basically calls 'socket()'
 */
BOOL NETCON_create(WININET_NETCONNECTION *connection, int domain,
	      int type, int protocol)
{
#ifdef SONAME_LIBSSL
    if (connection->useSSL)
        return FALSE;
#endif

    connection->socketFD = socket(domain, type, protocol);
    if (connection->socketFD == -1)
    {
        INTERNET_SetLastError(sock_get_error(errno));
        return FALSE;
    }
    return TRUE;
}
コード例 #22
0
void Meta_send(char *mesg, size_t len)
{
    int i;

    if (!options.reportToMetaServer)
	return;

    for (i = 0; i < NELEM(meta_servers); i++) {
	if (sock_send_dest(&contactSocket, meta_servers[i].addr,
			   META_PORT, mesg, (int)len) != (int)len) {
	    sock_get_error(&contactSocket);
	    sock_send_dest(&contactSocket, meta_servers[i].addr,
			   META_PORT, mesg, (int)len);
	}
    }
}
コード例 #23
0
ファイル: netconnection.c プロジェクト: WASSUM/longene_travel
/******************************************************************************
 * NETCON_connect
 * Connects to the specified address.
 */
BOOL NETCON_connect(WININET_NETCONNECTION *connection, const struct sockaddr *serv_addr,
		    unsigned int addrlen)
{
    int result;

    if (!NETCON_connected(connection)) return FALSE;

    result = connect(connection->socketFD, serv_addr, addrlen);
    if (result == -1)
    {
        WARN("Unable to connect to host (%s)\n", strerror(errno));
        INTERNET_SetLastError(sock_get_error(errno));

        closesocket(connection->socketFD);
        connection->socketFD = -1;
        return FALSE;
    }

    return TRUE;
}
コード例 #24
0
ファイル: net.c プロジェクト: mikekap/wine
BOOL netconn_send( netconn_t *conn, const void *msg, size_t len, int flags, int *sent )
{
    if (!netconn_connected( conn )) return FALSE;
    if (conn->secure)
    {
#ifdef SONAME_LIBSSL
        if (flags) FIXME("SSL_write doesn't support any flags (%08x)\n", flags);
        *sent = pSSL_write( conn->ssl_conn, msg, len );
        if (*sent < 1 && len) return FALSE;
        return TRUE;
#else
        return FALSE;
#endif
    }
    if ((*sent = send( conn->socket, msg, len, flags )) == -1)
    {
        set_last_error( sock_get_error( errno ) );
        return FALSE;
    }
    return TRUE;
}
コード例 #25
0
ファイル: net.c プロジェクト: ccpgames/wine
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;
}
コード例 #26
0
ファイル: net.c プロジェクト: mikekap/wine
BOOL netconn_recv( netconn_t *conn, void *buf, size_t len, int flags, int *recvd )
{
    int ret;

    *recvd = 0;
    if (!netconn_connected( conn )) return FALSE;
    if (!len) return TRUE;

    if (conn->secure)
    {
#ifdef SONAME_LIBSSL
        if (flags & ~(MSG_PEEK | MSG_WAITALL))
            FIXME("SSL_read does not support the following flags: %08x\n", flags);

        /* this ugly hack is all for MSG_PEEK */
        if (flags & MSG_PEEK && !conn->peek_msg)
        {
            if (!(conn->peek_msg = conn->peek_msg_mem = heap_alloc( len + 1 ))) return FALSE;
        }
        else if (flags & MSG_PEEK && conn->peek_msg)
        {
            if (len < conn->peek_len) FIXME("buffer isn't big enough, should we wrap?\n");
            *recvd = min( len, conn->peek_len );
            memcpy( buf, conn->peek_msg, *recvd );
            return TRUE;
        }
        else if (conn->peek_msg)
        {
            *recvd = min( len, conn->peek_len );
            memcpy( buf, conn->peek_msg, *recvd );
            conn->peek_len -= *recvd;
            conn->peek_msg += *recvd;

            if (conn->peek_len == 0)
            {
                heap_free( conn->peek_msg_mem );
                conn->peek_msg_mem = NULL;
                conn->peek_msg = NULL;
            }
            /* check if we have enough data from the peek buffer */
            if (!(flags & MSG_WAITALL) || (*recvd == len)) return TRUE;
        }
        ret = pSSL_read( conn->ssl_conn, (char *)buf + *recvd, len - *recvd );
        if (ret < 0)
            return FALSE;

        /* check if EOF was received */
        if (!ret && (pSSL_get_error( conn->ssl_conn, ret ) == SSL_ERROR_ZERO_RETURN ||
                     pSSL_get_error( conn->ssl_conn, ret ) == SSL_ERROR_SYSCALL ))
        {
            netconn_close( conn );
            return TRUE;
        }
        if (flags & MSG_PEEK) /* must copy into buffer */
        {
            conn->peek_len = ret;
            if (!ret)
            {
                heap_free( conn->peek_msg_mem );
                conn->peek_msg_mem = NULL;
                conn->peek_msg = NULL;
            }
            else memcpy( conn->peek_msg, buf, ret );
        }
        *recvd = ret;
        return TRUE;
#else
        return FALSE;
#endif
    }
    if ((*recvd = recv( conn->socket, buf, len, flags )) == -1)
    {
        set_last_error( sock_get_error( errno ) );
        return FALSE;
    }
    return TRUE;
}
コード例 #27
0
ファイル: netconnection.c プロジェクト: NVIDIA/winex_lgpl
/******************************************************************************
 * NETCON_recv
 * Basically calls 'recv()' unless we should use SSL
 * number of chars received is put in *recvd
 */
DWORD NETCON_recv(netconn_t *connection, void *buf, size_t len, blocking_mode_t mode, int *recvd)
{
    *recvd = 0;
    if (!len)
        return ERROR_SUCCESS;

    if (!connection->secure)
    {
        int flags = 0;

        switch(mode) {
        case BLOCKING_ALLOW:
            break;
        case BLOCKING_DISALLOW:
            flags = WINE_MSG_DONTWAIT;
            break;
        case BLOCKING_WAITALL:
            flags = MSG_WAITALL;
            break;
        }

        set_socket_blocking(connection->socket, mode);
	*recvd = sock_recv(connection->socket, buf, len, flags);
	return *recvd == -1 ? sock_get_error(errno) :  ERROR_SUCCESS;
    }
    else
    {
        SIZE_T size = 0, cread;
        BOOL eof;
        DWORD res;

        if(connection->peek_msg) {
            size = min(len, connection->peek_len);
            memcpy(buf, connection->peek_msg, size);
            connection->peek_len -= size;
            connection->peek_msg += size;

            if(!connection->peek_len) {
                heap_free(connection->peek_msg_mem);
                connection->peek_msg_mem = connection->peek_msg = NULL;
            }
            /* check if we have enough data from the peek buffer */
            if(mode != BLOCKING_WAITALL || size == len) {
                *recvd = size;
                return ERROR_SUCCESS;
            }

            mode = BLOCKING_DISALLOW;
        }

        do {
            res = read_ssl_chunk(connection, (BYTE*)buf+size, len-size, mode, &cread, &eof);
            if(res != ERROR_SUCCESS) {
                if(res == WSAEWOULDBLOCK) {
                    if(size)
                        res = ERROR_SUCCESS;
                }else {
                    WARN("read_ssl_chunk failed\n");
                }
                break;
            }

            if(eof) {
                TRACE("EOF\n");
                break;
            }

            size += cread;
        }while(!size || (mode == BLOCKING_WAITALL && size < len));

        TRACE("received %zd bytes\n", size);
        *recvd = size;
        return res;
    }
}
コード例 #28
0
BOOL netconn_get_next_line( netconn_t *conn, char *buffer, DWORD *buflen )
{
    struct pollfd pfd;
    BOOL ret = FALSE;
    DWORD recvd = 0;

    if (!netconn_connected( conn )) return FALSE;

    if (conn->secure)
    {
#ifdef SONAME_LIBSSL
        long timeout;

        timeout = pSSL_CTX_get_timeout( ctx );
        pSSL_CTX_set_timeout( ctx, DEFAULT_RECEIVE_TIMEOUT );

        while (recvd < *buflen)
        {
            int dummy;
            if (!netconn_recv( conn, &buffer[recvd], 1, 0, &dummy ))
            {
                set_last_error( ERROR_CONNECTION_ABORTED );
                break;
            }
            if (buffer[recvd] == '\n')
            {
                ret = TRUE;
                break;
            }
            if (buffer[recvd] != '\r') recvd++;
        }
        pSSL_CTX_set_timeout( ctx, timeout );
        if (ret)
        {
            buffer[recvd++] = 0;
            *buflen = recvd;
            TRACE("received line %s\n", debugstr_a(buffer));
        }
        return ret;
#else
        return FALSE;
#endif
    }

    pfd.fd = conn->socket;
    pfd.events = POLLIN;
    while (recvd < *buflen)
    {
        if (poll( &pfd, 1, DEFAULT_RECEIVE_TIMEOUT * 1000 ) > 0)
        {
            int res;
            if ((res = recv( conn->socket, &buffer[recvd], 1, 0 )) <= 0)
            {
                if (res == -1) set_last_error( sock_get_error( errno ) );
                break;
            }
            if (buffer[recvd] == '\n')
            {
                ret = TRUE;
                break;
            }
            if (buffer[recvd] != '\r') recvd++;
        }
        else
        {
            set_last_error( ERROR_WINHTTP_TIMEOUT );
            break;
        }
    }
    if (ret)
    {
        buffer[recvd++] = 0;
        *buflen = recvd;
        TRACE("received line %s\n", debugstr_a(buffer));
    }
    return ret;
}
コード例 #29
0
ファイル: net.c プロジェクト: mikekap/wine
BOOL netconn_get_next_line( netconn_t *conn, char *buffer, DWORD *buflen )
{
    struct pollfd pfd;
    BOOL ret = FALSE;
    DWORD recvd = 0;

    if (!netconn_connected( conn )) return FALSE;

    if (conn->secure)
    {
#ifdef SONAME_LIBSSL
        while (recvd < *buflen)
        {
            int dummy;
            if (!netconn_recv( conn, &buffer[recvd], 1, 0, &dummy ))
            {
                set_last_error( ERROR_CONNECTION_ABORTED );
                break;
            }
            if (buffer[recvd] == '\n')
            {
                ret = TRUE;
                break;
            }
            if (buffer[recvd] != '\r') recvd++;
        }
        if (ret)
        {
            buffer[recvd++] = 0;
            *buflen = recvd;
            TRACE("received line %s\n", debugstr_a(buffer));
        }
        return ret;
#else
        return FALSE;
#endif
    }

    pfd.fd = conn->socket;
    pfd.events = POLLIN;
    while (recvd < *buflen)
    {
        int timeout, res;
        struct timeval tv;
        socklen_t len = sizeof(tv);

        if ((res = getsockopt( conn->socket, SOL_SOCKET, SO_RCVTIMEO, (void*)&tv, &len ) != -1))
            timeout = tv.tv_sec * 1000 + tv.tv_usec / 1000;
        else
            timeout = -1;
        if (poll( &pfd, 1, timeout ) > 0)
        {
            if ((res = recv( conn->socket, &buffer[recvd], 1, 0 )) <= 0)
            {
                if (res == -1) set_last_error( sock_get_error( errno ) );
                break;
            }
            if (buffer[recvd] == '\n')
            {
                ret = TRUE;
                break;
            }
            if (buffer[recvd] != '\r') recvd++;
        }
        else
        {
            set_last_error( ERROR_WINHTTP_TIMEOUT );
            break;
        }
    }
    if (ret)
    {
        buffer[recvd++] = 0;
        *buflen = recvd;
        TRACE("received line %s\n", debugstr_a(buffer));
    }
    return ret;
}
コード例 #30
0
ファイル: netconnection.c プロジェクト: WASSUM/longene_travel
/******************************************************************************
 * NETCON_getNextLine
 */
BOOL NETCON_getNextLine(WININET_NETCONNECTION *connection, LPSTR lpszBuffer, LPDWORD dwBuffer)
{

    TRACE("\n");

    if (!NETCON_connected(connection)) return FALSE;

    if (!connection->useSSL)
    {
        struct pollfd pfd;
	BOOL bSuccess = FALSE;
	DWORD nRecv = 0;

        pfd.fd = connection->socketFD;
        pfd.events = POLLIN;

	while (nRecv < *dwBuffer)
	{
	    if (poll(&pfd,1, RESPONSE_TIMEOUT * 1000) > 0)
	    {
		if (recv(connection->socketFD, &lpszBuffer[nRecv], 1, 0) <= 0)
		{
		    INTERNET_SetLastError(sock_get_error(errno));
		    goto lend;
		}

		if (lpszBuffer[nRecv] == '\n')
		{
		    bSuccess = TRUE;
		    break;
		}
		if (lpszBuffer[nRecv] != '\r')
		    nRecv++;
	    }
	    else
	    {
		INTERNET_SetLastError(ERROR_INTERNET_TIMEOUT);
		goto lend;
	    }
	}

    lend:             /* FIXME: don't use labels */
	if (bSuccess)
	{
	    lpszBuffer[nRecv++] = '\0';
	    *dwBuffer = nRecv;
	    TRACE(":%u %s\n", nRecv, lpszBuffer);
            return TRUE;
	}
	else
	{
	    return FALSE;
	}
    }
    else
    {
#ifdef SONAME_LIBSSL
	long prev_timeout;
	DWORD nRecv = 0;
        BOOL success = TRUE;

        prev_timeout = pSSL_CTX_get_timeout(ctx);
	pSSL_CTX_set_timeout(ctx, RESPONSE_TIMEOUT);

	while (nRecv < *dwBuffer)
	{
	    int recv = 1;
	    if (!NETCON_recv(connection, &lpszBuffer[nRecv], 1, 0, &recv))
	    {
                INTERNET_SetLastError(ERROR_CONNECTION_ABORTED);
		success = FALSE;
	    }

	    if (lpszBuffer[nRecv] == '\n')
	    {
		success = TRUE;
                break;
	    }
	    if (lpszBuffer[nRecv] != '\r')
		nRecv++;
	}

        pSSL_CTX_set_timeout(ctx, prev_timeout);
	if (success)
	{
	    lpszBuffer[nRecv++] = '\0';
	    *dwBuffer = nRecv;
	    TRACE("_SSL:%u %s\n", nRecv, lpszBuffer);
            return TRUE;
	}
        return FALSE;
#else
	return FALSE;
#endif
    }
}