From: Ossama Othman Date: Thu, 3 Oct 2013 22:57:29 +0000 (-0700) Subject: Add support for systemd based socket activation. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=aaeb097e1cc435189d889142f726c15876f923cf;p=profile%2Fivi%2Flibwebsockets.git Add support for systemd based socket activation. Signed-off-by: Ossama Othman --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 3f9ebdc..0188cee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,6 +48,7 @@ option(WITHOUT_DEBUG "Don't compile debug related code" OFF) option(WITHOUT_EXTENSIONS "Don't compile with extensions" OFF) option(WITH_LATENCY "Build latency measuring code into the library" OFF) option(WITHOUT_DAEMONIZE "Don't build the daemonization api" OFF) +option(WITH_SD_DAEMON "Build support for systemd based socket activation" OFF) if (WITHOUT_CLIENT AND WITHOUT_SERVER) message(FATAL_ERROR "Makes no sense to compile without both client or server.") @@ -357,6 +358,19 @@ set(LIB_LIST) # # +# SD_DAEMON (Only needed if systemd socket activation is desired.) +# +if (WITH_SD_DAEMON) + find_package(PkgConfig) + pkg_check_modules(SD_DAEMON REQUIRED libsystemd-daemon) + + include_directories(${SD_DAEMON_INCLUDE_DIRS}) + list(APPEND LIB_LIST ${SD_DAEMON_LIBRARIES}) + add_definitions(${SD_DAEMON_CFLAGS_OTHER}) + add_definitions(-DHAVE_SYSTEMD_DAEMON) +endif() + +# # ZLIB (Only needed for deflate extensions). # if (NOT WITHOUT_EXTENSIONS) diff --git a/configure.ac b/configure.ac index 667cfbf..57866ef 100644 --- a/configure.ac +++ b/configure.ac @@ -19,6 +19,13 @@ AC_PROG_INSTALL AC_PROG_MAKE_SET AC_CONFIG_MACRO_DIR([m4]) +PKG_CHECK_MODULES([SD_DAEMON], + [libsystemd-daemon], + [AC_DEFINE([HAVE_SYSTEMD_DAEMON])], + [AC_MSG_NOTICE([Systemd socket activation won't be enabled])]) +AC_SUBST([SD_DAEMON_LIBS]) +AC_SUBST([SD_DAEMON_CFLAGS]) + applyhash='CFLAGS+= -DLWS_LIBRARY_VERSION=\"$(PACKAGE_VERSION)\" -DLWS_BUILD_HASH=\"${shell git log -n 1 --pretty=%h}\"' AC_SUBST([applyhash]) AM_SUBST_NOTMAKE([applyhash]) diff --git a/lib/Makefile.am b/lib/Makefile.am index e4f9ce0..bd2cb81 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -44,8 +44,9 @@ else dist_libwebsockets_la_SOURCES += sha-1.c endif -libwebsockets_la_CFLAGS=-Wall -std=gnu99 -pedantic +libwebsockets_la_CFLAGS=-Wall -std=gnu99 -pedantic $(SD_DAEMON_CFLAGS) libwebsockets_la_LDFLAGS= +libwebsockets_la_LIBADD=$(SD_DAEMON_LIBS) # uncomment below and use cat ./lib/.libs/*.su | sort -k2g | tac # to get a worst-first list of static stack usage if you have gcc 4.6+ diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c index 0c85f0a..2764dcb 100644 --- a/lib/libwebsockets.c +++ b/lib/libwebsockets.c @@ -37,6 +37,10 @@ #include #endif +#ifdef HAVE_SYSTEMD_DAEMON +#include +#endif /* HAVE_SYSTEMD_DAEMON */ + #ifdef LWS_OPENSSL_SUPPORT int openssl_websocket_private_data_index; #endif @@ -2020,55 +2024,88 @@ libwebsocket_create_context(struct lws_context_creation_info *info) /* set up our external listening socket we serve on */ if (info->port) { - int sockfd; + int sockfd = -1; - sockfd = socket(AF_INET, SOCK_STREAM, 0); - if (sockfd < 0) { - lwsl_err("ERROR opening socket\n"); - goto bail; - } +#ifdef HAVE_SYSTEMD_DAEMON + int nfds, i; -#ifndef WIN32 /* - * allow us to restart even if old sockets in TIME_WAIT - * (REUSEADDR on Unix means, "don't hang on to this - * address after the listener is closed." On Windows, though, - * it means "don't keep other processes from binding to - * this address while we're using it) + * Check if we have a systemd activated socket we can + * use. Otherwise explicitly create the socket. */ - setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, + nfds = sd_listen_fds(0); + for (i = 0; i < nfds; ++i) { + int const fd = SD_LISTEN_FDS_START + i; + + if (sd_is_socket_inet(fd, + AF_INET, + SOCK_STREAM, + 1, // check if in accepting mode + info->port)) { + sockfd = fd; + lwsl_notice(" Systemd socket activation " + "succeeded.\n" + " Listening on port " + "%d\n", info->port); + break; + } + } + + if (sockfd == -1) { +#endif /* HAVE_SYSTEMD_DAEMON */ + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd < 0) { + lwsl_err("ERROR opening socket\n"); + goto bail; + } + +#ifndef WIN32 + /* + * allow us to restart even if old sockets in TIME_WAIT + * (REUSEADDR on Unix means, "don't hang on to this + * address after the listener is closed." On Windows, though, + * it means "don't keep other processes from binding to + * this address while we're using it) + */ + setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const void *)&opt, sizeof(opt)); #endif - /* Disable Nagle */ - opt = 1; - setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, + /* Disable Nagle */ + opt = 1; + setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (const void *)&opt, sizeof(opt)); - #ifdef WIN32 - opt = 0; - ioctlsocket(sockfd, FIONBIO, (unsigned long *)&opt); - #else - fcntl(sockfd, F_SETFL, O_NONBLOCK); - #endif - - bzero((char *) &serv_addr, sizeof(serv_addr)); - serv_addr.sin_family = AF_INET; - if (info->iface == NULL) - serv_addr.sin_addr.s_addr = INADDR_ANY; - else - interface_to_sa(info->iface, &serv_addr, + #ifdef WIN32 + opt = 0; + ioctlsocket(sockfd, FIONBIO, (unsigned long *)&opt); + #else + fcntl(sockfd, F_SETFL, O_NONBLOCK); + #endif + + bzero((char *) &serv_addr, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + if (info->iface == NULL) + serv_addr.sin_addr.s_addr = INADDR_ANY; + else + interface_to_sa(info->iface, &serv_addr, sizeof(serv_addr)); - serv_addr.sin_port = htons(info->port); + serv_addr.sin_port = htons(info->port); - n = bind(sockfd, (struct sockaddr *) &serv_addr, + n = bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); - if (n < 0) { - lwsl_err("ERROR on binding to port %d (%d %d)\n", + if (n < 0) { + lwsl_err("ERROR on binding to port %d (%d %d)\n", info->port, n, errno); - close(sockfd); - goto bail; + close(sockfd); + goto bail; + } + + listen(sockfd, LWS_SOMAXCONN); + lwsl_notice(" Listening on port %d\n", info->port); +#ifdef HAVE_SYSTEMD_DAEMON } +#endif /* HAVE_SYSTEMD_DAEMON */ wsi = (struct libwebsocket *)malloc( sizeof(struct libwebsocket)); @@ -2089,10 +2126,8 @@ libwebsocket_create_context(struct lws_context_creation_info *info) context->listen_service_modulo = LWS_LISTEN_SERVICE_MODULO; context->listen_service_count = 0; context->listen_service_fd = sockfd; - - listen(sockfd, LWS_SOMAXCONN); - lwsl_notice(" Listening on port %d\n", info->port); } + #endif /* diff --git a/packaging/libwebsockets.spec b/packaging/libwebsockets.spec index 8f90a0a..fbfbe26 100644 --- a/packaging/libwebsockets.spec +++ b/packaging/libwebsockets.spec @@ -11,6 +11,7 @@ Requires(postun): /sbin/ldconfig BuildRequires: zlib-devel BuildRequires: openssl-devel BuildRequires: cmake +BuildRequires: pkgconfig(libsystemd-daemon) %description C Websockets Server Library @@ -28,7 +29,7 @@ Development files needed for building websocket clients and servers %build -%cmake -DWITH_SSL=On +%cmake -DWITH_SSL=On -DWITH_SD_DAEMON=ON make %{?jobs:-j%jobs}