From c33847c23d985cbd272dc870d0a75d6971b700f4 Mon Sep 17 00:00:00 2001 From: Martin Hecht Date: Thu, 17 Aug 2017 15:48:57 +0200 Subject: [PATCH] added --loop option for automatic reconnects --- doc/openfortivpn.1.in | 8 ++++++++ src/config.c | 9 +++++++++ src/config.h | 2 ++ src/io.c | 9 +++++++++ src/io.h | 2 ++ src/main.c | 21 ++++++++++++++++++++- 6 files changed, 50 insertions(+), 1 deletion(-) diff --git a/doc/openfortivpn.1.in b/doc/openfortivpn.1.in index 20838adb..9e57bb02 100644 --- a/doc/openfortivpn.1.in +++ b/doc/openfortivpn.1.in @@ -25,6 +25,7 @@ openfortivpn \- Client for PPP+SSL VPN tunnel services [\fB\-\-pppd-log=\fI\fR] [\fB\-\-pppd-plugin=\fI\fR] [\fB\-\-pppd-ipparam=\fI\fR] +[\fB\-\-loop\fR] [\fB\-c\fR \fI\fR] [\fB\-v|\-q\fR] .br @@ -124,6 +125,11 @@ Provides an extra parameter to the ip-up, ip-pre-up and ip-down scripts. see man .BR pppd(8) for further details .TP +\fB\-\-loop\=\fIfR +Runs the vpn in an endless loop and tries to reconnect forever. +The reconnect interval may be specified in seconds, where 0 means +no reconnect is done (this is the default). +.TP \fB\-v\fR Increase verbosity. Can be used multiple times to be even more verbose. .TP @@ -188,3 +194,5 @@ pppd-use-peerdns = 1 insecure-ssl = 0 .br cipher-list = HIGH:!aNULL:!kRSA:!PSK:!SRP:!MD5:!RC4 +.br +loop = 0 diff --git a/src/config.c b/src/config.c index ae9b4910..d57df2ab 100644 --- a/src/config.c +++ b/src/config.c @@ -200,6 +200,15 @@ int load_config(struct vpn_config *cfg, const char *filename) continue; } cfg->half_internet_routes = half_internet_routes; + } else if (strcmp(key, "loop") == 0) { + long int loop = strtol(val, NULL, 0); + if (loop < 0) { + log_warn("Bad loop in config file:" \ + " \"%s\".\n", + val); + continue; + } + cfg->loop =loop; } else if (strcmp(key, "pppd-use-peerdns") == 0) { int pppd_use_peerdns = strtob(val); if (pppd_use_peerdns < 0) { diff --git a/src/config.h b/src/config.h index 120edb6f..6156c5f2 100644 --- a/src/config.h +++ b/src/config.h @@ -67,6 +67,7 @@ struct vpn_config { int pppd_use_peerdns; int use_syslog; int half_internet_routes; + int loop; char *pppd_log; char *pppd_plugin; @@ -94,6 +95,7 @@ struct vpn_config { (cfg)->set_dns = 1; \ (cfg)->pppd_use_peerdns = 1; \ (cfg)->half_internet_routes = 0; \ + (cfg)->loop = 0; \ (cfg)->use_syslog = 0; \ (cfg)->pppd_log = NULL; \ (cfg)->pppd_plugin = NULL; \ diff --git a/src/io.c b/src/io.c index 4c4abcf3..a671504c 100644 --- a/src/io.c +++ b/src/io.c @@ -106,6 +106,14 @@ static void destroy_ssl_locks(void) } #endif +// global variable to pass signal out of its handler +volatile sig_atomic_t sig_received = 0; + +int get_sig_received(void) +{ + return (int)sig_received; +} + /* * Adds a new packet to a pool. * @@ -556,6 +564,7 @@ static void *if_config(void *arg) static void sig_handler(int signo) { + sig_received = signo; if (signo == SIGINT || signo == SIGTERM) SEM_POST(&sem_stop_io); } diff --git a/src/io.h b/src/io.h index de951723..1536d711 100644 --- a/src/io.h +++ b/src/io.h @@ -52,4 +52,6 @@ struct tunnel; int io_loop(struct tunnel *tunnel); +int get_sig_received(void); + #endif diff --git a/src/main.c b/src/main.c index 94017759..c900a2eb 100644 --- a/src/main.c +++ b/src/main.c @@ -29,7 +29,7 @@ " [--pppd-no-peerdns] [--pppd-log=]\n" \ " [--pppd-ipparam=] [--pppd-plugin=]\n" \ " [--ca-file=] [--user-cert=] [--user-key=] \n" \ -" [--trusted-cert=] [--use-syslog] \n" \ +" [--trusted-cert=] [--use-syslog] [--loop=]\n" \ " [-c ] [-v|-q]\n" \ " openfortivpn --help\n" \ " openfortivpn --version\n" \ @@ -87,6 +87,8 @@ " resolver and routes directly.\n" \ " --pppd-ipparam= Provides an extra parameter to the ip-up, ip-pre-up\n" \ " and ip-down scripts. see man (8) pppd\n" \ +" --loop= Run the vpn in a loop and try to reconnect every\n" \ +" seconds\n" \ " -v Increase verbosity. Can be used multiple times\n" \ " to be even more verbose.\n" \ " -q Decrease verbosity. Can be used multiple times\n" \ @@ -142,6 +144,7 @@ int main(int argc, char **argv) {"no-dns", no_argument, &cfg.set_dns, 0}, {"pppd-no-peerdns", no_argument, &cfg.pppd_use_peerdns, 0}, {"use-syslog", no_argument, &cfg.use_syslog, 1}, + {"loop", required_argument, 0, 0}, {"ca-file", required_argument, 0, 0}, {"user-cert", required_argument, 0, 0}, {"user-key", required_argument, 0, 0}, @@ -254,6 +257,17 @@ int main(int argc, char **argv) cfg.half_internet_routes = half_internet_routes; break; } + if (strcmp(long_options[option_index].name, + "loop") == 0) { + long int loop = strtol(optarg, NULL, 0); + if (loop < 0) { + log_warn("Bad loop option: " \ + "\"%s\"\n", optarg); + break; + } + cfg.loop = loop; + break; + } if (strcmp(long_options[option_index].name, "set-dns") == 0) { int set_dns = strtob(optarg); @@ -380,6 +394,11 @@ int main(int argc, char **argv) if (run_tunnel(&cfg) == 0) ret = EXIT_SUCCESS; + while ((ret == EXIT_SUCCESS) && (cfg.loop!=0) && (get_sig_received()==0)) { + sleep(cfg.loop); + if (run_tunnel(&cfg) != 0) + ret = EXIT_FAILURE; + } goto exit; user_error: