diff --git a/doc/openfortivpn.1.in b/doc/openfortivpn.1.in index d918cfaf..0b8da458 100644 --- a/doc/openfortivpn.1.in +++ b/doc/openfortivpn.1.in @@ -26,6 +26,7 @@ openfortivpn \- Client for PPP+SSL VPN tunnel services [\fB\-\-pppd-plugin=\fI\fR] [\fB\-\-pppd-ipparam=\fI\fR] [\fB\-\-pppd-ifname=\fI\fR] +[\fB\-\-loop\fR] [\fB\-c\fR \fI\fR] [\fB\-v|\-q\fR] .br @@ -125,9 +126,16 @@ Provides an extra parameter to the ip-up, ip-pre-up and ip-down scripts. See man .BR pppd(8) for further details .TP +<<<<<<< 5e9adc7e3fd27ee36b0a00583dce1225226f57a2 \fB\-\-pppd-ifname=\fI\fR Set the ppp interface name. Only if supported by pppd. Patched versions of pppd implement this option but may not be available on your platform. +======= +\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). +>>>>>>> added --loop option for automatic reconnects .TP \fB\-v\fR Increase verbosity. Can be used multiple times to be even more verbose. @@ -233,3 +241,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 54e86854..b81d9b93 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 05d0c3f3..ee67d309 100644 --- a/src/config.h +++ b/src/config.h @@ -68,6 +68,7 @@ struct vpn_config { int pppd_use_peerdns; int use_syslog; int half_internet_routes; + int loop; char *pppd_log; char *pppd_plugin; diff --git a/src/io.c b/src/io.c index a65e2fdd..65dd94d6 100644 --- a/src/io.c +++ b/src/io.c @@ -109,6 +109,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. * @@ -559,6 +567,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 b18d0a0d..f6a7f0db 100644 --- a/src/io.h +++ b/src/io.h @@ -56,4 +56,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 b3cd7b6e..f46046ec 100644 --- a/src/main.c +++ b/src/main.c @@ -34,7 +34,7 @@ " [--pppd-ifname=] [--pppd-ipparam=]\n" \ " [--pppd-plugin=] [--ca-file=]\n" \ " [--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" \ @@ -93,6 +93,8 @@ " --pppd-ifname= Set the pppd interface name, if supported by pppd.\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" \ @@ -181,6 +183,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}, @@ -301,6 +304,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); @@ -427,6 +441,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: