feat(server): handle client close

Release the session a client close names. A close is bound to a session only
when the token matches and the datagram arrived from that session's exact
endpoint, so holding a token is not by itself authority to tear the session
down: a close from a foreign source port, address, family or IPv6 scope leaves
the session live, and one close cannot take down a sibling session the same
peer opened separately. A token that is unknown, already closed or zero matches
nothing and leaves the table untouched; zero is reserved for no-test replies and
never issued.

Nothing is sent either way. Protocol version 1 defines no acknowledgement for a
client close, so a successful close returns the same `Ok(None)` as a rejected
one and a delivered close is indistinguishable to the client from a lost one.
A standalone `Reply|Close` datagram is tolerated by clients but has no
demonstrated use, so none is encoded.

Authentication still runs before the session is looked up. That keeps a bad MAC
on a live token indistinguishable from an unknown token, and means a close that
fails authentication — missing, wrongly keyed, corrupted, or unexpected on a
server with no key — cannot remove a session. Trailing bytes after the token
stay acceptable: the structural decoder already tolerates them and the server
does not re-parse the request.

The session table remains the only record of how full the server is, so a close
frees capacity immediately and a refused open can succeed once one is released.
Close draws no token and touches no other state; the endpoint lookup borrows
the table only until the comparison is made, so the removal needs no clone.

Echo remains ignored. The test that pinned close as a no-op is replaced by
`tests/close.rs`, which covers removal, silence, repeated close, echo after
close, endpoint binding, unknown/zero/stale tokens, authentication failure,
trailing bytes, sibling sessions and capacity reuse; `unsupported.rs` keeps
echo and structurally invalid traffic.
This commit is contained in:
Nils Andreas Svee committed 2026-08-12 10:30:50 +07:00
1 parent be66a6a61d
commit d269f77c87
8 files changed
+380 -54

No files matched your search

+4 -4
View File
@@ -31,10 +31,10 @@
//!
//! # Current scope
//!
//! Open handling and session creation only. Echo processing, client-initiated
//! close, session lifetime and expiry, and the Tokio runtime are separate
//! slices; structurally valid echo and close requests are currently accepted by
//! the admission boundary and then ignored.
//! Open handling, session creation and client-initiated close. Echo
//! processing, server-initiated close, session lifetime and expiry, and the
//! Tokio runtime are separate slices; a structurally valid echo request is
//! currently accepted by the admission boundary and then ignored.
#![forbid(unsafe_code)]
mod config;