From e1e977f3cc52e230031f8770b0a9c977eab7db69 Mon Sep 17 00:00:00 2001 From: james Date: Mon, 28 Sep 2009 07:27:22 +0000 Subject: Added --server-poll-timeout option : when polling possible remote servers to connect to in a round-robin fashion, spend no more than n seconds waiting for a response before trying the next server. git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@5010 e7ae566f-a301-0410-adde-c780ea21d3b5 --- forward-inline.h | 11 +++++++++++ forward.c | 17 +++++++++++++++++ init.c | 10 ++++++++++ openvpn.8 | 7 +++++++ openvpn.h | 2 ++ options.c | 15 +++++++++++++++ options.h | 2 ++ ssl.h | 6 ++++++ 8 files changed, 70 insertions(+) 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? */ diff --git a/forward.c b/forward.c index 2205054..87f3350 100644 --- a/forward.c +++ b/forward.c @@ -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; diff --git a/init.c b/init.c index 9d29af7..20ca0a5 100644 --- a/init.c +++ b/init.c @@ -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 */ diff --git a/openvpn.8 b/openvpn.8 index e9bc113..6f6138b 100644 --- a/openvpn.8 +++ b/openvpn.8 @@ -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 diff --git a/openvpn.h b/openvpn.h index b850fd0..70df9e0 100644 --- a/openvpn.h +++ b/openvpn.h @@ -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 diff --git a/options.c b/options.c index ce16b56..afd804f 100644 --- a/options.c +++ b/options.c @@ -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); diff --git a/options.h b/options.h index fbf0e3c..740e18e 100644 --- a/options.h +++ b/options.h @@ -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 diff --git a/ssl.h b/ssl.h index 910c77c..e7ccb42 100644 --- a/ssl.h +++ b/ssl.h @@ -702,6 +702,12 @@ bool tls_authenticate_key (struct tls_multi *multi, const unsigned int mda_key_i * 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) { -- cgit v1.2.3