summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>2006-11-13 09:31:40 +0000
committerjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>2006-11-13 09:31:40 +0000
commit2c21891ec156adc304f4012343d75808a1036d0f (patch)
treebae7dffb6eefb75ee653848bc1926b188eaf917b
parent1f99578ce98947170a8f3809e8d77cb2d4b9a4f4 (diff)
downloadopenvpn-2c21891ec156adc304f4012343d75808a1036d0f.tar.gz
openvpn-2c21891ec156adc304f4012343d75808a1036d0f.tar.xz
openvpn-2c21891ec156adc304f4012343d75808a1036d0f.zip
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.c8
-rw-r--r--manage.c58
-rw-r--r--manage.h9
-rw-r--r--openvpn.c5
4 files changed, 69 insertions, 11 deletions
diff --git a/init.c b/init.c
index 2eb1896..244f03c 100644
--- a/init.c
+++ b/init.c
@@ -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))
{
diff --git a/manage.c b/manage.c
index 1c28485..993afa2 100644
--- a/manage.c
+++ b/manage.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;
}
diff --git a/manage.h b/manage.h
index c7cce07..445f710 100644
--- a/manage.h
+++ b/manage.h
@@ -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);
diff --git a/openvpn.c b/openvpn.c
index cb6af50..66ade22 100644
--- a/openvpn.c
+++ b/openvpn.c
@@ -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);