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; }
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; }
int VNCServer::Client::ProcessMessage() { //While we have data while(buffer.length() && !wait.IsCanceled()) //Process message rfbProcessClientMessage(cl); //OK return 1; }
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); }
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; }
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; }
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; }
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 } } }