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 */