(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