summaryrefslogtreecommitdiffstats
path: root/libvncserver/main.c
diff options
context:
space:
mode:
authorChristian Beier <dontmind@freeshell.org>2012-02-20 15:52:19 +0100
committerChristian Beier <dontmind@freeshell.org>2012-02-20 15:52:19 +0100
commit83a7c713a99a65f910fabab1bb95428762f569fb (patch)
tree46e2fad855fd03a2e9a8bf6e03c2d2242b26de43 /libvncserver/main.c
parent1078e8a8b050b5b4ebbcb011750f5dd2d8eacc37 (diff)
downloadlibtdevnc-83a7c713a99a65f910fabab1bb95428762f569fb.tar.gz
libtdevnc-83a7c713a99a65f910fabab1bb95428762f569fb.zip
IPv6 support for LibVNCServer, part one: accept IPv4 and IPv6 connections.
This uses a separate-socket approach since there are systems that do not support dual binding sockets under *any* circumstances, for instance OpenBSD. Using separate sockets for IPv4 and IPv6 is thus more portable than having a v6 socket handle v4 connections as well. Signed-off-by: Christian Beier <dontmind@freeshell.org>
Diffstat (limited to 'libvncserver/main.c')
-rw-r--r--libvncserver/main.c38
1 files changed, 28 insertions, 10 deletions
diff --git a/libvncserver/main.c b/libvncserver/main.c
index 0edf994..7ecc842 100644
--- a/libvncserver/main.c
+++ b/libvncserver/main.c
@@ -569,21 +569,37 @@ listenerRun(void *data)
{
rfbScreenInfoPtr screen=(rfbScreenInfoPtr)data;
int client_fd;
- struct sockaddr_in peer;
- rfbClientPtr cl;
+ struct sockaddr_storage peer;
+ rfbClientPtr cl = NULL;
socklen_t len;
-
- len = sizeof(peer);
+ fd_set listen_fds; /* temp file descriptor list for select() */
/* TODO: this thread wont die by restarting the server */
/* TODO: HTTP is not handled */
- while ((client_fd = accept(screen->listenSock,
- (struct sockaddr*)&peer, &len)) >= 0) {
- cl = rfbNewClient(screen,client_fd);
- len = sizeof(peer);
-
+ while (1) {
+ client_fd = -1;
+ FD_ZERO(&listen_fds);
+ if(screen->listenSock >= 0)
+ FD_SET(screen->listenSock, &listen_fds);
+ if(screen->listen6Sock >= 0)
+ FD_SET(screen->listen6Sock, &listen_fds);
+
+ if (select(screen->maxFd+1, &listen_fds, NULL, NULL, NULL) == -1) {
+ rfbLogPerror("listenerRun: error in select");
+ return NULL;
+ }
+
+ /* there is something on the listening sockets, handle new connections */
+ len = sizeof (peer);
+ if (FD_ISSET(screen->listenSock, &listen_fds))
+ client_fd = accept(screen->listenSock, (struct sockaddr*)&peer, &len);
+ if (FD_ISSET(screen->listen6Sock, &listen_fds))
+ client_fd = accept(screen->listen6Sock, (struct sockaddr*)&peer, &len);
+
+ if(client_fd >= 0)
+ cl = rfbNewClient(screen,client_fd);
if (cl && !cl->onHold )
- rfbStartOnHoldClient(cl);
+ rfbStartOnHoldClient(cl);
}
return(NULL);
}
@@ -809,6 +825,7 @@ rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv,
screen->clientHead=NULL;
screen->pointerClient=NULL;
screen->port=5900;
+ screen->ipv6port=5900;
screen->socketState=RFB_SOCKET_INIT;
screen->inetdInitDone = FALSE;
@@ -821,6 +838,7 @@ rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv,
screen->maxFd=0;
screen->listenSock=-1;
+ screen->listen6Sock=-1;
screen->httpInitDone=FALSE;
screen->httpEnableProxyConnect=FALSE;