Exemple #1
0
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;
}
Exemple #2
0
/******************************************************************************
 * 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, BOOL blocking, int *recvd)
{
    *recvd = 0;
    if (!len)
        return ERROR_SUCCESS;

    if (!connection->secure)
    {
        set_socket_blocking(connection, blocking);
        *recvd = sock_recv(connection->socket, buf, len, 0);
        return *recvd == -1 ? WSAGetLastError() :  ERROR_SUCCESS;
    }
    else
    {
        SIZE_T size = 0;
        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;
            }

            *recvd = size;
            return ERROR_SUCCESS;
        }

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

        TRACE("received %ld bytes\n", size);
        *recvd = size;
        return res;
    }
}
Exemple #3
0
/******************************************************************************
 * 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;
    }
}
Exemple #4
0
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 (flags & ~(MSG_PEEK | MSG_WAITALL))
            FIXME("SSL_read does not support the following flags: %08x\n", flags);

        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;
        }
        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));

        if(size && (flags & MSG_PEEK)) {
            conn->peek_msg_mem = conn->peek_msg = heap_alloc(size);
            if(!conn->peek_msg)
                return FALSE;

            memcpy(conn->peek_msg, buf, size);
        }

        TRACE("received %ld bytes\n", size);
        *recvd = size;
        return TRUE;
    }
    if ((*recvd = recv( conn->socket, buf, len, flags )) == -1)
    {
        set_last_error( sock_get_error( errno ) );
        return FALSE;
    }
    return TRUE;
}