From: Selva Nair <[email protected]>
- 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.
v2: WIN32 --> _WIN32
add a chunk in management_sleep that was missed by sloppy
conflict-resolution
Signed-off-by: Selva Nair <[email protected]>
---
src/openvpn/manage.c | 16 +++++++-
src/openvpn/win32.c | 98 +++++++++++++++++++++++++++++---------------
src/openvpn/win32.h | 3 ++
3 files changed, 81 insertions(+), 36 deletions(-)
diff --git a/src/openvpn/manage.c b/src/openvpn/manage.c
index 5465b7e9..9bd5ef4e 100644
--- a/src/openvpn/manage.c
+++ b/src/openvpn/manage.c
@@ -4045,9 +4045,16 @@ management_sleep(const int n)
{
management_event_loop_n_seconds(management, n);
}
- else if (n > 0)
+ else
{
- sleep(n);
+#ifdef _WIN32
+ win32_sleep(n);
+#else
+ if (n > 0)
+ {
+ sleep(n);
+ }
+#endif
}
}
@@ -4088,13 +4095,18 @@ man_persist_client_stats(struct management *man, struct
context *c)
#else /* ifdef ENABLE_MANAGEMENT */
+#include "win32.h"
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 */
diff --git a/src/openvpn/win32.h b/src/openvpn/win32.h
index b1371999..26d5ef8f 100644
--- a/src/openvpn/win32.h
+++ b/src/openvpn/win32.h
@@ -330,5 +330,8 @@ openvpn_execve(const struct argv *a, const struct env_set
*es, const unsigned in
bool
openvpn_swprintf(wchar_t *const str, const size_t size, const wchar_t *const
format, ...);
+/* Sleep that can be interrupted by signals and exit event */
+void win32_sleep(const int n);
+
#endif /* ifndef OPENVPN_WIN32_H */
#endif /* ifdef _WIN32 */
--
2.34.1
_______________________________________________
Openvpn-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel