2 * sockets.c - deal with TCP sockets.
4 * This code should be independent of any changes in the RFB protocol. It just
5 * deals with the X server scheduling stuff, calling rfbNewClientConnection and
6 * rfbProcessClientMessage to actually deal with the protocol. If a socket
7 * needs to be closed for any reason then rfbCloseSock should be called, and
8 * this in turn will call rfbClientConnectionGone. To make an active
9 * connection out, call rfbConnect - note that this does _not_ call
10 * rfbNewClientConnection.
12 * This file is divided into two types of function. Those beginning with
13 * "rfb" are specific to sockets using the RFB protocol. Those without the
14 * "rfb" prefix are more general socket routines (which are used by the http
17 * Thanks to Karl Hakimian for pointing out that some platforms return EAGAIN
22 * Copyright (C) 2002 RealVNC Ltd.
23 * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
25 * This is free software; you can redistribute it and/or modify
26 * it under the terms of the GNU General Public License as published by
27 * the Free Software Foundation; either version 2 of the License, or
28 * (at your option) any later version.
30 * This software is distributed in the hope that it will be useful,
31 * but WITHOUT ANY WARRANTY; without even the implied warranty of
32 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 * GNU General Public License for more details.
35 * You should have received a copy of the GNU General Public License
36 * along with this software; if not, write to the Free Software
37 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
44 #include <sys/types.h>
46 #include <sys/socket.h>
47 #include <netinet/in.h>
48 #include <netinet/tcp.h>
49 #include <arpa/inet.h>
57 int rfbMaxClientWait = 20000; /* time (ms) after which we decide client has
58 gone away - needed to stop us hanging */
61 int rfbListenSock = -1;
62 Bool rfbLocalhostOnly = FALSE;
69 * rfbInitSockets sets up the TCP sockets to listen for RFB
70 * connections. It does nothing if called again.
76 static Bool done = FALSE;
83 if (inetdSock != -1) {
86 if (fcntl(inetdSock, F_SETFL, O_NONBLOCK) < 0) {
87 rfbLogPerror("fcntl");
91 if (setsockopt(inetdSock, IPPROTO_TCP, TCP_NODELAY,
92 (char *)&one, sizeof(one)) < 0) {
93 rfbLogPerror("setsockopt");
97 AddEnabledDevice(inetdSock);
99 FD_SET(inetdSock, &allFds);
105 rfbPort = 5900 + atoi(display);
108 rfbLog("Listening for VNC connections on TCP port %d\n", rfbPort);
110 if ((rfbListenSock = ListenOnTCPPort(rfbPort)) < 0) {
111 rfbLogPerror("ListenOnTCPPort");
115 AddEnabledDevice(rfbListenSock);
118 FD_SET(rfbListenSock, &allFds);
119 maxFd = rfbListenSock;
124 * rfbCheckFds is called from ProcessInputEvents to check for input on the RFB
125 * socket(s). If there is input to process, the appropriate function in the
126 * RFB server code will be called (rfbNewClientConnection,
127 * rfbProcessClientMessage, etc).
136 struct sockaddr_in addr;
137 unsigned int addrlen = sizeof(addr);
140 static Bool inetdInitDone = FALSE;
142 if (!inetdInitDone && inetdSock != -1) {
143 rfbNewClientConnection(inetdSock);
144 inetdInitDone = TRUE;
147 memcpy((char *)&fds, (char *)&allFds, sizeof(fd_set));
150 nfds = select(maxFd + 1, &fds, NULL, NULL, &tv);
155 rfbLogPerror("rfbCheckFds: select");
159 if (rfbListenSock != -1 && FD_ISSET(rfbListenSock, &fds)) {
161 if ((sock = accept(rfbListenSock,
162 (struct sockaddr *)&addr, &addrlen)) < 0) {
163 rfbLogPerror("rfbCheckFds: accept");
167 if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) {
168 rfbLogPerror("rfbCheckFds: fcntl");
173 if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
174 (char *)&one, sizeof(one)) < 0) {
175 rfbLogPerror("rfbCheckFds: setsockopt");
180 fprintf(stderr,"\n");
181 rfbLog("Got connection from client %s\n", inet_ntoa(addr.sin_addr));
183 AddEnabledDevice(sock);
184 FD_SET(sock, &allFds);
185 maxFd = max(sock,maxFd);
187 rfbNewClientConnection(sock);
189 FD_CLR(rfbListenSock, &fds);
194 for (sock = 0; sock <= maxFd; sock++) {
195 if (FD_ISSET(sock, &fds) && FD_ISSET(sock, &allFds)) {
196 rfbProcessClientMessage(sock);
207 RemoveEnabledDevice(sock);
208 FD_CLR(sock, &allFds);
209 rfbClientConnectionGone(sock);
210 if (sock == inetdSock)
216 * rfbWaitForClient can be called to wait for the RFB client to send us a
217 * message. When one is received it is processed by calling
218 * rfbProcessClientMessage().
222 rfbWaitForClient(sock)
231 tv.tv_sec = rfbMaxClientWait / 1000;
232 tv.tv_usec = (rfbMaxClientWait % 1000) * 1000;
233 n = select(sock+1, &fds, NULL, NULL, &tv);
235 rfbLogPerror("rfbWaitForClient: select");
243 rfbProcessClientMessage(sock);
248 * rfbConnect is called to make a connection out to a given TCP address.
252 rfbConnect(host, port)
259 fprintf(stderr,"\n");
260 rfbLog("Making connection to client on host %s port %d\n",
263 if ((sock = ConnectToTcpAddr(host, port)) < 0) {
264 rfbLogPerror("connection failed");
268 if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) {
269 rfbLogPerror("fcntl failed");
274 if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
275 (char *)&one, sizeof(one)) < 0) {
276 rfbLogPerror("setsockopt failed");
281 AddEnabledDevice(sock);
282 FD_SET(sock, &allFds);
283 maxFd = max(sock,maxFd);
292 * ReadExact reads an exact number of bytes on a TCP socket. Returns 1 if
293 * those bytes have been read, 0 if the other end has closed, or -1 if an error
294 * occurred (errno is set to ETIMEDOUT if it timed out).
298 ReadExact(sock, buf, len)
308 n = read(sock, buf, len);
320 if (errno != EWOULDBLOCK && errno != EAGAIN) {
326 tv.tv_sec = rfbMaxClientWait / 1000;
327 tv.tv_usec = (rfbMaxClientWait % 1000) * 1000;
328 n = select(sock+1, &fds, NULL, NULL, &tv);
330 rfbLogPerror("ReadExact: select");
345 * WriteExact writes an exact number of bytes on a TCP socket. Returns 1 if
346 * those bytes have been written, or -1 if an error occurred (errno is set to
347 * ETIMEDOUT if it timed out).
351 WriteExact(sock, buf, len)
359 int totalTimeWaited = 0;
363 n = write(sock, buf, len);
372 rfbLog("WriteExact: write returned 0?\n");
376 if (errno != EWOULDBLOCK && errno != EAGAIN) {
380 /* Retry every 5 seconds until we exceed rfbMaxClientWait. We
381 need to do this because select doesn't necessarily return
382 immediately when the other end has gone away */
388 n = select(sock+1, NULL, &fds, NULL, &tv);
390 rfbLogPerror("WriteExact: select");
394 totalTimeWaited += 5000;
395 if (totalTimeWaited >= rfbMaxClientWait) {
409 ListenOnTCPPort(port)
416 struct sockaddr_in6 addr6;
418 struct sockaddr_in addr;
420 memset(&addr, 0, sizeof(addr));
423 addr6.sin6_family = AF_INET6;
424 addr6.sin6_port = htons(port);
425 if (rfbLocalhostOnly)
426 addr6.sin6_addr = in6addr_loopback;
428 addr6.sin6_addr = in6addr_any;
430 /* Don't fail if an IPv6 socket cannot be established, but fall back to
432 if ((sock = socket(AF_INET6, SOCK_STREAM, 0)) < 0)
436 addr.sin_family = AF_INET;
437 addr.sin_port = htons(port);
438 if (rfbLocalhostOnly)
439 addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
441 addr.sin_addr.s_addr = htonl(INADDR_ANY);
443 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
449 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
450 (char *)&one, sizeof(one)) < 0) {
456 if (bind(sock, (struct sockaddr *)&addr6, sizeof(addr6)) < 0) {
463 if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
470 if (listen(sock, 5) < 0) {
480 ConnectToTcpAddr(host, port)
486 struct sockaddr_in addr;
488 addr.sin_family = AF_INET;
489 addr.sin_port = htons(port);
491 if ((addr.sin_addr.s_addr = inet_addr(host)) == -1)
493 if (!(hp = gethostbyname(host))) {
497 addr.sin_addr.s_addr = *(unsigned long *)hp->h_addr;
500 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
504 if (connect(sock, (struct sockaddr *)&addr, (sizeof(addr))) < 0) {