0
0
mirror of https://github.com/OpenVPN/openvpn.git synced 2024-09-20 12:02:28 +02:00

Assign and honour signal priority order

Signals are ordered as SIGUSR2, SIGUSR1, SIGHUP, SIGTERM, SIGINT
in increasing priority. Lower priority signals are not allowed to
overwrite higher ones.

This should fix Trac #311, #639 -- SIGTER/SIGINT lost during dns
resolution (except for the Windows-specific bug handled in previous commit).

On sending SIGTERM during dns resolution, it still takes several seconds
to terminate as the signal will get processed only after getaddrinfo times
out twice (in phase1 and phase2 inits).

Github: fixes OpenVPN/openvpn#205
Trac: #311, #639

Note: one has to still wait for address resolution to time out as
getaddrinfo() is no interruptible. But a single ctrl-C (and some
patience) is enough.

Signed-off-by: Selva Nair <selva.nair@gmail.com>
Acked-by: Arne Schwabe <arne@rfc2549.org>
Message-Id: <20230101215109.1521549-4-selva.nair@gmail.com>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg25871.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
This commit is contained in:
Selva Nair 2023-01-01 16:51:07 -05:00 committed by Gert Doering
parent 22977577ed
commit 3a72579257
4 changed files with 44 additions and 28 deletions

View File

@ -1080,10 +1080,7 @@ done:
return ret;
error:
if (!sig_info->signal_received)
{
register_signal(sig_info, SIGUSR1, "HTTP proxy error"); /* SOFT-SIGUSR1 -- HTTP proxy error */
}
gc_free(&gc);
return ret;
}

View File

@ -47,16 +47,17 @@ struct signal_info siginfo_static; /* GLOBAL */
struct signame {
int value;
int priority;
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, 5, "SIGINT", "sigint"},
{ SIGTERM, 4, "SIGTERM", "sigterm" },
{ SIGHUP, 3, "SIGHUP", "sighup" },
{ SIGUSR1, 2, "SIGUSR1", "sigusr1" },
{ SIGUSR2, 1, "SIGUSR2", "sigusr2" }
};
int
@ -73,6 +74,19 @@ parse_signal(const char *signame)
return -1;
}
static int
signal_priority(int sig)
{
for (size_t i = 0; i < SIZE(signames); ++i)
{
if (sig == signames[i].value)
{
return signames[i].priority;
}
}
return -1;
}
const char *
signal_name(const int sig, const bool upper)
{
@ -103,16 +117,22 @@ signal_description(const int signum, const char *sigtext)
void
throw_signal(const int signum)
{
if (signal_priority(signum) >= signal_priority(siginfo_static.signal_received))
{
siginfo_static.signal_received = signum;
siginfo_static.source = SIG_SOURCE_HARD;
}
}
void
throw_signal_soft(const int signum, const char *signal_text)
{
if (signal_priority(signum) >= signal_priority(siginfo_static.signal_received))
{
siginfo_static.signal_received = signum;
siginfo_static.source = SIG_SOURCE_SOFT;
siginfo_static.signal_text = signal_text;
}
}
void
@ -472,9 +492,10 @@ process_signal(struct context *c)
void
register_signal(struct signal_info *si, int sig, const char *text)
{
if (si->signal_received != SIGTERM)
if (signal_priority(sig) >= signal_priority(si->signal_received))
{
si->signal_received = sig;
}
si->signal_text = text;
si->source = SIG_SOURCE_SOFT;
}
}

View File

@ -2277,8 +2277,12 @@ link_socket_init_phase2(struct context *c)
done:
if (sig_save.signal_received)
{
/* This can potentially lose a saved high priority signal -- to be fixed */
if (!sig_info->signal_received)
/* Always restore the saved signal -- register/throw_signal will handle priority */
if (sig_save.source == SIG_SOURCE_HARD && sig_info == &siginfo_static)
{
throw_signal(sig_save.signal_received);
}
else
{
register_signal(sig_info, sig_save.signal_received, sig_save.signal_text);
}

View File

@ -499,11 +499,8 @@ establish_socks_proxy_passthru(struct socks_proxy_info *p,
return;
error:
if (!sig_info->signal_received)
{
/* SOFT-SIGUSR1 -- socks error */
register_signal(sig_info, SIGUSR1, "socks-error");
}
return;
}
@ -543,11 +540,8 @@ establish_socks_proxy_udpassoc(struct socks_proxy_info *p,
return;
error:
if (!sig_info->signal_received)
{
/* SOFT-SIGUSR1 -- socks error */
register_signal(sig_info, SIGUSR1, "socks-error");
}
return;
}