From: Selva Nair <selva.n...@gmail.com> - In win32_signal_get() re-order the check so that Windows signals are picked up even if signal_received is non-zero
- When management is not active, management_sleep() becomes sleep() but it is not interruptible by signals on Windows. Fix this by periodically checking for signal. Fixes Trac #311 #639 (windows specific part) Github: Fixes OpenVPN/openvpn#205 (windows specific part) Note: if stuck in address resolution, press ctrl-C and wait for getaddrinfo() to timeout. Signed-off-by: Selva Nair <selva.n...@gmail.com> --- src/openvpn/manage.c | 4 ++ src/openvpn/win32.c | 98 +++++++++++++++++++++++++++++--------------- 2 files changed, 68 insertions(+), 34 deletions(-) diff --git a/src/openvpn/manage.c b/src/openvpn/manage.c index 5465b7e9..ac37e557 100644 --- a/src/openvpn/manage.c +++ b/src/openvpn/manage.c @@ -4091,10 +4091,14 @@ man_persist_client_stats(struct management *man, struct context *c) void management_sleep(const int n) { +#ifdef WIN32 + win32_sleep(n); +#else if (n > 0) { sleep(n); } +#endif /* ifdef WIN32 */ } #endif /* ENABLE_MANAGEMENT */ diff --git a/src/openvpn/win32.c b/src/openvpn/win32.c index c3520bca..e16d5461 100644 --- a/src/openvpn/win32.c +++ b/src/openvpn/win32.c @@ -642,50 +642,44 @@ int win32_signal_get(struct win32_signal *ws) { int ret = 0; - if (siginfo_static.signal_received) - { - ret = siginfo_static.signal_received; - } - else + + if (ws->mode == WSO_MODE_SERVICE) { - if (ws->mode == WSO_MODE_SERVICE) + if (win32_service_interrupt(ws)) { - if (win32_service_interrupt(ws)) - { - ret = SIGTERM; - } + ret = SIGTERM; } - else if (ws->mode == WSO_MODE_CONSOLE) + } + else if (ws->mode == WSO_MODE_CONSOLE) + { + switch (win32_keyboard_get(ws)) { - switch (win32_keyboard_get(ws)) - { - case 0x3B: /* F1 -> USR1 */ - ret = SIGUSR1; - break; + case 0x3B: /* F1 -> USR1 */ + ret = SIGUSR1; + break; - case 0x3C: /* F2 -> USR2 */ - ret = SIGUSR2; - break; + case 0x3C: /* F2 -> USR2 */ + ret = SIGUSR2; + break; - case 0x3D: /* F3 -> HUP */ - ret = SIGHUP; - break; + case 0x3D: /* F3 -> HUP */ + ret = SIGHUP; + break; - case 0x3E: /* F4 -> TERM */ - ret = SIGTERM; - break; + case 0x3E: /* F4 -> TERM */ + ret = SIGTERM; + break; - case 0x03: /* CTRL-C -> TERM */ - ret = SIGTERM; - break; - } - } - if (ret) - { - throw_signal(ret); /* this will update signinfo_static.signal received */ + case 0x03: /* CTRL-C -> TERM */ + ret = SIGTERM; + break; } } - return ret; + if (ret) + { + throw_signal(ret); /* this will update signinfo_static.signal received */ + } + return (siginfo_static.signal_received); } void @@ -1603,4 +1597,40 @@ set_openssl_env_vars() } } +void +win32_sleep(const int n) +{ + if (n < 0) + { + return; + } + + /* Sleep() is not interruptible. Use a WAIT_OBJECT to catch signal */ + if (HANDLE_DEFINED(win32_signal.in.read)) + { + time_t expire = 0; + update_time(); + expire = now + n; + while (expire >= now) + { + DWORD status = WaitForSingleObject(win32_signal.in.read, (expire - now)*1000); + if (win32_signal_get(&win32_signal) || status == WAIT_TIMEOUT) + { + return; + } + + update_time(); + + if (status == WAIT_FAILED && expire > now) + { + Sleep((expire-now)*1000); + return; + } + } + } + else + { + Sleep(n*1000); + } +} #endif /* ifdef _WIN32 */ -- 2.34.1 _______________________________________________ Openvpn-devel mailing list Openvpn-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openvpn-devel