aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2012-05-31 15:53:47 +0200
committerTobias Brunner <tobias@strongswan.org>2012-06-04 18:09:56 +0200
commit89c97952bda75c2aca8a46614b90c7b07614372f (patch)
tree69c50dd88a76c12167ac58a44cd5cd9a4742db12 /src
parentc8f7a114b6b47e12bf411b2b2080bc4c41e01ae3 (diff)
downloadstrongswan-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.am2
-rw-r--r--src/starter/starter.c70
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 (;;)
{
/*