diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 8 | ||||
-rw-r--r-- | src/main.c | 9 | ||||
-rw-r--r-- | src/read_config_lex.l | 1 | ||||
-rw-r--r-- | src/read_config_yy.y | 19 | ||||
-rw-r--r-- | src/run.c | 2 | ||||
-rw-r--r-- | src/systemd.c | 82 |
6 files changed, 120 insertions, 1 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index a1d00f8..607f191 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -58,6 +58,10 @@ if HAVE_CTHELPER conntrackd_SOURCES += cthelper.c helpers.c utils.c expect.c endif +if HAVE_SYSTEMD +conntrackd_SOURCES += systemd.c +endif + # yacc and lex generate dirty code read_config_yy.o read_config_lex.o: AM_CFLAGS += -Wno-missing-prototypes -Wno-missing-declarations -Wno-implicit-function-declaration -Wno-nested-externs -Wno-undef -Wno-redundant-decls @@ -68,6 +72,10 @@ if HAVE_CTHELPER conntrackd_LDADD += ${LIBNETFILTER_CTHELPER_LIBS} ${LIBNETFILTER_QUEUE_LIBS} endif +if HAVE_SYSTEMD +conntrackd_LDADD += ${LIBSYSTEMD_LIBS} +endif + conntrackd_LDFLAGS = -export-dynamic EXTRA_DIST = read_config_yy.h @@ -20,6 +20,7 @@ #include "conntrackd.h" #include "log.h" #include "helper.h" +#include "systemd.h" #include <sys/types.h> #include <sys/stat.h> @@ -403,6 +404,8 @@ int main(int argc, char *argv[]) do_chdir("/"); close(STDIN_FILENO); + sd_ct_watchdog_init(); + /* Daemonize conntrackd */ if (type == DAEMON) { pid_t pid; @@ -410,8 +413,10 @@ int main(int argc, char *argv[]) if ((pid = fork()) == -1) { perror("fork has failed: "); exit(EXIT_FAILURE); - } else if (pid) + } else if (pid) { + sd_ct_mainpid(pid); exit(EXIT_SUCCESS); + } setsid(); @@ -422,6 +427,8 @@ int main(int argc, char *argv[]) } else dlog(LOG_NOTICE, "-- starting in console mode --"); + sd_ct_init(); + /* * run main process */ diff --git a/src/read_config_lex.l b/src/read_config_lex.l index 8350069..2404058 100644 --- a/src/read_config_lex.l +++ b/src/read_config_lex.l @@ -148,6 +148,7 @@ notrack [N|n][O|o][T|t][R|r][A|a][C|c][K|k] "Policy" { return T_HELPER_POLICY; } "ExpectMax" { return T_HELPER_EXPECT_MAX; } "ExpectTimeout" { return T_HELPER_EXPECT_TIMEOUT; } +"Systemd" { return T_SYSTEMD; } {is_on} { return T_ON; } {is_off} { return T_OFF; } diff --git a/src/read_config_yy.y b/src/read_config_yy.y index 73fabbf..58ad2d0 100644 --- a/src/read_config_yy.y +++ b/src/read_config_yy.y @@ -89,6 +89,7 @@ enum { %token T_OPTIONS T_TCP_WINDOW_TRACKING T_EXPECT_SYNC %token T_HELPER T_HELPER_QUEUE_NUM T_HELPER_QUEUE_LEN T_HELPER_POLICY %token T_HELPER_EXPECT_TIMEOUT T_HELPER_EXPECT_MAX +%token T_SYSTEMD %token <string> T_IP T_PATH_VAL %token <val> T_NUMBER @@ -1122,8 +1123,15 @@ general_line: hashsize | netlink_events_reliable | nice | scheduler + | systemd ; +systemd: T_SYSTEMD T_ON { /* already enabled in init_config() */ }; +systemd: T_SYSTEMD T_OFF +{ + conf.systemd = 0; +}; + netlink_buffer_size: T_BUFFER_SIZE T_NUMBER { conf.netlink_buffer_size = $2; @@ -1856,6 +1864,9 @@ init_config(char *filename) CONFIG(stats).syslog_facility = -1; CONFIG(netlink).subsys_id = -1; + /* enable systemd by default */ + CONFIG(systemd) = 1; + /* Initialize list of user-space helpers */ INIT_LIST_HEAD(&CONFIG(cthelper).list); @@ -1865,6 +1876,14 @@ init_config(char *filename) yyparse(); fclose(fp); +#ifndef BUILD_SYSTEMD + if (CONFIG(systemd) == 1) { + print_err(CTD_CFG_WARN, "systemd runtime support activated but" + " conntrackd was built without support" + " for it. Recompile conntrackd"); + } +#endif /* BUILD_SYSTEMD */ + /* set to default is not specified */ if (strcmp(CONFIG(lockfile), "") == 0) strncpy(CONFIG(lockfile), DEFAULT_LOCKFILE, FILENAME_MAXLEN); @@ -30,6 +30,7 @@ #include "origin.h" #include "date.h" #include "internal.h" +#include "systemd.h" #include <errno.h> #include <signal.h> @@ -64,6 +65,7 @@ void killer(int signo) dlog(LOG_NOTICE, "---- shutdown received ----"); close_log(); + sd_ct_stop(); exit(0); } diff --git a/src/systemd.c b/src/systemd.c new file mode 100644 index 0000000..4eb880c --- /dev/null +++ b/src/systemd.c @@ -0,0 +1,82 @@ +/* + * (C) 2015 by Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "systemd.h" +#include "conntrackd.h" +#include "alarm.h" +#include <systemd/sd-daemon.h> +#include <sys/types.h> +#include <unistd.h> +#include <string.h> + +static struct alarm_block sd_watchdog; +static uint64_t sd_watchdog_interval; + +static void sd_ct_watchdog_alarm(struct alarm_block *a, void *data) +{ + sd_notify(0, "WATCHDOG=1"); + add_alarm(&sd_watchdog, 0, sd_watchdog_interval); +} + +void sd_ct_watchdog_init(void) +{ + int ret; + + if (CONFIG(systemd) == 0) + return; + + ret = sd_watchdog_enabled(0, &sd_watchdog_interval); + if (ret < 0) { + fprintf(stderr, "WARNING: failed to get watchdog details from" + " systemd: %s\n", strerror(-ret)); + return; + } else if (ret == 0) { + /* no watchdog required */ + return; + } + + /* from man page, recommended interval is half of set by admin */ + sd_watchdog_interval = sd_watchdog_interval / 2; + + init_alarm(&sd_watchdog, &sd_watchdog_interval, sd_ct_watchdog_alarm); + add_alarm(&sd_watchdog, 0, sd_watchdog_interval); +} + +void sd_ct_init(void) +{ + if (CONFIG(systemd) == 0) + return; + + sd_notify(0, "READY=1"); +} + +void sd_ct_mainpid(pid_t pid) +{ + if (CONFIG(systemd) == 0) + return; + + sd_notifyf(0, "MAINPID=%d", pid); +} + +void sd_ct_stop(void) +{ + if (CONFIG(systemd) == 0) + return; + + sd_notify(0, "STOPPING=1"); +} |