Esempio n. 1
0
int
lazy_operation_addlayer (unsigned int layer_id, unsigned int buffer_id,
                         int width, int height,
                         int sx, int sy, int sw, int sh,
                         int dx, int dy, int dw, int dh)
{
    lazy_operation_addlayer_t op;
    lazy_operation_addlayer_res_t ret;

    memset (&op, 0, sizeof (op));
    op.operation = LAZY_OPERATION_ADD_LAYER;
    op.layer_id = layer_id;
    op.width = width;
    op.height = height;
    op.src.x = sx;
    op.src.y = sy;
    op.src.w = sw;
    op.src.h = sh;
    op.dst.x = dx;
    op.dst.y = dy;
    op.dst.w = dw;
    op.dst.h = dh;

    op.buffer_id = buffer_id;

    SOCKET_LOCK ();

    if (write (socket_fd, &op, sizeof (op)) != sizeof (op))
    {
        perror ("write");
        goto addlayer_fail;
    }

    if (read (socket_fd, &ret, sizeof (ret)) != sizeof (ret))
    {
        perror ("read");
        goto addlayer_fail;
    }

    if (ret.result != LAZY_OPERATION_RESULT_SUCCESS)
        goto addlayer_fail;

    SOCKET_UNLOCK ();

    return 1;

addlayer_fail:

    SOCKET_UNLOCK ();

    return 0;
}
Esempio n. 2
0
void
lazy_operation_fini (void)
{
    SOCKET_LOCK ();

    close (socket_fd);
    socket_fd = -1;

    SOCKET_UNLOCK ();
}
Esempio n. 3
0
void
lazy_operation_init (void)
{
    struct sockaddr_in sv_addr;
    struct hostent *host;

    SOCKET_LOCK ();

    if (socket_fd != -1)
    {
        socket_fd = -1;
        close (socket_fd);
    }

    /* Resolv name */
    if (!(host = gethostbyname (LAZY_PASSTHROUGH_HOST)))
    {
        SOCKET_UNLOCK ();
        return;
    }

    memset (&sv_addr, 0, sizeof (struct sockaddr_in));

    sv_addr.sin_family = AF_INET;
    sv_addr.sin_addr = *((struct in_addr *) host->h_addr);
    sv_addr.sin_port = htons (LAZY_PASSTHROUGH_PORT);

    if ((socket_fd = socket (AF_INET, SOCK_STREAM, IPPROTO_IP)) >= 0)
    {
        if (connect (socket_fd,
                     (struct sockaddr *) &sv_addr,
                     sizeof (struct sockaddr)) < 0)
        {
            perror ("connect");
            close (socket_fd);
        }
    }
    else
        perror ("socket");

    SOCKET_UNLOCK ();
}
Esempio n. 4
0
int
lazy_operation_addbuffer (int width, int height, int bpp,
                          unsigned int *buffer_id)
{
    lazy_operation_addbuffer_t op;
    lazy_operation_addbuffer_res_t ret;

    memset (&op, 0, sizeof (op));
    op.operation = LAZY_OPERATION_ADD_BUFFER;
    op.width = width;
    op.height = height;
    op.bpp = bpp;

    SOCKET_LOCK ();

    if (write (socket_fd, &op, sizeof (op)) != sizeof (op))
    {
        perror ("write");
        goto addlayer_fail;
    }

    if (read (socket_fd, &ret, sizeof (ret)) != sizeof (ret))
    {
        perror ("read");
        goto addlayer_fail;
    }

    if (ret.result != LAZY_OPERATION_RESULT_SUCCESS)
        goto addlayer_fail;

    SOCKET_UNLOCK ();

    *buffer_id = ret.buffer_id;

    return 1;

addlayer_fail:

    SOCKET_UNLOCK ();

    return 0;
}
Esempio n. 5
0
int
lazy_operation_fliplayer (unsigned int layer_id, unsigned int buffer_id)
{
    lazy_operation_fliplayer_t op;
    lazy_operation_fliplayer_res_t ret;

    memset (&op, 0, sizeof (op));
    op.operation = LAZY_OPERATION_FLIP_LAYER;
    op.layer_id = layer_id;
    op.buffer_id = buffer_id;

    SOCKET_LOCK ();

    if (write (socket_fd, &op, sizeof (op)) != sizeof (op))
    {
        perror ("write");
        goto addlayer_fail;
    }

    if (read (socket_fd, &ret, sizeof (ret)) != sizeof (ret))
    {
        perror ("read");
        goto addlayer_fail;
    }

    if (ret.result != LAZY_OPERATION_RESULT_SUCCESS)
        goto addlayer_fail;

    SOCKET_UNLOCK ();

    return 1;

addlayer_fail:

    SOCKET_UNLOCK ();

    return 0;
}
void
udp_detach(PNATState pData, struct socket *so)
{
    if (so != &pData->icmp_socket)
    {
        Assert(so->so_type == IPPROTO_UDP);
        QSOCKET_LOCK(udb);
        SOCKET_LOCK(so);
        QSOCKET_UNLOCK(udb);
        closesocket(so->s);
        sofree(pData, so);
        SOCKET_UNLOCK(so);
    }
}
Esempio n. 7
0
void
udp_detach(PNATState pData, struct socket *so)
{
    if (so != &pData->icmp_socket)
    {
        Assert(so->so_type == IPPROTO_UDP);
        QSOCKET_LOCK(udb);
        SOCKET_LOCK(so);
        QSOCKET_UNLOCK(udb);
#ifdef VBOX_WITH_NAT_UDP_SOCKET_CLONE
        if (so->so_cloneOf)
            so->so_cloneOf->so_cCloneCounter--;
        else if (so->so_cCloneCounter > 0)
        {
            /* we can't close socket yet */
            SOCKET_UNLOCK(so);
            return;
        }
#endif
        closesocket(so->s);
        sofree(pData, so);
        SOCKET_UNLOCK(so);
    }
}
/*
 * Read from so's socket into sb_snd, updating all relevant sbuf fields
 * NOTE: This will only be called if it is select()ed for reading, so
 * a read() of 0 (or less) means it's disconnected
 */
