[vpnc-devel] Script when connection is ended?

David Woodhouse dwmw2 at infradead.org
Fri Aug 13 07:31:45 EDT 2010


On Fri, 2010-08-13 at 09:57 +0100, David Woodhouse wrote:
> However, before changing the interface to vpnc-script by adding a new
> variable like this, we should talk to vpnc folks and see if they want to
> add something similar. 

Something like this... I'd prefer to use the same string that we
generate in the end of vpnc_main_loop() but figured it was slightly
cleaner just to act on the numeric return value.

diff --git a/tunip.c b/tunip.c
index 5fd42a8..83319ae 100644
--- a/tunip.c
+++ b/tunip.c
@@ -981,7 +981,7 @@ static void write_pidfile(const char *pidfile)
 	fclose(pf);
 }
 
-void vpnc_doit(struct sa_block *s)
+int vpnc_doit(struct sa_block *s)
 {
 	struct sigaction act;
 	struct encap_method meth;
@@ -1065,4 +1065,6 @@ void vpnc_doit(struct sa_block *s)
 
 	if (pidfile)
 		unlink(pidfile); /* ignore errors */
+
+	return do_kill;
 }
diff --git a/tunip.h b/tunip.h
index fb82ff3..8c8d204 100644
--- a/tunip.h
+++ b/tunip.h
@@ -124,6 +124,6 @@ struct sa_block {
 };
 
 extern int volatile do_kill;
-extern void vpnc_doit(struct sa_block *s);
+extern int vpnc_doit(struct sa_block *s);
 
 #endif
diff --git a/vpnc.c b/vpnc.c
index e53c81b..21b0905 100644
--- a/vpnc.c
+++ b/vpnc.c
@@ -358,9 +358,10 @@ static void config_tunnel(struct sa_block *s)
 	system(config[CONFIG_SCRIPT]);
 }
 
-static void close_tunnel(struct sa_block *s)
+static void close_tunnel(struct sa_block *s, const char *reason)
 {
 	setenv("reason", "disconnect", 1);
+	setenv("CISCO_DISCONNECT_REASON", reason, 1);
 	system(config[CONFIG_SCRIPT]);
 	tun_close(s->tun_fd, s->tun_name);
 }
@@ -2792,7 +2793,7 @@ static void do_phase2_qm(struct sa_block *s)
 
 			s->esp_fd = socket(PF_INET, SOCK_RAW, IPPROTO_ESP);
 			if (s->esp_fd == -1) {
-				close_tunnel(s);
+				close_tunnel(s, "Opening ESP socket failed");
 				error(1, errno, "Couldn't open socket of ESP. Maybe something registered ESP already.\nPlease try '--natt-mode force-natt' or disable whatever is using ESP.\nsocket(PF_INET, SOCK_RAW, IPPROTO_ESP)");
 			}
 #ifdef FD_CLOEXEC
@@ -2801,7 +2802,7 @@ static void do_phase2_qm(struct sa_block *s)
 #endif
 #ifdef IP_HDRINCL
 			if (setsockopt(s->esp_fd, IPPROTO_IP, IP_HDRINCL, &hincl, sizeof(hincl)) == -1) {
-				close_tunnel(s);
+				close_tunnel(s, "setsockopt(IPHDRINCL) failed");
 				error(1, errno, "setsockopt(esp_fd, IPPROTO_IP, IP_HDRINCL, 1)");
 			}
 #endif
@@ -3124,7 +3125,7 @@ void process_late_ike(struct sa_block *s, uint8_t *r_packet, ssize_t r_length)
 
 int main(int argc, char **argv)
 {
-	int do_load_balance;
+	int reason, do_load_balance;
 	const uint8_t hex_test[] = { 0, 1, 2, 3 };
 	struct sa_block oursa[1];
 	struct sa_block *s = oursa;
@@ -3173,7 +3174,7 @@ int main(int argc, char **argv)
 	config_tunnel(s);
 	do_phase2_qm(s);
 	DEBUGTOP(2, printf("S7.9 main loop (receive and transmit ipsec packets)\n"));
-	vpnc_doit(s);
+	reason = vpnc_doit(s);
 
 	/* Tear down phase 2 and 1 tunnels */
 	send_delete_ipsec(s);
@@ -3181,7 +3182,15 @@ int main(int argc, char **argv)
 
 	/* Cleanup routing */
 	DEBUGTOP(2, printf("S8 close_tunnel\n"));
-	close_tunnel(s);
+	if (reason == -2)
+		close_tunnel(s, "connection terminated by dead peer detection");
+	else if (reason == -1)
+		close_tunnel(s, "connection terminated by peer");
+	else {
+		char buf[80];
+		sprintf(buf, "terminated by signal: %d", reason);
+		close_tunnel(s, buf);
+	}
 
 	/* Free resources */
 	DEBUGTOP(2, printf("S9 cleanup\n"));

-- 
dwmw2




More information about the openconnect-devel mailing list