diff options
-rw-r--r-- | forward-inline.h | 11 | ||||
-rw-r--r-- | forward.c | 17 | ||||
-rw-r--r-- | init.c | 10 | ||||
-rw-r--r-- | openvpn.8 | 7 | ||||
-rw-r--r-- | openvpn.h | 2 | ||||
-rw-r--r-- | options.c | 15 | ||||
-rw-r--r-- | options.h | 2 | ||||
-rw-r--r-- | ssl.h | 6 |
8 files changed, 70 insertions, 0 deletions
diff --git a/forward-inline.h b/forward-inline.h index c87996d..bb8f542 100644 --- a/forward-inline.h +++ b/forward-inline.h @@ -119,6 +119,17 @@ check_inactivity_timeout (struct context *c) } #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? */ @@ -314,6 +314,19 @@ check_inactivity_timeout_dowork (struct context *c) #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. */ @@ -516,6 +529,10 @@ process_coarse_timers (struct context *c) return; #if P2MP + check_server_poll_timeout (c); + if (c->sig->signal_received) + return; + check_scheduled_exit (c); if (c->sig->signal_received) return; @@ -792,6 +792,11 @@ do_init_timers (struct context *c, bool deferred) 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 */ @@ -1444,10 +1449,15 @@ socket_restart_pause (struct context *c) #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 */ @@ -3279,6 +3279,13 @@ Note that while this option cannot be pushed, it can be controlled 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 @@ -433,6 +433,8 @@ struct context_2 struct md5_state pulled_options_state; struct md5_digest pulled_options_digest; + struct event_timeout server_poll_interval; + struct event_timeout scheduled_exit; #endif @@ -432,6 +432,9 @@ static const char usage_message[] = " 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" @@ -726,6 +729,7 @@ init_options (struct options *o, const bool init_gc) #endif #if P2MP o->scheduled_exit_interval = 5; + o->server_poll_timeout = 0; #endif #ifdef USE_CRYPTO o->ciphername = "BF-CBC"; @@ -4464,6 +4468,12 @@ add_option (struct options *options, { 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")) @@ -4887,6 +4897,11 @@ add_option (struct options *options, 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); @@ -399,6 +399,8 @@ struct options const char *auth_user_pass_file; struct options_pre_pull *pre_pull; + int server_poll_timeout; + int scheduled_exit_interval; #endif @@ -703,6 +703,12 @@ bool tls_authenticate_key (struct tls_multi *multi, const unsigned int mda_key_i */ 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) { if (multi) |