Set opcode correctly for binary frames.
[libvncserver.git] / libvncclient / sockets.c
blobc97a90f85164a5ca0d06829da9834b3a0269b1b8
1 /*
2 * Copyright (C) 2011-2012 Christian Beier <dontmind@freeshell.org>
3 * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
5 * This is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This software is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
18 * USA.
22 * sockets.c - functions to deal with sockets.
25 #ifdef __STRICT_ANSI__
26 #define _BSD_SOURCE
27 #ifdef __linux__
28 /* Setting this on other systems hides definitions such as INADDR_LOOPBACK.
29 * The check should be for __GLIBC__ in fact. */
30 # define _POSIX_SOURCE
31 #endif
32 #endif
33 #include <unistd.h>
34 #include <errno.h>
35 #include <fcntl.h>
36 #include <assert.h>
37 #include <rfb/rfbclient.h>
38 #ifdef WIN32
39 #undef SOCKET
40 #include <winsock2.h>
41 #define EWOULDBLOCK WSAEWOULDBLOCK
42 #define close closesocket
43 #define read(sock,buf,len) recv(sock,buf,len,0)
44 #define write(sock,buf,len) send(sock,buf,len,0)
45 #define socklen_t int
46 #ifdef LIBVNCSERVER_HAVE_WS2TCPIP_H
47 #undef socklen_t
48 #include <ws2tcpip.h>
49 #endif
50 #else
51 #include <sys/socket.h>
52 #include <netinet/in.h>
53 #include <sys/un.h>
54 #include <netinet/tcp.h>
55 #include <arpa/inet.h>
56 #include <netdb.h>
57 #endif
58 #include "tls.h"
60 void PrintInHex(char *buf, int len);
62 rfbBool errorMessageOnReadFailure = TRUE;
65 * ReadFromRFBServer is called whenever we want to read some data from the RFB
66 * server. It is non-trivial for two reasons:
68 * 1. For efficiency it performs some intelligent buffering, avoiding invoking
69 * the read() system call too often. For small chunks of data, it simply
70 * copies the data out of an internal buffer. For large amounts of data it
71 * reads directly into the buffer provided by the caller.
73 * 2. Whenever read() would block, it invokes the Xt event dispatching
74 * mechanism to process X events. In fact, this is the only place these
75 * events are processed, as there is no XtAppMainLoop in the program.
78 rfbBool
79 ReadFromRFBServer(rfbClient* client, char *out, unsigned int n)
81 #undef DEBUG_READ_EXACT
82 #ifdef DEBUG_READ_EXACT
83 char* oout=out;
84 int nn=n;
85 rfbClientLog("ReadFromRFBServer %d bytes\n",n);
86 #endif
87 if (client->serverPort==-1) {
88 /* vncrec playing */
89 rfbVNCRec* rec = client->vncRec;
90 struct timeval tv;
92 if (rec->readTimestamp) {
93 rec->readTimestamp = FALSE;
94 if (!fread(&tv,sizeof(struct timeval),1,rec->file))
95 return FALSE;
97 tv.tv_sec = rfbClientSwap32IfLE (tv.tv_sec);
98 tv.tv_usec = rfbClientSwap32IfLE (tv.tv_usec);
100 if (rec->tv.tv_sec!=0 && !rec->doNotSleep) {
101 struct timeval diff;
102 diff.tv_sec = tv.tv_sec - rec->tv.tv_sec;
103 diff.tv_usec = tv.tv_usec - rec->tv.tv_usec;
104 if(diff.tv_usec<0) {
105 diff.tv_sec--;
106 diff.tv_usec+=1000000;
108 #ifndef __MINGW32__
109 sleep (diff.tv_sec);
110 usleep (diff.tv_usec);
111 #else
112 Sleep (diff.tv_sec * 1000 + diff.tv_usec/1000);
113 #endif
116 rec->tv=tv;
119 return (fread(out,1,n,rec->file) != n ? FALSE : TRUE);
122 if (n <= client->buffered) {
123 memcpy(out, client->bufoutptr, n);
124 client->bufoutptr += n;
125 client->buffered -= n;
126 #ifdef DEBUG_READ_EXACT
127 goto hexdump;
128 #endif
129 return TRUE;
132 memcpy(out, client->bufoutptr, client->buffered);
134 out += client->buffered;
135 n -= client->buffered;
137 client->bufoutptr = client->buf;
138 client->buffered = 0;
140 if (n <= RFB_BUF_SIZE) {
142 while (client->buffered < n) {
143 int i;
144 if (client->tlsSession) {
145 i = ReadFromTLS(client, client->buf + client->buffered, RFB_BUF_SIZE - client->buffered);
146 } else {
147 i = read(client->sock, client->buf + client->buffered, RFB_BUF_SIZE - client->buffered);
149 if (i <= 0) {
150 if (i < 0) {
151 #ifdef WIN32
152 errno=WSAGetLastError();
153 #endif
154 if (errno == EWOULDBLOCK || errno == EAGAIN) {
155 /* TODO:
156 ProcessXtEvents();
158 WaitForMessage(client, 100000);
159 i = 0;
160 } else {
161 rfbClientErr("read (%d: %s)\n",errno,strerror(errno));
162 return FALSE;
164 } else {
165 if (errorMessageOnReadFailure) {
166 rfbClientLog("VNC server closed connection\n");
168 return FALSE;
171 client->buffered += i;
174 memcpy(out, client->bufoutptr, n);
175 client->bufoutptr += n;
176 client->buffered -= n;
178 } else {
180 while (n > 0) {
181 int i;
182 if (client->tlsSession) {
183 i = ReadFromTLS(client, out, n);
184 } else {
185 i = read(client->sock, out, n);
188 if (i <= 0) {
189 if (i < 0) {
190 #ifdef WIN32
191 errno=WSAGetLastError();
192 #endif
193 if (errno == EWOULDBLOCK || errno == EAGAIN) {
194 /* TODO:
195 ProcessXtEvents();
197 WaitForMessage(client, 100000);
198 i = 0;
199 } else {
200 rfbClientErr("read (%s)\n",strerror(errno));
201 return FALSE;
203 } else {
204 if (errorMessageOnReadFailure) {
205 rfbClientLog("VNC server closed connection\n");
207 return FALSE;
210 out += i;
211 n -= i;
215 #ifdef DEBUG_READ_EXACT
216 hexdump:
217 { int ii;
218 for(ii=0;ii<nn;ii++)
219 fprintf(stderr,"%02x ",(unsigned char)oout[ii]);
220 fprintf(stderr,"\n");
222 #endif
224 return TRUE;
229 * Write an exact number of bytes, and don't return until you've sent them.
232 rfbBool
233 WriteToRFBServer(rfbClient* client, char *buf, int n)
235 fd_set fds;
236 int i = 0;
237 int j;
239 if (client->serverPort==-1)
240 return TRUE; /* vncrec playing */
242 if (client->tlsSession) {
243 /* WriteToTLS() will guarantee either everything is written, or error/eof returns */
244 i = WriteToTLS(client, buf, n);
245 if (i <= 0) return FALSE;
247 return TRUE;
250 while (i < n) {
251 j = write(client->sock, buf + i, (n - i));
252 if (j <= 0) {
253 if (j < 0) {
254 #ifdef WIN32
255 errno=WSAGetLastError();
256 #endif
257 if (errno == EWOULDBLOCK ||
258 #ifdef LIBVNCSERVER_ENOENT_WORKAROUND
259 errno == ENOENT ||
260 #endif
261 errno == EAGAIN) {
262 FD_ZERO(&fds);
263 FD_SET(client->sock,&fds);
265 if (select(client->sock+1, NULL, &fds, NULL, NULL) <= 0) {
266 rfbClientErr("select\n");
267 return FALSE;
269 j = 0;
270 } else {
271 rfbClientErr("write\n");
272 return FALSE;
274 } else {
275 rfbClientLog("write failed\n");
276 return FALSE;
279 i += j;
281 return TRUE;
286 static int initSockets() {
287 #ifdef WIN32
288 WSADATA trash;
289 static rfbBool WSAinitted=FALSE;
290 if(!WSAinitted) {
291 int i=WSAStartup(MAKEWORD(2,0),&trash);
292 if(i!=0) {
293 rfbClientErr("Couldn't init Windows Sockets\n");
294 return 0;
296 WSAinitted=TRUE;
298 #endif
299 return 1;
303 * ConnectToTcpAddr connects to the given TCP port.
307 ConnectClientToTcpAddr(unsigned int host, int port)
309 int sock;
310 struct sockaddr_in addr;
311 int one = 1;
313 if (!initSockets())
314 return -1;
316 addr.sin_family = AF_INET;
317 addr.sin_port = htons(port);
318 addr.sin_addr.s_addr = host;
320 sock = socket(AF_INET, SOCK_STREAM, 0);
321 if (sock < 0) {
322 #ifdef WIN32
323 errno=WSAGetLastError();
324 #endif
325 rfbClientErr("ConnectToTcpAddr: socket (%s)\n",strerror(errno));
326 return -1;
329 if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
330 rfbClientErr("ConnectToTcpAddr: connect\n");
331 close(sock);
332 return -1;
335 if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
336 (char *)&one, sizeof(one)) < 0) {
337 rfbClientErr("ConnectToTcpAddr: setsockopt\n");
338 close(sock);
339 return -1;
342 return sock;
346 ConnectClientToTcpAddr6(const char *hostname, int port)
348 #ifdef LIBVNCSERVER_IPv6
349 int sock;
350 int n;
351 struct addrinfo hints, *res, *ressave;
352 char port_s[10];
353 int one = 1;
355 if (!initSockets())
356 return -1;
358 snprintf(port_s, 10, "%d", port);
359 memset(&hints, 0, sizeof(struct addrinfo));
360 hints.ai_family = AF_UNSPEC;
361 hints.ai_socktype = SOCK_STREAM;
362 if ((n = getaddrinfo(hostname, port_s, &hints, &res)))
364 rfbClientErr("ConnectClientToTcpAddr6: getaddrinfo (%s)\n", gai_strerror(n));
365 return -1;
368 ressave = res;
369 sock = -1;
370 while (res)
372 sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
373 if (sock >= 0)
375 if (connect(sock, res->ai_addr, res->ai_addrlen) == 0)
376 break;
377 close(sock);
378 sock = -1;
380 res = res->ai_next;
382 freeaddrinfo(ressave);
384 if (sock == -1)
386 rfbClientErr("ConnectClientToTcpAddr6: connect\n");
387 return -1;
390 if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
391 (char *)&one, sizeof(one)) < 0) {
392 rfbClientErr("ConnectToTcpAddr: setsockopt\n");
393 close(sock);
394 return -1;
397 return sock;
399 #else
401 rfbClientErr("ConnectClientToTcpAddr6: IPv6 disabled\n");
402 return -1;
404 #endif
408 ConnectClientToUnixSock(const char *sockFile)
410 #ifdef WIN32
411 rfbClientErr("Windows doesn't support UNIX sockets\n");
412 return -1;
413 #else
414 int sock;
415 struct sockaddr_un addr;
416 addr.sun_family = AF_UNIX;
417 strcpy(addr.sun_path, sockFile);
419 sock = socket(AF_UNIX, SOCK_STREAM, 0);
420 if (sock < 0) {
421 rfbClientErr("ConnectToUnixSock: socket (%s)\n",strerror(errno));
422 return -1;
425 if (connect(sock, (struct sockaddr *)&addr, sizeof(addr.sun_family) + strlen(addr.sun_path)) < 0) {
426 rfbClientErr("ConnectToUnixSock: connect\n");
427 close(sock);
428 return -1;
431 return sock;
432 #endif
438 * FindFreeTcpPort tries to find unused TCP port in the range
439 * (TUNNEL_PORT_OFFSET, TUNNEL_PORT_OFFSET + 99]. Returns 0 on failure.
443 FindFreeTcpPort(void)
445 int sock, port;
446 struct sockaddr_in addr;
448 addr.sin_family = AF_INET;
449 addr.sin_addr.s_addr = htonl(INADDR_ANY);
451 if (!initSockets())
452 return -1;
454 sock = socket(AF_INET, SOCK_STREAM, 0);
455 if (sock < 0) {
456 rfbClientErr(": FindFreeTcpPort: socket\n");
457 return 0;
460 for (port = TUNNEL_PORT_OFFSET + 99; port > TUNNEL_PORT_OFFSET; port--) {
461 addr.sin_port = htons((unsigned short)port);
462 if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) {
463 close(sock);
464 return port;
468 close(sock);
469 return 0;
474 * ListenAtTcpPort starts listening at the given TCP port.
478 ListenAtTcpPort(int port)
480 return ListenAtTcpPortAndAddress(port, NULL);
486 * ListenAtTcpPortAndAddress starts listening at the given TCP port on
487 * the given IP address
491 ListenAtTcpPortAndAddress(int port, const char *address)
493 int sock;
494 int one = 1;
495 #ifndef LIBVNCSERVER_IPv6
496 struct sockaddr_in addr;
498 addr.sin_family = AF_INET;
499 addr.sin_port = htons(port);
500 if (address) {
501 addr.sin_addr.s_addr = inet_addr(address);
502 } else {
503 addr.sin_addr.s_addr = htonl(INADDR_ANY);
506 if (!initSockets())
507 return -1;
509 sock = socket(AF_INET, SOCK_STREAM, 0);
510 if (sock < 0) {
511 rfbClientErr("ListenAtTcpPort: socket\n");
512 return -1;
515 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
516 (const char *)&one, sizeof(one)) < 0) {
517 rfbClientErr("ListenAtTcpPort: setsockopt\n");
518 close(sock);
519 return -1;
522 if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
523 rfbClientErr("ListenAtTcpPort: bind\n");
524 close(sock);
525 return -1;
528 #else
529 int rv;
530 struct addrinfo hints, *servinfo, *p;
531 char port_str[8];
533 snprintf(port_str, 8, "%d", port);
535 memset(&hints, 0, sizeof(hints));
536 hints.ai_family = AF_UNSPEC;
537 hints.ai_socktype = SOCK_STREAM;
538 hints.ai_flags = AI_PASSIVE; /* fill in wildcard address if address == NULL */
540 if (!initSockets())
541 return -1;
543 if ((rv = getaddrinfo(address, port_str, &hints, &servinfo)) != 0) {
544 rfbClientErr("ListenAtTcpPortAndAddress: error in getaddrinfo: %s\n", gai_strerror(rv));
545 return -1;
548 /* loop through all the results and bind to the first we can */
549 for(p = servinfo; p != NULL; p = p->ai_next) {
550 if ((sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) < 0) {
551 continue;
554 #ifdef IPV6_V6ONLY
555 /* we have seperate IPv4 and IPv6 sockets since some OS's do not support dual binding */
556 if (p->ai_family == AF_INET6 && setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&one, sizeof(one)) < 0) {
557 rfbClientErr("ListenAtTcpPortAndAddress: error in setsockopt IPV6_V6ONLY: %s\n", strerror(errno));
558 close(sock);
559 freeaddrinfo(servinfo);
560 return -1;
562 #endif
564 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)) < 0) {
565 rfbClientErr("ListenAtTcpPortAndAddress: error in setsockopt SO_REUSEADDR: %s\n", strerror(errno));
566 close(sock);
567 freeaddrinfo(servinfo);
568 return -1;
571 if (bind(sock, p->ai_addr, p->ai_addrlen) < 0) {
572 close(sock);
573 continue;
576 break;
579 if (p == NULL) {
580 rfbClientErr("ListenAtTcpPortAndAddress: error in bind: %s\n", strerror(errno));
581 return -1;
584 /* all done with this structure now */
585 freeaddrinfo(servinfo);
586 #endif
588 if (listen(sock, 5) < 0) {
589 rfbClientErr("ListenAtTcpPort: listen\n");
590 close(sock);
591 return -1;
594 return sock;
599 * AcceptTcpConnection accepts a TCP connection.
603 AcceptTcpConnection(int listenSock)
605 int sock;
606 struct sockaddr_in addr;
607 socklen_t addrlen = sizeof(addr);
608 int one = 1;
610 sock = accept(listenSock, (struct sockaddr *) &addr, &addrlen);
611 if (sock < 0) {
612 rfbClientErr("AcceptTcpConnection: accept\n");
613 return -1;
616 if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
617 (char *)&one, sizeof(one)) < 0) {
618 rfbClientErr("AcceptTcpConnection: setsockopt\n");
619 close(sock);
620 return -1;
623 return sock;
628 * SetNonBlocking sets a socket into non-blocking mode.
631 rfbBool
632 SetNonBlocking(int sock)
634 #ifdef WIN32
635 unsigned long block=1;
636 if(ioctlsocket(sock, FIONBIO, &block) == SOCKET_ERROR) {
637 errno=WSAGetLastError();
638 #else
639 int flags = fcntl(sock, F_GETFL);
640 if(flags < 0 || fcntl(sock, F_SETFL, flags | O_NONBLOCK) < 0) {
641 #endif
642 rfbClientErr("Setting socket to non-blocking failed: %s\n",strerror(errno));
643 return FALSE;
645 return TRUE;
651 * SetDSCP sets a socket's IP QoS parameters aka Differentiated Services Code Point field
654 rfbBool
655 SetDSCP(int sock, int dscp)
657 #ifdef WIN32
658 rfbClientErr("Setting of QoS IP DSCP not implemented for Windows\n");
659 return TRUE;
660 #else
661 int level, cmd;
662 struct sockaddr addr;
663 socklen_t addrlen = sizeof(addr);
665 if(getsockname(sock, &addr, &addrlen) != 0) {
666 rfbClientErr("Setting socket QoS failed while getting socket address: %s\n",strerror(errno));
667 return FALSE;
670 switch(addr.sa_family)
672 #if defined LIBVNCSERVER_IPv6 && defined IPV6_TCLASS
673 case AF_INET6:
674 level = IPPROTO_IPV6;
675 cmd = IPV6_TCLASS;
676 break;
677 #endif
678 case AF_INET:
679 level = IPPROTO_IP;
680 cmd = IP_TOS;
681 break;
682 default:
683 rfbClientErr("Setting socket QoS failed: Not bound to IP address");
684 return FALSE;
687 if(setsockopt(sock, level, cmd, (void*)&dscp, sizeof(dscp)) != 0) {
688 rfbClientErr("Setting socket QoS failed: %s\n", strerror(errno));
689 return FALSE;
692 return TRUE;
693 #endif
699 * StringToIPAddr - convert a host string to an IP address.
702 rfbBool
703 StringToIPAddr(const char *str, unsigned int *addr)
705 struct hostent *hp;
707 if (strcmp(str,"") == 0) {
708 *addr = htonl(INADDR_LOOPBACK); /* local */
709 return TRUE;
712 *addr = inet_addr(str);
714 if (*addr != -1)
715 return TRUE;
717 if (!initSockets())
718 return -1;
720 hp = gethostbyname(str);
722 if (hp) {
723 *addr = *(unsigned int *)hp->h_addr;
724 return TRUE;
727 return FALSE;
732 * Test if the other end of a socket is on the same machine.
735 rfbBool
736 SameMachine(int sock)
738 struct sockaddr_in peeraddr, myaddr;
739 socklen_t addrlen = sizeof(struct sockaddr_in);
741 getpeername(sock, (struct sockaddr *)&peeraddr, &addrlen);
742 getsockname(sock, (struct sockaddr *)&myaddr, &addrlen);
744 return (peeraddr.sin_addr.s_addr == myaddr.sin_addr.s_addr);
749 * Print out the contents of a packet for debugging.
752 void
753 PrintInHex(char *buf, int len)
755 int i, j;
756 char c, str[17];
758 str[16] = 0;
760 rfbClientLog("ReadExact: ");
762 for (i = 0; i < len; i++)
764 if ((i % 16 == 0) && (i != 0)) {
765 rfbClientLog(" ");
767 c = buf[i];
768 str[i % 16] = (((c > 31) && (c < 127)) ? c : '.');
769 rfbClientLog("%02x ",(unsigned char)c);
770 if ((i % 4) == 3)
771 rfbClientLog(" ");
772 if ((i % 16) == 15)
774 rfbClientLog("%s\n",str);
777 if ((i % 16) != 0)
779 for (j = i % 16; j < 16; j++)
781 rfbClientLog(" ");
782 if ((j % 4) == 3) rfbClientLog(" ");
784 str[i % 16] = 0;
785 rfbClientLog("%s\n",str);
788 fflush(stderr);
791 int WaitForMessage(rfbClient* client,unsigned int usecs)
793 fd_set fds;
794 struct timeval timeout;
795 int num;
797 if (client->serverPort==-1)
798 /* playing back vncrec file */
799 return 1;
801 timeout.tv_sec=(usecs/1000000);
802 timeout.tv_usec=(usecs%1000000);
804 FD_ZERO(&fds);
805 FD_SET(client->sock,&fds);
807 num=select(client->sock+1, &fds, NULL, NULL, &timeout);
808 if(num<0) {
809 #ifdef WIN32
810 errno=WSAGetLastError();
811 #endif
812 rfbClientLog("Waiting for message failed: %d (%s)\n",errno,strerror(errno));
815 return num;