示例#1
0
int
ReadExact(rfbClientPtr cl, char *buf, int len)
{
    int n;
    fd_set fds;
    struct timeval tv;
    int sock = cl->sock;

    while (len > 0) {
        do {
#if USETLS
            if (cl->sslctx)
                n = rfbssl_read(cl, buf, len);
            else
#endif
            n = read(sock, buf, len);
        } while (n < 0 && errno == EINTR);

        if (n > 0) {

            buf += n;
            len -= n;

        } else if (n == 0) {

            return 0;

        } else {
            if (errno != EWOULDBLOCK && errno != EAGAIN) {
                return n;
            }

#if USETLS
            if (cl->sslctx) {
                if (rfbssl_pending(cl))
                    continue;
            }
#endif
            FD_ZERO(&fds);
            FD_SET(sock, &fds);
            tv.tv_sec = rfbMaxClientWait / 1000;
            tv.tv_usec = (rfbMaxClientWait % 1000) * 1000;
            do {
                n = select(sock + 1, &fds, NULL, NULL, &tv);
            } while (n < 0 && errno == EINTR);
            if (n < 0) {
                rfbLogPerror("ReadExact: select");
                return n;
            }
            if (n == 0) {
                errno = ETIMEDOUT;
                return -1;
            }
        }
    }
    return 1;
}
示例#2
0
int
rfbPeekExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout)
{
    int sock = cl->sock;
    int n;
    fd_set fds;
    struct timeval tv;

    while (len > 0) {
#ifdef LIBVNCSERVER_WITH_WEBSOCKETS
	if (cl->sslctx)
	    n = rfbssl_peek(cl, buf, len);
	else
#endif
	    n = recv(sock, buf, len, MSG_PEEK);

        if (n == len) {

            break;

        } else if (n == 0) {

            return 0;

        } else {
#ifdef WIN32
	    errno = WSAGetLastError();
#endif
	    if (errno == EINTR)
		continue;

#ifdef LIBVNCSERVER_ENOENT_WORKAROUND
	    if (errno != ENOENT)
#endif
            if (errno != EWOULDBLOCK && errno != EAGAIN) {
                return n;
            }

#ifdef LIBVNCSERVER_WITH_WEBSOCKETS
	    if (cl->sslctx) {
		if (rfbssl_pending(cl))
		    continue;
	    }
#endif
            FD_ZERO(&fds);
            FD_SET(sock, &fds);
            tv.tv_sec = timeout / 1000;
            tv.tv_usec = (timeout % 1000) * 1000;
            n = select(sock+1, &fds, NULL, &fds, &tv);
            if (n < 0) {
                rfbLogPerror("PeekExact: select");
                return n;
            }
            if (n == 0) {
                errno = ETIMEDOUT;
                return -1;
            }
        }
    }
#undef DEBUG_READ_EXACT
#ifdef DEBUG_READ_EXACT
    rfbLog("PeekExact %d bytes\n",len);
    for(n=0;n<len;n++)
	    fprintf(stderr,"%02x ",(unsigned char)buf[n]);
    fprintf(stderr,"\n");
#endif

    return 1;
}
示例#3
0
void
rfbCheckFds()
{
    int nfds;
    fd_set fds;
    struct timeval tv;
    struct sockaddr_storage addr;
    socklen_t addrlen = sizeof(addr);
    char addrStr[INET6_ADDRSTRLEN];
    char buf[6];
    const int one = 1;
    int sock;
    rfbClientPtr cl;
    static Bool inetdInitDone = FALSE;

    if (!inetdInitDone && inetdSock != -1) {
        rfbNewClientConnection(inetdSock);
        inetdInitDone = TRUE;
    }

    memcpy((char *)&fds, (char *)&allFds, sizeof(fd_set));
    tv.tv_sec = 0;
    tv.tv_usec = 0;
    nfds = select(maxFd + 1, &fds, NULL, NULL, &tv);
    if (nfds == 0) {
        return;
    }
    if (nfds < 0) {
        rfbLogPerror("rfbCheckFds: select");
        return;
    }

    if (rfbListenSock != -1 && FD_ISSET(rfbListenSock, &fds)) {

        if ((sock = accept(rfbListenSock,
                           (struct sockaddr *)&addr, &addrlen)) < 0) {
            rfbLogPerror("rfbCheckFds: accept");
            return;
        }

        if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) {
            rfbLogPerror("rfbCheckFds: fcntl");
            close(sock);
            return;
        }

        if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
                       (char *)&one, sizeof(one)) < 0) {
            rfbLogPerror("rfbCheckFds: setsockopt");
            close(sock);
            return;
        }

        fprintf(stderr, "\n");

#if USE_LIBWRAP
        if (!hosts_ctl("Xvnc", STRING_UNKNOWN,
                       sockaddr_string(&addr, addrStr, INET6_ADDRSTRLEN),
                       STRING_UNKNOWN)) {
          rfbLog("Rejected connection from client %s\n",
                 sockaddr_string(&addr, addrStr, INET6_ADDRSTRLEN))
          close(sock);
          return;
        }
#endif

        rfbLog("Got connection from client %s\n",
               sockaddr_string(&addr, addrStr, INET6_ADDRSTRLEN));

        AddEnabledDevice(sock);
        FD_SET(sock, &allFds);
        maxFd = max(sock, maxFd);

        rfbNewClientConnection(sock);

        FD_CLR(rfbListenSock, &fds);
        if (--nfds == 0)
            return;
    }

    if ((udpSock != -1) && FD_ISSET(udpSock, &fds)) {

        if (recvfrom(udpSock, buf, 1, MSG_PEEK,
                     (struct sockaddr *)&addr, &addrlen) < 0) {

            rfbLogPerror("rfbCheckFds: UDP: recvfrom");
            rfbDisconnectUDPSock();

        } else {

            if (!udpSockConnected ||
                (memcmp(&addr, &udpRemoteAddr, addrlen) != 0))
            {
                /* new remote end */
                rfbLog("rfbCheckFds: UDP: got connection\n");

                memcpy(&udpRemoteAddr, &addr, addrlen);
                udpSockConnected = TRUE;

                if (connect(udpSock,
                            (struct sockaddr *)&addr, addrlen) < 0) {
                    rfbLogPerror("rfbCheckFds: UDP: connect");
                    rfbDisconnectUDPSock();
                    return;
                }

                rfbNewUDPConnection(udpSock);
            }

            rfbProcessUDPInput(udpSock);
        }

        FD_CLR(udpSock, &fds);
        if (--nfds == 0)
            return;
    }

    for (cl = rfbClientHead; cl; cl = cl->next) {
        if (FD_ISSET(cl->sock, &fds) && FD_ISSET(cl->sock, &allFds)) {
            rfbClientPtr cl2;
#if USETLS
            do {
                rfbProcessClientMessage(cl);
                /* Make sure cl hasn't been freed */
                for (cl2 = rfbClientHead; cl2; cl2 = cl2->next) {
                    if (cl2 == cl)
                        break;
                }
                if (cl2 == NULL) return;
            } while (cl->sslctx && rfbssl_pending(cl) > 0);
#else
            rfbProcessClientMessage(cl);
            for (cl2 = rfbClientHead; cl2; cl2 = cl2->next) {
                if (cl2 == cl)
                    break;
            }
            if (cl2 == NULL) return;
#endif
        }
    }
}