From fca41e2fa294ac53770b240ee0ed663b6632cbb8 Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Mon, 6 Apr 2020 14:21:34 +0200 Subject: [PATCH] Distinguish the bye packet interpretation In openconnect client the BYE packet indicates an explicit user disconnect by sending 0x0b as payload. In anyconnect clients it may indicate an intention to reconnect (e.g., because network was changed). We introduce a check for 0x0b to identify the user disconnect and add debugging output for other disconnect reasons. Relates: #281 Signed-off-by: Nikos Mavrogiannopoulos --- src/common/common.c | 2 ++ src/defs.h | 1 + src/worker-vpn.c | 16 +++++++++++++++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/common/common.c b/src/common/common.c index d5efdcac..d47bc84c 100644 --- a/src/common/common.c +++ b/src/common/common.c @@ -170,6 +170,8 @@ const char *discon_reason_to_str(unsigned reason) return "unspecified"; case REASON_USER_DISCONNECT: return "user disconnected"; + case REASON_TEMP_DISCONNECT: + return "anyconnect client disconnected"; case REASON_SERVER_DISCONNECT: return "server disconnected"; case REASON_IDLE_TIMEOUT: diff --git a/src/defs.h b/src/defs.h index e007eba2..5f2430d1 100644 --- a/src/defs.h +++ b/src/defs.h @@ -37,6 +37,7 @@ #define REASON_DPD_TIMEOUT 5 #define REASON_ERROR 6 #define REASON_SESSION_TIMEOUT 7 +#define REASON_TEMP_DISCONNECT 8 /* Timeout (secs) for communication between main and sec-mod */ #define MAIN_SEC_MOD_TIMEOUT 120 diff --git a/src/worker-vpn.c b/src/worker-vpn.c index 4080054a..8b872656 100644 --- a/src/worker-vpn.c +++ b/src/worker-vpn.c @@ -2514,7 +2514,21 @@ static int parse_data(struct worker_st *ws, uint8_t *buf, size_t buf_size, break; case AC_PKT_DISCONN: oclog(ws, LOG_INFO, "received BYE packet; exiting"); - exit_worker_reason(ws, REASON_USER_DISCONNECT); + /* In openconnect the BYE packet indicates an explicit + * user disconnect. In anyconnect clients it may indicate + * an intention to reconnect (e.g., because network was + * changed). We separate the error codes to ensure we do + * 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) { + oclog(ws, LOG_DEBUG, "bye packet with payload: %u/%.2x", (unsigned)plain_size, plain[0]); + return -1; + } + + exit_worker_reason(ws, REASON_TEMP_DISCONNECT); + } break; case AC_PKT_COMPRESSED: /* decompress */