[WS] Detect disconnection due to protocol errors

When wslay receives a message that is too big or cause a protocol error,
it automatically sends a close request to the remote peer but it also
completely stop calling the receive callback resulting in the state
being "stuck" as CONNECTED (even if both client and server have
disconnected).

We now check if we sent a close message and reading has been disabled to
manually transition to the "closed" state with the proper reason.
This commit is contained in:
Fabio Alessandrelli
2024-10-07 02:01:03 +02:00
parent 1bffd6c73b
commit 6cdfc8c9fe

View File

@ -689,12 +689,37 @@ void WSLPeer::poll() {
close(-1); close(-1);
return; return;
} }
if (wslay_event_get_close_sent(wsl_ctx) && wslay_event_get_close_received(wsl_ctx)) { if (wslay_event_get_close_sent(wsl_ctx)) {
// Clean close. if (wslay_event_get_close_received(wsl_ctx)) {
wslay_event_context_free(wsl_ctx); // Clean close.
wsl_ctx = nullptr; wslay_event_context_free(wsl_ctx);
close(-1); wsl_ctx = nullptr;
return; close(-1);
return;
} else if (!wslay_event_get_read_enabled(wsl_ctx)) {
// Some protocol error caused wslay to stop processing incoming events, we'll never receive a close from the other peer.
close_code = wslay_event_get_status_code_sent(wsl_ctx);
switch (close_code) {
case WSLAY_CODE_MESSAGE_TOO_BIG:
close_reason = "Message too big";
break;
case WSLAY_CODE_PROTOCOL_ERROR:
close_reason = "Protocol error";
break;
case WSLAY_CODE_ABNORMAL_CLOSURE:
close_reason = "Abnormal closure";
break;
case WSLAY_CODE_INVALID_FRAME_PAYLOAD_DATA:
close_reason = "Invalid frame payload data";
break;
default:
close_reason = "Unknown";
}
wslay_event_context_free(wsl_ctx);
wsl_ctx = nullptr;
close(-1);
return;
}
} }
} }
} }