This allows persisted tun device to be cleaned up for reuse.
This is the minimal change to reach the goal using atexit(),
not sure it is the best way.
Signed-off-by: Alon Bar-Lev <alon.barlev@gmail.com>
---
tunip.h | 1 +
vpnc-script | 5 +++++
vpnc.c | 28 +++++++++++++++++++++++++---
3 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/tunip.h b/tunip.h
index 216fdf0..eaeab5a 100644
--- a/tunip.h
+++ b/tunip.h
@@ -64,6 +64,7 @@ struct sa_block {
int tun_fd; /* fd to host via tun/tap */
char tun_name[IFNAMSIZ];
uint8_t tun_hwaddr[ETH_ALEN];
+ int tun_configured;
struct in_addr dst; /* ip of concentrator, must be set */
struct in_addr src; /* local ip, from getsockname() */
diff --git a/vpnc-script b/vpnc-script
index 0b68623..eb9749d 100755
--- a/vpnc-script
+++ b/vpnc-script
@@ -738,7 +738,9 @@ do_disconnect() {
$IPROUTE -6 addr del $INTERNAL_IP6_NETMASK dev $TUNDEV
fi
fi
+}
+do_destroy() {
destroy_tun_device
}
@@ -767,6 +769,9 @@ case "$reason" in
reconnect)
run_hooks reconnect
;;
+ destroy)
+ do_destroy
+ ;;
*)
echo "unknown reason '$reason'. Maybe vpnc-script is out of date" 1>&2
exit 1
diff --git a/vpnc.c b/vpnc.c
index eaa29fa..66e3560 100644
--- a/vpnc.c
+++ b/vpnc.c
@@ -373,18 +373,40 @@ static void setup_tunnel(struct sa_block *s)
}
}
+static struct sa_block *s_atexit_sa;
+static void close_tunnel(struct sa_block *s);
+static void atexit_close(void)
+{
+ if (s_atexit_sa != NULL) {
+ close_tunnel(s_atexit_sa);
+ s_atexit_sa = NULL;
+ }
+}
+
static void config_tunnel(struct sa_block *s)
{
setenv("VPNGATEWAY", inet_ntoa(s->dst), 1);
setenv("reason", "connect", 1);
system(config[CONFIG_SCRIPT]);
+ s->tun_configured = 1;
+ s_atexit_sa = s;
+ atexit(atexit_close);
}
static void close_tunnel(struct sa_block *s)
{
- setenv("reason", "disconnect", 1);
- system(config[CONFIG_SCRIPT]);
- tun_close(s->tun_fd, s->tun_name);
+ if (s->tun_configured) {
+ s->tun_configured = 0;
+ setenv("reason", "disconnect", 1);
+ system(config[CONFIG_SCRIPT]);
+ }
+ if (s->tun_fd != -1) {
+ tun_close(s->tun_fd, s->tun_name);
+ if (!config[CONFIG_IF_NAME]) {
+ setenv("reason", "destroy", 1);
+ system(config[CONFIG_SCRIPT]);
+ }
+ }
}
static int recv_ignore_dup(struct sa_block *s, void *recvbuf, size_t recvbufsize)
--
1.8.1.5
_______________________________________________
vpnc-devel mailing list
vpnc-devel@unix-ag.uni-kl.de
https://lists.unix-ag.uni-kl.de/mailman/listinfo/vpnc-devel
http://www.unix-ag.uni-kl.de/~massar/vpnc/
This is the minimal change to reach the goal using atexit(),
not sure it is the best way.
Signed-off-by: Alon Bar-Lev <alon.barlev@gmail.com>
---
tunip.h | 1 +
vpnc-script | 5 +++++
vpnc.c | 28 +++++++++++++++++++++++++---
3 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/tunip.h b/tunip.h
index 216fdf0..eaeab5a 100644
--- a/tunip.h
+++ b/tunip.h
@@ -64,6 +64,7 @@ struct sa_block {
int tun_fd; /* fd to host via tun/tap */
char tun_name[IFNAMSIZ];
uint8_t tun_hwaddr[ETH_ALEN];
+ int tun_configured;
struct in_addr dst; /* ip of concentrator, must be set */
struct in_addr src; /* local ip, from getsockname() */
diff --git a/vpnc-script b/vpnc-script
index 0b68623..eb9749d 100755
--- a/vpnc-script
+++ b/vpnc-script
@@ -738,7 +738,9 @@ do_disconnect() {
$IPROUTE -6 addr del $INTERNAL_IP6_NETMASK dev $TUNDEV
fi
fi
+}
+do_destroy() {
destroy_tun_device
}
@@ -767,6 +769,9 @@ case "$reason" in
reconnect)
run_hooks reconnect
;;
+ destroy)
+ do_destroy
+ ;;
*)
echo "unknown reason '$reason'. Maybe vpnc-script is out of date" 1>&2
exit 1
diff --git a/vpnc.c b/vpnc.c
index eaa29fa..66e3560 100644
--- a/vpnc.c
+++ b/vpnc.c
@@ -373,18 +373,40 @@ static void setup_tunnel(struct sa_block *s)
}
}
+static struct sa_block *s_atexit_sa;
+static void close_tunnel(struct sa_block *s);
+static void atexit_close(void)
+{
+ if (s_atexit_sa != NULL) {
+ close_tunnel(s_atexit_sa);
+ s_atexit_sa = NULL;
+ }
+}
+
static void config_tunnel(struct sa_block *s)
{
setenv("VPNGATEWAY", inet_ntoa(s->dst), 1);
setenv("reason", "connect", 1);
system(config[CONFIG_SCRIPT]);
+ s->tun_configured = 1;
+ s_atexit_sa = s;
+ atexit(atexit_close);
}
static void close_tunnel(struct sa_block *s)
{
- setenv("reason", "disconnect", 1);
- system(config[CONFIG_SCRIPT]);
- tun_close(s->tun_fd, s->tun_name);
+ if (s->tun_configured) {
+ s->tun_configured = 0;
+ setenv("reason", "disconnect", 1);
+ system(config[CONFIG_SCRIPT]);
+ }
+ if (s->tun_fd != -1) {
+ tun_close(s->tun_fd, s->tun_name);
+ if (!config[CONFIG_IF_NAME]) {
+ setenv("reason", "destroy", 1);
+ system(config[CONFIG_SCRIPT]);
+ }
+ }
}
static int recv_ignore_dup(struct sa_block *s, void *recvbuf, size_t recvbufsize)
--
1.8.1.5
_______________________________________________
vpnc-devel mailing list
vpnc-devel@unix-ag.uni-kl.de
https://lists.unix-ag.uni-kl.de/mailman/listinfo/vpnc-devel
http://www.unix-ag.uni-kl.de/~massar/vpnc/