Support systemd socket activation

pull/1/head
Kyle Russell 8 years ago
parent 1f8c443cbc
commit 21fd4d27bb

@ -36,6 +36,7 @@ find_package(GnuTLS)
find_package(Threads)
find_package(X11)
find_package(OpenSSL)
find_package(PkgConfig)
find_library(LIBGCRYPT_LIBRARIES gcrypt)
# Check whether the version of libjpeg we found was libjpeg-turbo and print a
@ -102,6 +103,17 @@ if(PNG_FOUND)
endif(PNG_FOUND)
option(LIBVNCSERVER_ALLOW24BPP "Allow 24 bpp" ON)
pkg_check_modules(SYSTEMD "libsystemd")
if(SYSTEMD_FOUND)
option(LIBVNCSERVER_WITH_SYSTEMD "Build with systemd socket activation support" ON)
endif(SYSTEMD_FOUND)
if(LIBVNCSERVER_WITH_SYSTEMD)
add_definitions(-DLIBVNCSERVER_WITH_SYSTEMD)
include_directories(${SYSTEMD_INCLUDE_DIRS})
set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} ${SYSTEMD_LIBRARIES})
endif(LIBVNCSERVER_WITH_SYSTEMD)
if(GNUTLS_FOUND)
set(LIBVNCSERVER_WITH_CLIENT_TLS 1)
option(LIBVNCSERVER_WITH_WEBSOCKETS "Build with websockets support (gnutls)" ON)

@ -68,6 +68,9 @@ if test ! -z "$with_ffmpeg"; then
fi
AM_CONDITIONAL(HAVE_MP3LAME, test "$HAVE_MP3LAME" = "true")
PKG_CHECK_MODULES([LIBSYSTEMD], [libsystemd], [with_systemd=1], [with_systemd=0])
AM_CONDITIONAL([WITH_SYSTEMD], [test $with_systemd -eq 1])
# Seem to need this dummy here to induce the 'checking for egrep... grep -E', etc.
# before it seemed to be inside the with_jpeg conditional.
AC_CHECK_HEADER(thenonexistentheader.h, HAVE_THENONEXISTENTHEADER_H="true")

@ -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

@ -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;
@ -411,14 +477,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;
@ -439,47 +498,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);
}

Loading…
Cancel
Save