diff options
Diffstat (limited to 'src/openvpn/sig.c')
-rw-r--r-- | src/openvpn/sig.c | 454 |
1 files changed, 243 insertions, 211 deletions
diff --git a/src/openvpn/sig.c b/src/openvpn/sig.c index b3ae645..9f4841a 100644 --- a/src/openvpn/sig.c +++ b/src/openvpn/sig.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -47,164 +47,182 @@ struct signal_info siginfo_static; /* GLOBAL */ struct signame { - int value; - const char *upper; - const char *lower; + int value; + const char *upper; + const char *lower; }; static const struct signame signames[] = { - { SIGINT, "SIGINT", "sigint"}, - { SIGTERM, "SIGTERM", "sigterm" }, - { SIGHUP, "SIGHUP", "sighup" }, - { SIGUSR1, "SIGUSR1", "sigusr1" }, - { SIGUSR2, "SIGUSR2", "sigusr2" } + { SIGINT, "SIGINT", "sigint"}, + { SIGTERM, "SIGTERM", "sigterm" }, + { SIGHUP, "SIGHUP", "sighup" }, + { SIGUSR1, "SIGUSR1", "sigusr1" }, + { SIGUSR2, "SIGUSR2", "sigusr2" } }; int -parse_signal (const char *signame) +parse_signal(const char *signame) { - int i; - for (i = 0; i < (int)SIZE (signames); ++i) + int i; + for (i = 0; i < (int)SIZE(signames); ++i) { - if (!strcmp (signame, signames[i].upper)) - return signames[i].value; + if (!strcmp(signame, signames[i].upper)) + { + return signames[i].value; + } } - return -1; + return -1; } const char * -signal_name (const int sig, const bool upper) +signal_name(const int sig, const bool upper) { - int i; - for (i = 0; i < (int)SIZE (signames); ++i) + int i; + for (i = 0; i < (int)SIZE(signames); ++i) { - if (sig == signames[i].value) - return upper ? signames[i].upper : signames[i].lower; + if (sig == signames[i].value) + { + return upper ? signames[i].upper : signames[i].lower; + } } - return "UNKNOWN"; + return "UNKNOWN"; } const char * -signal_description (const int signum, const char *sigtext) +signal_description(const int signum, const char *sigtext) { - if (sigtext) - return sigtext; - else - return signal_name (signum, false); + if (sigtext) + { + return sigtext; + } + else + { + return signal_name(signum, false); + } } void -throw_signal (const int signum) +throw_signal(const int signum) { - siginfo_static.signal_received = signum; - siginfo_static.source = SIG_SOURCE_HARD; + siginfo_static.signal_received = signum; + siginfo_static.source = SIG_SOURCE_HARD; } void -throw_signal_soft (const int signum, const char *signal_text) +throw_signal_soft(const int signum, const char *signal_text) { - siginfo_static.signal_received = signum; - siginfo_static.source = SIG_SOURCE_SOFT; - siginfo_static.signal_text = signal_text; + siginfo_static.signal_received = signum; + siginfo_static.source = SIG_SOURCE_SOFT; + siginfo_static.signal_text = signal_text; } static void -signal_reset (struct signal_info *si) +signal_reset(struct signal_info *si) { - if (si) + if (si) { - si->signal_received = 0; - si->signal_text = NULL; - si->source = SIG_SOURCE_SOFT; + si->signal_received = 0; + si->signal_text = NULL; + si->source = SIG_SOURCE_SOFT; } } void -print_signal (const struct signal_info *si, const char *title, int msglevel) +print_signal(const struct signal_info *si, const char *title, int msglevel) { - if (si) + if (si) { - const char *type = (si->signal_text ? si->signal_text : ""); - const char *t = (title ? title : "process"); - const char *hs = NULL; - switch (si->source) + const char *type = (si->signal_text ? si->signal_text : ""); + const char *t = (title ? title : "process"); + const char *hs = NULL; + switch (si->source) { - case SIG_SOURCE_SOFT: - hs= "soft"; - break; - case SIG_SOURCE_HARD: - hs = "hard"; - break; - case SIG_SOURCE_CONNECTION_FAILED: - hs = "connection failed(soft)"; - break; - default: - ASSERT(0); + case SIG_SOURCE_SOFT: + hs = "soft"; + break; + + case SIG_SOURCE_HARD: + hs = "hard"; + break; + + case SIG_SOURCE_CONNECTION_FAILED: + hs = "connection failed(soft)"; + break; + + default: + ASSERT(0); } - switch (si->signal_received) - { - case SIGINT: - case SIGTERM: - msg (msglevel, "%s[%s,%s] received, %s exiting", - signal_name (si->signal_received, true), hs, type, t); - break; - case SIGHUP: - case SIGUSR1: - msg (msglevel, "%s[%s,%s] received, %s restarting", - signal_name (si->signal_received, true), hs, type, t); - break; - default: - msg (msglevel, "Unknown signal %d [%s,%s] received by %s", si->signal_received, hs, type, t); - break; - } + switch (si->signal_received) + { + case SIGINT: + case SIGTERM: + msg(msglevel, "%s[%s,%s] received, %s exiting", + signal_name(si->signal_received, true), hs, type, t); + break; + + case SIGHUP: + case SIGUSR1: + msg(msglevel, "%s[%s,%s] received, %s restarting", + signal_name(si->signal_received, true), hs, type, t); + break; + + default: + msg(msglevel, "Unknown signal %d [%s,%s] received by %s", si->signal_received, hs, type, t); + break; + } + } + else + { + msg(msglevel, "Unknown signal received"); } - else - msg (msglevel, "Unknown signal received"); } /* * Call management interface with restart info */ void -signal_restart_status (const struct signal_info *si) +signal_restart_status(const struct signal_info *si) { #ifdef ENABLE_MANAGEMENT - if (management) + if (management) { - int state = -1; - switch (si->signal_received) - { - case SIGINT: - case SIGTERM: - state = OPENVPN_STATE_EXITING; - break; - case SIGHUP: - case SIGUSR1: - state = OPENVPN_STATE_RECONNECTING; - break; - } - - if (state >= 0) - management_set_state (management, - state, - si->signal_text ? si->signal_text : signal_name (si->signal_received, true), - NULL, - NULL, - NULL, - NULL); + int state = -1; + switch (si->signal_received) + { + case SIGINT: + case SIGTERM: + state = OPENVPN_STATE_EXITING; + break; + + case SIGHUP: + case SIGUSR1: + state = OPENVPN_STATE_RECONNECTING; + break; + } + + if (state >= 0) + { + management_set_state(management, + state, + si->signal_text ? si->signal_text : signal_name(si->signal_received, true), + NULL, + NULL, + NULL, + NULL); + } } -#endif +#endif /* ifdef ENABLE_MANAGEMENT */ } #ifdef HAVE_SIGNAL_H /* normal signal handler, when we are in event loop */ static void -signal_handler (const int signum) +signal_handler(const int signum) { - throw_signal (signum); - signal (signum, signal_handler); + throw_signal(signum); + signal(signum, signal_handler); } #endif @@ -219,46 +237,50 @@ static int signal_mode; /* GLOBAL */ #endif void -pre_init_signal_catch (void) +pre_init_signal_catch(void) { #ifndef _WIN32 #ifdef HAVE_SIGNAL_H - signal_mode = SM_PRE_INIT; - signal (SIGINT, signal_handler); - signal (SIGTERM, signal_handler); - signal (SIGHUP, SIG_IGN); - signal (SIGUSR1, SIG_IGN); - signal (SIGUSR2, SIG_IGN); - signal (SIGPIPE, SIG_IGN); + signal_mode = SM_PRE_INIT; + signal(SIGINT, signal_handler); + signal(SIGTERM, signal_handler); + signal(SIGHUP, SIG_IGN); + signal(SIGUSR1, SIG_IGN); + signal(SIGUSR2, SIG_IGN); + signal(SIGPIPE, SIG_IGN); #endif /* HAVE_SIGNAL_H */ #endif /* _WIN32 */ } void -post_init_signal_catch (void) +post_init_signal_catch(void) { #ifndef _WIN32 #ifdef HAVE_SIGNAL_H - signal_mode = SM_POST_INIT; - signal (SIGINT, signal_handler); - signal (SIGTERM, signal_handler); - signal (SIGHUP, signal_handler); - signal (SIGUSR1, signal_handler); - signal (SIGUSR2, signal_handler); - signal (SIGPIPE, SIG_IGN); + signal_mode = SM_POST_INIT; + signal(SIGINT, signal_handler); + signal(SIGTERM, signal_handler); + signal(SIGHUP, signal_handler); + signal(SIGUSR1, signal_handler); + signal(SIGUSR2, signal_handler); + signal(SIGPIPE, SIG_IGN); #endif /* HAVE_SIGNAL_H */ #endif } /* called after daemonization to retain signal settings */ void -restore_signal_state (void) +restore_signal_state(void) { #ifdef HAVE_SIGNAL_H - if (signal_mode == SM_PRE_INIT) - pre_init_signal_catch (); - else if (signal_mode == SM_POST_INIT) - post_init_signal_catch (); + if (signal_mode == SM_PRE_INIT) + { + pre_init_signal_catch(); + } + else if (signal_mode == SM_POST_INIT) + { + post_init_signal_catch(); + } #endif } @@ -268,38 +290,42 @@ restore_signal_state (void) * Triggered by SIGUSR2 or F2 on Windows. */ void -print_status (const struct context *c, struct status_output *so) +print_status(const struct context *c, struct status_output *so) { - struct gc_arena gc = gc_new (); + struct gc_arena gc = gc_new(); - status_reset (so); + status_reset(so); - status_printf (so, "OpenVPN STATISTICS"); - status_printf (so, "Updated,%s", time_string (0, 0, false, &gc)); - status_printf (so, "TUN/TAP read bytes," counter_format, c->c2.tun_read_bytes); - status_printf (so, "TUN/TAP write bytes," counter_format, c->c2.tun_write_bytes); - status_printf (so, "TCP/UDP read bytes," counter_format, c->c2.link_read_bytes); - status_printf (so, "TCP/UDP write bytes," counter_format, c->c2.link_write_bytes); - status_printf (so, "Auth read bytes," counter_format, c->c2.link_read_bytes_auth); + status_printf(so, "OpenVPN STATISTICS"); + status_printf(so, "Updated,%s", time_string(0, 0, false, &gc)); + status_printf(so, "TUN/TAP read bytes," counter_format, c->c2.tun_read_bytes); + status_printf(so, "TUN/TAP write bytes," counter_format, c->c2.tun_write_bytes); + status_printf(so, "TCP/UDP read bytes," counter_format, c->c2.link_read_bytes); + status_printf(so, "TCP/UDP write bytes," counter_format, c->c2.link_write_bytes); + status_printf(so, "Auth read bytes," counter_format, c->c2.link_read_bytes_auth); #ifdef USE_COMP - if (c->c2.comp_context) - comp_print_stats (c->c2.comp_context, so); + if (c->c2.comp_context) + { + comp_print_stats(c->c2.comp_context, so); + } #endif #ifdef PACKET_TRUNCATION_CHECK - status_printf (so, "TUN read truncations," counter_format, c->c2.n_trunc_tun_read); - status_printf (so, "TUN write truncations," counter_format, c->c2.n_trunc_tun_write); - status_printf (so, "Pre-encrypt truncations," counter_format, c->c2.n_trunc_pre_encrypt); - status_printf (so, "Post-decrypt truncations," counter_format, c->c2.n_trunc_post_decrypt); + status_printf(so, "TUN read truncations," counter_format, c->c2.n_trunc_tun_read); + status_printf(so, "TUN write truncations," counter_format, c->c2.n_trunc_tun_write); + status_printf(so, "Pre-encrypt truncations," counter_format, c->c2.n_trunc_pre_encrypt); + status_printf(so, "Post-decrypt truncations," counter_format, c->c2.n_trunc_post_decrypt); #endif #ifdef _WIN32 - if (tuntap_defined (c->c1.tuntap)) - status_printf (so, "TAP-WIN32 driver status,\"%s\"", - tap_win_getinfo (c->c1.tuntap, &gc)); + if (tuntap_defined(c->c1.tuntap)) + { + status_printf(so, "TAP-WIN32 driver status,\"%s\"", + tap_win_getinfo(c->c1.tuntap, &gc)); + } #endif - status_printf (so, "END"); - status_flush (so); - gc_free (&gc); + status_printf(so, "END"); + status_flush(so); + gc_free(&gc); } #ifdef ENABLE_OCC @@ -309,71 +335,73 @@ print_status (const struct context *c, struct status_output *so) */ static void -process_explicit_exit_notification_init (struct context *c) +process_explicit_exit_notification_init(struct context *c) { - msg (M_INFO, "SIGTERM received, sending exit notification to peer"); - event_timeout_init (&c->c2.explicit_exit_notification_interval, 1, 0); - reset_coarse_timers (c); - signal_reset (c->sig); - halt_non_edge_triggered_signals (); - c->c2.explicit_exit_notification_time_wait = now; + msg(M_INFO, "SIGTERM received, sending exit notification to peer"); + event_timeout_init(&c->c2.explicit_exit_notification_interval, 1, 0); + reset_coarse_timers(c); + signal_reset(c->sig); + halt_non_edge_triggered_signals(); + c->c2.explicit_exit_notification_time_wait = now; } void -process_explicit_exit_notification_timer_wakeup (struct context *c) +process_explicit_exit_notification_timer_wakeup(struct context *c) { - if (event_timeout_trigger (&c->c2.explicit_exit_notification_interval, - &c->c2.timeval, - ETT_DEFAULT)) + if (event_timeout_trigger(&c->c2.explicit_exit_notification_interval, + &c->c2.timeval, + ETT_DEFAULT)) { - ASSERT (c->c2.explicit_exit_notification_time_wait && c->options.ce.explicit_exit_notification); - if (now >= c->c2.explicit_exit_notification_time_wait + c->options.ce.explicit_exit_notification) - { - event_timeout_clear (&c->c2.explicit_exit_notification_interval); - c->sig->signal_received = SIGTERM; - c->sig->signal_text = "exit-with-notification"; - } - else - { - c->c2.occ_op = OCC_EXIT; - } + ASSERT(c->c2.explicit_exit_notification_time_wait && c->options.ce.explicit_exit_notification); + if (now >= c->c2.explicit_exit_notification_time_wait + c->options.ce.explicit_exit_notification) + { + event_timeout_clear(&c->c2.explicit_exit_notification_interval); + c->sig->signal_received = SIGTERM; + c->sig->signal_text = "exit-with-notification"; + } + else + { + c->c2.occ_op = OCC_EXIT; + } } } -#endif +#endif /* ifdef ENABLE_OCC */ /* * Process signals */ void -remap_signal (struct context *c) +remap_signal(struct context *c) { - if (c->sig->signal_received == SIGUSR1 && c->options.remap_sigusr1) - c->sig->signal_received = c->options.remap_sigusr1; + if (c->sig->signal_received == SIGUSR1 && c->options.remap_sigusr1) + { + c->sig->signal_received = c->options.remap_sigusr1; + } } static void -process_sigusr2 (const struct context *c) +process_sigusr2(const struct context *c) { - struct status_output *so = status_open (NULL, 0, M_INFO, NULL, 0); - print_status (c, so); - status_close (so); - signal_reset (c->sig); + struct status_output *so = status_open(NULL, 0, M_INFO, NULL, 0); + print_status(c, so); + status_close(so); + signal_reset(c->sig); } static bool -process_sigterm (struct context *c) +process_sigterm(struct context *c) { - bool ret = true; + bool ret = true; #ifdef ENABLE_OCC - if (c->options.ce.explicit_exit_notification - && !c->c2.explicit_exit_notification_time_wait) + if (c->options.ce.explicit_exit_notification + && !c->c2.explicit_exit_notification_time_wait) { - process_explicit_exit_notification_init (c); - ret = false; + process_explicit_exit_notification_init(c); + ret = false; } #endif - return ret; + return ret; } /** @@ -382,55 +410,59 @@ process_sigterm (struct context *c) * which implies the loop cannot continue, remap to SIGTERM to exit promptly. */ static bool -ignore_restart_signals (struct context *c) +ignore_restart_signals(struct context *c) { - bool ret = false; + bool ret = false; #ifdef ENABLE_OCC - if ( (c->sig->signal_received == SIGUSR1 || c->sig->signal_received == SIGHUP) && - event_timeout_defined(&c->c2.explicit_exit_notification_interval) ) + if ( (c->sig->signal_received == SIGUSR1 || c->sig->signal_received == SIGHUP) + && event_timeout_defined(&c->c2.explicit_exit_notification_interval) ) { - if (c->sig->source == SIG_SOURCE_HARD) - { - msg (M_INFO, "Ignoring %s received during exit notification", - signal_name(c->sig->signal_received, true)); - signal_reset (c->sig); + if (c->sig->source == SIG_SOURCE_HARD) + { + msg(M_INFO, "Ignoring %s received during exit notification", + signal_name(c->sig->signal_received, true)); + signal_reset(c->sig); ret = true; - } - else - { - msg (M_INFO, "Converting soft %s received during exit notification to SIGTERM", - signal_name(c->sig->signal_received, true)); + } + else + { + msg(M_INFO, "Converting soft %s received during exit notification to SIGTERM", + signal_name(c->sig->signal_received, true)); register_signal(c, SIGTERM, "exit-with-notification"); ret = false; - } + } } #endif - return ret; + return ret; } bool -process_signal (struct context *c) +process_signal(struct context *c) { - bool ret = true; + bool ret = true; - if (ignore_restart_signals (c)) - ret = false; - else if (c->sig->signal_received == SIGTERM || c->sig->signal_received == SIGINT) + if (ignore_restart_signals(c)) + { + ret = false; + } + else if (c->sig->signal_received == SIGTERM || c->sig->signal_received == SIGINT) { - ret = process_sigterm (c); + ret = process_sigterm(c); } - else if (c->sig->signal_received == SIGUSR2) + else if (c->sig->signal_received == SIGUSR2) { - process_sigusr2 (c); - ret = false; + process_sigusr2(c); + ret = false; } - return ret; + return ret; } void -register_signal (struct context *c, int sig, const char *text) +register_signal(struct context *c, int sig, const char *text) { - if (c->sig->signal_received != SIGTERM) - c->sig->signal_received = sig; - c->sig->signal_text = text; + if (c->sig->signal_received != SIGTERM) + { + c->sig->signal_received = sig; + } + c->sig->signal_text = text; } |