[
https://issues.apache.org/jira/browse/GUACAMOLE-2303?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Ciro Iriarte updated GUACAMOLE-2303:
------------------------------------
Priority: Minor (was: Major)
> [RFC] Optional session resume so a short network drop does not end the session
> ------------------------------------------------------------------------------
>
> Key: GUACAMOLE-2303
> URL: https://issues.apache.org/jira/browse/GUACAMOLE-2303
> Project: Guacamole
> Issue Type: New Feature
> Reporter: Ciro Iriarte
> Priority: Minor
>
> h2. Summary
> Add an optional session-resume capability so a short network drop doesn't end
> a Guacamole session. Today a stall longer than ~15s closes the tunnel, and
> the built-in reconnect starts a new session, so the user loses their work.
> This lets the client rejoin the same live session instead. It's off by
> default.
> h2. Problem
> When the browser-to-server link stalls, the client tunnel's receiveTimeout
> (default 15000ms) fires and the tunnel closes. The built-in reconnect then
> opens a new connection, so the previous guacd session is gone and the user is
> back at a login/parameter prompt with their work lost. There's currently no
> way to recover a session after a drop.
> The 15s threshold is easier to hit than it sounds:
> * TCP retransmission backoff stretches short drops. On a netem test rig, an
> ~8s outage left the tunnel frozen for ~14s, and a 20s outage closed the
> session.
> * Ordinary WAN/mobile events go past it: Wi-Fi handoff and DHCP renewal,
> cellular dead zones, VPN reconnects, laptop sleep/resume, NAT rebinding, and
> background-tab throttling (the client's pings pause and a proxy idle timeout
> then closes the socket).
> h2. Proposal
> Let a reconnecting client rejoin its existing guacd connection instead of
> starting a new one. Three parts:
> # guacd: an optional grace window on connection-sharing teardown. When the
> last user of a connection disconnects, hold it for a configurable number of
> seconds (GUACD_RESUME_GRACE, default 0 = off) before tearing it down, so a
> reconnecting client can rejoin by connection ID. This uses the existing
> {{$<uuid>}} join path.
> # guacamole-client webapp: a session-scoped registry mapping a resume token
> to the guacd connection ID. A reconnect that presents the token rejoins via
> {{select $uuid}} (owner-checked, time-limited), and the old tunnel is closed.
> # guacamole-common-js and the Angular client: a reconnect controller that,
> after a drop on a connection that had reached OPEN, opens a fresh
> WebSocketTunnel on the same Guacamole.Client (keeping display, input, and
> streams), sends the resume token, and redisplays the last frame during the
> gap.
> This also fixes a related problem: a dropped tunnel was reported as a
> terminal TUNNEL_ERROR, which started the existing 15s reconnect-countdown
> notification and replaced the client that had already resumed.
> h2. Configuration and scope
> * Off by default. GUACD_RESUME_GRACE defaults to 0 and the client controller
> is disabled, so existing installs behave exactly as before.
> * Suggested control: enable it per connection, with a server-side maximum
> grace. Calling it "session resume" rather than a broad "WAN mode" seems
> clearer.
> * It should be possible to turn off, and it should be off for share/anonymous
> connections and anywhere a hard drop on disconnect is required.
> h2. Evidence
> * Recovers a 20s outage in every trial (8/8 through an nginx reverse proxy,
> 2/2 direct), rejoining the same guacd session (guacd logs {{Joining existing
> connection $<uuid>}}) with work intact.
> * Tested on SSH and VNC (VNC replays its framebuffer on rejoin).
> * No change to steady-state input latency, which is bound by round-trip time
> and isn't the target here.
> * guacamole-common-js karma tests pass, including new coverage for the
> reconnect tunnel lifecycle.
> h2. Non-goals
> * Not HA or session migration. The registry is per-JVM and in-memory, and
> relies on the same session affinity the existing in-memory auth-token map
> already needs. Rejoining across nodes is out of scope.
> * Not a bandwidth or latency optimization; it's about recovering from a drop.
> h2. Compatibility and risk
> * The grace window holds a guacd session briefly after its last user leaves,
> which changes teardown timing and uses resources, so it's opt-in and bounded.
> * The resume token is currently the client-facing tunnel UUID; an opaque
> single-use token would be a good follow-up.
> * A "reconnecting" overlay with a manual retry is worth adding before
> enabling this widely, since users tend to hit refresh, which throws away the
> client state and prevents the resume.
> h2. Patch
> Implemented on forks, branch wan-optimization:
> * github.com/ciroiriarte/guacamole-server -- guacd grace window
> * github.com/ciroiriarte/guacamole-client -- webapp rebind, client reconnect
> controller, diagnostics
> * github.com/ciroiriarte/guacamole-manual -- reverse-proxy WAN-tuning docs
> I can submit these as separate PRs and adjust the configuration to whatever
> you'd prefer. A reasonable order:
> # diagnostics/telemetry (off by default)
> # client reconnect-lifecycle hardening (ignore stale tunnels, don't raise a
> terminal error during an active retry, clean tunnel swap)
> # the resume feature (guacd grace + webapp rebind + client controller)
> # the reconnecting overlay and manual retry
--
This message was sent by Atlassian Jira
(v8.20.10#820010)