int
soread(PNATState pData, struct socket *so)
{
    int n, nn, lss, total;
    struct sbuf *sb = &so->so_snd;
    u_int len = sb->sb_datalen - sb->sb_cc;
    struct iovec iov[2];
    int mss = so->so_tcpcb->t_maxseg;
    int sockerr;

    STAM_PROFILE_START(&pData->StatIOread, a);
    STAM_COUNTER_RESET(&pData->StatIORead_in_1);
    STAM_COUNTER_RESET(&pData->StatIORead_in_2);

    QSOCKET_LOCK(tcb);
    SOCKET_LOCK(so);
    QSOCKET_UNLOCK(tcb);

    LogFlow(("soread: so = %R[natsock]\n", so));
    Log2(("%s: so = %R[natsock] so->so_snd = %R[sbuf]\n", RT_GCC_EXTENSION __PRETTY_FUNCTION__, so, sb));

    /*
     * No need to check if there's enough room to read.
     * soread wouldn't have been called if there weren't
     */

    len = sb->sb_datalen - sb->sb_cc;

    iov[0].iov_base = sb->sb_wptr;
    iov[1].iov_base = 0;
    iov[1].iov_len  = 0;
    if (sb->sb_wptr < sb->sb_rptr)
    {
        iov[0].iov_len = sb->sb_rptr - sb->sb_wptr;
        /* Should never succeed, but... */
        if (iov[0].iov_len > len)
            iov[0].iov_len = len;
        if (iov[0].iov_len > mss)
            iov[0].iov_len -= iov[0].iov_len%mss;
        n = 1;
    }
    else
    {
        iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_wptr;
        /* Should never succeed, but... */
        if (iov[0].iov_len > len)
            iov[0].iov_len = len;
        len -= iov[0].iov_len;
        if (len)
        {
            iov[1].iov_base = sb->sb_data;
            iov[1].iov_len = sb->sb_rptr - sb->sb_data;
            if (iov[1].iov_len > len)
                iov[1].iov_len = len;
            total = iov[0].iov_len + iov[1].iov_len;
            if (total > mss)
            {
                lss = total % mss;
                if (iov[1].iov_len > lss)
                {
                    iov[1].iov_len -= lss;
                    n = 2;
                }
                else
                {
                    lss -= iov[1].iov_len;
                    iov[0].iov_len -= lss;
                    n = 1;
                }
            }
            else
                n = 2;
        }
        else
        {
            if (iov[0].iov_len > mss)
                iov[0].iov_len -= iov[0].iov_len%mss;
            n = 1;
        }
    }

#ifdef HAVE_READV
    nn = readv(so->s, (struct iovec *)iov, n);
#else
    nn = recv(so->s, iov[0].iov_base, iov[0].iov_len, (so->so_tcpcb->t_force? MSG_OOB:0));
#endif
    if (nn < 0)
        sockerr = errno; /* save it, as it may be clobbered by logging */
    else
        sockerr = 0;

    Log2(("%s: read(1) nn = %d bytes\n", RT_GCC_EXTENSION __PRETTY_FUNCTION__, nn));
    Log2(("%s: so = %R[natsock] so->so_snd = %R[sbuf]\n", RT_GCC_EXTENSION __PRETTY_FUNCTION__, so, sb));
    if (nn <= 0)
    {
#ifdef RT_OS_WINDOWS
        /*
         * Windows reports ESHUTDOWN after SHUT_RD (SD_RECEIVE)
         * instead of just returning EOF indication.
         */
        if (nn < 0 && sockerr == ESHUTDOWN)
        {
            nn = 0;
            sockerr = 0;
        }
#endif

        if (nn == 0) /* XXX: should this be inside #if defined(RT_OS_WINDOWS)? */
        {
            /*
             * Special case for WSAEnumNetworkEvents: If we receive 0 bytes that
             * _could_ mean that the connection is closed. But we will receive an
             * FD_CLOSE event later if the connection was _really_ closed. With
             * www.youtube.com I see this very often. Closing the socket too early
             * would be dangerous.
             */
            int status;
            unsigned long pending = 0;
            status = ioctlsocket(so->s, FIONREAD, &pending);
            if (status < 0)
                Log(("NAT:%s: error in WSAIoctl: %d\n", RT_GCC_EXTENSION __PRETTY_FUNCTION__, errno));
            if (pending != 0)
            {
                SOCKET_UNLOCK(so);
                STAM_PROFILE_STOP(&pData->StatIOread, a);
                return 0;
            }
        }

        if (   nn < 0
            && soIgnorableErrorCode(sockerr))
        {
            SOCKET_UNLOCK(so);
            STAM_PROFILE_STOP(&pData->StatIOread, a);
            return 0;
        }
        else
        {
            int fUninitializedTemplate = 0;
            int shuterr;

            fUninitializedTemplate = RT_BOOL((   sototcpcb(so)
                                              && (  sototcpcb(so)->t_template.ti_src.s_addr == INADDR_ANY
                                                 || sototcpcb(so)->t_template.ti_dst.s_addr == INADDR_ANY)));
            /* nn == 0 means peer has performed an orderly shutdown */
            Log2(("%s: disconnected, nn = %d, errno = %d (%s)\n",
                  RT_GCC_EXTENSION __PRETTY_FUNCTION__, nn, sockerr, strerror(sockerr)));

            shuterr = sofcantrcvmore(so);
            if (!sockerr && !shuterr && !fUninitializedTemplate)
                tcp_sockclosed(pData, sototcpcb(so));
            else
            {
                LogRel2(("NAT: sockerr %d, shuterr %d - %R[natsock]\n", sockerr, shuterr, so));
                tcp_drop(pData, sototcpcb(so), sockerr);
            }
            SOCKET_UNLOCK(so);
            STAM_PROFILE_STOP(&pData->StatIOread, a);
            return -1;
        }
    }
    STAM_STATS(
        if (n == 1)
        {
            STAM_COUNTER_INC(&pData->StatIORead_in_1);
            STAM_COUNTER_ADD(&pData->StatIORead_in_1_bytes, nn);
        }
        else
        {
            STAM_COUNTER_INC(&pData->StatIORead_in_2);
            STAM_COUNTER_ADD(&pData->StatIORead_in_2_1st_bytes, nn);
        }
    );