rather than waiting for a timeout. The
.B n
parameter (default=1) controls the maximum number of attempts that the client
-will try to resend the exit notification message. OpenVPN will not send any exit
+will try to resend the exit notification message.
+
+In UDP server mode, send RESTART control channel command to connected clients. The
+.B n
+parameter (default=1) controls client behavior. With
+.B n
+= 1 client will attempt to reconnect
+to the same server, with
+.B n
+= 2 client will advance to the next server.
+
+OpenVPN will not send any exit
notifications unless this option is enabled.
.\"*********************************************************
.SS Data Channel Encryption Options:
t->options.stale_routes_check_interval, t->options.stale_routes_ageing_time);
event_timeout_init (&m->stale_routes_check_et, t->options.stale_routes_check_interval, 0);
}
+
+ m->deferred_shutdown_signal.signal_received = 0;
}
const char *
/* instance marked for wakeup? */
if (m->earliest_wakeup)
{
- set_prefix (m->earliest_wakeup);
- ret = multi_process_post (m, m->earliest_wakeup, mpp_flags);
+ if (m->earliest_wakeup == (struct multi_instance*)&m->deferred_shutdown_signal)
+ {
+ schedule_remove_entry(m->schedule, (struct schedule_entry*) &m->deferred_shutdown_signal);
+ throw_signal(m->deferred_shutdown_signal.signal_received);
+ }
+ else
+ {
+ set_prefix (m->earliest_wakeup);
+ ret = multi_process_post (m, m->earliest_wakeup, mpp_flags);
+ clear_prefix ();
+ }
m->earliest_wakeup = NULL;
- clear_prefix ();
}
return ret;
}
free_context_buffers (m->top.c2.buffers);
}
+static bool
+is_exit_restart(int sig)
+{
+ return (sig == SIGUSR1 || sig == SIGTERM || sig == SIGHUP || sig == SIGINT);
+}
+
+static void
+multi_push_restart_schedule_exit(struct multi_context *m, bool next_server)
+{
+ struct hash_iterator hi;
+ struct hash_element *he;
+ struct timeval tv;
+
+ /* tell all clients to restart */
+ hash_iterator_init (m->iter, &hi);
+ while ((he = hash_iterator_next (&hi)))
+ {
+ struct multi_instance *mi = (struct multi_instance *) he->value;
+ if (!mi->halt)
+ {
+ send_control_channel_string (&mi->context, next_server ? "RESTART,[N]" : "RESTART", D_PUSH);
+ multi_schedule_context_wakeup(m, mi);
+ }
+ }
+ hash_iterator_free (&hi);
+
+ /* reschedule signal */
+ ASSERT (!openvpn_gettimeofday (&m->deferred_shutdown_signal.wakeup, NULL));
+ tv.tv_sec = 2;
+ tv.tv_usec = 0;
+ tv_add (&m->deferred_shutdown_signal.wakeup, &tv);
+
+ m->deferred_shutdown_signal.signal_received = m->top.sig->signal_received;
+
+ schedule_add_entry (m->schedule,
+ (struct schedule_entry *) &m->deferred_shutdown_signal,
+ &m->deferred_shutdown_signal.wakeup,
+ compute_wakeup_sigma (&m->deferred_shutdown_signal.wakeup));
+
+ m->top.sig->signal_received = 0;
+}
+
/*
* Return true if event loop should break,
* false if it should continue.
m->top.sig->signal_received = 0;
return false;
}
+ else if (proto_is_dgram(m->top.options.ce.proto) &&
+ is_exit_restart(m->top.sig->signal_received) &&
+ (m->deferred_shutdown_signal.signal_received == 0) &&
+ m->top.options.ce.explicit_exit_notification != 0)
+ {
+ multi_push_restart_schedule_exit(m, m->top.options.ce.explicit_exit_notification == 2);
+ return false;
+ }
return true;
}
"--stale-routes-check n [t] : Remove routes with a last activity timestamp\n"
" older than n seconds. Run this check every t\n"
" seconds (defaults to n).\n"
+ "--explicit-exit-notify [n] : In UDP server mode send [RESTART] command on exit/restart to connected\n"
+ " clients. n = 1 - reconnect to same server,\n"
+ " 2 - advance to next server, default=1.\n"
#if PORT_SHARE
"--port-share host port [dir] : When run in TCP mode, proxy incoming HTTPS\n"
" sessions to a web server at host:port. dir specifies an\n"
msg (M_USAGE, "--connect-freq only works with --mode server --proto udp. Try --max-clients instead.");
if (!(dev == DEV_TYPE_TAP || (dev == DEV_TYPE_TUN && options->topology == TOP_SUBNET)) && options->ifconfig_pool_netmask)
msg (M_USAGE, "The third parameter to --ifconfig-pool (netmask) is only valid in --dev tap mode");
-#ifdef ENABLE_OCC
- if (ce->explicit_exit_notification)
- msg (M_USAGE, "--explicit-exit-notify cannot be used with --mode server");
-#endif
if (options->routes && (options->routes->flags & RG_ENABLE))
msg (M_USAGE, "--redirect-gateway cannot be used with --mode server (however --push \"redirect-gateway\" is fine)");
if (options->route_delay_defined)