diff --git a/cstp.c b/cstp.c index 2adef393..b1235ef5 100644 --- a/cstp.c +++ b/cstp.c @@ -322,6 +322,8 @@ static int start_cstp_connection(struct openconnect_info *vpninfo) if (dtlsmtu > mtu) mtu = dtlsmtu; } else if (!strcmp(buf + 7, "Session-ID")) { + int dtls_sessid_changed = 0; + if (strlen(colon) != 64) { vpn_progress(vpninfo, PRG_ERR, _("X-DTLS-Session-ID not 64 characters; is: \"%s\"\n"), @@ -329,9 +331,17 @@ static int start_cstp_connection(struct openconnect_info *vpninfo) vpninfo->dtls_attempt_period = 0; return -EINVAL; } - for (i = 0; i < 64; i += 2) - vpninfo->dtls_session_id[i/2] = unhex(colon + i); + for (i = 0; i < 64; i += 2) { + unsigned char c = unhex(colon + i); + if (vpninfo->dtls_session_id[i/2] != c) { + vpninfo->dtls_session_id[i/2] = c; + dtls_sessid_changed = 1; + } + } sessid_found = 1; + + if (dtls_sessid_changed && vpninfo->dtls_state > DTLS_SLEEPING) + vpninfo->dtls_need_reconnect = 1; } continue; } @@ -922,9 +932,9 @@ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout) do_dtls_reconnect: /* succeeded, let's rekey DTLS, if it is not rekeying * itself. */ - if (vpninfo->dtls_state != DTLS_DISABLED && + if (vpninfo->dtls_state > DTLS_SLEEPING && vpninfo->dtls_times.rekey_method == REKEY_NONE) { - dtls_reconnect(vpninfo); + vpninfo->dtls_need_reconnect = 1; } return 1; diff --git a/dtls.c b/dtls.c index 565983e8..c44f99cd 100644 --- a/dtls.c +++ b/dtls.c @@ -586,7 +586,7 @@ void dtls_close(struct openconnect_info *vpninfo) } } -int dtls_reconnect(struct openconnect_info *vpninfo) +static int dtls_reconnect(struct openconnect_info *vpninfo) { dtls_close(vpninfo); vpninfo->dtls_state = DTLS_SLEEPING; @@ -685,6 +685,12 @@ int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout) int work_done = 0; char magic_pkt; + if (vpninfo->dtls_need_reconnect) { + vpninfo->dtls_need_reconnect = 0; + dtls_reconnect(vpninfo); + return 1; + } + if (vpninfo->dtls_state == DTLS_CONNECTING) { dtls_try_handshake(vpninfo); return 0; @@ -903,11 +909,6 @@ int openconnect_setup_dtls(struct openconnect_info *vpninfo, int dtls_attempt_pe return -EINVAL; } -int dtls_reconnect(struct openconnect_info *vpninfo) -{ - return -EINVAL; -} - void dtls_close(struct openconnect_info *vpninfo) { } diff --git a/openconnect-internal.h b/openconnect-internal.h index bc377091..9722b470 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -369,6 +369,7 @@ struct openconnect_info { char *cstp_cipher; int dtls_state; + int dtls_need_reconnect; struct keepalive_info dtls_times; unsigned char dtls_session_id[32]; unsigned char dtls_secret[48]; @@ -601,7 +602,6 @@ int dtls_try_handshake(struct openconnect_info *vpninfo); int connect_dtls_socket(struct openconnect_info *vpninfo); void dtls_close(struct openconnect_info *vpninfo); void dtls_shutdown(struct openconnect_info *vpninfo); -int dtls_reconnect(struct openconnect_info *vpninfo); /* cstp.c */ int cstp_mainloop(struct openconnect_info *vpninfo, int *timeout);