LibVNCServer/LibVNCClient
sockets.c
Go to the documentation of this file.
1 /*
2  * sockets.c - deal with TCP & UDP sockets.
3  *
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. In turn,
8  * rfbClientConnectionGone will be called by rfbProcessEvents (non-threaded case)
9  * or clientInput (threaded case) in main.c. To make an active
10  * connection out, call rfbConnect - note that this does _not_ call
11  * rfbNewClientConnection.
12  *
13  * This file is divided into two types of function. Those beginning with
14  * "rfb" are specific to sockets using the RFB protocol. Those without the
15  * "rfb" prefix are more general socket routines (which are used by the http
16  * code).
17  *
18  * Thanks to Karl Hakimian for pointing out that some platforms return EAGAIN
19  * not EWOULDBLOCK.
20  */
21 
22 /*
23  * Copyright (C) 2011-2012 Christian Beier <dontmind@freeshell.org>
24  * Copyright (C) 2005 Rohit Kumar, Johannes E. Schindelin
25  * OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
26  * Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge.
27  * All Rights Reserved.
28  *
29  * This is free software; you can redistribute it and/or modify
30  * it under the terms of the GNU General Public License as published by
31  * the Free Software Foundation; either version 2 of the License, or
32  * (at your option) any later version.
33  *
34  * This software is distributed in the hope that it will be useful,
35  * but WITHOUT ANY WARRANTY; without even the implied warranty of
36  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37  * GNU General Public License for more details.
38  *
39  * You should have received a copy of the GNU General Public License
40  * along with this software; if not, write to the Free Software
41  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
42  * USA.
43  */
44 
45 #ifdef __STRICT_ANSI__
46 #define _BSD_SOURCE
47 #ifdef __linux__
48 /* Setting this on other systems hides definitions such as INADDR_LOOPBACK.
49  * The check should be for __GLIBC__ in fact. */
50 # define _POSIX_SOURCE
51 #endif
52 #endif
53 
54 #include <rfb/rfb.h>
55 
56 #ifdef LIBVNCSERVER_HAVE_SYS_TYPES_H
57 #include <sys/types.h>
58 #endif
59 
60 #ifdef LIBVNCSERVER_HAVE_SYS_TIME_H
61 #include <sys/time.h>
62 #endif
63 #ifdef LIBVNCSERVER_HAVE_SYS_RESOURCE_H
64 #include <sys/resource.h>
65 #endif
66 #ifdef LIBVNCSERVER_HAVE_UNISTD_H
67 #include <unistd.h>
68 #endif
69 
70 #ifdef LIBVNCSERVER_WITH_WEBSOCKETS
71 #include "rfbssl.h"
72 #endif
73 
74 #ifdef LIBVNCSERVER_WITH_SYSTEMD
75 #include <systemd/sd-daemon.h>
76 #endif
77 
78 #if defined(__linux__) && defined(NEED_TIMEVAL)
79 struct timeval
80 {
81  long int tv_sec,tv_usec;
82 }
83 ;
84 #endif
85 
86 #ifdef LIBVNCSERVER_HAVE_FCNTL_H
87 #include <fcntl.h>
88 #endif
89 
90 #include <errno.h>
91 
92 #ifdef USE_LIBWRAP
93 #include <syslog.h>
94 #include <tcpd.h>
95 int allow_severity=LOG_INFO;
96 int deny_severity=LOG_WARNING;
97 #endif
98 
99 #include "sockets.h"
100 
101 int rfbMaxClientWait = 20000; /* time (ms) after which we decide client has
102  gone away - needed to stop us hanging */
103 
104 static rfbBool
105 rfbNewConnectionFromSock(rfbScreenInfoPtr rfbScreen, rfbSocket sock)
106 {
107  const int one = 1;
108 #ifdef LIBVNCSERVER_IPv6
109  struct sockaddr_storage addr;
110 #else
111  struct sockaddr_in addr;
112 #endif
113  socklen_t addrlen = sizeof(addr);
114 
115  getpeername(sock, (struct sockaddr *)&addr, &addrlen);
116 
117  if(!rfbSetNonBlocking(sock)) {
118  rfbLogPerror("rfbCheckFds: setnonblock");
119  rfbCloseSocket(sock);
120  return FALSE;
121  }
122 
123  if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
124  (const char *)&one, sizeof(one)) < 0) {
125  rfbLogPerror("rfbCheckFds: setsockopt failed: can't set TCP_NODELAY flag, non TCP socket?");
126  }
127 
128 #ifdef USE_LIBWRAP
129  if(!hosts_ctl("vnc",STRING_UNKNOWN,inet_ntoa(addr.sin_addr),
130  STRING_UNKNOWN)) {
131  rfbLog("Rejected connection from client %s\n",
132  inet_ntoa(addr.sin_addr));
133  rfbCloseSocket(sock);
134  return FALSE;
135  }
136 #endif
137 
138 #ifdef LIBVNCSERVER_IPv6
139  char host[1024];
140  if(getnameinfo((struct sockaddr*)&addr, addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST) != 0) {
141  rfbLogPerror("rfbProcessNewConnection: error in getnameinfo");
142  } else {
143  rfbLog("Got connection from client %s\n", host);
144  }
145 #else
146  rfbLog("Got connection from client %s\n", inet_ntoa(addr.sin_addr));
147 #endif
148 
149  rfbNewClient(rfbScreen,sock);
150  return TRUE;
151 }
152 
153 /*
154  * rfbInitSockets sets up the TCP and UDP sockets to listen for RFB
155  * connections. It does nothing if called again.
156  */
157 
158 void
159 rfbInitSockets(rfbScreenInfoPtr rfbScreen)
160 {
161 #ifdef WIN32
162  WSADATA unused;
163 #endif
164 
165  in_addr_t iface = rfbScreen->listenInterface;
166 
167  if (rfbScreen->socketState == RFB_SOCKET_READY) {
168  return;
169  }
170 
171 #ifdef WIN32
172  if((errno = WSAStartup(MAKEWORD(2,0), &unused)) != 0) {
173  rfbLogPerror("Could not init Windows Sockets\n");
174  return;
175  }
176 #endif
177 
178  rfbScreen->socketState = RFB_SOCKET_READY;
179 
180 #ifdef LIBVNCSERVER_WITH_SYSTEMD
181  if (sd_listen_fds(0) == 1)
182  {
183  rfbSocket sock = SD_LISTEN_FDS_START + 0;
184  if (sd_is_socket(sock, AF_UNSPEC, 0, 0))
185  rfbNewConnectionFromSock(rfbScreen, sock);
186  else if (sd_is_socket(sock, AF_UNSPEC, 0, 1))
187  rfbProcessNewConnection(rfbScreen);
188  return;
189  }
190  else
191  rfbLog("Unable to establish connection with systemd socket\n");
192 #endif
193 
194  if (rfbScreen->inetdSock != RFB_INVALID_SOCKET) {
195  const int one = 1;
196 
197  if(!rfbSetNonBlocking(rfbScreen->inetdSock))
198  return;
199 
200  if (setsockopt(rfbScreen->inetdSock, IPPROTO_TCP, TCP_NODELAY,
201  (const char *)&one, sizeof(one)) < 0) {
202  rfbLogPerror("setsockopt failed: can't set TCP_NODELAY flag, non TCP socket?");
203  }
204 
205  FD_ZERO(&(rfbScreen->allFds));
206  FD_SET(rfbScreen->inetdSock, &(rfbScreen->allFds));
207  rfbScreen->maxFd = rfbScreen->inetdSock;
208  return;
209  }
210 
211  FD_ZERO(&(rfbScreen->allFds));
212 
213  if(rfbScreen->autoPort && rfbScreen->port>0) {
214  int i;
215  rfbLog("Autoprobing TCP port \n");
216  for (i = 5900; i < 6000; i++) {
217  if ((rfbScreen->listenSock = rfbListenOnTCPPort(i, iface)) != RFB_INVALID_SOCKET) {
218  rfbScreen->port = i;
219  break;
220  }
221  }
222 
223  if (i >= 6000) {
224  rfbLogPerror("Failure autoprobing");
225  return;
226  }
227 
228  rfbLog("Autoprobing selected TCP port %d\n", rfbScreen->port);
229  FD_SET(rfbScreen->listenSock, &(rfbScreen->allFds));
230  rfbScreen->maxFd = rfbScreen->listenSock;
231  }
232 
233 #ifdef LIBVNCSERVER_IPv6
234  if(rfbScreen->autoPort && rfbScreen->ipv6port>0) {
235  int i;
236  rfbLog("Autoprobing TCP6 port \n");
237  for (i = 5900; i < 6000; i++) {
238  if ((rfbScreen->listen6Sock = rfbListenOnTCP6Port(i, rfbScreen->listen6Interface)) != RFB_INVALID_SOCKET) {
239  rfbScreen->ipv6port = i;
240  break;
241  }
242  }
243 
244  if (i >= 6000) {
245  rfbLogPerror("Failure autoprobing");
246  return;
247  }
248 
249  rfbLog("Autoprobing selected TCP6 port %d\n", rfbScreen->ipv6port);
250  FD_SET(rfbScreen->listen6Sock, &(rfbScreen->allFds));
251  rfbScreen->maxFd = rfbMax((int)rfbScreen->listen6Sock,rfbScreen->maxFd);
252  }
253 #endif
254 
255  if(!rfbScreen->autoPort) {
256  if(rfbScreen->port>0) {
257 
258  if ((rfbScreen->listenSock = rfbListenOnTCPPort(rfbScreen->port, iface)) == RFB_INVALID_SOCKET) {
259  rfbLogPerror("ListenOnTCPPort");
260  return;
261  }
262  rfbLog("Listening for VNC connections on TCP port %d\n", rfbScreen->port);
263 
264  FD_SET(rfbScreen->listenSock, &(rfbScreen->allFds));
265  rfbScreen->maxFd = rfbScreen->listenSock;
266  }
267 
268 #ifdef LIBVNCSERVER_IPv6
269  if (rfbScreen->ipv6port>0) {
270  if ((rfbScreen->listen6Sock = rfbListenOnTCP6Port(rfbScreen->ipv6port, rfbScreen->listen6Interface)) == RFB_INVALID_SOCKET) {
271  /* ListenOnTCP6Port has its own detailed error printout */
272  return;
273  }
274  rfbLog("Listening for VNC connections on TCP6 port %d\n", rfbScreen->ipv6port);
275 
276  FD_SET(rfbScreen->listen6Sock, &(rfbScreen->allFds));
277  rfbScreen->maxFd = rfbMax((int)rfbScreen->listen6Sock,rfbScreen->maxFd);
278  }
279 #endif
280 
281  }
282 
283  if (rfbScreen->udpPort != 0) {
284  rfbLog("rfbInitSockets: listening for input on UDP port %d\n",rfbScreen->udpPort);
285 
286  if ((rfbScreen->udpSock = rfbListenOnUDPPort(rfbScreen->udpPort, iface)) == RFB_INVALID_SOCKET) {
287  rfbLogPerror("ListenOnUDPPort");
288  return;
289  }
290  rfbLog("Listening for VNC connections on TCP port %d\n", rfbScreen->port);
291 
292  FD_SET(rfbScreen->udpSock, &(rfbScreen->allFds));
293  rfbScreen->maxFd = rfbMax((int)rfbScreen->udpSock,rfbScreen->maxFd);
294  }
295 }
296 
297 void rfbShutdownSockets(rfbScreenInfoPtr rfbScreen)
298 {
299  if (rfbScreen->socketState!=RFB_SOCKET_READY)
300  return;
301 
302  rfbScreen->socketState = RFB_SOCKET_SHUTDOWN;
303 
304  if(rfbScreen->inetdSock!=RFB_INVALID_SOCKET) {
305  rfbCloseSocket(rfbScreen->inetdSock);
306  FD_CLR(rfbScreen->inetdSock,&rfbScreen->allFds);
307  rfbScreen->inetdSock=RFB_INVALID_SOCKET;
308  }
309 
310  if(rfbScreen->listenSock!=RFB_INVALID_SOCKET) {
311  rfbCloseSocket(rfbScreen->listenSock);
312  FD_CLR(rfbScreen->listenSock,&rfbScreen->allFds);
313  rfbScreen->listenSock=RFB_INVALID_SOCKET;
314  }
315 
316  if(rfbScreen->listen6Sock!=RFB_INVALID_SOCKET) {
317  rfbCloseSocket(rfbScreen->listen6Sock);
318  FD_CLR(rfbScreen->listen6Sock,&rfbScreen->allFds);
319  rfbScreen->listen6Sock=RFB_INVALID_SOCKET;
320  }
321 
322  if(rfbScreen->udpSock!=RFB_INVALID_SOCKET) {
323  rfbCloseSocket(rfbScreen->udpSock);
324  FD_CLR(rfbScreen->udpSock,&rfbScreen->allFds);
325  rfbScreen->udpSock=RFB_INVALID_SOCKET;
326  }
327 
328 #ifdef WIN32
329  if(WSACleanup() != 0) {
330  errno=WSAGetLastError();
331  rfbLogPerror("Could not terminate Windows Sockets\n");
332  }
333 #endif
334 }
335 
336 /*
337  * rfbCheckFds is called from ProcessInputEvents to check for input on the RFB
338  * socket(s). If there is input to process, the appropriate function in the
339  * RFB server code will be called (rfbNewClientConnection,
340  * rfbProcessClientMessage, etc).
341  */
342 
343 int
344 rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec)
345 {
346  int nfds;
347  fd_set fds;
348  struct timeval tv;
349  struct sockaddr_in addr;
350  socklen_t addrlen = sizeof(addr);
351  char buf[6];
352  rfbClientIteratorPtr i;
353  rfbClientPtr cl;
354  int result = 0;
355 
356  if (!rfbScreen->inetdInitDone && rfbScreen->inetdSock != RFB_INVALID_SOCKET) {
357  rfbNewClientConnection(rfbScreen,rfbScreen->inetdSock);
358  rfbScreen->inetdInitDone = TRUE;
359  }
360 
361  do {
362  memcpy((char *)&fds, (char *)&(rfbScreen->allFds), sizeof(fd_set));
363  tv.tv_sec = 0;
364  tv.tv_usec = usec;
365  nfds = select(rfbScreen->maxFd + 1, &fds, NULL, NULL /* &fds */, &tv);
366  if (nfds == 0) {
367  /* timed out, check for async events */
368  i = rfbGetClientIterator(rfbScreen);
369  while((cl = rfbClientIteratorNext(i))) {
370  if (cl->onHold)
371  continue;
372  if (FD_ISSET(cl->sock, &(rfbScreen->allFds)))
374  }
376  return result;
377  }
378 
379  if (nfds < 0) {
380 #ifdef WIN32
381  errno = WSAGetLastError();
382 #endif
383  if (errno != EINTR)
384  rfbLogPerror("rfbCheckFds: select");
385  return -1;
386  }
387 
388  result += nfds;
389 
390  if (rfbScreen->listenSock != RFB_INVALID_SOCKET && FD_ISSET(rfbScreen->listenSock, &fds)) {
391 
392  if (!rfbProcessNewConnection(rfbScreen))
393  return -1;
394 
395  FD_CLR(rfbScreen->listenSock, &fds);
396  if (--nfds == 0)
397  return result;
398  }
399 
400  if (rfbScreen->listen6Sock != RFB_INVALID_SOCKET && FD_ISSET(rfbScreen->listen6Sock, &fds)) {
401 
402  if (!rfbProcessNewConnection(rfbScreen))
403  return -1;
404 
405  FD_CLR(rfbScreen->listen6Sock, &fds);
406  if (--nfds == 0)
407  return result;
408  }
409 
410  if ((rfbScreen->udpSock != RFB_INVALID_SOCKET) && FD_ISSET(rfbScreen->udpSock, &fds)) {
411  if(!rfbScreen->udpClient)
412  rfbNewUDPClient(rfbScreen);
413  if (recvfrom(rfbScreen->udpSock, buf, 1, MSG_PEEK,
414  (struct sockaddr *)&addr, &addrlen) < 0) {
415  rfbLogPerror("rfbCheckFds: UDP: recvfrom");
416  rfbDisconnectUDPSock(rfbScreen);
417  rfbScreen->udpSockConnected = FALSE;
418  } else {
419  if (!rfbScreen->udpSockConnected ||
420  (memcmp(&addr, &rfbScreen->udpRemoteAddr, addrlen) != 0))
421  {
422  /* new remote end */
423  rfbLog("rfbCheckFds: UDP: got connection\n");
424 
425  memcpy(&rfbScreen->udpRemoteAddr, &addr, addrlen);
426  rfbScreen->udpSockConnected = TRUE;
427 
428  if (connect(rfbScreen->udpSock,
429  (struct sockaddr *)&addr, addrlen) < 0) {
430  rfbLogPerror("rfbCheckFds: UDP: connect");
431  rfbDisconnectUDPSock(rfbScreen);
432  return -1;
433  }
434 
435  rfbNewUDPConnection(rfbScreen,rfbScreen->udpSock);
436  }
437 
438  rfbProcessUDPInput(rfbScreen);
439  }
440 
441  FD_CLR(rfbScreen->udpSock, &fds);
442  if (--nfds == 0)
443  return result;
444  }
445 
446  i = rfbGetClientIterator(rfbScreen);
447  while((cl = rfbClientIteratorNext(i))) {
448 
449  if (cl->onHold)
450  continue;
451 
452  if (FD_ISSET(cl->sock, &(rfbScreen->allFds)))
453  {
454  if (FD_ISSET(cl->sock, &fds))
455  {
456 #ifdef LIBVNCSERVER_WITH_WEBSOCKETS
457  do {
459  } while (cl->sock != RFB_INVALID_SOCKET && webSocketsHasDataInBuffer(cl));
460 #else
462 #endif
463  }
464  else
466  }
467  }
469  } while(rfbScreen->handleEventsEagerly);
470  return result;
471 }
472 
473 rfbBool
474 rfbProcessNewConnection(rfbScreenInfoPtr rfbScreen)
475 {
477  fd_set listen_fds;
478  rfbSocket chosen_listen_sock = RFB_INVALID_SOCKET;
479 #if defined LIBVNCSERVER_HAVE_SYS_RESOURCE_H && defined LIBVNCSERVER_HAVE_FCNTL_H
480  struct rlimit rlim;
481  size_t maxfds, curfds, i;
482 #endif
483  /* Do another select() call to find out which listen socket
484  has an incoming connection pending. We know that at least
485  one of them has, so this should not block for too long! */
486  FD_ZERO(&listen_fds);
487  if(rfbScreen->listenSock != RFB_INVALID_SOCKET)
488  FD_SET(rfbScreen->listenSock, &listen_fds);
489  if(rfbScreen->listen6Sock != RFB_INVALID_SOCKET)
490  FD_SET(rfbScreen->listen6Sock, &listen_fds);
491  if (select(rfbScreen->maxFd+1, &listen_fds, NULL, NULL, NULL) == -1) {
492  rfbLogPerror("rfbProcessNewConnection: error in select");
493  return FALSE;
494  }
495  if (rfbScreen->listenSock != RFB_INVALID_SOCKET && FD_ISSET(rfbScreen->listenSock, &listen_fds))
496  chosen_listen_sock = rfbScreen->listenSock;
497  if (rfbScreen->listen6Sock != RFB_INVALID_SOCKET && FD_ISSET(rfbScreen->listen6Sock, &listen_fds))
498  chosen_listen_sock = rfbScreen->listen6Sock;
499 
500 
501  /*
502  Avoid accept() giving EMFILE, i.e. running out of file descriptors, a situation that's hard to recover from.
503  https://stackoverflow.com/questions/47179793/how-to-gracefully-handle-accept-giving-emfile-and-close-the-connection
504  describes the problem nicely.
505  Our approach is to deny new clients when we have reached a certain fraction of the per-process limit of file descriptors.
506  TODO: add Windows support.
507  */
508 #if defined LIBVNCSERVER_HAVE_SYS_RESOURCE_H && defined LIBVNCSERVER_HAVE_FCNTL_H
509  if(getrlimit(RLIMIT_NOFILE, &rlim) < 0)
510  maxfds = 100; /* use a sane default if getting the limit fails */
511  else
512  maxfds = rlim.rlim_cur;
513 
514  /* get the number of currently open fds as per https://stackoverflow.com/a/7976880/361413 */
515  curfds = 0;
516  for(i = 0; i < maxfds; ++i)
517  if(fcntl(i, F_GETFD) != -1)
518  ++curfds;
519 
520  if(curfds > maxfds * rfbScreen->fdQuota) {
521  rfbErr("rfbProcessNewconnection: open fd count of %lu exceeds quota %.1f of limit %lu, denying connection\n", curfds, rfbScreen->fdQuota, maxfds);
522  sock = accept(chosen_listen_sock, NULL, NULL);
523  rfbCloseSocket(sock);
524  return FALSE;
525  }
526 #endif
527 
528  if ((sock = accept(chosen_listen_sock, NULL, NULL)) == RFB_INVALID_SOCKET) {
529  rfbLogPerror("rfbProcessNewconnection: accept");
530  return FALSE;
531  }
532 
533  return rfbNewConnectionFromSock(rfbScreen, sock);
534 }
535 
536 
537 void
538 rfbDisconnectUDPSock(rfbScreenInfoPtr rfbScreen)
539 {
540  rfbScreen->udpSockConnected = FALSE;
541 }
542 
543 
544 
545 void
546 rfbCloseClient(rfbClientPtr cl)
547 {
548  rfbExtensionData* extension;
549 
550  for(extension=cl->extensions; extension; extension=extension->next)
551  if(extension->extension->close)
552  extension->extension->close(cl, extension->data);
553 
554  LOCK(cl->updateMutex);
555 #if defined(LIBVNCSERVER_HAVE_LIBPTHREAD) || defined(LIBVNCSERVER_HAVE_WIN32THREADS)
556  if (cl->sock != RFB_INVALID_SOCKET)
557 #endif
558  {
559  FD_CLR(cl->sock,&(cl->screen->allFds));
560  if(cl->sock==cl->screen->maxFd)
561  while(cl->screen->maxFd>0
562  && !FD_ISSET(cl->screen->maxFd,&(cl->screen->allFds)))
563  cl->screen->maxFd--;
564 #ifdef LIBVNCSERVER_WITH_WEBSOCKETS
565  if (cl->sslctx)
566  rfbssl_destroy(cl);
567  free(cl->wspath);
568 #endif
569 #ifndef __MINGW32__
570  shutdown(cl->sock,SHUT_RDWR);
571 #endif
572  rfbCloseSocket(cl->sock);
573  cl->sock = RFB_INVALID_SOCKET;
574  }
575  TSIGNAL(cl->updateCond);
576  UNLOCK(cl->updateMutex);
577 }
578 
579 
580 /*
581  * rfbConnect is called to make a connection out to a given TCP address.
582  */
583 
584 rfbSocket
585 rfbConnect(rfbScreenInfoPtr rfbScreen,
586  char *host,
587  int port)
588 {
589  rfbSocket sock;
590  int one = 1;
591 
592  rfbLog("Making connection to client on host %s port %d\n",
593  host,port);
594 
595  if ((sock = rfbConnectToTcpAddr(host, port)) == RFB_INVALID_SOCKET) {
596  rfbLogPerror("connection failed");
597  return RFB_INVALID_SOCKET;
598  }
599 
600  if(!rfbSetNonBlocking(sock)) {
601  rfbCloseSocket(sock);
602  return RFB_INVALID_SOCKET;
603  }
604 
605  if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
606  (const char *)&one, sizeof(one)) < 0) {
607  rfbLogPerror("setsockopt failed: can't set TCP_NODELAY flag, non TCP socket?");
608  }
609 
610  /* AddEnabledDevice(sock); */
611  FD_SET(sock, &rfbScreen->allFds);
612  rfbScreen->maxFd = rfbMax(sock,rfbScreen->maxFd);
613 
614  return sock;
615 }
616 
617 /*
618  * ReadExact reads an exact number of bytes from a client. Returns 1 if
619  * those bytes have been read, 0 if the other end has closed, or -1 if an error
620  * occurred (errno is set to ETIMEDOUT if it timed out).
621  */
622 
623 int
624 rfbReadExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout)
625 {
626  rfbSocket sock = cl->sock;
627  int n;
628  fd_set fds;
629  struct timeval tv;
630 
631  while (len > 0) {
632 #ifdef LIBVNCSERVER_WITH_WEBSOCKETS
633  if (cl->wsctx) {
634  n = webSocketsDecode(cl, buf, len);
635  } else if (cl->sslctx) {
636  n = rfbssl_read(cl, buf, len);
637  } else {
638  n = read(sock, buf, len);
639  }
640 #else
641  n = read(sock, buf, len);
642 #endif
643 
644  if (n > 0) {
645 
646  buf += n;
647  len -= n;
648 
649  } else if (n == 0) {
650 
651  return 0;
652 
653  } else {
654 #ifdef WIN32
655  errno = WSAGetLastError();
656 #endif
657  if (errno == EINTR)
658  continue;
659 
660 #ifdef LIBVNCSERVER_ENOENT_WORKAROUND
661  if (errno != ENOENT)
662 #endif
663  if (errno != EWOULDBLOCK && errno != EAGAIN) {
664  return n;
665  }
666 
667 #ifdef LIBVNCSERVER_WITH_WEBSOCKETS
668  if (cl->sslctx) {
669  if (rfbssl_pending(cl))
670  continue;
671  }
672 #endif
673  FD_ZERO(&fds);
674  FD_SET(sock, &fds);
675  tv.tv_sec = timeout / 1000;
676  tv.tv_usec = (timeout % 1000) * 1000;
677  n = select(sock+1, &fds, NULL, &fds, &tv);
678  if (n < 0) {
679  rfbLogPerror("ReadExact: select");
680  return n;
681  }
682  if (n == 0) {
683  rfbErr("ReadExact: select timeout\n");
684  errno = ETIMEDOUT;
685  return -1;
686  }
687  }
688  }
689 #undef DEBUG_READ_EXACT
690 #ifdef DEBUG_READ_EXACT
691  rfbLog("ReadExact %d bytes\n",len);
692  for(n=0;n<len;n++)
693  fprintf(stderr,"%02x ",(unsigned char)buf[n]);
694  fprintf(stderr,"\n");
695 #endif
696 
697  return 1;
698 }
699 
700 int rfbReadExact(rfbClientPtr cl,char* buf,int len)
701 {
702  /* favor the per-screen value if set */
703  if(cl->screen && cl->screen->maxClientWait)
704  return(rfbReadExactTimeout(cl,buf,len,cl->screen->maxClientWait));
705  else
706  return(rfbReadExactTimeout(cl,buf,len,rfbMaxClientWait));
707 }
708 
709 /*
710  * PeekExact peeks at an exact number of bytes from a client. Returns 1 if
711  * those bytes have been read, 0 if the other end has closed, or -1 if an
712  * error occurred (errno is set to ETIMEDOUT if it timed out).
713  */
714 
715 int
716 rfbPeekExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout)
717 {
718  rfbSocket sock = cl->sock;
719  int n;
720  fd_set fds;
721  struct timeval tv;
722 
723  while (len > 0) {
724 #ifdef LIBVNCSERVER_WITH_WEBSOCKETS
725  if (cl->sslctx)
726  n = rfbssl_peek(cl, buf, len);
727  else
728 #endif
729  n = recv(sock, buf, len, MSG_PEEK);
730 
731  if (n == len) {
732 
733  break;
734 
735  } else if (n == 0) {
736 
737  return 0;
738 
739  } else {
740 #ifdef WIN32
741  errno = WSAGetLastError();
742 #endif
743  if (errno == EINTR)
744  continue;
745 
746 #ifdef LIBVNCSERVER_ENOENT_WORKAROUND
747  if (errno != ENOENT)
748 #endif
749  if (errno != EWOULDBLOCK && errno != EAGAIN) {
750  return n;
751  }
752 
753 #ifdef LIBVNCSERVER_WITH_WEBSOCKETS
754  if (cl->sslctx) {
755  if (rfbssl_pending(cl))
756  continue;
757  }
758 #endif
759  FD_ZERO(&fds);
760  FD_SET(sock, &fds);
761  tv.tv_sec = timeout / 1000;
762  tv.tv_usec = (timeout % 1000) * 1000;
763  n = select(sock+1, &fds, NULL, &fds, &tv);
764  if (n < 0) {
765  rfbLogPerror("PeekExact: select");
766  return n;
767  }
768  if (n == 0) {
769  errno = ETIMEDOUT;
770  return -1;
771  }
772  }
773  }
774 #undef DEBUG_READ_EXACT
775 #ifdef DEBUG_READ_EXACT
776  rfbLog("PeekExact %d bytes\n",len);
777  for(n=0;n<len;n++)
778  fprintf(stderr,"%02x ",(unsigned char)buf[n]);
779  fprintf(stderr,"\n");
780 #endif
781 
782  return 1;
783 }
784 
785 /*
786  * WriteExact writes an exact number of bytes to a client. Returns 1 if
787  * those bytes have been written, or -1 if an error occurred (errno is set to
788  * ETIMEDOUT if it timed out).
789  */
790 
791 int
792 rfbWriteExact(rfbClientPtr cl,
793  const char *buf,
794  int len)
795 {
796  rfbSocket sock = cl->sock;
797  int n;
798  fd_set fds;
799  struct timeval tv;
800  int totalTimeWaited = 0;
801  const int timeout = (cl->screen && cl->screen->maxClientWait) ? cl->screen->maxClientWait : rfbMaxClientWait;
802 
803 #undef DEBUG_WRITE_EXACT
804 #ifdef DEBUG_WRITE_EXACT
805  rfbLog("WriteExact %d bytes\n",len);
806  for(n=0;n<len;n++)
807  fprintf(stderr,"%02x ",(unsigned char)buf[n]);
808  fprintf(stderr,"\n");
809 #endif
810 
811 #ifdef LIBVNCSERVER_WITH_WEBSOCKETS
812  if (cl->wsctx) {
813  char *tmp = NULL;
814  if ((len = webSocketsEncode(cl, buf, len, &tmp)) < 0) {
815  rfbErr("WriteExact: WebSockets encode error\n");
816  return -1;
817  }
818  buf = tmp;
819  }
820 #endif
821 
822  LOCK(cl->outputMutex);
823  while (len > 0) {
824 #ifdef LIBVNCSERVER_WITH_WEBSOCKETS
825  if (cl->sslctx)
826  n = rfbssl_write(cl, buf, len);
827  else
828 #endif
829  n = write(sock, buf, len);
830 
831  if (n > 0) {
832 
833  buf += n;
834  len -= n;
835 
836  } else if (n == 0) {
837 
838  rfbErr("WriteExact: write returned 0?\n");
839  UNLOCK(cl->outputMutex);
840  return 0;
841 
842  } else {
843 #ifdef WIN32
844  errno = WSAGetLastError();
845 #endif
846  if (errno == EINTR)
847  continue;
848 
849  if (errno != EWOULDBLOCK && errno != EAGAIN) {
850  UNLOCK(cl->outputMutex);
851  return n;
852  }
853 
854  /* Retry every 5 seconds until we exceed timeout. We
855  need to do this because select doesn't necessarily return
856  immediately when the other end has gone away */
857 
858  FD_ZERO(&fds);
859  FD_SET(sock, &fds);
860  tv.tv_sec = 5;
861  tv.tv_usec = 0;
862  n = select(sock+1, NULL, &fds, NULL /* &fds */, &tv);
863  if (n < 0) {
864 #ifdef WIN32
865  errno=WSAGetLastError();
866 #endif
867  if(errno==EINTR)
868  continue;
869  rfbLogPerror("WriteExact: select");
870  UNLOCK(cl->outputMutex);
871  return n;
872  }
873  if (n == 0) {
874  totalTimeWaited += 5000;
875  if (totalTimeWaited >= timeout) {
876  errno = ETIMEDOUT;
877  UNLOCK(cl->outputMutex);
878  return -1;
879  }
880  } else {
881  totalTimeWaited = 0;
882  }
883  }
884  }
885  UNLOCK(cl->outputMutex);
886  return 1;
887 }
888 
889 /* currently private, called by rfbProcessArguments() */
890 int
891 rfbStringToAddr(char *str, in_addr_t *addr) {
892  if (str == NULL || *str == '\0' || strcmp(str, "any") == 0) {
893  *addr = htonl(INADDR_ANY);
894  } else if (strcmp(str, "localhost") == 0) {
895  *addr = htonl(INADDR_LOOPBACK);
896  } else {
897  struct hostent *hp;
898  if ((*addr = inet_addr(str)) == htonl(INADDR_NONE)) {
899  if (!(hp = gethostbyname(str))) {
900  return 0;
901  }
902  *addr = *(unsigned long *)hp->h_addr;
903  }
904  }
905  return 1;
906 }
907 
908 rfbSocket
910  in_addr_t iface)
911 {
912  struct sockaddr_in addr;
913  rfbSocket sock;
914  int one = 1;
915 
916  memset(&addr, 0, sizeof(addr));
917  addr.sin_family = AF_INET;
918  addr.sin_port = htons(port);
919  addr.sin_addr.s_addr = iface;
920 
921  if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == RFB_INVALID_SOCKET) {
922  return RFB_INVALID_SOCKET;
923  }
924  if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
925  (const char *)&one, sizeof(one)) < 0) {
926  rfbCloseSocket(sock);
927  return RFB_INVALID_SOCKET;
928  }
929  if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
930  rfbCloseSocket(sock);
931  return RFB_INVALID_SOCKET;
932  }
933  if (listen(sock, 32) < 0) {
934  rfbCloseSocket(sock);
935  return RFB_INVALID_SOCKET;
936  }
937 
938  return sock;
939 }
940 
941 
942 rfbSocket
944  const char* iface)
945 {
946 #ifndef LIBVNCSERVER_IPv6
947  rfbLogPerror("This LibVNCServer does not have IPv6 support");
948  return RFB_INVALID_SOCKET;
949 #else
950  rfbSocket sock;
951  int one = 1;
952  int rv;
953  struct addrinfo hints, *servinfo, *p;
954  char port_str[8];
955 
956  snprintf(port_str, 8, "%d", port);
957 
958  memset(&hints, 0, sizeof(hints));
959  hints.ai_family = AF_INET6;
960  hints.ai_socktype = SOCK_STREAM;
961  hints.ai_flags = AI_PASSIVE; /* fill in wildcard address if iface == NULL */
962 
963  if ((rv = getaddrinfo(iface, port_str, &hints, &servinfo)) != 0) {
964  rfbErr("rfbListenOnTCP6Port error in getaddrinfo: %s\n", gai_strerror(rv));
965  return RFB_INVALID_SOCKET;
966  }
967 
968  /* loop through all the results and bind to the first we can */
969  for(p = servinfo; p != NULL; p = p->ai_next) {
970  if ((sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) < 0) {
971  continue;
972  }
973 
974 #ifdef IPV6_V6ONLY
975  /* we have separate IPv4 and IPv6 sockets since some OS's do not support dual binding */
976  if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char *)&one, sizeof(one)) < 0) {
977  rfbLogPerror("rfbListenOnTCP6Port error in setsockopt IPV6_V6ONLY");
978  rfbCloseSocket(sock);
979  freeaddrinfo(servinfo);
980  return RFB_INVALID_SOCKET;
981  }
982 #endif
983 
984  if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&one, sizeof(one)) < 0) {
985  rfbLogPerror("rfbListenOnTCP6Port: error in setsockopt SO_REUSEADDR");
986  rfbCloseSocket(sock);
987  freeaddrinfo(servinfo);
988  return RFB_INVALID_SOCKET;
989  }
990 
991  if (bind(sock, p->ai_addr, p->ai_addrlen) < 0) {
992  rfbCloseSocket(sock);
993  continue;
994  }
995 
996  break;
997  }
998 
999  if (p == NULL) {
1000  rfbLogPerror("rfbListenOnTCP6Port: error in bind IPv6 socket");
1001  freeaddrinfo(servinfo);
1002  return RFB_INVALID_SOCKET;
1003  }
1004 
1005  /* all done with this structure now */
1006  freeaddrinfo(servinfo);
1007 
1008  if (listen(sock, 32) < 0) {
1009  rfbLogPerror("rfbListenOnTCP6Port: error in listen on IPv6 socket");
1010  rfbCloseSocket(sock);
1011  return RFB_INVALID_SOCKET;
1012  }
1013 
1014  return sock;
1015 #endif
1016 }
1017 
1018 
1019 rfbSocket
1021  int port)
1022 {
1023  rfbSocket sock;
1024 #ifdef LIBVNCSERVER_IPv6
1025  struct addrinfo hints, *servinfo, *p;
1026  int rv;
1027  char port_str[8];
1028 
1029  snprintf(port_str, 8, "%d", port);
1030 
1031  memset(&hints, 0, sizeof hints);
1032  hints.ai_family = AF_UNSPEC;
1033  hints.ai_socktype = SOCK_STREAM;
1034 
1035  if ((rv = getaddrinfo(host, port_str, &hints, &servinfo)) != 0) {
1036  rfbErr("rfbConnectToTcpAddr: error in getaddrinfo: %s\n", gai_strerror(rv));
1037  return RFB_INVALID_SOCKET;
1038  }
1039 
1040  /* loop through all the results and connect to the first we can */
1041  for(p = servinfo; p != NULL; p = p->ai_next) {
1042  if ((sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == RFB_INVALID_SOCKET)
1043  continue;
1044 
1045  if (connect(sock, p->ai_addr, p->ai_addrlen) < 0) {
1046  rfbCloseSocket(sock);
1047  continue;
1048  }
1049 
1050  break;
1051  }
1052 
1053  /* all failed */
1054  if (p == NULL) {
1055  rfbLogPerror("rfbConnectToTcoAddr: failed to connect\n");
1056  sock = RFB_INVALID_SOCKET; /* set return value */
1057  }
1058 
1059  /* all done with this structure now */
1060  freeaddrinfo(servinfo);
1061 #else
1062  struct hostent *hp;
1063  struct sockaddr_in addr;
1064 
1065  memset(&addr, 0, sizeof(addr));
1066  addr.sin_family = AF_INET;
1067  addr.sin_port = htons(port);
1068 
1069  if ((addr.sin_addr.s_addr = inet_addr(host)) == htonl(INADDR_NONE))
1070  {
1071  if (!(hp = gethostbyname(host))) {
1072  errno = EINVAL;
1073  return RFB_INVALID_SOCKET;
1074  }
1075  addr.sin_addr.s_addr = *(unsigned long *)hp->h_addr;
1076  }
1077 
1078  if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == RFB_INVALID_SOCKET) {
1079  return RFB_INVALID_SOCKET;
1080  }
1081 
1082  if (connect(sock, (struct sockaddr *)&addr, (sizeof(addr))) < 0) {
1083  rfbCloseSocket(sock);
1084  return RFB_INVALID_SOCKET;
1085  }
1086 #endif
1087  return sock;
1088 }
1089 
1090 rfbSocket
1092  in_addr_t iface)
1093 {
1094  struct sockaddr_in addr;
1095  rfbSocket sock;
1096  int one = 1;
1097 
1098  memset(&addr, 0, sizeof(addr));
1099  addr.sin_family = AF_INET;
1100  addr.sin_port = htons(port);
1101  addr.sin_addr.s_addr = iface;
1102 
1103  if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == RFB_INVALID_SOCKET) {
1104  return RFB_INVALID_SOCKET;
1105  }
1106  if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
1107  (const char *)&one, sizeof(one)) < 0) {
1108  return RFB_INVALID_SOCKET;
1109  }
1110  if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
1111  return RFB_INVALID_SOCKET;
1112  }
1113 
1114  return sock;
1115 }
1116 
1117 /*
1118  * rfbSetNonBlocking sets a socket into non-blocking mode.
1119  */
1120 rfbBool
1122 {
1123 #ifdef WIN32
1124  unsigned long block=1;
1125  if(ioctlsocket(sock, FIONBIO, &block) == SOCKET_ERROR) {
1126  errno=WSAGetLastError();
1127 #else
1128  int flags = fcntl(sock, F_GETFL);
1129  if(flags < 0 || fcntl(sock, F_SETFL, flags | O_NONBLOCK) < 0) {
1130 #endif
1131  rfbLogPerror("Setting socket to non-blocking failed");
1132  return FALSE;
1133  }
1134  return TRUE;
1135 }
int rfbReadExactTimeout(rfbClientPtr cl, char *buf, int len, int timeout)
Definition: sockets.c:624
rfbClientPtr rfbNewUDPClient(rfbScreenInfoPtr rfbScreen)
Definition: rfbserver.c:527
rfbSocket rfbListenOnUDPPort(int port, in_addr_t iface)
Definition: sockets.c:1091
int rfbCheckFds(rfbScreenInfoPtr rfbScreen, long usec)
Definition: sockets.c:344
rfbClientIteratorPtr rfbGetClientIterator(rfbScreenInfoPtr rfbScreen)
Definition: rfbserver.c:167
void rfbNewUDPConnection(rfbScreenInfoPtr rfbScreen, rfbSocket sock)
Definition: rfbserver.c:3765
rfbLogProc rfbErr
Definition: main.c:264
int rfbssl_read(rfbClientPtr cl, char *buf, int bufsize)
void rfbNewClientConnection(rfbScreenInfoPtr rfbScreen, rfbSocket sock)
Definition: rfbserver.c:247
int rfbPeekExactTimeout(rfbClientPtr cl, char *buf, int len, int timeout)
Definition: sockets.c:716
#define TRUE
Definition: rfbproto.h:112
#define UNLOCK(mutex)
Definition: threading.h:83
int8_t rfbBool
Definition: rfbproto.h:108
#define RFB_INVALID_SOCKET
Definition: rfbproto.h:106
void rfbDisconnectUDPSock(rfbScreenInfoPtr rfbScreen)
Definition: sockets.c:538
int webSocketsEncode(rfbClientPtr cl, const char *src, int len, char **dst)
Definition: websockets.c:423
#define rfbSocket
Definition: rfbproto.h:104
int rfbWriteExact(rfbClientPtr cl, const char *buf, int len)
Definition: sockets.c:792
void rfbShutdownSockets(rfbScreenInfoPtr rfbScreen)
Definition: sockets.c:297
#define TSIGNAL(cond)
Definition: threading.h:87
void(* close)(struct _rfbClientRec *client, void *data)
Definition: rfb.h:179
int rfbStringToAddr(char *str, in_addr_t *addr)
Definition: sockets.c:891
int rfbReadExact(rfbClientPtr cl, char *buf, int len)
Definition: sockets.c:700
rfbBool rfbSetNonBlocking(rfbSocket sock)
Definition: sockets.c:1121
rfbClientPtr rfbClientIteratorNext(rfbClientIteratorPtr iterator)
Definition: rfbserver.c:208
int rfbssl_peek(rfbClientPtr cl, char *buf, int bufsize)
rfbProtocolExtension * extension
Definition: rfb.h:187
void rfbProcessUDPInput(rfbScreenInfoPtr rfbScreen)
Definition: rfbserver.c:3781
#define rfbMax(a, b)
Definition: rfbproto.h:92
int webSocketsDecode(rfbClientPtr cl, char *dst, int len)
Definition: websockets.c:429
void rfbLogPerror(const char *str)
Definition: main.c:266
rfbSocket rfbConnectToTcpAddr(char *host, int port)
Definition: sockets.c:1020
#define LOCK(mutex)
Definition: threading.h:82
rfbBool rfbProcessNewConnection(rfbScreenInfoPtr rfbScreen)
Definition: sockets.c:474
rfbLogProc rfbLog
Definition: main.c:263
void rfbssl_destroy(rfbClientPtr cl)
rfbSocket rfbListenOnTCPPort(int port, in_addr_t iface)
Definition: sockets.c:909
void rfbReleaseClientIterator(rfbClientIteratorPtr iterator)
Definition: rfbserver.c:234
struct _rfbExtensionData * next
Definition: rfb.h:189
void rfbProcessClientMessage(rfbClientPtr cl)
Definition: rfbserver.c:645
#define FALSE
Definition: rfbproto.h:110
int rfbMaxClientWait
Definition: sockets.c:101
rfbBool rfbSendFileTransferChunk(rfbClientPtr cl)
Definition: rfbserver.c:1516
rfbBool webSocketsHasDataInBuffer(rfbClientPtr cl)
Definition: websockets.c:451
int rfbssl_write(rfbClientPtr cl, const char *buf, int bufsize)
rfbSocket rfbListenOnTCP6Port(int port, const char *iface)
Definition: sockets.c:943
#define INADDR_NONE
Definition: rfbproto.h:123
void rfbInitSockets(rfbScreenInfoPtr rfbScreen)
Definition: sockets.c:159
rfbClientPtr rfbNewClient(rfbScreenInfoPtr rfbScreen, rfbSocket sock)
Definition: rfbserver.c:520
rfbSocket rfbConnect(rfbScreenInfoPtr rfbScreen, char *host, int port)
Definition: sockets.c:585
#define rfbCloseSocket
Definition: rfbproto.h:107
void rfbCloseClient(rfbClientPtr cl)
Definition: sockets.c:546
void * data
Definition: rfb.h:188
int rfbssl_pending(rfbClientPtr cl)