示例#1
0
文件: main.c 项目: UIKit0/picogui
static void *
clientInput(void *data)
{
    rfbClientPtr cl = (rfbClientPtr)data;
    pthread_t output_thread;
    pthread_create(&output_thread, NULL, clientOutput, (void *)cl);

    while (1) {
        rfbProcessClientMessage(cl);
        if (cl->sock == -1) {
            /* Client has disconnected. */
            break;
        }
    }

    /* Get rid of the output thread. */
    LOCK(cl->updateMutex);
    TSIGNAL(cl->updateCond);
    UNLOCK(cl->updateMutex);
    IF_PTHREADS(pthread_join(output_thread, NULL));

    rfbClientConnectionGone(cl);

    return NULL;
}
示例#2
0
文件: main.c 项目: Sharm/libvncserver
static void *
clientInput(void *data)
{
    rfbClientPtr cl = (rfbClientPtr)data;
    pthread_t output_thread;
    pthread_create(&output_thread, NULL, clientOutput, (void *)cl);

    while (1) {
	fd_set rfds, wfds, efds;
	struct timeval tv;
	int n;

	if (cl->sock == -1) {
	  /* Client has disconnected. */
            break;
        }

	FD_ZERO(&rfds);
	FD_SET(cl->sock, &rfds);
	FD_ZERO(&efds);
	FD_SET(cl->sock, &efds);

	/* Are we transferring a file in the background? */
	FD_ZERO(&wfds);
	if ((cl->fileTransfer.fd!=-1) && (cl->fileTransfer.sending==1))
	    FD_SET(cl->sock, &wfds);

	tv.tv_sec = 60; /* 1 minute */
	tv.tv_usec = 0;
	n = select(cl->sock + 1, &rfds, &wfds, &efds, &tv);
	if (n < 0) {
	    rfbLogPerror("ReadExact: select");
	    break;
	}
	if (n == 0) /* timeout */
	{
            rfbSendFileTransferChunk(cl);
	    continue;
        }
        
        /* We have some space on the transmit queue, send some data */
        if (FD_ISSET(cl->sock, &wfds))
            rfbSendFileTransferChunk(cl);

        if (FD_ISSET(cl->sock, &rfds) || FD_ISSET(cl->sock, &efds))
            rfbProcessClientMessage(cl);
    }

    /* Get rid of the output thread. */
    LOCK(cl->updateMutex);
    TSIGNAL(cl->updateCond);
    UNLOCK(cl->updateMutex);
    IF_PTHREADS(pthread_join(output_thread, NULL));

    rfbClientConnectionGone(cl);

    return NULL;
}
示例#3
0
文件: VNCServer.cpp 项目: crubia/wt
int VNCServer::Client::ProcessMessage()
{
	//While we have data
	while(buffer.length() && !wait.IsCanceled())
		//Process message
		rfbProcessClientMessage(cl);

	//OK
	return 1;
}
示例#4
0
文件: sockets.c 项目: DjCBS3/vino
void
rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec)
{
    int nfds;
    int n;
    fd_set fds;
    struct timeval tv;
    rfbClientIteratorPtr i;
    rfbClientPtr cl;

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

    memcpy(&fds, &rfbScreen->allFds, sizeof(fd_set));
    tv.tv_sec = 0;
    tv.tv_usec = usec;
    nfds = select(rfbScreen->maxFd + 1, &fds, NULL, NULL /* &fds */, &tv);
    if (nfds == 0) {
	return;
    }
    if (nfds < 0) {
#ifdef WIN32
		errno = WSAGetLastError();
#endif
	if (errno != EINTR)
		rfbLogPerror("rfbCheckFds: select");
	return;
    }
    printf("DUMP: nfds = %d\n", nfds);
    for(n=0; n < rfbScreen->rfbListenSockTotal; n++) {
        if (rfbScreen->rfbListenSock[n] != -1 && FD_ISSET(rfbScreen->rfbListenSock[n], &fds)) {
          rfbProcessNewConnection(rfbScreen, rfbScreen->rfbListenSock[n]);
          FD_CLR(rfbScreen->rfbListenSock[n], &fds);
          if (--nfds == 0)
            return;
        }
    }

    i = rfbGetClientIterator(rfbScreen);
    while((cl = rfbClientIteratorNext(i))) {
      if (cl->onHold)
	continue;
      if (FD_ISSET(cl->sock, &fds) && FD_ISSET(cl->sock, &(rfbScreen->allFds)))
	rfbProcessClientMessage(cl);
    }
    rfbReleaseClientIterator(i);
}
示例#5
0
文件: auth.c 项目: djyos/djyos
static void
rfbVncAuthNone(rfbClientPtr cl)
{
    /* The built-in Mac OS X VNC client behaves in a non-conforming fashion
     * when the server version is 3.7 or later AND the list of security types
     * sent to the OS X client contains the 'None' authentication type AND
     * the OS X client sends back the 'None' type as its choice.  In this case,
     * and this case ONLY, the built-in Mac OS X VNC client will NOT send the
     * ClientInit message and instead will behave as though an implicit
     * ClientInit message containing a shared-flag of true has been sent.
     * The special state RFB_INITIALISATION_SHARED represents this case.
     * The Mac OS X VNC client can be detected by checking protocolMinorVersion
     * for a value of 889.  No other VNC client is known to use this value
     * for protocolMinorVersion. */
    uint32_t authResult;

    /* The built-in Mac OS X VNC client expects to NOT receive a SecurityResult
     * message for authentication type 'None'.  Since its protocolMinorVersion
     * is greater than 7 (it is 889) this case must be tested for specially. */
    if (cl->protocolMajorVersion==3 && cl->protocolMinorVersion > 7 && cl->protocolMinorVersion != 889) {
        rfbLog("rfbProcessClientSecurityType: returning securityResult for client rfb version >= 3.8\n");
        authResult = Swap32IfLE(rfbVncAuthOK);
        if (rfbWriteExact(cl, (char *)&authResult, 4) < 0) {
            rfbLogPerror("rfbAuthProcessClientMessage: write");
            rfbCloseClient(cl);
            return;
        }
    }
    cl->state = cl->protocolMinorVersion == 889 ? RFB_INITIALISATION_SHARED : RFB_INITIALISATION;
    if (cl->state == RFB_INITIALISATION_SHARED)
        /* In this case we must call rfbProcessClientMessage now because
         * otherwise we would hang waiting for data to be received from the
         * client (the ClientInit message which will never come). */
        rfbProcessClientMessage(cl);
    return;
}
示例#6
0
int
rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec)
{
    int nfds;
    fd_set fds;
    struct timeval tv;
    struct sockaddr_in addr;
    socklen_t addrlen = sizeof(addr);
    char buf[6];
    const int one = 1;
    int sock;
    rfbClientIteratorPtr i;
    rfbClientPtr cl;
    struct timeval tv_msg;
    fd_set fds_msg;
    int nfds_msg;
    int result = 0;

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

    do {
        memcpy((char *)&fds, (char *)&(rfbScreen->allFds), sizeof(fd_set));
        tv.tv_sec = 0;
        tv.tv_usec = usec;
        nfds = select(rfbScreen->maxFd + 1, &fds, NULL, NULL /* &fds */, &tv);
        if (nfds == 0) {
            /* timed out, check for async events */
            i = rfbGetClientIterator(rfbScreen);
            while((cl = rfbClientIteratorNext(i))) {
                if (cl->onHold)
                    continue;
                if (FD_ISSET(cl->sock, &(rfbScreen->allFds)))
                    rfbSendFileTransferChunk(cl);
            }
            rfbReleaseClientIterator(i);
            return result;
        }

        if (nfds < 0) {
#ifdef WIN32
            errno = WSAGetLastError();
#endif
            if (errno != EINTR)
                rfbLogPerror("rfbCheckFds: select");
            return -1;
        }

        result += nfds;

        if (rfbScreen->listenSock != -1 && FD_ISSET(rfbScreen->listenSock, &fds)) {
            if ((sock = accept(rfbScreen->listenSock,
                               (struct sockaddr *)&addr, &addrlen)) < 0) {
                rfbLogPerror("rfbCheckFds: accept");
                return -1;
            }

#ifndef WIN32
            if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) {
                rfbLogPerror("rfbCheckFds: fcntl");
                closesocket(sock);
                return -1;
            }
#endif

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

#ifdef USE_LIBWRAP
            if(!hosts_ctl("vnc",STRING_UNKNOWN,inet_ntoa(addr.sin_addr),
                          STRING_UNKNOWN)) {
                rfbLog("Rejected connection from client %s\n",
                       inet_ntoa(addr.sin_addr));
                closesocket(sock);
                return -1;
            }
#endif

            rfbLog("Got connection from client %s\n", inet_ntoa(addr.sin_addr));

            rfbNewClient(rfbScreen,sock);

            FD_CLR(rfbScreen->listenSock, &fds);
            if (--nfds == 0)
                return result;
        }

        if ((rfbScreen->udpSock != -1) && FD_ISSET(rfbScreen->udpSock, &fds)) {
            if(!rfbScreen->udpClient)
                rfbNewUDPClient(rfbScreen);
            if (recvfrom(rfbScreen->udpSock, buf, 1, MSG_PEEK,
                         (struct sockaddr *)&addr, &addrlen) < 0) {
                rfbLogPerror("rfbCheckFds: UDP: recvfrom");
                rfbDisconnectUDPSock(rfbScreen);
                rfbScreen->udpSockConnected = FALSE;
            } else {
                if (!rfbScreen->udpSockConnected ||
                        (memcmp(&addr, &rfbScreen->udpRemoteAddr, addrlen) != 0))
                {
                    /* new remote end */
                    rfbLog("rfbCheckFds: UDP: got connection\n");

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

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

                    rfbNewUDPConnection(rfbScreen,rfbScreen->udpSock);
                }

                rfbProcessUDPInput(rfbScreen);
            }

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

        i = rfbGetClientIterator(rfbScreen);
        while((cl = rfbClientIteratorNext(i))) {

            if (cl->onHold)
                continue;

            if (FD_ISSET(cl->sock, &(rfbScreen->allFds)))
            {
                if (FD_ISSET(cl->sock, &fds)) {
                    tv_msg.tv_sec = 0;
                    tv_msg.tv_usec = 0;
                    FD_ZERO(&fds_msg);
                    FD_SET(cl->sock, &fds_msg);
                    do {
                        /* drain all messages, speed up mouse move processing */
                        rfbProcessClientMessage(cl);
                        nfds_msg = select(cl->sock + 1, &fds_msg, NULL, NULL, &tv_msg);
                    } while (nfds_msg > 0);
                }
                else
                    rfbSendFileTransferChunk(cl);
            }
        }
        rfbReleaseClientIterator(i);
    } while(rfbScreen->handleEventsEagerly);
    return result;
}
示例#7
0
int
rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec)
{
    int nfds;
    fd_set fds;
    struct timeval tv;
    struct sockaddr_in addr;
    socklen_t addrlen = sizeof(addr);
    char buf[6];
    rfbClientIteratorPtr i;
    rfbClientPtr cl;
    int result = 0;

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

    do {
	memcpy((char *)&fds, (char *)&(rfbScreen->allFds), sizeof(fd_set));
	tv.tv_sec = 0;
	tv.tv_usec = usec;
	nfds = select(rfbScreen->maxFd + 1, &fds, NULL, NULL /* &fds */, &tv);
	if (nfds == 0) {
	    /* timed out, check for async events */
            i = rfbGetClientIterator(rfbScreen);
            while((cl = rfbClientIteratorNext(i))) {
                if (cl->onHold)
                    continue;
                if (FD_ISSET(cl->sock, &(rfbScreen->allFds)))
                    rfbSendFileTransferChunk(cl);
            }
            rfbReleaseClientIterator(i);
	    return result;
	}

	if (nfds < 0) {
#ifdef WIN32
	    errno = WSAGetLastError();
#endif
	    if (errno != EINTR)
		rfbLogPerror("rfbCheckFds: select");
	    return -1;
	}

	result += nfds;

	if (rfbScreen->listenSock != -1 && FD_ISSET(rfbScreen->listenSock, &fds)) {

	    if (!rfbProcessNewConnection(rfbScreen))
                return -1;

	    FD_CLR(rfbScreen->listenSock, &fds);
	    if (--nfds == 0)
		return result;
	}

	if (rfbScreen->listen6Sock != -1 && FD_ISSET(rfbScreen->listen6Sock, &fds)) {

	    if (!rfbProcessNewConnection(rfbScreen))
                return -1;

	    FD_CLR(rfbScreen->listen6Sock, &fds);
	    if (--nfds == 0)
		return result;
	}

	if ((rfbScreen->udpSock != -1) && FD_ISSET(rfbScreen->udpSock, &fds)) {
	    if(!rfbScreen->udpClient)
		rfbNewUDPClient(rfbScreen);
	    if (recvfrom(rfbScreen->udpSock, buf, 1, MSG_PEEK,
			(struct sockaddr *)&addr, &addrlen) < 0) {
		rfbLogPerror("rfbCheckFds: UDP: recvfrom");
		rfbDisconnectUDPSock(rfbScreen);
		rfbScreen->udpSockConnected = FALSE;
	    } else {
		if (!rfbScreen->udpSockConnected ||
			(memcmp(&addr, &rfbScreen->udpRemoteAddr, addrlen) != 0))
		{
		    /* new remote end */
		    rfbLog("rfbCheckFds: UDP: got connection\n");

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

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

		    rfbNewUDPConnection(rfbScreen,rfbScreen->udpSock);
		}

		rfbProcessUDPInput(rfbScreen);
	    }

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

	i = rfbGetClientIterator(rfbScreen);
	while((cl = rfbClientIteratorNext(i))) {

	    if (cl->onHold)
		continue;

            if (FD_ISSET(cl->sock, &(rfbScreen->allFds)))
            {
                if (FD_ISSET(cl->sock, &fds))
                    rfbProcessClientMessage(cl);
                else
                    rfbSendFileTransferChunk(cl);
            }
	}
	rfbReleaseClientIterator(i);
    } while(rfbScreen->handleEventsEagerly);
    return result;
}
示例#8
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
        }
    }
}