2 * sockets.c - deal with TCP & UDP 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 rfbCloseClient 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) 2005 Rohit Kumar, Johannes E. Schindelin
23 * OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
24 * Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge.
25 * All Rights Reserved.
27 * This is free software; you can redistribute it and/or modify
28 * it under the terms of the GNU General Public License as published by
29 * the Free Software Foundation; either version 2 of the License, or
30 * (at your option) any later version.
32 * This software is distributed in the hope that it will be useful,
33 * but WITHOUT ANY WARRANTY; without even the implied warranty of
34 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35 * GNU General Public License for more details.
37 * You should have received a copy of the GNU General Public License
38 * along with this software; if not, write to the Free Software
39 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
45 #ifdef LIBVNCSERVER_HAVE_SYS_TYPES_H
46 #include <sys/types.h>
49 #ifdef LIBVNCSERVER_HAVE_SYS_TIME_H
52 #ifdef LIBVNCSERVER_HAVE_SYS_SOCKET_H
53 #include <sys/socket.h>
55 #ifdef LIBVNCSERVER_HAVE_NETINET_IN_H
56 #include <netinet/in.h>
57 #include <netinet/tcp.h>
59 #include <arpa/inet.h>
61 #ifdef LIBVNCSERVER_HAVE_UNISTD_H
65 #if defined(__linux__) && defined(NEED_TIMEVAL)
68 long int tv_sec,tv_usec;
73 #ifdef LIBVNCSERVER_HAVE_FCNTL_H
82 int allow_severity=LOG_INFO;
83 int deny_severity=LOG_WARNING;
88 #pragma warning (disable: 4018 4761)
90 #define read(sock,buf,len) recv(sock,buf,len,0)
91 #define EWOULDBLOCK WSAEWOULDBLOCK
92 #define ETIMEDOUT WSAETIMEDOUT
93 #define write(sock,buf,len) send(sock,buf,len,0)
95 #define closesocket close
98 int rfbMaxClientWait = 20000; /* time (ms) after which we decide client has
99 gone away - needed to stop us hanging */
102 * rfbInitSockets sets up the TCP and UDP sockets to listen for RFB
103 * connections. It does nothing if called again.
107 rfbInitSockets(rfbScreenInfoPtr rfbScreen)
109 in_addr_t iface = rfbScreen->listenInterface;
111 if (rfbScreen->socketState!=RFB_SOCKET_INIT)
114 rfbScreen->socketState = RFB_SOCKET_READY;
116 if (rfbScreen->inetdSock != -1) {
120 if (fcntl(rfbScreen->inetdSock, F_SETFL, O_NONBLOCK) < 0) {
121 rfbLogPerror("fcntl");
126 if (setsockopt(rfbScreen->inetdSock, IPPROTO_TCP, TCP_NODELAY,
127 (char *)&one, sizeof(one)) < 0) {
128 rfbLogPerror("setsockopt");
132 FD_ZERO(&(rfbScreen->allFds));
133 FD_SET(rfbScreen->inetdSock, &(rfbScreen->allFds));
134 rfbScreen->maxFd = rfbScreen->inetdSock;
138 if(rfbScreen->autoPort) {
140 rfbLog("Autoprobing TCP port \n");
141 for (i = 5900; i < 6000; i++) {
142 if ((rfbScreen->listenSock = rfbListenOnTCPPort(i, iface)) >= 0) {
149 rfbLogPerror("Failure autoprobing");
153 rfbLog("Autoprobing selected port %d\n", rfbScreen->port);
154 FD_ZERO(&(rfbScreen->allFds));
155 FD_SET(rfbScreen->listenSock, &(rfbScreen->allFds));
156 rfbScreen->maxFd = rfbScreen->listenSock;
158 else if(rfbScreen->port>0) {
159 rfbLog("Listening for VNC connections on TCP port %d\n", rfbScreen->port);
161 if ((rfbScreen->listenSock = rfbListenOnTCPPort(rfbScreen->port, iface)) < 0) {
162 rfbLogPerror("ListenOnTCPPort");
166 FD_ZERO(&(rfbScreen->allFds));
167 FD_SET(rfbScreen->listenSock, &(rfbScreen->allFds));
168 rfbScreen->maxFd = rfbScreen->listenSock;
171 if (rfbScreen->udpPort != 0) {
172 rfbLog("rfbInitSockets: listening for input on UDP port %d\n",rfbScreen->udpPort);
174 if ((rfbScreen->udpSock = rfbListenOnUDPPort(rfbScreen->udpPort, iface)) < 0) {
175 rfbLogPerror("ListenOnUDPPort");
178 FD_SET(rfbScreen->udpSock, &(rfbScreen->allFds));
179 rfbScreen->maxFd = max((int)rfbScreen->udpSock,rfbScreen->maxFd);
183 void rfbShutdownSockets(rfbScreenInfoPtr rfbScreen)
185 if (rfbScreen->socketState!=RFB_SOCKET_READY)
188 rfbScreen->socketState = RFB_SOCKET_SHUTDOWN;
190 if(rfbScreen->inetdSock>-1) {
191 closesocket(rfbScreen->inetdSock);
192 FD_CLR(rfbScreen->inetdSock,&rfbScreen->allFds);
193 rfbScreen->inetdSock=-1;
196 if(rfbScreen->listenSock>-1) {
197 closesocket(rfbScreen->listenSock);
198 FD_CLR(rfbScreen->listenSock,&rfbScreen->allFds);
199 rfbScreen->listenSock=-1;
202 if(rfbScreen->udpSock>-1) {
203 closesocket(rfbScreen->udpSock);
204 FD_CLR(rfbScreen->udpSock,&rfbScreen->allFds);
205 rfbScreen->udpSock=-1;
210 * rfbCheckFds is called from ProcessInputEvents to check for input on the RFB
211 * socket(s). If there is input to process, the appropriate function in the
212 * RFB server code will be called (rfbNewClientConnection,
213 * rfbProcessClientMessage, etc).
217 rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec)
222 struct sockaddr_in addr;
223 socklen_t addrlen = sizeof(addr);
227 rfbClientIteratorPtr i;
231 if (!rfbScreen->inetdInitDone && rfbScreen->inetdSock != -1) {
232 rfbNewClientConnection(rfbScreen,rfbScreen->inetdSock);
233 rfbScreen->inetdInitDone = TRUE;
237 memcpy((char *)&fds, (char *)&(rfbScreen->allFds), sizeof(fd_set));
240 nfds = select(rfbScreen->maxFd + 1, &fds, NULL, NULL /* &fds */, &tv);
242 /* timed out, check for async events */
243 i = rfbGetClientIterator(rfbScreen);
244 while((cl = rfbClientIteratorNext(i))) {
247 if (FD_ISSET(cl->sock, &(rfbScreen->allFds)))
248 rfbSendFileTransferChunk(cl);
250 rfbReleaseClientIterator(i);
256 errno = WSAGetLastError();
259 rfbLogPerror("rfbCheckFds: select");
265 if (rfbScreen->listenSock != -1 && FD_ISSET(rfbScreen->listenSock, &fds)) {
267 if ((sock = accept(rfbScreen->listenSock,
268 (struct sockaddr *)&addr, &addrlen)) < 0) {
269 rfbLogPerror("rfbCheckFds: accept");
274 if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) {
275 rfbLogPerror("rfbCheckFds: fcntl");
281 if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
282 (char *)&one, sizeof(one)) < 0) {
283 rfbLogPerror("rfbCheckFds: setsockopt");
289 if(!hosts_ctl("vnc",STRING_UNKNOWN,inet_ntoa(addr.sin_addr),
291 rfbLog("Rejected connection from client %s\n",
292 inet_ntoa(addr.sin_addr));
298 rfbLog("Got connection from client %s\n", inet_ntoa(addr.sin_addr));
300 rfbNewClient(rfbScreen,sock);
302 FD_CLR(rfbScreen->listenSock, &fds);
307 if ((rfbScreen->udpSock != -1) && FD_ISSET(rfbScreen->udpSock, &fds)) {
308 if(!rfbScreen->udpClient)
309 rfbNewUDPClient(rfbScreen);
310 if (recvfrom(rfbScreen->udpSock, buf, 1, MSG_PEEK,
311 (struct sockaddr *)&addr, &addrlen) < 0) {
312 rfbLogPerror("rfbCheckFds: UDP: recvfrom");
313 rfbDisconnectUDPSock(rfbScreen);
314 rfbScreen->udpSockConnected = FALSE;
316 if (!rfbScreen->udpSockConnected ||
317 (memcmp(&addr, &rfbScreen->udpRemoteAddr, addrlen) != 0))
320 rfbLog("rfbCheckFds: UDP: got connection\n");
322 memcpy(&rfbScreen->udpRemoteAddr, &addr, addrlen);
323 rfbScreen->udpSockConnected = TRUE;
325 if (connect(rfbScreen->udpSock,
326 (struct sockaddr *)&addr, addrlen) < 0) {
327 rfbLogPerror("rfbCheckFds: UDP: connect");
328 rfbDisconnectUDPSock(rfbScreen);
332 rfbNewUDPConnection(rfbScreen,rfbScreen->udpSock);
335 rfbProcessUDPInput(rfbScreen);
338 FD_CLR(rfbScreen->udpSock, &fds);
343 i = rfbGetClientIterator(rfbScreen);
344 while((cl = rfbClientIteratorNext(i))) {
349 if (FD_ISSET(cl->sock, &(rfbScreen->allFds)))
351 if (FD_ISSET(cl->sock, &fds))
352 rfbProcessClientMessage(cl);
354 rfbSendFileTransferChunk(cl);
357 rfbReleaseClientIterator(i);
358 } while(rfbScreen->handleEventsEagerly);
364 rfbDisconnectUDPSock(rfbScreenInfoPtr rfbScreen)
366 rfbScreen->udpSockConnected = FALSE;
372 rfbCloseClient(rfbClientPtr cl)
374 rfbExtensionData* extension;
376 for(extension=cl->extensions; extension; extension=extension->next)
377 if(extension->extension->close)
378 extension->extension->close(cl, extension->data);
380 LOCK(cl->updateMutex);
381 #ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
385 FD_CLR(cl->sock,&(cl->screen->allFds));
386 if(cl->sock==cl->screen->maxFd)
387 while(cl->screen->maxFd>0
388 && !FD_ISSET(cl->screen->maxFd,&(cl->screen->allFds)))
391 shutdown(cl->sock,SHUT_RDWR);
393 closesocket(cl->sock);
396 TSIGNAL(cl->updateCond);
397 UNLOCK(cl->updateMutex);
402 * rfbConnect is called to make a connection out to a given TCP address.
406 rfbConnect(rfbScreenInfoPtr rfbScreen,
413 rfbLog("Making connection to client on host %s port %d\n",
416 if ((sock = rfbConnectToTcpAddr(host, port)) < 0) {
417 rfbLogPerror("connection failed");
422 if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) {
423 rfbLogPerror("fcntl failed");
429 if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
430 (char *)&one, sizeof(one)) < 0) {
431 rfbLogPerror("setsockopt failed");
436 /* AddEnabledDevice(sock); */
437 FD_SET(sock, &rfbScreen->allFds);
438 rfbScreen->maxFd = max(sock,rfbScreen->maxFd);
444 * ReadExact reads an exact number of bytes from a client. Returns 1 if
445 * those bytes have been read, 0 if the other end has closed, or -1 if an error
446 * occurred (errno is set to ETIMEDOUT if it timed out).
450 rfbReadExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout)
458 n = read(sock, buf, len);
471 errno = WSAGetLastError();
476 #ifdef LIBVNCSERVER_ENOENT_WORKAROUND
479 if (errno != EWOULDBLOCK && errno != EAGAIN) {
485 tv.tv_sec = timeout / 1000;
486 tv.tv_usec = (timeout % 1000) * 1000;
487 n = select(sock+1, &fds, NULL, &fds, &tv);
489 rfbLogPerror("ReadExact: select");
498 #undef DEBUG_READ_EXACT
499 #ifdef DEBUG_READ_EXACT
500 rfbLog("ReadExact %d bytes\n",len);
502 fprintf(stderr,"%02x ",(unsigned char)buf[n]);
503 fprintf(stderr,"\n");
509 int rfbReadExact(rfbClientPtr cl,char* buf,int len)
511 return(rfbReadExactTimeout(cl,buf,len,rfbMaxClientWait));
515 * WriteExact writes an exact number of bytes to a client. Returns 1 if
516 * those bytes have been written, or -1 if an error occurred (errno is set to
517 * ETIMEDOUT if it timed out).
521 rfbWriteExact(rfbClientPtr cl,
529 int totalTimeWaited = 0;
531 #undef DEBUG_WRITE_EXACT
532 #ifdef DEBUG_WRITE_EXACT
533 rfbLog("WriteExact %d bytes\n",len);
535 fprintf(stderr,"%02x ",(unsigned char)buf[n]);
536 fprintf(stderr,"\n");
539 LOCK(cl->outputMutex);
541 n = write(sock, buf, len);
550 rfbErr("WriteExact: write returned 0?\n");
555 errno = WSAGetLastError();
560 if (errno != EWOULDBLOCK && errno != EAGAIN) {
561 UNLOCK(cl->outputMutex);
565 /* Retry every 5 seconds until we exceed rfbMaxClientWait. We
566 need to do this because select doesn't necessarily return
567 immediately when the other end has gone away */
573 n = select(sock+1, NULL, &fds, NULL /* &fds */, &tv);
577 rfbLogPerror("WriteExact: select");
578 UNLOCK(cl->outputMutex);
582 totalTimeWaited += 5000;
583 if (totalTimeWaited >= rfbMaxClientWait) {
585 UNLOCK(cl->outputMutex);
593 UNLOCK(cl->outputMutex);
597 /* currently private, called by rfbProcessArguments() */
599 rfbStringToAddr(char *str, in_addr_t *addr) {
600 if (str == NULL || *str == '\0' || strcmp(str, "any") == 0) {
601 *addr = htonl(INADDR_ANY);
602 } else if (strcmp(str, "localhost") == 0) {
603 *addr = htonl(INADDR_LOOPBACK);
606 if ((*addr = inet_addr(str)) == htonl(INADDR_NONE)) {
607 if (!(hp = gethostbyname(str))) {
610 *addr = *(unsigned long *)hp->h_addr;
617 rfbListenOnTCPPort(int port,
620 struct sockaddr_in addr;
624 memset(&addr, 0, sizeof(addr));
625 addr.sin_family = AF_INET;
626 addr.sin_port = htons(port);
627 addr.sin_addr.s_addr = iface;
629 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
632 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
633 (char *)&one, sizeof(one)) < 0) {
637 if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
641 if (listen(sock, 5) < 0) {
650 rfbConnectToTcpAddr(char *host,
655 struct sockaddr_in addr;
657 memset(&addr, 0, sizeof(addr));
658 addr.sin_family = AF_INET;
659 addr.sin_port = htons(port);
661 if ((addr.sin_addr.s_addr = inet_addr(host)) == htonl(INADDR_NONE))
663 if (!(hp = gethostbyname(host))) {
667 addr.sin_addr.s_addr = *(unsigned long *)hp->h_addr;
670 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
674 if (connect(sock, (struct sockaddr *)&addr, (sizeof(addr))) < 0) {
683 rfbListenOnUDPPort(int port,
686 struct sockaddr_in addr;
690 memset(&addr, 0, sizeof(addr));
691 addr.sin_family = AF_INET;
692 addr.sin_port = htons(port);
693 addr.sin_addr.s_addr = iface;
695 if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
698 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
699 (char *)&one, sizeof(one)) < 0) {
702 if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {