}
#if P2MP
+
+static inline void
+check_server_poll_timeout (struct context *c)
+{
+ void check_server_poll_timeout_dowork (struct context *c);
+
+ if (c->options.server_poll_timeout
+ && event_timeout_trigger (&c->c2.server_poll_interval, &c->c2.timeval, ETT_DEFAULT))
+ check_server_poll_timeout_dowork (c);
+}
+
/*
* Scheduled exit?
*/
#if P2MP
+void
+check_server_poll_timeout_dowork (struct context *c)
+{
+ event_timeout_reset (&c->c2.server_poll_interval);
+ if (!tls_initial_packet_received (c->c2.tls_multi))
+ {
+ msg (M_INFO, "Server poll timeout, restarting");
+ c->sig->signal_received = SIGUSR1;
+ c->sig->signal_text = "server_poll";
+ c->persist.restart_sleep_seconds = -1;
+ }
+}
+
/*
* Schedule a SIGTERM n_seconds from now.
*/
return;
#if P2MP
+ check_server_poll_timeout (c);
+ if (c->sig->signal_received)
+ return;
+
check_scheduled_exit (c);
if (c->sig->signal_received)
return;
if (c->options.ping_rec_timeout)
event_timeout_init (&c->c2.ping_rec_interval, c->options.ping_rec_timeout, now);
+#if P2MP
+ if (c->options.server_poll_timeout)
+ event_timeout_init (&c->c2.server_poll_interval, c->options.server_poll_timeout, now);
+#endif
+
if (!deferred)
{
/* initialize connection establishment timer */
#if P2MP
if (auth_retry_get () == AR_NOINTERACT)
sec = 10;
+
+ if (c->options.server_poll_timeout && sec > 1)
+ sec = 1;
#endif
if (c->persist.restart_sleep_seconds > 0 && c->persist.restart_sleep_seconds > sec)
sec = c->persist.restart_sleep_seconds;
+ else if (c->persist.restart_sleep_seconds == -1)
+ sec = 0;
c->persist.restart_sleep_seconds = 0;
/* do managment hold on context restart, i.e. second, third, fourth, etc. initialization */
from the management interface.
.\"*********************************************************
.TP
+.B --server-poll-timeout n
+when polling possible remote servers to connect to
+in a round-robin fashion, spend no more than
+.B n
+seconds waiting for a response before trying the next server.
+.\"*********************************************************
+.TP
.B --explicit-exit-notify [n]
In UDP client mode or point-to-point mode, send server/peer an exit notification
if tunnel is restarted or OpenVPN process is exited. In client mode, on
struct md5_state pulled_options_state;
struct md5_digest pulled_options_digest;
+ struct event_timeout server_poll_interval;
+
struct event_timeout scheduled_exit;
#endif
" when connecting to a '--mode server' remote host.\n"
"--auth-retry t : How to handle auth failures. Set t to\n"
" none (default), interact, or nointeract.\n"
+ "--server-poll-timeout n : when polling possible remote servers to connect to\n"
+ " in a round-robin fashion, spend no more than n seconds\n"
+ " waiting for a response before trying the next server.\n"
#endif
#ifdef ENABLE_OCC
"--explicit-exit-notify [n] : On exit/restart, send exit signal to\n"
#endif
#if P2MP
o->scheduled_exit_interval = 5;
+ o->server_poll_timeout = 0;
#endif
#ifdef USE_CRYPTO
o->ciphername = "BF-CBC";
{
options->sockflags |= SF_HOST_RANDOMIZE;
}
+#if P2MP
+ else if (streq (p[1], "SERVER_POLL_TIMEOUT") && p[2])
+ {
+ options->server_poll_timeout = positive_atoi(p[2]);
+ }
+#endif
else
{
if (streq (p[1], "FORWARD_COMPATIBLE") && p[2] && streq (p[2], "1"))
VERIFY_PERMISSION (OPT_P_PULL_MODE);
options->push_continuation = atoi(p[1]);
}
+ else if (streq (p[0], "server-poll-timeout") && p[1])
+ {
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ options->server_poll_timeout = positive_atoi(p[1]);
+ }
else if (streq (p[0], "auth-user-pass"))
{
VERIFY_PERMISSION (OPT_P_GENERAL);
const char *auth_user_pass_file;
struct options_pre_pull *pre_pull;
+ int server_poll_timeout;
+
int scheduled_exit_interval;
#endif
* inline functions
*/
+static inline bool
+tls_initial_packet_received (const struct tls_multi *multi)
+{
+ return multi->n_sessions > 0;
+}
+
static inline bool
tls_test_auth_deferred_interval (const struct tls_multi *multi)
{