diff options
author | james <james@e7ae566f-a301-0410-adde-c780ea21d3b5> | 2006-11-13 09:31:40 +0000 |
---|---|---|
committer | james <james@e7ae566f-a301-0410-adde-c780ea21d3b5> | 2006-11-13 09:31:40 +0000 |
commit | 2c21891ec156adc304f4012343d75808a1036d0f (patch) | |
tree | bae7dffb6eefb75ee653848bc1926b188eaf917b | |
parent | Backed out AUTO_USERID feature introduced in r1436. (diff) | |
download | openvpn-2c21891ec156adc304f4012343d75808a1036d0f.tar.xz |
Attempt at rational signal handling when in the
management hold state.
During management hold, ignore SIGUSR1/SIGHUP signals
thrown with the "signal" command.
Also, "signal" command will now apply remapping as
specified with the --remap-usr1 option.
When a signal entered using the "signal" command from a management
hold is ignored, output:
>HOLD:Waiting for hold release
git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@1458 e7ae566f-a301-0410-adde-c780ea21d3b5
-rw-r--r-- | init.c | 8 | ||||
-rw-r--r-- | manage.c | 58 | ||||
-rw-r--r-- | manage.h | 9 | ||||
-rw-r--r-- | openvpn.c | 5 |
4 files changed, 69 insertions, 11 deletions
@@ -1225,6 +1225,7 @@ socket_restart_pause (struct context *c) sec = c->persist.restart_sleep_seconds; c->persist.restart_sleep_seconds = 0; + /* do managment hold on context restart, i.e. second, third, fourth, etc. initialization */ if (do_hold (NULL)) sec = 0; @@ -1244,7 +1245,7 @@ do_startup_pause (struct context *c) if (!c->first_time) socket_restart_pause (c); else - do_hold (NULL); + do_hold (NULL); /* do management hold on first context initialization */ } /* @@ -2456,7 +2457,8 @@ open_management (struct context *c) c->options.management_state_buffer_size, c->options.management_hold, c->options.management_client, - c->options.management_write_peer_info_file)) + c->options.management_write_peer_info_file, + c->options.remap_sigusr1)) { management_set_state (management, OPENVPN_STATE_CONNECTING, @@ -2465,7 +2467,7 @@ open_management (struct context *c) (in_addr_t)0); } - /* possible wait */ + /* initial management hold, called early, before first context initialization */ do_hold (c); if (IS_SIG (c)) { @@ -277,14 +277,49 @@ virtual_output_callback_func (void *arg, const unsigned int flags, const char *s } } +/* + * Given a signal, return the signal with possible remapping applied, + * or -1 if the signal should be ignored. + */ +static int +man_mod_signal (const struct management *man, const int signum) +{ + const unsigned int flags = man->settings.mansig; + int s = signum; + if (s == SIGUSR1) + { + if (flags & MANSIG_MAP_USR1_TO_HUP) + s = SIGHUP; + if (flags & MANSIG_MAP_USR1_TO_TERM) + s = SIGTERM; + } + if (flags & MANSIG_IGNORE_USR1_HUP) + { + if (s == SIGHUP || s == SIGUSR1) + s = -1; + } + return s; +} + static void man_signal (struct management *man, const char *name) { const int sig = parse_signal (name); if (sig >= 0) { - throw_signal (sig); - msg (M_CLIENT, "SUCCESS: signal %s thrown", signal_name (sig, true)); + const int sig_mod = man_mod_signal (man, sig); + if (sig_mod >= 0) + { + throw_signal (sig_mod); + msg (M_CLIENT, "SUCCESS: signal %s thrown", signal_name (sig_mod, true)); + } + else + { + if (man->persist.special_state_msg) + msg (M_CLIENT, "%s", man->persist.special_state_msg); + else + msg (M_CLIENT, "ERROR: signal '%s' is currently ignored", name); + } } else { @@ -1276,7 +1311,8 @@ man_settings_init (struct man_settings *ms, const int state_buffer_size, const bool hold, const bool connect_as_client, - const char *write_peer_info_file) + const char *write_peer_info_file, + const int remap_sigusr1) { if (!ms->defined) { @@ -1340,6 +1376,14 @@ man_settings_init (struct man_settings *ms, ms->echo_buffer_size = echo_buffer_size; ms->state_buffer_size = state_buffer_size; + /* + * Set remap sigusr1 flags + */ + if (remap_sigusr1 == SIGHUP) + ms->mansig |= MANSIG_MAP_USR1_TO_HUP; + else if (remap_sigusr1 == SIGTERM) + ms->mansig |= MANSIG_MAP_USR1_TO_TERM; + ms->defined = true; } } @@ -1440,7 +1484,8 @@ management_open (struct management *man, const int state_buffer_size, const bool hold, const bool connect_as_client, - const char *write_peer_info_file) + const char *write_peer_info_file, + const int remap_sigusr1) { bool ret = false; @@ -1459,7 +1504,8 @@ management_open (struct management *man, state_buffer_size, hold, connect_as_client, - write_peer_info_file); + write_peer_info_file, + remap_sigusr1); /* * The log is initially sized to MANAGEMENT_LOG_HISTORY_INITIAL_SIZE, @@ -2052,6 +2098,7 @@ management_hold (struct management *man) man->persist.standalone_disabled = false; /* This is so M_CLIENT messages will be correctly passed through msg() */ man->persist.special_state_msg = NULL; + man->settings.mansig |= MANSIG_IGNORE_USR1_HUP; man_wait_for_client_connection (man, &signal_received, 0, MWCC_HOLD_WAIT); @@ -2072,6 +2119,7 @@ management_hold (struct management *man) /* revert state */ man->persist.standalone_disabled = standalone_disabled_save; man->persist.special_state_msg = NULL; + man->settings.mansig &= ~MANSIG_IGNORE_USR1_HUP; return true; } @@ -207,6 +207,12 @@ struct man_settings { bool hold; bool connect_as_client; char *write_peer_info_file; + +/* flags for handling the management interface "signal" command */ +# define MANSIG_IGNORE_USR1_HUP (1<<0) +# define MANSIG_MAP_USR1_TO_HUP (1<<1) +# define MANSIG_MAP_USR1_TO_TERM (1<<2) + unsigned int mansig; }; /* up_query modes */ @@ -276,7 +282,8 @@ bool management_open (struct management *man, const int state_buffer_size, const bool hold, const bool connect_as_client, - const char *write_peer_info_file); + const char *write_peer_info_file, + const int remap_sigusr1); void management_close (struct management *man); @@ -107,8 +107,6 @@ main (int argc, char *argv[]) return 1; #endif - pre_init_signal_catch (); - CLEAR (c); /* signify first time for components which can @@ -124,6 +122,9 @@ main (int argc, char *argv[]) */ do { + /* enter pre-initialization mode with regard to signal handling */ + pre_init_signal_catch (); + /* zero context struct but leave first_time member alone */ context_clear_all_except_first_time (&c); |