diff options
Diffstat (limited to 'libvncserver')
| -rw-r--r-- | libvncserver/Makefile.am | 6 | ||||
| -rw-r--r-- | libvncserver/main.c | 2 | ||||
| -rw-r--r-- | libvncserver/sockets.c | 112 |
3 files changed, 75 insertions, 45 deletions
diff --git a/libvncserver/Makefile.am b/libvncserver/Makefile.am index 2f23e31..e25784b 100644 --- a/libvncserver/Makefile.am +++ b/libvncserver/Makefile.am @@ -59,6 +59,12 @@ LIB_SRCS = main.c rfbserver.c rfbregion.c auth.c sockets.c $(WEBSOCKETSSRCS) \ libvncserver_la_SOURCES=$(LIB_SRCS) libvncserver_la_LIBADD=$(WEBSOCKETSSSLLIBS) +if WITH_SYSTEMD +AM_CPPFLAGS += -DLIBVNCSERVER_WITH_SYSTEMD +libvncserver_la_CFLAGS = $(LIBSYSTEMD_CFLAGS) +libvncserver_la_LIBADD += $(LIBSYSTEMD_LIBS) +endif + lib_LTLIBRARIES=libvncserver.la libvncserver_la_LDFLAGS = -version-info 1:0:0 diff --git a/libvncserver/main.c b/libvncserver/main.c index a8458e4..47dac11 100644 --- a/libvncserver/main.c +++ b/libvncserver/main.c @@ -582,7 +582,7 @@ listenerRun(void *data) socklen_t len; fd_set listen_fds; /* temp file descriptor list for select() */ - /* TODO: this thread wont die by restarting the server */ + /* TODO: this thread won't die by restarting the server */ /* TODO: HTTP is not handled */ while (1) { client_fd = -1; diff --git a/libvncserver/sockets.c b/libvncserver/sockets.c index 6467b1c..bbc3d90 100644 --- a/libvncserver/sockets.c +++ b/libvncserver/sockets.c @@ -77,6 +77,10 @@ #include "rfbssl.h" #endif +#ifdef LIBVNCSERVER_WITH_SYSTEMD +#include <systemd/sd-daemon.h> +#endif + #if defined(__linux__) && defined(NEED_TIMEVAL) struct timeval { @@ -122,6 +126,54 @@ int deny_severity=LOG_WARNING; int rfbMaxClientWait = 20000; /* time (ms) after which we decide client has gone away - needed to stop us hanging */ +static rfbBool +rfbNewConnectionFromSock(rfbScreenInfoPtr rfbScreen, int sock) +{ + const int one = 1; +#ifdef LIBVNCSERVER_IPv6 + struct sockaddr_storage addr; +#else + struct sockaddr_in addr; +#endif + socklen_t addrlen = sizeof(addr); + + getpeername(sock, (struct sockaddr *)&addr, &addrlen); + + if(!rfbSetNonBlocking(sock)) { + rfbLogPerror("rfbCheckFds: setnonblock"); + closesocket(sock); + return FALSE; + } + + if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, + (char *)&one, sizeof(one)) < 0) { + rfbLogPerror("rfbCheckFds: setsockopt failed: can't set TCP_NODELAY flag, non TCP socket?"); + } + +#ifdef USE_LIBWRAP + if(!hosts_ctl("vnc",STRING_UNKNOWN,inet_ntoa(addr.sin_addr), + STRING_UNKNOWN)) { + rfbLog("Rejected connection from client %s\n", + inet_ntoa(addr.sin_addr)); + closesocket(sock); + return FALSE; + } +#endif + +#ifdef LIBVNCSERVER_IPv6 + char host[1024]; + if(getnameinfo((struct sockaddr*)&addr, addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST) != 0) { + rfbLogPerror("rfbProcessNewConnection: error in getnameinfo"); + } + rfbLog("Got connection from client %s\n", host); +#else + rfbLog("Got connection from client %s\n", inet_ntoa(addr.sin_addr)); +#endif + + rfbNewClient(rfbScreen,sock); + return TRUE; +} + /* * rfbInitSockets sets up the TCP and UDP sockets to listen for RFB * connections. It does nothing if called again. @@ -138,6 +190,20 @@ rfbInitSockets(rfbScreenInfoPtr rfbScreen) rfbScreen->socketState = RFB_SOCKET_READY; +#ifdef LIBVNCSERVER_WITH_SYSTEMD + if (sd_listen_fds(0) == 1) + { + int sock = SD_LISTEN_FDS_START + 0; + if (sd_is_socket(sock, AF_UNSPEC, 0, 0)) + rfbNewConnectionFromSock(rfbScreen, sock); + else if (sd_is_socket(sock, AF_UNSPEC, 0, 1)) + rfbProcessNewConnection(rfbScreen); + return; + } + else + rfbLog("Unable to establish connection with systemd socket\n"); +#endif + if (rfbScreen->inetdSock != -1) { const int one = 1; @@ -413,14 +479,7 @@ rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec) rfbBool rfbProcessNewConnection(rfbScreenInfoPtr rfbScreen) { - const int one = 1; int sock = -1; -#ifdef LIBVNCSERVER_IPv6 - struct sockaddr_storage addr; -#else - struct sockaddr_in addr; -#endif - socklen_t addrlen = sizeof(addr); fd_set listen_fds; int chosen_listen_sock = -1; @@ -441,47 +500,12 @@ rfbProcessNewConnection(rfbScreenInfoPtr rfbScreen) if (rfbScreen->listen6Sock >= 0 && FD_ISSET(rfbScreen->listen6Sock, &listen_fds)) chosen_listen_sock = rfbScreen->listen6Sock; - if ((sock = accept(chosen_listen_sock, - (struct sockaddr *)&addr, &addrlen)) < 0) { + if ((sock = accept(chosen_listen_sock, NULL, NULL)) < 0) { rfbLogPerror("rfbCheckFds: accept"); return FALSE; } - if(!rfbSetNonBlocking(sock)) { - closesocket(sock); - return FALSE; - } - - if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, - (char *)&one, sizeof(one)) < 0) { - rfbLogPerror("rfbCheckFds: setsockopt failed: can't set TCP_NODELAY flag, non TCP socket?"); - } - -#ifdef USE_LIBWRAP - if(!hosts_ctl("vnc",STRING_UNKNOWN,inet_ntoa(addr.sin_addr), - STRING_UNKNOWN)) { - rfbLog("Rejected connection from client %s\n", - inet_ntoa(addr.sin_addr)); - closesocket(sock); - return FALSE; - } -#endif - -#ifdef LIBVNCSERVER_IPv6 - { - char host[1024]; - if(getnameinfo((struct sockaddr*)&addr, addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST) != 0) { - rfbLogPerror("rfbProcessNewConnection: error in getnameinfo"); - } - rfbLog("Got connection from client %s\n", host); - } -#else - rfbLog("Got connection from client %s\n", inet_ntoa(addr.sin_addr)); -#endif - - rfbNewClient(rfbScreen,sock); - - return TRUE; + return rfbNewConnectionFromSock(rfbScreen, sock); } |
