From: Selva Nair <selva.n...@gmail.com> 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 next 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 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.n...@gmail.com> --- src/openvpn/proxy.c | 5 +---- src/openvpn/sig.c | 45 ++++++++++++++++++++++++++++++++------------ src/openvpn/socket.c | 8 ++++++-- src/openvpn/socks.c | 14 ++++---------- 4 files changed, 44 insertions(+), 28 deletions(-) diff --git a/src/openvpn/proxy.c b/src/openvpn/proxy.c index 91121f25..120ba85e 100644 --- a/src/openvpn/proxy.c +++ b/src/openvpn/proxy.c @@ -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 */ - } + register_signal(sig_info, SIGUSR1, "HTTP proxy error"); /* SOFT-SIGUSR1 -- HTTP proxy error */ gc_free(&gc); return ret; } diff --git a/src/openvpn/sig.c b/src/openvpn/sig.c index e462b93e..d6b18cb1 100644 --- a/src/openvpn/sig.c +++ b/src/openvpn/sig.c @@ -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) { - siginfo_static.signal_received = signum; - siginfo_static.source = SIG_SOURCE_HARD; + 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) { - siginfo_static.signal_received = signum; - siginfo_static.source = SIG_SOURCE_SOFT; - siginfo_static.signal_text = 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; } - si->signal_text = text; } diff --git a/src/openvpn/socket.c b/src/openvpn/socket.c index faaa2748..59d89352 100644 --- a/src/openvpn/socket.c +++ b/src/openvpn/socket.c @@ -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); } diff --git a/src/openvpn/socks.c b/src/openvpn/socks.c index b2ca3744..8f2ae226 100644 --- a/src/openvpn/socks.c +++ b/src/openvpn/socks.c @@ -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"); - } + /* 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"); - } + /* SOFT-SIGUSR1 -- socks error */ + register_signal(sig_info, SIGUSR1, "socks-error"); return; } -- 2.34.1 _______________________________________________ Openvpn-devel mailing list Openvpn-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openvpn-devel