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;
if (!c->first_time)
socket_restart_pause (c);
else
- do_hold (NULL);
+ do_hold (NULL); /* do management hold on first context initialization */
}
/*
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,
(in_addr_t)0);
}
- /* possible wait */
+ /* initial management hold, called early, before first context initialization */
do_hold (c);
if (IS_SIG (c))
{
}
}
+/*
+ * 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
{
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)
{
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;
}
}
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;
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,
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);
/* revert state */
man->persist.standalone_disabled = standalone_disabled_save;
man->persist.special_state_msg = NULL;
+ man->settings.mansig &= ~MANSIG_IGNORE_USR1_HUP;
return true;
}
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 */
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);