diff --git a/cstp.c b/cstp.c index 0588959e..284dcdf0 100644 --- a/cstp.c +++ b/cstp.c @@ -810,10 +810,17 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout) ->select_wfds if appropriate, so we can just return and wait. Unless it's been stalled for so long that DPD kicks in and we kill the connection. */ - if (ka_stalled_dpd_time(&vpninfo->ssl_times, timeout)) + switch (ka_stalled_action(&vpninfo->ssl_times, timeout)) { + case KA_DPD_DEAD: goto peer_dead; - - return work_done; + case KA_REKEY: + goto do_rekey; + case KA_NONE: + return work_done; + default: + /* This should never happen */ + ; + } } if (ret != vpninfo->current_ssl_pkt->len + 8) { @@ -842,6 +849,7 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout) switch (keepalive_action(&vpninfo->ssl_times, timeout)) { case KA_REKEY: + do_rekey: /* Not that this will ever happen; we don't even process the setting when we're asked for it. */ vpn_progress(vpninfo, PRG_INFO, _("CSTP rekey due\n")); diff --git a/mainloop.c b/mainloop.c index 5f65c677..2d10147e 100644 --- a/mainloop.c +++ b/mainloop.c @@ -136,23 +136,32 @@ int vpn_mainloop(struct openconnect_info *vpninfo) /* Called when the socket is unwritable, to get the deadline for DPD. Returns 1 if DPD deadline has already arrived. */ -int ka_stalled_dpd_time(struct keepalive_info *ka, int *timeout) +int ka_stalled_action(struct keepalive_info *ka, int *timeout) { - time_t now, due; + time_t due, now = time(NULL); + + if (ka->rekey) { + due = ka->last_rekey + ka->rekey; + + if (now >= due) + return KA_REKEY; + + if (*timeout > (due - now) * 1000) + *timeout = (due - now) * 1000; + } if (!ka->dpd) - return 0; + return KA_NONE; - time(&now); due = ka->last_rx + (2 * ka->dpd); if (now > due) - return 1; + return KA_DPD_DEAD; if (*timeout > (due - now) * 1000) *timeout = (due - now) * 1000; - return 0; + return KA_NONE; } diff --git a/openconnect-internal.h b/openconnect-internal.h index 6e0a10b5..be958281 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -377,7 +377,7 @@ int vpn_mainloop(struct openconnect_info *vpninfo); int queue_new_packet(struct pkt **q, void *buf, int len); void queue_packet(struct pkt **q, struct pkt *new); int keepalive_action(struct keepalive_info *ka, int *timeout); -int ka_stalled_dpd_time(struct keepalive_info *ka, int *timeout); +int ka_stalled_action(struct keepalive_info *ka, int *timeout); extern int killed;