diff -Naurp openvpn-2.6.8.orig/src/openvpn/forward.c openvpn-2.6.8/src/openvpn/forward.c --- openvpn-2.6.8.orig/src/openvpn/forward.c 2024-09-05 12:43:17.633337355 +0200 +++ openvpn-2.6.8/src/openvpn/forward.c 2024-09-05 13:09:07.395797797 +0200 @@ -514,17 +514,24 @@ check_server_poll_timeout(struct context } /* - * Schedule a signal n_seconds from now. + * Schedule a SIGTERM signal c->options.scheduled_exit_interval seconds from now. */ -void -schedule_exit(struct context *c, const int n_seconds, const int signal) +bool +schedule_exit(struct context *c) { + const int n_seconds = c->options.scheduled_exit_interval; + /* don't reshcedule if already scheduled. */ + if (event_timeout_defined(&c->c2.scheduled_exit)) + { + return false; + } tls_set_single_session(c->c2.tls_multi); update_time(); reset_coarse_timers(c); event_timeout_init(&c->c2.scheduled_exit, n_seconds, now); - c->c2.scheduled_exit_signal = signal; + c->c2.scheduled_exit_signal = SIGTERM; msg(D_SCHED_EXIT, "Delayed exit in %d seconds", n_seconds); + return true; } /* diff -Naurp openvpn-2.6.8.orig/src/openvpn/forward.h openvpn-2.6.8/src/openvpn/forward.h --- openvpn-2.6.8.orig/src/openvpn/forward.h 2024-09-05 12:43:17.636670737 +0200 +++ openvpn-2.6.8/src/openvpn/forward.h 2024-09-05 13:11:05.550847481 +0200 @@ -302,7 +302,8 @@ void reschedule_multi_process(struct con void process_ip_header(struct context *c, unsigned int flags, struct buffer *buf); -void schedule_exit(struct context *c, const int n_seconds, const int signal); + +bool schedule_exit(struct context *c); static inline struct link_socket_info * get_link_socket_info(struct context *c) diff -Naurp openvpn-2.6.8.orig/src/openvpn/push.c openvpn-2.6.8/src/openvpn/push.c --- openvpn-2.6.8.orig/src/openvpn/push.c 2024-09-05 12:43:17.636670737 +0200 +++ openvpn-2.6.8/src/openvpn/push.c 2024-09-05 13:32:53.496512873 +0200 @@ -204,7 +204,11 @@ receive_exit_message(struct context *c) * */ if (c->options.mode == MODE_SERVER) { - schedule_exit(c, c->options.scheduled_exit_interval, SIGTERM); + if (!schedule_exit(c)) + { + /* Return early when we don't need to notify management */ + return; + } } else { @@ -391,7 +395,7 @@ __attribute__ ((format(__printf__, 4, 5) void send_auth_failed(struct context *c, const char *client_reason) { - if (event_timeout_defined(&c->c2.scheduled_exit)) + if (!schedule_exit(c)) { msg(D_TLS_DEBUG, "exit already scheduled for context"); return; @@ -401,7 +405,6 @@ send_auth_failed(struct context *c, cons static const char auth_failed[] = "AUTH_FAILED"; size_t len; - schedule_exit(c, c->options.scheduled_exit_interval, SIGTERM); len = (client_reason ? strlen(client_reason)+1 : 0) + sizeof(auth_failed); if (len > PUSH_BUNDLE_SIZE) @@ -492,7 +495,7 @@ send_auth_pending_messages(struct tls_mu void send_restart(struct context *c, const char *kill_msg) { - schedule_exit(c, c->options.scheduled_exit_interval, SIGTERM); + schedule_exit(c); send_control_channel_string(c, kill_msg ? kill_msg : "RESTART", D_PUSH); }