X-Git-Url: https://git.sesse.net/?p=rdpsrv;a=blobdiff_plain;f=Xserver%2Fprograms%2FXserver%2Fhw%2Fvnc%2Fsockets.c;fp=Xserver%2Fprograms%2FXserver%2Fhw%2Fvnc%2Fsockets.c;h=0000000000000000000000000000000000000000;hp=370a46a56a9fd5d893fceedba836d36813bdeb93;hb=ce66b81460e5353db09d45c02339d4583fbda255;hpb=7772d71ffd742cfc9b7ff214659d16c5bb56a391 diff --git a/Xserver/programs/Xserver/hw/vnc/sockets.c b/Xserver/programs/Xserver/hw/vnc/sockets.c deleted file mode 100644 index 370a46a..0000000 --- a/Xserver/programs/Xserver/hw/vnc/sockets.c +++ /dev/null @@ -1,510 +0,0 @@ -/* - * sockets.c - deal with TCP sockets. - * - * This code should be independent of any changes in the RFB protocol. It just - * deals with the X server scheduling stuff, calling rfbNewClientConnection and - * rfbProcessClientMessage to actually deal with the protocol. If a socket - * needs to be closed for any reason then rfbCloseSock should be called, and - * this in turn will call rfbClientConnectionGone. To make an active - * connection out, call rfbConnect - note that this does _not_ call - * rfbNewClientConnection. - * - * This file is divided into two types of function. Those beginning with - * "rfb" are specific to sockets using the RFB protocol. Those without the - * "rfb" prefix are more general socket routines (which are used by the http - * code). - * - * Thanks to Karl Hakimian for pointing out that some platforms return EAGAIN - * not EWOULDBLOCK. - */ - -/* - * Copyright (C) 2002 RealVNC Ltd. - * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rfb.h" - - -int rfbMaxClientWait = 20000; /* time (ms) after which we decide client has - gone away - needed to stop us hanging */ - -int rfbPort = 0; -int rfbListenSock = -1; -Bool rfbLocalhostOnly = FALSE; - -static fd_set allFds; -static int maxFd = 0; - - -/* - * rfbInitSockets sets up the TCP sockets to listen for RFB - * connections. It does nothing if called again. - */ - -void -rfbInitSockets() -{ - static Bool done = FALSE; - - if (done) - return; - - done = TRUE; - - if (inetdSock != -1) { - const int one = 1; - - if (fcntl(inetdSock, F_SETFL, O_NONBLOCK) < 0) { - rfbLogPerror("fcntl"); - exit(1); - } - - if (setsockopt(inetdSock, IPPROTO_TCP, TCP_NODELAY, - (char *)&one, sizeof(one)) < 0) { - rfbLogPerror("setsockopt"); - exit(1); - } - - AddEnabledDevice(inetdSock); - FD_ZERO(&allFds); - FD_SET(inetdSock, &allFds); - maxFd = inetdSock; - return; - } - - if (rfbPort == 0) { - rfbPort = 5900 + atoi(display); - } - - rfbLog("Listening for VNC connections on TCP port %d\n", rfbPort); - - if ((rfbListenSock = ListenOnTCPPort(rfbPort)) < 0) { - rfbLogPerror("ListenOnTCPPort"); - exit(1); - } - - AddEnabledDevice(rfbListenSock); - - FD_ZERO(&allFds); - FD_SET(rfbListenSock, &allFds); - maxFd = rfbListenSock; -} - - -/* - * rfbCheckFds is called from ProcessInputEvents to check for input on the RFB - * socket(s). If there is input to process, the appropriate function in the - * RFB server code will be called (rfbNewClientConnection, - * rfbProcessClientMessage, etc). - */ - -void -rfbCheckFds() -{ - int nfds; - fd_set fds; - struct timeval tv; - struct sockaddr_in addr; - unsigned int addrlen = sizeof(addr); - const int one = 1; - int sock; - 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"); - rfbLog("Got connection from client %s\n", inet_ntoa(addr.sin_addr)); - - AddEnabledDevice(sock); - FD_SET(sock, &allFds); - maxFd = max(sock,maxFd); - - rfbNewClientConnection(sock); - - FD_CLR(rfbListenSock, &fds); - if (--nfds == 0) - return; - } - - for (sock = 0; sock <= maxFd; sock++) { - if (FD_ISSET(sock, &fds) && FD_ISSET(sock, &allFds)) { - rfbProcessClientMessage(sock); - } - } -} - - -void -rfbCloseSock(sock) - int sock; -{ - close(sock); - RemoveEnabledDevice(sock); - FD_CLR(sock, &allFds); - rfbClientConnectionGone(sock); - if (sock == inetdSock) - GiveUp(0); -} - - -/* - * rfbWaitForClient can be called to wait for the RFB client to send us a - * message. When one is received it is processed by calling - * rfbProcessClientMessage(). - */ - -void -rfbWaitForClient(sock) - int sock; -{ - int n; - fd_set fds; - struct timeval tv; - - FD_ZERO(&fds); - FD_SET(sock, &fds); - tv.tv_sec = rfbMaxClientWait / 1000; - tv.tv_usec = (rfbMaxClientWait % 1000) * 1000; - n = select(sock+1, &fds, NULL, NULL, &tv); - if (n < 0) { - rfbLogPerror("rfbWaitForClient: select"); - exit(1); - } - if (n == 0) { - rfbCloseSock(sock); - return; - } - - rfbProcessClientMessage(sock); -} - - -/* - * rfbConnect is called to make a connection out to a given TCP address. - */ - -int -rfbConnect(host, port) - char *host; - int port; -{ - int sock; - int one = 1; - - fprintf(stderr,"\n"); - rfbLog("Making connection to client on host %s port %d\n", - host,port); - - if ((sock = ConnectToTcpAddr(host, port)) < 0) { - rfbLogPerror("connection failed"); - return -1; - } - - if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) { - rfbLogPerror("fcntl failed"); - close(sock); - return -1; - } - - if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, - (char *)&one, sizeof(one)) < 0) { - rfbLogPerror("setsockopt failed"); - close(sock); - return -1; - } - - AddEnabledDevice(sock); - FD_SET(sock, &allFds); - maxFd = max(sock,maxFd); - - return sock; -} - - - - -/* - * ReadExact reads an exact number of bytes on a TCP socket. Returns 1 if - * those bytes have been read, 0 if the other end has closed, or -1 if an error - * occurred (errno is set to ETIMEDOUT if it timed out). - */ - -int -ReadExact(sock, buf, len) - int sock; - char *buf; - int len; -{ - int n; - fd_set fds; - struct timeval tv; - - while (len > 0) { - n = read(sock, buf, len); - - if (n > 0) { - - buf += n; - len -= n; - - } else if (n == 0) { - - return 0; - - } else { - if (errno != EWOULDBLOCK && errno != EAGAIN) { - return n; - } - - FD_ZERO(&fds); - FD_SET(sock, &fds); - tv.tv_sec = rfbMaxClientWait / 1000; - tv.tv_usec = (rfbMaxClientWait % 1000) * 1000; - n = select(sock+1, &fds, NULL, NULL, &tv); - if (n < 0) { - rfbLogPerror("ReadExact: select"); - return n; - } - if (n == 0) { - errno = ETIMEDOUT; - return -1; - } - } - } - return 1; -} - - - -/* - * WriteExact writes an exact number of bytes on a TCP socket. Returns 1 if - * those bytes have been written, or -1 if an error occurred (errno is set to - * ETIMEDOUT if it timed out). - */ - -int -WriteExact(sock, buf, len) - int sock; - char *buf; - int len; -{ - int n; - fd_set fds; - struct timeval tv; - int totalTimeWaited = 0; - - - while (len > 0) { - n = write(sock, buf, len); - - if (n > 0) { - - buf += n; - len -= n; - - } else if (n == 0) { - - rfbLog("WriteExact: write returned 0?\n"); - exit(1); - - } else { - if (errno != EWOULDBLOCK && errno != EAGAIN) { - return n; - } - - /* Retry every 5 seconds until we exceed rfbMaxClientWait. We - need to do this because select doesn't necessarily return - immediately when the other end has gone away */ - - FD_ZERO(&fds); - FD_SET(sock, &fds); - tv.tv_sec = 5; - tv.tv_usec = 0; - n = select(sock+1, NULL, &fds, NULL, &tv); - if (n < 0) { - rfbLogPerror("WriteExact: select"); - return n; - } - if (n == 0) { - totalTimeWaited += 5000; - if (totalTimeWaited >= rfbMaxClientWait) { - errno = ETIMEDOUT; - return -1; - } - } else { - totalTimeWaited = 0; - } - } - } - return 1; -} - - -int -ListenOnTCPPort(port) - int port; -{ - int sock; - int one = 1; -#ifdef AF_INET6 - int ipv = 4; - struct sockaddr_in6 addr6; -#endif - struct sockaddr_in addr; - - memset(&addr, 0, sizeof(addr)); -#ifdef AF_INET6 - ipv = 6; - addr6.sin6_family = AF_INET6; - addr6.sin6_port = htons(port); - if (rfbLocalhostOnly) - addr6.sin6_addr = in6addr_loopback; - else - addr6.sin6_addr = in6addr_any; - - /* Don't fail if an IPv6 socket cannot be established, but fall back to - IPv4 */ - if ((sock = socket(AF_INET6, SOCK_STREAM, 0)) < 0) - { - ipv = 4; -#endif - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - if (rfbLocalhostOnly) - addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - else - addr.sin_addr.s_addr = htonl(INADDR_ANY); - - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - return -1; - } -#ifdef AF_INET6 - } -#endif - if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, - (char *)&one, sizeof(one)) < 0) { - close(sock); - return -1; - } -#ifdef AF_INET6 - if (ipv == 6) { - if (bind(sock, (struct sockaddr *)&addr6, sizeof(addr6)) < 0) { - close(sock); - return -1; - } - } - else if (ipv == 4) { -#endif - if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - close(sock); - return -1; - } -#ifdef AF_INET6 - } -#endif - if (listen(sock, 5) < 0) { - close(sock); - return -1; - } - - return sock; -} - - -int -ConnectToTcpAddr(host, port) - char *host; - int port; -{ - struct hostent *hp; - int sock; - struct sockaddr_in addr; - - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - - if ((addr.sin_addr.s_addr = inet_addr(host)) == -1) - { - if (!(hp = gethostbyname(host))) { - errno = EINVAL; - return -1; - } - addr.sin_addr.s_addr = *(unsigned long *)hp->h_addr; - } - - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - return -1; - } - - if (connect(sock, (struct sockaddr *)&addr, (sizeof(addr))) < 0) { - close(sock); - return -1; - } - - return sock; -}