Reconnection problem on roam
David Woodhouse
dwmw2 at infradead.org
Wed Feb 24 09:56:51 EST 2010
On Sun, 2009-12-06 at 13:59 -0500, Colin Jia Zheng wrote:
> > > “netstat -r” gets stuck after printing these lines
> > > Kernel IP routing table
> > > Destination Gateway Genmask Flags MSS Window irtt Iface
> > > 140.247.5.0 * 255.255.255.0 U 0 0 0 wlan0
> > > default
> >
> > OK, this is your problem. The explicit route to the VPN server through
> > your local gateway is gone. Your vpnc-script will have added it, but
> > when you restarted the network, it went away again. You may need to add
> > it back again manually.
>
> Manually adding it back works, thanks you! But how do I know the VPN
> gateway (as VPNGATEWAY in the vpnc script) in general? For now I shall
> simply kill/start openconnect in the network start/shutdown script,
> which is fine. But when roaming (eg when the laptop resumes from RAM
> and automatically reconnects to a different wireless network), I hope
> openconnect could detect connection loss and call the vpnc script to
> reset and then set the routes?
It'll notice the connection loss through dead peer detection, and will
automatically reconnect. Note that this may happen due to a temporary
routing problem or network outage, as well as due to a rehoming -- so
you don't necessarily want to tear down the VPN routes and DNS setup and
then set them up again from scratch, because that could lead to
applications getting incorrect DNS results and/or connecting to external
instead of internal hosts.
The patch below will make openconnect invoke the vpnc-script again with
'reason=reconnecting' before attempting to reconnect. This will allow
the script to check that the route to $VPNGATEWAY doesn't go via
$TUNDEV, and fix things as appropriate.
That's not a trivial thing to do though, even if you were willing to
solve it only for Linux -- it's all very well observing that the
existing route is no good, but finding a _correct_ route to $VPNGATEWAY
that doesn't go through $TUNDEV is left as an exercise for the reader.
In your case, I can't see if you have a second default route or not --
can you post 'route -n' output when this happens?
One option might be to do 'ip route flush dev $TUNDEV' if we notice that
the route to $VPNGATEWAY goes via $TUNDEV, and then set all the VPN
routes up from scratch again. Would that actually work in your case, or
would you be left with _no_ route to the gateway? It's not ideal, since
it does tear down the routes which I said we didn't want to do.
When invoked with 'reason=reconnecting', the script should also repeat
the original routing/DNS setup if necessary -- it should
check /etc/resolv.conf for the @VPNC_GENERATED@ string in case it's been
replaced by (e.g.) a DHCP client, and it should check that all the
appropriate routes to $TUNDEV are in place too.
I'll leave the changes in vpnc-script to you or someone else.
This should be co-ordinated with vpnc, since the same vpnc-script is
used there too. It looks like vpnc will just abort if DPD triggers, and
won't cope with the client being relocated at all. Is that fixable?
diff --git a/cstp.c b/cstp.c
index 2e13d4d..2afabe3 100644
--- a/cstp.c
+++ b/cstp.c
@@ -369,6 +369,8 @@ static int cstp_reconnect(struct openconnect_info *vpninfo)
int timeout;
int interval;
+ script_signal_reconnecting(vpninfo);
+
timeout = vpninfo->reconnect_timeout;
interval = vpninfo->reconnect_interval;
diff --git a/openconnect.h b/openconnect.h
index 3438e78..bec9685 100644
--- a/openconnect.h
+++ b/openconnect.h
@@ -285,6 +285,7 @@ struct openconnect_info {
int setup_tun(struct openconnect_info *vpninfo);
int tun_mainloop(struct openconnect_info *vpninfo, int *timeout);
void shutdown_tun(struct openconnect_info *vpninfo);
+void script_signal_reconnecting(struct openconnect_info *vpninfo);
/* dtls.c */
int setup_dtls(struct openconnect_info *vpninfo);
diff --git a/tun.c b/tun.c
index cdae108..83bee25 100644
--- a/tun.c
+++ b/tun.c
@@ -343,6 +343,13 @@ static int script_config_tun(struct openconnect_info *vpninfo)
return 0;
}
+void script_signal_reconnecting(struct openconnect_info *vpninfo)
+{
+ if (vpninfo->vpnc_script && !vpninfo->script_tun) {
+ setenv("reason", "reconnecting", 1);
+ script_config_tun(vpninfo);
+ }
+}
/* Set up a tuntap device. */
int setup_tun(struct openconnect_info *vpninfo)
--
David Woodhouse Open Source Technology Centre
David.Woodhouse at intel.com Intel Corporation
More information about the openconnect-devel
mailing list