[PATCH 07/10] Fix a really subtle bug causing 100% CPU utilization after ESP tunnel failure, and subsequent reconnect
Daniel Lenski
dlenski at gmail.com
Tue Jan 9 00:01:21 PST 2018
(This was reported at https://github.com/dlenski/openconnect/issues/76.)
Here's what was happening:
1. GlobalProtect connect, start ESP
-> dtls_state = DTLS_CONNECTED, dtls_fd is read-monitored
2. ESP tunnel fails and GP switches to HTTPS (due to network outage, dead peer?),
-> dtls_state = DTLS_NOSECRET, dtls_fd is still read-monitored (!!!)
3. Tunnel restarts (due to rekey or pause-and-reconnect signal, USR2) and
/ssl-vpn/getconfig.esp is repulled, including new ESP keys.
-> dtls_state = DTLS_SECRET, dtls_fd is still read-monitored (!!!)
4. ESP probes are sent out *once* in esp_setup(), but dtls_fd != -1, so the
dtls_state is *not* upgraded to DTLS_SLEEPING.
-> dtls_state = DTLS_SECRET, dtls_fd is still read-monitored (!!!)
As a result of the probes being sent out, ESP packets will subsequently arrive
and select() call in openconnect_mainloop() will wake up… but
udp_mainloop() will never be called to service it because…
if (vpninfo->dtls_state > DTLS_DISABLED) {
...
ret = vpninfo->proto->udp_mainloop(vpninfo, &timeout);
}
This patch fixes that by not just setting dtls_state = DTLS_SECRET when the
HTTPS tunnel connects, but actually calling esp_close_secret (which closes
dtls_fd, unmonitors it, and sets it to -1).
Signed-off-by: Daniel Lenski <dlenski at gmail.com>
---
esp.c | 3 ++-
gpst.c | 3 +--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/esp.c b/esp.c
index 6285ff8..80b4723 100644
--- a/esp.c
+++ b/esp.c
@@ -455,7 +455,8 @@ void esp_close(struct openconnect_info *vpninfo)
void esp_close_secret(struct openconnect_info *vpninfo)
{
esp_close(vpninfo);
- vpninfo->dtls_state = DTLS_NOSECRET;
+ if (vpninfo->dtls_state > DTLS_DISABLED)
+ vpninfo->dtls_state = DTLS_NOSECRET;
}
void esp_shutdown(struct openconnect_info *vpninfo)
diff --git a/gpst.c b/gpst.c
index b314732..092dcca 100644
--- a/gpst.c
+++ b/gpst.c
@@ -648,8 +648,7 @@ static int gpst_connect(struct openconnect_info *vpninfo)
monitor_read_fd(vpninfo, ssl);
monitor_except_fd(vpninfo, ssl);
vpninfo->ssl_times.last_rx = vpninfo->ssl_times.last_tx = time(NULL);
- if (vpninfo->dtls_state != DTLS_DISABLED)
- vpninfo->dtls_state = DTLS_NOSECRET;
+ esp_close_secret(vpninfo);
}
return ret;
--
2.7.4
More information about the openconnect-devel
mailing list