From: Daniel Lenski Date: Fri, 25 Sep 2020 00:14:00 +0000 (-0700) Subject: add working do_attempt_reconnect X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=7526802233c74651c3a42cb87b8b160352f55e00;p=users%2Fdwmw2%2Fvpnc-scripts.git add working do_attempt_reconnect This initial implementation requires iproute2. It find all routes that match the VPN gateway (excluding those matching "dev $TUNDEV", since the goal is to prevent loopback), and simply tries adding them one-by-one. See https://gitlab.com/openconnect/openconnect/-/issues/17 for the original motivation for adding `reason=attempt-reconnect`. See https://github.com/dlenski/vpn-slice/pull/14#issuecomment-489293114 for a discussion of the complexities of implementing it correctly. Signed-off-by: Daniel Lenski --- diff --git a/vpnc-script b/vpnc-script index 4e2d6ea..4749c8c 100755 --- a/vpnc-script +++ b/vpnc-script @@ -245,6 +245,22 @@ if [ -n "$IPROUTE" ]; then $IPROUTE route flush cache 2>/dev/null } + set_vpngateway_route_attempt_reconnect() { + # We'll attempt to add a host route to the gateway through every route that matches + # its address (excluding those through TUNDEV because the goal is to avoid loopback). + + echo "$VPNGATEWAY" | grep -q : && FAMILY=-6 ROOT=::/0 || FAMILY=-4 ROOT=0/0 + $IPROUTE $FAMILY route show to "$VPNGATEWAY" root "$ROOT" | grep -v "dev $TUNDEV" | cut -d' ' -f2- | + while read LINE ; do + # We do not want to use 'replace', since a route to the gateway that already + # exists is mostly likely the correct one (e.g. the case of a reconnect attempt + # after dead-peer detection, but no change in the underlying network devices). + # Using "add" will succeed at most once + $IPROUTE $FAMILY route add `echo "$VPNGATEWAY $LINE" | fix_ip_get_output` 2>/dev/null && break + done + $IPROUTE $FAMILY route flush cache 2>/dev/null + } + del_vpngateway_route() { $IPROUTE route $route_syntax_del "$VPNGATEWAY" $IPROUTE route flush cache 2>/dev/null @@ -369,6 +385,11 @@ else # use route command route add -host "$VPNGATEWAY" $route_syntax_gw "`get_default_gw`" } + set_vpngateway_route_attempt_reconnect() { + # FIXME: needs implementation similar to IPROUTE version + set_vpngateway_route + } + del_vpngateway_route() { route $route_syntax_del -host "$VPNGATEWAY" $route_syntax_gw "`get_default_gw`" } @@ -1047,6 +1068,10 @@ do_disconnect() { destroy_tun_device } +do_attempt_reconnect() { + set_vpngateway_route_attempt_reconnect +} + #### Main if [ -z "$reason" ]; then @@ -1075,6 +1100,8 @@ case "$reason" in # be left with a route to the VPN server through the VPN # itself, which would need to be fixed. run_hooks attempt-reconnect + do_attempt_reconnect + run_hooks post-attempt-reconnect ;; reconnect) # After successfully re-establishing the session.