summaryrefslogtreecommitdiffstats
path: root/libvncclient/listen.c
diff options
context:
space:
mode:
Diffstat (limited to 'libvncclient/listen.c')
-rw-r--r--libvncclient/listen.c77
1 files changed, 66 insertions, 11 deletions
diff --git a/libvncclient/listen.c b/libvncclient/listen.c
index 2e9fafb..c91ad6e 100644
--- a/libvncclient/listen.c
+++ b/libvncclient/listen.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2011-2012 Christian Beier <dontmind@freeshell.org>
* Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
*
* This is free software; you can redistribute it and/or modify
@@ -50,7 +51,7 @@ listenForIncomingConnections(rfbClient* client)
rfbClientErr("listenForIncomingConnections on MinGW32 NOT IMPLEMENTED\n");
return;
#else
- int listenSocket;
+ int listenSocket, listen6Socket = -1;
fd_set fds;
client->listenSpecified = TRUE;
@@ -65,8 +66,24 @@ listenForIncomingConnections(rfbClient* client)
rfbClientLog("%s -listen: Command line errors are not reported until "
"a connection comes in.\n", client->programName);
- while (TRUE) {
+#ifdef LIBVNCSERVER_IPv6 /* only try that if we're IPv6-capable, otherwise we may try to bind to the same port which would make all that listening fail */
+ /* only do IPv6 listen of listen6Port is set */
+ if (client->listen6Port > 0)
+ {
+ listen6Socket = ListenAtTcpPortAndAddress(client->listen6Port, client->listen6Address);
+
+ if (listen6Socket < 0)
+ return;
+
+ rfbClientLog("%s -listen: Listening on IPV6 port %d\n",
+ client->programName,client->listenPort);
+ rfbClientLog("%s -listen: Command line errors are not reported until "
+ "a connection comes in.\n", client->programName);
+ }
+#endif
+ while (TRUE) {
+ int r;
/* reap any zombies */
int status, pid;
while ((pid= wait3(&status, WNOHANG, (struct rusage *)0))>0);
@@ -75,12 +92,19 @@ listenForIncomingConnections(rfbClient* client)
FD_ZERO(&fds);
- FD_SET(listenSocket, &fds);
+ if(listenSocket >= 0)
+ FD_SET(listenSocket, &fds);
+ if(listen6Socket >= 0)
+ FD_SET(listen6Socket, &fds);
+
+ r = select(max(listenSocket, listen6Socket)+1, &fds, NULL, NULL, NULL);
- select(listenSocket+1, &fds, NULL, NULL, NULL);
+ if (r > 0) {
+ if (FD_ISSET(listenSocket, &fds))
+ client->sock = AcceptTcpConnection(client->listenSock);
+ else if (FD_ISSET(listen6Socket, &fds))
+ client->sock = AcceptTcpConnection(client->listen6Sock);
- if (FD_ISSET(listenSocket, &fds)) {
- client->sock = AcceptTcpConnection(listenSocket);
if (client->sock < 0)
return;
if (!SetNonBlocking(client->sock))
@@ -97,6 +121,7 @@ listenForIncomingConnections(rfbClient* client)
case 0:
/* child - return to caller */
close(listenSocket);
+ close(listen6Socket);
return;
default:
@@ -144,24 +169,54 @@ listenForIncomingConnectionsNoFork(rfbClient* client, int timeout)
"a connection comes in.\n", client->programName);
}
+#ifdef LIBVNCSERVER_IPv6 /* only try that if we're IPv6-capable, otherwise we may try to bind to the same port which would make all that listening fail */
+ /* only do IPv6 listen of listen6Port is set */
+ if (client->listen6Port > 0 && client->listen6Sock < 0)
+ {
+ client->listen6Sock = ListenAtTcpPortAndAddress(client->listen6Port, client->listen6Address);
+
+ if (client->listen6Sock < 0)
+ return -1;
+
+ rfbClientLog("%s -listennofork: Listening on IPV6 port %d\n",
+ client->programName,client->listenPort);
+ rfbClientLog("%s -listennofork: Command line errors are not reported until "
+ "a connection comes in.\n", client->programName);
+ }
+#endif
+
FD_ZERO(&fds);
- FD_SET(client->listenSock, &fds);
+ if(client->listenSock >= 0)
+ FD_SET(client->listenSock, &fds);
+ if(client->listen6Sock >= 0)
+ FD_SET(client->listen6Sock, &fds);
if (timeout < 0)
- r = select(client->listenSock+1, &fds, NULL, NULL, NULL);
+ r = select(max(client->listenSock, client->listen6Sock) +1, &fds, NULL, NULL, NULL);
else
- r = select(client->listenSock+1, &fds, NULL, NULL, &to);
+ r = select(max(client->listenSock, client->listen6Sock) +1, &fds, NULL, NULL, &to);
if (r > 0)
{
- client->sock = AcceptTcpConnection(client->listenSock);
+ if (FD_ISSET(client->listenSock, &fds))
+ client->sock = AcceptTcpConnection(client->listenSock);
+ else if (FD_ISSET(client->listen6Sock, &fds))
+ client->sock = AcceptTcpConnection(client->listen6Sock);
+
if (client->sock < 0)
return -1;
if (!SetNonBlocking(client->sock))
return -1;
- close(client->listenSock);
+ if(client->listenSock >= 0) {
+ close(client->listenSock);
+ client->listenSock = -1;
+ }
+ if(client->listen6Sock >= 0) {
+ close(client->listen6Sock);
+ client->listen6Sock = -1;
+ }
return r;
}