diff options
author | Tobias Brunner <tobias@strongswan.org> | 2012-05-31 15:53:47 +0200 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2012-06-04 18:09:56 +0200 |
commit | 89c97952bda75c2aca8a46614b90c7b07614372f (patch) | |
tree | 69c50dd88a76c12167ac58a44cd5cd9a4742db12 /src | |
parent | c8f7a114b6b47e12bf411b2b2080bc4c41e01ae3 (diff) | |
download | strongswan-89c97952bda75c2aca8a46614b90c7b07614372f.tar.bz2 strongswan-89c97952bda75c2aca8a46614b90c7b07614372f.tar.xz |
starter: Changed signal handling now that starter is multi-threaded.
Diffstat (limited to 'src')
-rw-r--r-- | src/starter/Makefile.am | 2 | ||||
-rw-r--r-- | src/starter/starter.c | 70 |
2 files changed, 57 insertions, 15 deletions
diff --git a/src/starter/Makefile.am b/src/starter/Makefile.am index 94ddf5aba..884f6e2ab 100644 --- a/src/starter/Makefile.am +++ b/src/starter/Makefile.am @@ -27,7 +27,7 @@ AM_CFLAGS = \ AM_YFLAGS = -v -d -starter_LDADD = defs.o $(top_builddir)/src/libfreeswan/libfreeswan.a $(top_builddir)/src/libstrongswan/libstrongswan.la $(top_builddir)/src/libhydra/libhydra.la $(SOCKLIB) +starter_LDADD = defs.o $(top_builddir)/src/libfreeswan/libfreeswan.a $(top_builddir)/src/libstrongswan/libstrongswan.la $(top_builddir)/src/libhydra/libhydra.la $(SOCKLIB) $(PTHREADLIB) EXTRA_DIST = keywords.txt ipsec.conf Android.mk MAINTAINERCLEANFILES = keywords.c BUILT_SOURCES = parser.h diff --git a/src/starter/starter.c b/src/starter/starter.c index abc3dd7c7..fb44cad26 100644 --- a/src/starter/starter.c +++ b/src/starter/starter.c @@ -26,10 +26,13 @@ #include <fcntl.h> #include <pwd.h> #include <grp.h> +#include <pthread.h> #include <freeswan.h> #include <library.h> #include <hydra.h> +#include <utils/backtrace.h> +#include <threading/thread.h> #include "../pluto/constants.h" #include "../pluto/defs.h" @@ -73,7 +76,10 @@ static unsigned int _action_ = 0; -static void fsig(int signal) +/** + * Handle signals in the main thread + */ +static void signal_handler(int signal) { switch (signal) { @@ -137,10 +143,6 @@ static void fsig(int signal) } break; - case SIGPIPE: - /** ignore **/ - break; - case SIGALRM: _action_ |= FLAG_ACTION_START_PLUTO; _action_ |= FLAG_ACTION_START_CHARON; @@ -167,6 +169,22 @@ static void fsig(int signal) } } +/** + * Handle fatal signals raised by threads + */ +static void fatal_signal_handler(int signal) +{ + backtrace_t *backtrace; + + plog("thread %u received %d", thread_current_id(), signal); + backtrace = backtrace_create(2); + backtrace->log(backtrace, stderr, TRUE); + backtrace->destroy(backtrace); + + plog("killing ourself, received critical signal"); + abort(); +} + #ifdef GENERATE_SELFCERT static void generate_selfcert() { @@ -269,6 +287,7 @@ int main (int argc, char **argv) starter_conn_t *conn, *conn2; starter_ca_t *ca, *ca2; + struct sigaction action; struct stat stb; int i; @@ -330,15 +349,6 @@ int main (int argc, char **argv) init_log("ipsec_starter"); cur_debugging = base_debugging; - signal(SIGHUP, fsig); - signal(SIGCHLD, fsig); - signal(SIGPIPE, fsig); - signal(SIGINT, fsig); - signal(SIGTERM, fsig); - signal(SIGQUIT, fsig); - signal(SIGALRM, fsig); - signal(SIGUSR1, fsig); - plog("Starting strongSwan "VERSION" IPsec [starter]..."); #ifdef LOAD_WARNING @@ -480,11 +490,43 @@ int main (int argc, char **argv) { exit(LSB_RC_FAILURE); } + + /* we handle these signals in the main thread, so we don't want any + * of the others to catch them. install a handler for fatal signals. */ + memset(&action, 0, sizeof(action)); + sigemptyset(&action.sa_mask); + sigaddset(&action.sa_mask, SIGHUP); + sigaddset(&action.sa_mask, SIGINT); + sigaddset(&action.sa_mask, SIGTERM); + sigaddset(&action.sa_mask, SIGQUIT); + sigaddset(&action.sa_mask, SIGALRM); + sigaddset(&action.sa_mask, SIGCHLD); + sigaddset(&action.sa_mask, SIGUSR1); + pthread_sigmask(SIG_SETMASK, &action.sa_mask, NULL); + + action.sa_handler = fatal_signal_handler; + sigaction(SIGSEGV, &action, NULL); + sigaction(SIGILL, &action, NULL); + sigaction(SIGBUS, &action, NULL); + action.sa_handler = SIG_IGN; + sigaction(SIGPIPE, &action, NULL); + /* we need threads to read events from the kernel */ lib->processor->set_threads(lib->processor, lib->settings->get_int(lib->settings, "starter.threads", DEFAULT_THREADS)); + /* enable signals for main thread and install signal handler */ + pthread_sigmask(SIG_UNBLOCK, &action.sa_mask, NULL); + action.sa_handler = signal_handler; + sigaction(SIGHUP, &action, NULL); + sigaction(SIGINT, &action, NULL); + sigaction(SIGTERM, &action, NULL); + sigaction(SIGQUIT, &action, NULL); + sigaction(SIGALRM, &action, NULL); + sigaction(SIGCHLD, &action, NULL); + sigaction(SIGUSR1, &action, NULL); + for (;;) { /* |