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