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