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