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,
22 * sockets.c - functions to deal with sockets.
25 #ifdef __STRICT_ANSI__
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
37 #include <rfb/rfbclient.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)
46 #ifdef LIBVNCSERVER_HAVE_WS2TCPIP_H
51 #include <sys/socket.h>
52 #include <netinet/in.h>
54 #include <netinet/tcp.h>
55 #include <arpa/inet.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.
79 ReadFromRFBServer(rfbClient
* client
, char *out
, unsigned int n
)
81 #undef DEBUG_READ_EXACT
82 #ifdef DEBUG_READ_EXACT
85 rfbClientLog("ReadFromRFBServer %d bytes\n",n
);
87 if (client
->serverPort
==-1) {
89 rfbVNCRec
* rec
= client
->vncRec
;
92 if (rec
->readTimestamp
) {
93 rec
->readTimestamp
= FALSE
;
94 if (!fread(&tv
,sizeof(struct timeval
),1,rec
->file
))
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
) {
102 diff
.tv_sec
= tv
.tv_sec
- rec
->tv
.tv_sec
;
103 diff
.tv_usec
= tv
.tv_usec
- rec
->tv
.tv_usec
;
106 diff
.tv_usec
+=1000000;
110 usleep (diff
.tv_usec
);
112 Sleep (diff
.tv_sec
* 1000 + diff
.tv_usec
/1000);
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
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
) {
144 if (client
->tlsSession
) {
145 i
= ReadFromTLS(client
, client
->buf
+ client
->buffered
, RFB_BUF_SIZE
- client
->buffered
);
147 i
= read(client
->sock
, client
->buf
+ client
->buffered
, RFB_BUF_SIZE
- client
->buffered
);
152 errno
=WSAGetLastError();
154 if (errno
== EWOULDBLOCK
|| errno
== EAGAIN
) {
158 WaitForMessage(client
, 100000);
161 rfbClientErr("read (%d: %s)\n",errno
,strerror(errno
));
165 if (errorMessageOnReadFailure
) {
166 rfbClientLog("VNC server closed connection\n");
171 client
->buffered
+= i
;
174 memcpy(out
, client
->bufoutptr
, n
);
175 client
->bufoutptr
+= n
;
176 client
->buffered
-= n
;
182 if (client
->tlsSession
) {
183 i
= ReadFromTLS(client
, out
, n
);
185 i
= read(client
->sock
, out
, n
);
191 errno
=WSAGetLastError();
193 if (errno
== EWOULDBLOCK
|| errno
== EAGAIN
) {
197 WaitForMessage(client
, 100000);
200 rfbClientErr("read (%s)\n",strerror(errno
));
204 if (errorMessageOnReadFailure
) {
205 rfbClientLog("VNC server closed connection\n");
215 #ifdef DEBUG_READ_EXACT
219 fprintf(stderr
,"%02x ",(unsigned char)oout
[ii
]);
220 fprintf(stderr
,"\n");
229 * Write an exact number of bytes, and don't return until you've sent them.
233 WriteToRFBServer(rfbClient
* client
, char *buf
, int n
)
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
;
251 j
= write(client
->sock
, buf
+ i
, (n
- i
));
255 errno
=WSAGetLastError();
257 if (errno
== EWOULDBLOCK
||
258 #ifdef LIBVNCSERVER_ENOENT_WORKAROUND
263 FD_SET(client
->sock
,&fds
);
265 if (select(client
->sock
+1, NULL
, &fds
, NULL
, NULL
) <= 0) {
266 rfbClientErr("select\n");
271 rfbClientErr("write\n");
275 rfbClientLog("write failed\n");
286 static int initSockets() {
289 static rfbBool WSAinitted
=FALSE
;
291 int i
=WSAStartup(MAKEWORD(2,0),&trash
);
293 rfbClientErr("Couldn't init Windows Sockets\n");
303 * ConnectToTcpAddr connects to the given TCP port.
307 ConnectClientToTcpAddr(unsigned int host
, int port
)
310 struct sockaddr_in addr
;
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);
323 errno
=WSAGetLastError();
325 rfbClientErr("ConnectToTcpAddr: socket (%s)\n",strerror(errno
));
329 if (connect(sock
, (struct sockaddr
*)&addr
, sizeof(addr
)) < 0) {
330 rfbClientErr("ConnectToTcpAddr: connect\n");
335 if (setsockopt(sock
, IPPROTO_TCP
, TCP_NODELAY
,
336 (char *)&one
, sizeof(one
)) < 0) {
337 rfbClientErr("ConnectToTcpAddr: setsockopt\n");
346 ConnectClientToTcpAddr6(const char *hostname
, int port
)
348 #ifdef LIBVNCSERVER_IPv6
351 struct addrinfo hints
, *res
, *ressave
;
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
));
372 sock
= socket(res
->ai_family
, res
->ai_socktype
, res
->ai_protocol
);
375 if (connect(sock
, res
->ai_addr
, res
->ai_addrlen
) == 0)
382 freeaddrinfo(ressave
);
386 rfbClientErr("ConnectClientToTcpAddr6: connect\n");
390 if (setsockopt(sock
, IPPROTO_TCP
, TCP_NODELAY
,
391 (char *)&one
, sizeof(one
)) < 0) {
392 rfbClientErr("ConnectToTcpAddr: setsockopt\n");
401 rfbClientErr("ConnectClientToTcpAddr6: IPv6 disabled\n");
408 ConnectClientToUnixSock(const char *sockFile
)
411 rfbClientErr("Windows doesn't support UNIX sockets\n");
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);
421 rfbClientErr("ConnectToUnixSock: socket (%s)\n",strerror(errno
));
425 if (connect(sock
, (struct sockaddr
*)&addr
, sizeof(addr
.sun_family
) + strlen(addr
.sun_path
)) < 0) {
426 rfbClientErr("ConnectToUnixSock: connect\n");
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)
446 struct sockaddr_in addr
;
448 addr
.sin_family
= AF_INET
;
449 addr
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
454 sock
= socket(AF_INET
, SOCK_STREAM
, 0);
456 rfbClientErr(": FindFreeTcpPort: socket\n");
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) {
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
)
495 #ifndef LIBVNCSERVER_IPv6
496 struct sockaddr_in addr
;
498 addr
.sin_family
= AF_INET
;
499 addr
.sin_port
= htons(port
);
501 addr
.sin_addr
.s_addr
= inet_addr(address
);
503 addr
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
509 sock
= socket(AF_INET
, SOCK_STREAM
, 0);
511 rfbClientErr("ListenAtTcpPort: socket\n");
515 if (setsockopt(sock
, SOL_SOCKET
, SO_REUSEADDR
,
516 (const char *)&one
, sizeof(one
)) < 0) {
517 rfbClientErr("ListenAtTcpPort: setsockopt\n");
522 if (bind(sock
, (struct sockaddr
*)&addr
, sizeof(addr
)) < 0) {
523 rfbClientErr("ListenAtTcpPort: bind\n");
530 struct addrinfo hints
, *servinfo
, *p
;
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 */
543 if ((rv
= getaddrinfo(address
, port_str
, &hints
, &servinfo
)) != 0) {
544 rfbClientErr("ListenAtTcpPortAndAddress: error in getaddrinfo: %s\n", gai_strerror(rv
));
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) {
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
));
559 freeaddrinfo(servinfo
);
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
));
567 freeaddrinfo(servinfo
);
571 if (bind(sock
, p
->ai_addr
, p
->ai_addrlen
) < 0) {
580 rfbClientErr("ListenAtTcpPortAndAddress: error in bind: %s\n", strerror(errno
));
584 /* all done with this structure now */
585 freeaddrinfo(servinfo
);
588 if (listen(sock
, 5) < 0) {
589 rfbClientErr("ListenAtTcpPort: listen\n");
599 * AcceptTcpConnection accepts a TCP connection.
603 AcceptTcpConnection(int listenSock
)
606 struct sockaddr_in addr
;
607 socklen_t addrlen
= sizeof(addr
);
610 sock
= accept(listenSock
, (struct sockaddr
*) &addr
, &addrlen
);
612 rfbClientErr("AcceptTcpConnection: accept\n");
616 if (setsockopt(sock
, IPPROTO_TCP
, TCP_NODELAY
,
617 (char *)&one
, sizeof(one
)) < 0) {
618 rfbClientErr("AcceptTcpConnection: setsockopt\n");
628 * SetNonBlocking sets a socket into non-blocking mode.
632 SetNonBlocking(int sock
)
635 unsigned long block
=1;
636 if(ioctlsocket(sock
, FIONBIO
, &block
) == SOCKET_ERROR
) {
637 errno
=WSAGetLastError();
639 int flags
= fcntl(sock
, F_GETFL
);
640 if(flags
< 0 || fcntl(sock
, F_SETFL
, flags
| O_NONBLOCK
) < 0) {
642 rfbClientErr("Setting socket to non-blocking failed: %s\n",strerror(errno
));
651 * SetDSCP sets a socket's IP QoS parameters aka Differentiated Services Code Point field
655 SetDSCP(int sock
, int dscp
)
658 rfbClientErr("Setting of QoS IP DSCP not implemented for Windows\n");
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
));
670 switch(addr
.sa_family
)
672 #if defined LIBVNCSERVER_IPv6 && defined IPV6_TCLASS
674 level
= IPPROTO_IPV6
;
683 rfbClientErr("Setting socket QoS failed: Not bound to IP address");
687 if(setsockopt(sock
, level
, cmd
, (void*)&dscp
, sizeof(dscp
)) != 0) {
688 rfbClientErr("Setting socket QoS failed: %s\n", strerror(errno
));
699 * StringToIPAddr - convert a host string to an IP address.
703 StringToIPAddr(const char *str
, unsigned int *addr
)
707 if (strcmp(str
,"") == 0) {
708 *addr
= htonl(INADDR_LOOPBACK
); /* local */
712 *addr
= inet_addr(str
);
720 hp
= gethostbyname(str
);
723 *addr
= *(unsigned int *)hp
->h_addr
;
732 * Test if the other end of a socket is on the same machine.
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.
753 PrintInHex(char *buf
, int len
)
760 rfbClientLog("ReadExact: ");
762 for (i
= 0; i
< len
; i
++)
764 if ((i
% 16 == 0) && (i
!= 0)) {
768 str
[i
% 16] = (((c
> 31) && (c
< 127)) ? c
: '.');
769 rfbClientLog("%02x ",(unsigned char)c
);
774 rfbClientLog("%s\n",str
);
779 for (j
= i
% 16; j
< 16; j
++)
782 if ((j
% 4) == 3) rfbClientLog(" ");
785 rfbClientLog("%s\n",str
);
791 int WaitForMessage(rfbClient
* client
,unsigned int usecs
)
794 struct timeval timeout
;
797 if (client
->serverPort
==-1)
798 /* playing back vncrec file */
801 timeout
.tv_sec
=(usecs
/1000000);
802 timeout
.tv_usec
=(usecs
%1000000);
805 FD_SET(client
->sock
,&fds
);
807 num
=select(client
->sock
+1, &fds
, NULL
, NULL
, &timeout
);
810 errno
=WSAGetLastError();
812 rfbClientLog("Waiting for message failed: %d (%s)\n",errno
,strerror(errno
));