Skip to content

Instantly share code, notes, and snippets.

@marktheunissen
Last active March 7, 2017 23:50
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marktheunissen/7ce9426e66aa8f0ec2e1 to your computer and use it in GitHub Desktop.
Save marktheunissen/7ce9426e66aa8f0ec2e1 to your computer and use it in GitHub Desktop.
Stunnel patch for systemd socket activation
diff a/configure.ac b/configure.ac
--- a/configure.ac
+++ b/configure.ac
@@ -478,8 +478,18 @@ if test "$fips" = "auto"; then
])
fi
+# Check for systemd support for socket activation.
+AC_CHECK_LIB(systemd-daemon, sd_notify, SYSTEMD_LIBS="-lsystemd-daemon")
+AC_CHECK_HEADERS(systemd/sd-daemon.h)
+if test "${ac_cv_header_systemd_sd_daemon_h}" = "no" || test -z "${SYSTEMD_LIBS}"; then
+ AC_MSG_NOTICE([Your system does not support systemd.])
+else
+ AC_DEFINE(HAVE_SYSTEMD, 1, [Define if systemd is supported])
+ AC_MSG_NOTICE([systemd detected])
+fi
+
CPPFLAGS="$valid_CPPFLAGS"
-LIBS="$valid_LIBS"
+LIBS="$valid_LIBS $SYSTEMD_LIBS"
AC_MSG_NOTICE([**************************************** write the results])
AC_CONFIG_FILES([Makefile src/Makefile src/stunnel3 doc/Makefile tools/Makefile tools/stunnel.conf-sample tools/stunnel.init tools/stunnel.service])
diff a/src/stunnel.c b/src/stunnel.c
--- a/src/stunnel.c
+++ b/src/stunnel.c
@@ -37,6 +37,9 @@
#include "common.h"
#include "prototypes.h"
+#ifdef HAVE_SYSTEMD
+#include <systemd/sd-daemon.h>
+#endif
/* http://www.openssl.org/support/faq.html#PROG2 */
#ifdef USE_WIN32
@@ -374,6 +377,7 @@ void unbind_ports(void) {
int bind_ports(void) {
SERVICE_OPTIONS *opt;
char *local_address;
+ int systemd_fds;
#ifdef USE_LIBWRAP
/* execute after parse_commandline() to know service_options.next,
@@ -394,8 +398,23 @@ int bind_ports(void) {
for(opt=service_options.next; opt; opt=opt->next) {
if(opt->option.accept) {
- opt->fd=s_socket(opt->local_addr.sa.sa_family,
- SOCK_STREAM, 0, 1, "accept socket");
+ systemd_fds=0;
+#ifdef HAVE_SYSTEMD
+ systemd_fds = sd_listen_fds(0);
+ if(systemd_fds>1) {
+ s_log(LOG_ERR, "Too many file descriptors received from systemd, got %d", systemd_fds);
+ return 1;
+ } else if(systemd_fds==1) {
+ s_log(LOG_INFO, "Received file descriptor from systemd");
+ opt->fd = SD_LISTEN_FDS_START + 0;
+ } else if(systemd_fds<0) {
+ s_log(LOG_ERR, "Error from systemd, code %d", systemd_fds);
+ return 1;
+ }
+#endif
+ if(systemd_fds<1)
+ opt->fd=s_socket(opt->local_addr.sa.sa_family,
+ SOCK_STREAM, 0, 1, "accept socket");
if(opt->fd<0)
return 1;
if(set_socket_options(opt->fd, 0)<0) {
@@ -405,21 +424,24 @@ int bind_ports(void) {
}
/* local socket can't be unnamed */
local_address=s_ntop(&opt->local_addr, addr_len(&opt->local_addr));
- if(bind(opt->fd, &opt->local_addr.sa, addr_len(&opt->local_addr))) {
- s_log(LOG_ERR, "Error binding service [%s] to %s",
- opt->servname, local_address);
- sockerror("bind");
- closesocket(opt->fd);
- opt->fd=-1;
- str_free(local_address);
- return 1;
- }
- if(listen(opt->fd, SOMAXCONN)) {
- sockerror("listen");
- closesocket(opt->fd);
- opt->fd=-1;
- str_free(local_address);
- return 1;
+ /* we don't bind or listen on a socket inherited from systemd */
+ if(systemd_fds<1) {
+ if(bind(opt->fd, &opt->local_addr.sa, addr_len(&opt->local_addr))) {
+ s_log(LOG_ERR, "Error binding service [%s] to %s",
+ opt->servname, local_address);
+ sockerror("bind");
+ closesocket(opt->fd);
+ opt->fd=-1;
+ str_free(local_address);
+ return 1;
+ }
+ if(listen(opt->fd, SOMAXCONN)) {
+ sockerror("listen");
+ closesocket(opt->fd);
+ opt->fd=-1;
+ str_free(local_address);
+ return 1;
+ }
}
s_poll_add(fds, opt->fd, 1, 0);
s_log(LOG_DEBUG, "Service [%s] (FD=%d) bound to %s",
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment