diff --git a/NEWS b/NEWS index 40fe2de5..520df5f9 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,7 @@ configurable PAM service names, enabling per-vhost PAM stacks (#718) - ocserv-fw-nftables: dropped runtime dependency on ipcalc/ipcalc-ng (#709) - Fixed sudden disconnects after authentication for AnyConnect clients (#706) +- Distinguish disconnect reasons in AnyConnect BYE packets (#732) - Vhosts now inherit configuration options from the default vhost if they are not overridden (#705) - `tunnel-all-dns` now works correctly when set in per-user/group config (#708) diff --git a/src/vpn.h b/src/vpn.h index 4360292a..715f849d 100644 --- a/src/vpn.h +++ b/src/vpn.h @@ -119,6 +119,12 @@ inline static const char *proto_to_str(fw_proto_t proto) #define AC_PKT_COMPRESSED 8 /* Compressed data */ #define AC_PKT_TERM_SERVER 9 /* Server kick */ +/* Disconnect reason for AC_PKT_DISCONN */ +#define AC_BYE_USER_DISCONNECT 0xb0 /* User requested to disconnect */ +#define AC_BYE_LOCAL_ERROR 0x70 /* E.g., unable to modify routing table */ +#define AC_BYE_VPN_RECONNECT 0x91 /* VPN tunnel is reconnecting */ +#define AC_BYE_VPN_PAUSE 0xd1 /* VPN tunnel is paused */ + #define REKEY_METHOD_SSL 1 #define REKEY_METHOD_NEW_TUNNEL 2 diff --git a/src/worker-vpn.c b/src/worker-vpn.c index 5b22fbe2..e0ed7c67 100644 --- a/src/worker-vpn.c +++ b/src/worker-vpn.c @@ -2688,19 +2688,27 @@ static int parse_data(struct worker_st *ws, uint8_t *buf, size_t buf_size, * an intention to reconnect (e.g., because network was * changed). We separate the error codes to ensure we do * not interpret the intention incorrectly (see #281). */ - if (plain_size > 0 && plain[0] == 0xb0) { - exit_worker_reason(ws, REASON_USER_DISCONNECT); - } else { - if (plain_size > 0) { + if (plain_size > 0) { + const uint8_t bye_reason = plain[0]; + + switch (bye_reason) { + case AC_BYE_USER_DISCONNECT: + oclog(ws, LOG_DEBUG, + "User requested to disconnect"); + exit_worker_reason(ws, REASON_USER_DISCONNECT); + case AC_BYE_VPN_RECONNECT: + oclog(ws, LOG_DEBUG, + "VPN tunnel is reconnecting"); + exit_worker_reason(ws, REASON_TEMP_DISCONNECT); + default: oclog_hex(ws, LOG_DEBUG, "bye packet with unknown payload", plain, plain_size, 0); return -1; } - - exit_worker_reason(ws, REASON_TEMP_DISCONNECT); } - break; + exit_worker_reason(ws, REASON_TEMP_DISCONNECT); + case AC_PKT_COMPRESSED: /* decompress */ if (is_dtls == 0) { /* CSTP */