From: Selva Nair <selva.n...@gmail.com> - Do not directly update signal_received: always use register_signal() throw_signal() or signal_reset(). To facilitate this, register_signal() now takes c->sig as an argument instead of the context c itself, and sig_info struct is passed-in to functions that need to set a signal.
- openvpn_getaddrinfo() is updated in a following commit as it could benefit from some logic changes that we may or may not want to do. No functional changes. TODO: (i) update signal handling in openvpn_getaddrinfo (ii) enforce signal priority (iii) fix signal handling on Windows for 2.7? (iv) replace system-V signal with POSIX sigaction Signed-off-by: Selva Nair <selva.n...@gmail.com> --- src/openvpn/dco_win.c | 11 +++++---- src/openvpn/dco_win.h | 3 ++- src/openvpn/forward.c | 34 +++++++++++++-------------- src/openvpn/init.c | 13 ++++------- src/openvpn/multi.c | 6 ++--- src/openvpn/occ.c | 3 +-- src/openvpn/ping.c | 6 ++--- src/openvpn/proxy.c | 7 +++--- src/openvpn/proxy.h | 2 +- src/openvpn/push.c | 33 +++++++++++++------------- src/openvpn/sig.c | 17 +++++++------- src/openvpn/sig.h | 37 +++++++++++++++-------------- src/openvpn/socket.c | 54 +++++++++++++++++++++---------------------- src/openvpn/socks.c | 22 ++++++++++-------- src/openvpn/socks.h | 4 ++-- src/openvpn/win32.c | 3 +-- 16 files changed, 125 insertions(+), 130 deletions(-) diff --git a/src/openvpn/dco_win.c b/src/openvpn/dco_win.c index 0d0d7946..825b1cd3 100644 --- a/src/openvpn/dco_win.c +++ b/src/openvpn/dco_win.c @@ -106,8 +106,9 @@ dco_start_tun(struct tuntap *tt) } static void -dco_connect_wait(HANDLE handle, OVERLAPPED *ov, int timeout, volatile int *signal_received) +dco_connect_wait(HANDLE handle, OVERLAPPED *ov, int timeout, struct signal_info *sig_info) { + volatile int *signal_received = &sig_info->signal_received; /* GetOverlappedResultEx is available starting from Windows 8 */ typedef BOOL (*get_overlapped_result_ex_t) (HANDLE, LPOVERLAPPED, LPDWORD, DWORD, BOOL); get_overlapped_result_ex_t get_overlapped_result_ex = @@ -138,7 +139,7 @@ dco_connect_wait(HANDLE handle, OVERLAPPED *ov, int timeout, volatile int *signa { /* dco reported connection error */ msg(M_NONFATAL | M_ERRNO, "dco connect error"); - *signal_received = SIGUSR1; + register_signal(sig_info, SIGUSR1, "dco-connect-error"); return; } @@ -153,13 +154,13 @@ dco_connect_wait(HANDLE handle, OVERLAPPED *ov, int timeout, volatile int *signa /* we end up here when timeout occurs in userspace */ msg(M_NONFATAL, "dco connect timeout"); - *signal_received = SIGUSR1; + register_signal(sig_info, SIGUSR1, "dco-connect-timeout"); } void dco_create_socket(HANDLE handle, struct addrinfo *remoteaddr, bool bind_local, struct addrinfo *bind, int timeout, - volatile int *signal_received) + struct signal_info *sig_info) { msg(D_DCO_DEBUG, "%s", __func__); @@ -240,7 +241,7 @@ dco_create_socket(HANDLE handle, struct addrinfo *remoteaddr, bool bind_local, } else { - dco_connect_wait(handle, &ov, timeout, signal_received); + dco_connect_wait(handle, &ov, timeout, sig_info); } } } diff --git a/src/openvpn/dco_win.h b/src/openvpn/dco_win.h index b3cdbbbd..bba7b340 100644 --- a/src/openvpn/dco_win.h +++ b/src/openvpn/dco_win.h @@ -26,6 +26,7 @@ #include "buffer.h" #include "ovpn_dco_win.h" +#include "sig.h" typedef OVPN_KEY_SLOT dco_key_slot_t; typedef OVPN_CIPHER_ALG dco_cipher_t; @@ -42,7 +43,7 @@ create_dco_handle(const char *devname, struct gc_arena *gc); void dco_create_socket(HANDLE handle, struct addrinfo *remoteaddr, bool bind_local, struct addrinfo *bind, int timeout, - volatile int *signal_received); + struct signal_info *sig_info); void dco_start_tun(struct tuntap *tt); diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c index af4ed05d..ae0512fc 100644 --- a/src/openvpn/forward.c +++ b/src/openvpn/forward.c @@ -82,13 +82,13 @@ static void check_tls_errors_co(struct context *c) { msg(D_STREAM_ERRORS, "Fatal TLS error (check_tls_errors_co), restarting"); - register_signal(c, c->c2.tls_exit_signal, "tls-error"); /* SOFT-SIGUSR1 -- TLS error */ + register_signal(c->sig, c->c2.tls_exit_signal, "tls-error"); /* SOFT-SIGUSR1 -- TLS error */ } static void check_tls_errors_nco(struct context *c) { - register_signal(c, c->c2.tls_exit_signal, "tls-error"); /* SOFT-SIGUSR1 -- TLS error */ + register_signal(c->sig, c->c2.tls_exit_signal, "tls-error"); /* SOFT-SIGUSR1 -- TLS error */ } /* @@ -155,7 +155,7 @@ check_dco_key_status(struct context *c) { /* Something bad happened. Kill the connection to * be able to recover. */ - register_signal(c, SIGUSR1, "dco update keys error"); + register_signal(c->sig, SIGUSR1, "dco update keys error"); } } @@ -199,7 +199,7 @@ check_tls(struct context *c) } else { - register_signal(c, SIGTERM, "auth-control-exit"); + register_signal(c->sig, SIGTERM, "auth-control-exit"); } } @@ -351,7 +351,7 @@ check_connection_established(struct context *c) { if (!do_up(c, false, 0)) { - register_signal(c, SIGUSR1, "connection initialisation failed"); + register_signal(c->sig, SIGUSR1, "connection initialisation failed"); } } @@ -431,7 +431,7 @@ check_add_routes(struct context *c) { if (!tun_standby(c->c1.tuntap)) { - register_signal(c, SIGHUP, "ip-fail"); + register_signal(c->sig, SIGHUP, "ip-fail"); c->persist.restart_sleep_seconds = 10; #ifdef _WIN32 show_routes(M_INFO|M_NOPREFIX); @@ -455,7 +455,7 @@ static void check_inactivity_timeout(struct context *c) { msg(M_INFO, "Inactivity timeout (--inactive), exiting"); - register_signal(c, SIGTERM, "inactive"); + register_signal(c->sig, SIGTERM, "inactive"); } int @@ -474,7 +474,7 @@ check_server_poll_timeout(struct context *c) if (!tls_initial_packet_received(c->c2.tls_multi)) { msg(M_INFO, "Server poll timeout, restarting"); - register_signal(c, SIGUSR1, "server_poll"); + register_signal(c->sig, SIGUSR1, "server_poll"); c->persist.restart_sleep_seconds = -1; } } @@ -499,7 +499,7 @@ schedule_exit(struct context *c, const int n_seconds, const int signal) static void check_scheduled_exit(struct context *c) { - register_signal(c, c->c2.scheduled_exit_signal, "delayed-exit"); + register_signal(c->sig, c->c2.scheduled_exit_signal, "delayed-exit"); } /* @@ -661,7 +661,7 @@ check_session_timeout(struct context *c) ETT_DEFAULT)) { msg(M_INFO, "Session timeout, exiting"); - register_signal(c, SIGTERM, "session-timeout"); + register_signal(c->sig, SIGTERM, "session-timeout"); } } @@ -902,7 +902,7 @@ read_incoming_link(struct context *c) const struct buffer *fbuf = socket_foreign_protocol_head(c->c2.link_socket); const int sd = socket_foreign_protocol_sd(c->c2.link_socket); port_share_redirect(port_share, fbuf, sd); - register_signal(c, SIGTERM, "port-share-redirect"); + register_signal(c->sig, SIGTERM, "port-share-redirect"); } else #endif @@ -915,7 +915,7 @@ read_incoming_link(struct context *c) } else { - register_signal(c, SIGUSR1, "connection-reset"); /* SOFT-SIGUSR1 -- TCP connection reset */ + register_signal(c->sig, SIGUSR1, "connection-reset"); /* SOFT-SIGUSR1 -- TCP connection reset */ msg(D_STREAM_ERRORS, "Connection reset, restarting [%d]", status); } } @@ -1067,7 +1067,7 @@ process_incoming_link_part1(struct context *c, struct link_socket_info *lsi, boo if (!decrypt_status && link_socket_connection_oriented(c->c2.link_socket)) { /* decryption errors are fatal in TCP mode */ - register_signal(c, SIGUSR1, "decryption-error"); /* SOFT-SIGUSR1 -- decryption error in TCP mode */ + register_signal(c->sig, SIGUSR1, "decryption-error"); /* SOFT-SIGUSR1 -- decryption error in TCP mode */ msg(D_STREAM_ERRORS, "Fatal decryption error (process_incoming_link), restarting"); } } @@ -1248,7 +1248,7 @@ read_incoming_tun(struct context *c) read_wintun(c->c1.tuntap, &c->c2.buf); if (c->c2.buf.len == -1) { - register_signal(c, SIGHUP, "tun-abort"); + register_signal(c->sig, SIGHUP, "tun-abort"); c->persist.restart_sleep_seconds = 1; msg(M_INFO, "Wintun read error, restarting"); perf_pop(); @@ -1277,7 +1277,7 @@ read_incoming_tun(struct context *c) /* Was TUN/TAP interface stopped? */ if (tuntap_stop(c->c2.buf.len)) { - register_signal(c, SIGTERM, "tun-stop"); + register_signal(c->sig, SIGTERM, "tun-stop"); msg(M_INFO, "TUN/TAP interface has been stopped, exiting"); perf_pop(); return; @@ -1286,7 +1286,7 @@ read_incoming_tun(struct context *c) /* Was TUN/TAP I/O operation aborted? */ if (tuntap_abort(c->c2.buf.len)) { - register_signal(c, SIGHUP, "tun-abort"); + register_signal(c->sig, SIGHUP, "tun-abort"); c->persist.restart_sleep_seconds = 10; msg(M_INFO, "TUN/TAP I/O operation aborted, restarting"); perf_pop(); @@ -1845,7 +1845,7 @@ process_outgoing_link(struct context *c) && !tls_initial_packet_received(c->c2.tls_multi) && c->options.mode == MODE_POINT_TO_POINT) { msg(M_INFO, "Network unreachable, restarting"); - register_signal(c, SIGUSR1, "network-unreachable"); + register_signal(c->sig, SIGUSR1, "network-unreachable"); } } else diff --git a/src/openvpn/init.c b/src/openvpn/init.c index 3380ed9e..eec25acf 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -2934,13 +2934,13 @@ do_init_crypto_tls_c1(struct context *c) /* Intentional [[fallthrough]]; */ case AR_NOINTERACT: - c->sig->signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- Password failure error */ + /* SOFT-SIGUSR1 -- Password failure error */ + register_signal(c->sig, SIGUSR1, "private-key-password-failure"); break; default: ASSERT(0); } - c->sig->signal_text = "private-key-password-failure"; return; } @@ -4229,9 +4229,7 @@ init_instance(struct context *c, const struct env_set *env, const unsigned int f } /* signals caught here will abort */ - c->sig->signal_received = 0; - c->sig->signal_text = NULL; - c->sig->source = SIG_SOURCE_SOFT; + signal_reset(c->sig); if (c->mode == CM_P2P) { @@ -4733,7 +4731,7 @@ close_context(struct context *c, int sig, unsigned int flags) if (sig >= 0) { - c->sig->signal_received = sig; + register_signal(c->sig, sig, "close_context"); } if (c->sig->signal_received == SIGUSR1) @@ -4741,8 +4739,7 @@ close_context(struct context *c, int sig, unsigned int flags) if ((flags & CC_USR1_TO_HUP) || (c->sig->source == SIG_SOURCE_HARD && (flags & CC_HARD_USR1_TO_HUP))) { - c->sig->signal_received = SIGHUP; - c->sig->signal_text = "close_context usr1 to hup"; + register_signal(c->sig, SIGHUP, "close_context usr1 to hup"); } } diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c index 92e63dd2..c2254399 100644 --- a/src/openvpn/multi.c +++ b/src/openvpn/multi.c @@ -2364,7 +2364,7 @@ multi_client_generate_tls_keys(struct context *c) get_link_socket_info(c))) { msg(D_TLS_ERRORS, "TLS Error: initializing data channel failed"); - register_signal(c, SIGUSR1, "process-push-msg-failed"); + register_signal(c->sig, SIGUSR1, "process-push-msg-failed"); return false; } @@ -3828,7 +3828,7 @@ multi_push_restart_schedule_exit(struct multi_context *m, bool next_server) &m->deferred_shutdown_signal.wakeup, compute_wakeup_sigma(&m->deferred_shutdown_signal.wakeup)); - m->top.sig->signal_received = 0; + signal_reset(m->top.sig); } /* @@ -3843,7 +3843,7 @@ multi_process_signal(struct multi_context *m) struct status_output *so = status_open(NULL, 0, M_INFO, NULL, 0); multi_print_status(m, so, m->status_file_version); status_close(so); - m->top.sig->signal_received = 0; + signal_reset(m->top.sig); return false; } else if (proto_is_dgram(m->top.options.ce.proto) diff --git a/src/openvpn/occ.c b/src/openvpn/occ.c index eb1f2fae..0b291756 100644 --- a/src/openvpn/occ.c +++ b/src/openvpn/occ.c @@ -431,8 +431,7 @@ process_received_occ_msg(struct context *c) case OCC_EXIT: dmsg(D_PACKET_CONTENT, "RECEIVED OCC_EXIT"); - c->sig->signal_received = SIGUSR1; - c->sig->signal_text = "remote-exit"; + register_signal(c->sig, SIGUSR1, "remote-exit"); break; } c->c2.buf.len = 0; /* don't pass packet on */ diff --git a/src/openvpn/ping.c b/src/openvpn/ping.c index 588723d0..cf1861a6 100644 --- a/src/openvpn/ping.c +++ b/src/openvpn/ping.c @@ -55,15 +55,13 @@ trigger_ping_timeout_signal(struct context *c) case PING_EXIT: msg(M_INFO, "%sInactivity timeout (--ping-exit), exiting", format_common_name(c, &gc)); - c->sig->signal_received = SIGTERM; - c->sig->signal_text = "ping-exit"; + register_signal(c->sig, SIGTERM, "ping-exit"); break; case PING_RESTART: msg(M_INFO, "%sInactivity timeout (--ping-restart), restarting", format_common_name(c, &gc)); - c->sig->signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- Ping Restart */ - c->sig->signal_text = "ping-restart"; + register_signal(c->sig, SIGUSR1, "ping-restart"); break; default: diff --git a/src/openvpn/proxy.c b/src/openvpn/proxy.c index 633caee0..91121f25 100644 --- a/src/openvpn/proxy.c +++ b/src/openvpn/proxy.c @@ -636,7 +636,7 @@ establish_http_proxy_passthru(struct http_proxy_info *p, const char *port, /* openvpn server port */ struct event_timeout *server_poll_timeout, struct buffer *lookahead, - volatile int *signal_received) + struct signal_info *sig_info) { struct gc_arena gc = gc_new(); char buf[512]; @@ -646,6 +646,7 @@ establish_http_proxy_passthru(struct http_proxy_info *p, int nparms; bool ret = false; bool processed = false; + volatile int *signal_received = &sig_info->signal_received; /* get user/pass if not previously given */ if (p->auth_method == HTTP_AUTH_BASIC @@ -1079,9 +1080,9 @@ done: return ret; error: - if (!*signal_received) + if (!sig_info->signal_received) { - *signal_received = SIGUSR1; /* 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/proxy.h b/src/openvpn/proxy.h index 9d719382..4fe2a08f 100644 --- a/src/openvpn/proxy.h +++ b/src/openvpn/proxy.h @@ -86,7 +86,7 @@ bool establish_http_proxy_passthru(struct http_proxy_info *p, const char *port, /* openvpn server port */ struct event_timeout *server_poll_timeout, struct buffer *lookahead, - volatile int *signal_received); + struct signal_info *sig_info); uint8_t *make_base64_string2(const uint8_t *str, int str_len, struct gc_arena *gc); diff --git a/src/openvpn/push.c b/src/openvpn/push.c index e765d2a9..9796da4e 100644 --- a/src/openvpn/push.c +++ b/src/openvpn/push.c @@ -74,8 +74,7 @@ receive_auth_failed(struct context *c, const struct buffer *buffer) if (authfail_extended && buf_string_match_head_str(&buf, "TEMP")) { parse_auth_failed_temp(&c->options, reason + strlen("TEMP")); - c->sig->signal_received = SIGUSR1; - c->sig->signal_text = "auth-temp-failure (server temporary reject)"; + register_signal(c->sig, SIGUSR1, "auth-temp-failure (server temporary reject)"); } /* Before checking how to react on AUTH_FAILED, first check if the @@ -85,8 +84,8 @@ receive_auth_failed(struct context *c, const struct buffer *buffer) * identical for this scenario */ else if (ssl_clean_auth_token()) { - c->sig->signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- Auth failure error */ - c->sig->signal_text = "auth-failure (auth-token)"; + /* SOFT-SIGUSR1 -- Auth failure error */ + register_signal(c->sig, SIGUSR1, "auth-failure (auth-token)"); c->options.no_advance = true; } else @@ -94,20 +93,21 @@ receive_auth_failed(struct context *c, const struct buffer *buffer) switch (auth_retry_get()) { case AR_NONE: - c->sig->signal_received = SIGTERM; /* SOFT-SIGTERM -- Auth failure error */ + /* SOFT-SIGTERM -- Auth failure error */ + register_signal(c->sig, SIGTERM, "auth-failure"); break; case AR_INTERACT: ssl_purge_auth(false); case AR_NOINTERACT: - c->sig->signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- Auth failure error */ + /* SOFT-SIGTUSR1 -- Auth failure error */ + register_signal(c->sig, SIGUSR1, "auth-failure"); break; default: ASSERT(0); } - c->sig->signal_text = "auth-failure"; } #ifdef ENABLE_MANAGEMENT if (management) @@ -171,14 +171,14 @@ server_pushed_signal(struct context *c, const struct buffer *buffer, const bool if (restart) { msg(D_STREAM_ERRORS, "Connection reset command was pushed by server ('%s')", m); - c->sig->signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- server-pushed connection reset */ - c->sig->signal_text = "server-pushed-connection-reset"; + /* SOFT-SIGUSR1 -- server-pushed connection reset */ + register_signal(c->sig, SIGUSR1, "server-pushed-connection-reset"); } else { msg(D_STREAM_ERRORS, "Halt command was pushed by server ('%s')", m); - c->sig->signal_received = SIGTERM; /* SOFT-SIGTERM -- server-pushed halt */ - c->sig->signal_text = "server-pushed-halt"; + /* SOFT-SIGTERM -- server-pushed halt */ + register_signal(c->sig, SIGTERM, "server-pushed-halt"); } #ifdef ENABLE_MANAGEMENT if (management) @@ -210,13 +210,12 @@ receive_exit_message(struct context *c) } else { - c->sig->signal_received = SIGUSR1; + register_signal(c->sig, SIGUSR1, "remote-exit"); } - c->sig->signal_text = "remote-exit"; #ifdef ENABLE_MANAGEMENT if (management) { - management_notify(management, "info", c->sig->signal_text, "EXIT"); + management_notify(management, "info", "remote-exit", "EXIT"); } #endif } @@ -527,7 +526,7 @@ incoming_push_message(struct context *c, const struct buffer *buffer) goto cleanup; error: - register_signal(c, SIGUSR1, "process-push-msg-failed"); + register_signal(c->sig, SIGUSR1, "process-push-msg-failed"); cleanup: gc_free(&gc); } @@ -555,8 +554,8 @@ send_push_request(struct context *c) { msg(D_STREAM_ERRORS, "No reply from server to push requests in %ds", (int)(now - ks->established)); - c->sig->signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- server-pushed connection reset */ - c->sig->signal_text = "no-push-reply"; + /* SOFT-SIGUSR1 -- server-pushed connection reset */ + register_signal(c->sig, SIGUSR1, "no-push-reply"); return false; } } diff --git a/src/openvpn/sig.c b/src/openvpn/sig.c index 65cd25c6..e462b93e 100644 --- a/src/openvpn/sig.c +++ b/src/openvpn/sig.c @@ -115,7 +115,7 @@ throw_signal_soft(const int signum, const char *signal_text) siginfo_static.signal_text = signal_text; } -static void +void signal_reset(struct signal_info *si) { if (si) @@ -374,8 +374,7 @@ process_explicit_exit_notification_timer_wakeup(struct context *c) if (now >= c->c2.explicit_exit_notification_time_wait + c->options.ce.explicit_exit_notification) { event_timeout_clear(&c->c2.explicit_exit_notification_interval); - c->sig->signal_received = SIGTERM; - c->sig->signal_text = "exit-with-notification"; + register_signal(c->sig, SIGTERM, "exit-with-notification"); } else if (!cc_exit_notify_enabled(c)) { @@ -393,7 +392,7 @@ remap_signal(struct context *c) { if (c->sig->signal_received == SIGUSR1 && c->options.remap_sigusr1) { - c->sig->signal_received = c->options.remap_sigusr1; + register_signal(c->sig, c->options.remap_sigusr1, c->sig->signal_text); } } @@ -442,7 +441,7 @@ ignore_restart_signals(struct context *c) { msg(M_INFO, "Converting soft %s received during exit notification to SIGTERM", signal_name(c->sig->signal_received, true)); - register_signal(c, SIGTERM, "exit-with-notification"); + register_signal(c->sig, SIGTERM, "exit-with-notification"); ret = false; } } @@ -471,11 +470,11 @@ process_signal(struct context *c) } void -register_signal(struct context *c, int sig, const char *text) +register_signal(struct signal_info *si, int sig, const char *text) { - if (c->sig->signal_received != SIGTERM) + if (si->signal_received != SIGTERM) { - c->sig->signal_received = sig; + si->signal_received = sig; } - c->sig->signal_text = text; + si->signal_text = text; } diff --git a/src/openvpn/sig.h b/src/openvpn/sig.h index 091f16b3..83adc543 100644 --- a/src/openvpn/sig.h +++ b/src/openvpn/sig.h @@ -27,8 +27,6 @@ #include "status.h" #include "win32.h" - - #define SIG_SOURCE_SOFT 0 #define SIG_SOURCE_HARD 1 /* CONNECTION_FAILED is also a "soft" status, @@ -79,41 +77,42 @@ void signal_restart_status(const struct signal_info *si); bool process_signal(struct context *c); -void register_signal(struct context *c, int sig, const char *text); +void register_signal(struct signal_info *si, int sig, const char *text); void process_explicit_exit_notification_timer_wakeup(struct context *c); -#ifdef _WIN32 - -static inline void -get_signal(volatile int *sig) -{ - *sig = win32_signal_get(&win32_signal); -} +void signal_reset(struct signal_info *si); static inline void halt_non_edge_triggered_signals(void) { +#ifdef _WIN32 win32_signal_close(&win32_signal); +#endif } -#else /* ifdef _WIN32 */ +/** + * Copy the global signal_received (if non-zero) to the passed-in argument sig. + * As the former is volatile, do not assign if sig and &signal_received are the + * same. Even on windows signal_received is really volatile as it can change if + * a ctrl-C or ctrl-break is delivered. So use the same logic as above. + * + * Also, on windows always call win32_signal_get to pickup any signals simulated by + * key-board short cuts or the exit event. + */ static inline void get_signal(volatile int *sig) { +#ifdef _WIN32 + const int i = win32_signal_get(&win32_signal); +#else const int i = siginfo_static.signal_received; - if (i) +#endif + if (i && sig != &siginfo_static.signal_received) { *sig = i; } } -static inline void -halt_non_edge_triggered_signals(void) -{ -} - -#endif /* ifdef _WIN32 */ - #endif /* ifndef SIG_H */ diff --git a/src/openvpn/socket.c b/src/openvpn/socket.c index c7ec0e06..273f378e 100644 --- a/src/openvpn/socket.c +++ b/src/openvpn/socket.c @@ -1586,7 +1586,7 @@ socket_connect(socket_descriptor_t *sd, openvpn_close_socket(*sd); *sd = SOCKET_UNDEFINED; - sig_info->signal_received = SIGUSR1; + register_signal(sig_info, SIGUSR1, "connection-failed"); sig_info->source = SIG_SOURCE_CONNECTION_FAILED; } else @@ -1694,8 +1694,9 @@ static void resolve_remote(struct link_socket *sock, int phase, const char **remote_dynamic, - volatile int *signal_received) + struct signal_info *sig_info) { + volatile int *signal_received = sig_info ? &sig_info->signal_received : NULL; struct gc_arena gc = gc_new(); /* resolve remote address if undefined */ @@ -1774,18 +1775,16 @@ resolve_remote(struct link_socket *sock, signal_received ? *signal_received : -1, status); } - if (signal_received) + if (signal_received && *signal_received) { - if (*signal_received) - { - goto done; - } + goto done; } if (status!=0) { if (signal_received) { - *signal_received = SIGUSR1; + /* potential overwrite of signal */ + register_signal(sig_info, SIGUSR1, "socks-resolve-failure"); } goto done; } @@ -2002,8 +2001,9 @@ linksock_print_addr(struct link_socket *sock) static void phase2_tcp_server(struct link_socket *sock, const char *remote_dynamic, - volatile int *signal_received) + struct signal_info *sig_info) { + volatile int *signal_received = sig_info ? &sig_info->signal_received : NULL; switch (sock->mode) { case LS_MODE_DEFAULT: @@ -2029,7 +2029,7 @@ phase2_tcp_server(struct link_socket *sock, const char *remote_dynamic, false); if (!socket_defined(sock->sd)) { - *signal_received = SIGTERM; + register_signal(sig_info, SIGTERM, "socket-undefiled"); return; } tcp_connection_established(&sock->info.lsa->actual); @@ -2065,7 +2065,7 @@ phase2_tcp_client(struct link_socket *sock, struct signal_info *sig_info) sock->proxy_dest_port, sock->server_poll_timeout, &sock->stream_buf.residual, - &sig_info->signal_received); + sig_info); } else if (sock->socks_proxy) { @@ -2073,7 +2073,7 @@ phase2_tcp_client(struct link_socket *sock, struct signal_info *sig_info) sock->sd, sock->proxy_dest_host, sock->proxy_dest_port, - &sig_info->signal_received); + sig_info); } if (proxy_retry) { @@ -2102,7 +2102,7 @@ phase2_socks_client(struct link_socket *sock, struct signal_info *sig_info) sock->ctrl_sd, sock->sd, &sock->socks_relay.dest, - &sig_info->signal_received); + sig_info); if (sig_info->signal_received) { @@ -2120,13 +2120,13 @@ phase2_socks_client(struct link_socket *sock, struct signal_info *sig_info) sock->info.lsa->remote_list = NULL; } - resolve_remote(sock, 1, NULL, &sig_info->signal_received); + resolve_remote(sock, 1, NULL, sig_info); } #if defined(_WIN32) static void create_socket_dco_win(struct context *c, struct link_socket *sock, - volatile int *signal_received) + struct signal_info *sig_info) { if (!c->c1.tuntap) { @@ -2145,11 +2145,11 @@ create_socket_dco_win(struct context *c, struct link_socket *sock, sock->info.lsa->current_remote, sock->bind_local, sock->info.lsa->bind_local, get_server_poll_remaining_time(sock->server_poll_timeout), - signal_received); + sig_info); sock->dco_installed = true; - if (*signal_received) + if (sig_info->signal_received) { return; } @@ -2168,15 +2168,15 @@ link_socket_init_phase2(struct context *c) struct signal_info *sig_info = c->sig; const char *remote_dynamic = NULL; - int sig_save = 0; + struct signal_info sig_save = {0}; ASSERT(sock); ASSERT(sig_info); if (sig_info->signal_received) { - sig_save = sig_info->signal_received; - sig_info->signal_received = 0; + sig_save = *sig_info; + signal_reset(sig_info); } /* initialize buffers */ @@ -2193,7 +2193,7 @@ link_socket_init_phase2(struct context *c) } /* Second chance to resolv/create socket */ - resolve_remote(sock, 2, &remote_dynamic, &sig_info->signal_received); + resolve_remote(sock, 2, &remote_dynamic, sig_info); /* If a valid remote has been found, create the socket with its addrinfo */ if (sock->info.lsa->current_remote) @@ -2201,7 +2201,7 @@ link_socket_init_phase2(struct context *c) #if defined(_WIN32) if (dco_enabled(&c->options)) { - create_socket_dco_win(c, sock, &sig_info->signal_received); + create_socket_dco_win(c, sock, sig_info); goto done; } else @@ -2237,7 +2237,7 @@ link_socket_init_phase2(struct context *c) if (sock->sd == SOCKET_UNDEFINED) { msg(M_WARN, "Could not determine IPv4/IPv6 protocol"); - sig_info->signal_received = SIGUSR1; + register_signal(sig_info, SIGUSR1, "Could not determine IPv4/IPv6 protocol"); goto done; } @@ -2248,8 +2248,7 @@ link_socket_init_phase2(struct context *c) if (sock->info.proto == PROTO_TCP_SERVER) { - phase2_tcp_server(sock, remote_dynamic, - &sig_info->signal_received); + phase2_tcp_server(sock, remote_dynamic, sig_info); } else if (sock->info.proto == PROTO_TCP_CLIENT) { @@ -2275,11 +2274,12 @@ link_socket_init_phase2(struct context *c) linksock_print_addr(sock); done: - if (sig_save) + if (sig_save.signal_received) { + /* This can potentially lose a saved high priority signal -- to be fixed */ if (!sig_info->signal_received) { - sig_info->signal_received = sig_save; + 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 ef178a35..b2ca3744 100644 --- a/src/openvpn/socks.c +++ b/src/openvpn/socks.c @@ -448,12 +448,12 @@ establish_socks_proxy_passthru(struct socks_proxy_info *p, socket_descriptor_t sd, /* already open to proxy */ const char *host, /* openvpn server remote */ const char *servname, /* openvpn server port */ - volatile int *signal_received) + struct signal_info *sig_info) { char buf[270]; size_t len; - if (!socks_handshake(p, sd, signal_received)) + if (!socks_handshake(p, sd, &sig_info->signal_received)) { goto error; } @@ -491,7 +491,7 @@ establish_socks_proxy_passthru(struct socks_proxy_info *p, /* receive reply from Socks proxy and discard */ - if (!recv_socks_reply(sd, NULL, signal_received)) + if (!recv_socks_reply(sd, NULL, &sig_info->signal_received)) { goto error; } @@ -499,9 +499,10 @@ establish_socks_proxy_passthru(struct socks_proxy_info *p, return; error: - if (!*signal_received) + if (!sig_info->signal_received) { - *signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- socks error */ + /* SOFT-SIGUSR1 -- socks error */ + register_signal(sig_info, SIGUSR1, "socks-error"); } return; } @@ -511,9 +512,9 @@ establish_socks_proxy_udpassoc(struct socks_proxy_info *p, socket_descriptor_t ctrl_sd, /* already open to proxy */ socket_descriptor_t udp_sd, struct openvpn_sockaddr *relay_addr, - volatile int *signal_received) + struct signal_info *sig_info) { - if (!socks_handshake(p, ctrl_sd, signal_received)) + if (!socks_handshake(p, ctrl_sd, &sig_info->signal_received)) { goto error; } @@ -534,7 +535,7 @@ establish_socks_proxy_udpassoc(struct socks_proxy_info *p, /* receive reply from Socks proxy */ CLEAR(*relay_addr); - if (!recv_socks_reply(ctrl_sd, relay_addr, signal_received)) + if (!recv_socks_reply(ctrl_sd, relay_addr, &sig_info->signal_received)) { goto error; } @@ -542,9 +543,10 @@ establish_socks_proxy_udpassoc(struct socks_proxy_info *p, return; error: - if (!*signal_received) + if (!sig_info->signal_received) { - *signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- socks error */ + /* SOFT-SIGUSR1 -- socks error */ + register_signal(sig_info, SIGUSR1, "socks-error"); } return; } diff --git a/src/openvpn/socks.h b/src/openvpn/socks.h index 47cdac10..55c75c60 100644 --- a/src/openvpn/socks.h +++ b/src/openvpn/socks.h @@ -52,13 +52,13 @@ void establish_socks_proxy_passthru(struct socks_proxy_info *p, socket_descriptor_t sd, /* already open to proxy */ const char *host, /* openvpn server remote */ const char *servname, /* openvpn server port */ - volatile int *signal_received); + struct signal_info *sig_info); void establish_socks_proxy_udpassoc(struct socks_proxy_info *p, socket_descriptor_t ctrl_sd, /* already open to proxy */ socket_descriptor_t udp_sd, struct openvpn_sockaddr *relay_addr, - volatile int *signal_received); + struct signal_info *sig_info); void socks_process_incoming_udp(struct buffer *buf, struct link_socket_actual *from); diff --git a/src/openvpn/win32.c b/src/openvpn/win32.c index cfe4dbde..c3520bca 100644 --- a/src/openvpn/win32.c +++ b/src/openvpn/win32.c @@ -682,8 +682,7 @@ win32_signal_get(struct win32_signal *ws) } if (ret) { - siginfo_static.signal_received = ret; - siginfo_static.source = SIG_SOURCE_HARD; + throw_signal(ret); /* this will update signinfo_static.signal received */ } } return ret; -- 2.34.1 _______________________________________________ Openvpn-devel mailing list Openvpn-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openvpn-devel