Skip to content

feat: send WakeRequest to the tunnel on system resume - #175

Merged
EhabY merged 4 commits into
mainfrom
feat/send-wake-request-on-system-resume
Jul 20, 2026
Merged

feat: send WakeRequest to the tunnel on system resume#175
EhabY merged 4 commits into
mainfrom
feat/send-wake-request-on-system-resume

Conversation

@EhabY

@EhabY EhabY commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Fixes #172

After the machine sleeps and wakes, the Coder Connect tunnel can stay unusable for several minutes until magicsock's periodic re-STUN recovers the path on its own. The daemon side (coder/coder#26739, tunnel protocol 1.3) added a WakeRequest RPC that forces network path re-discovery on demand. This PR makes the Windows manager emit it on system resume.

Changes

  • Vpn.Proto/vpn.proto: synced with upstream coder/coder; adds WakeRequest / WakeResponse (bindings generated at build time).
  • RpcVersion: Current bumped 1.1 -> 1.3; new IsAtLeast() ordered comparison for version-gating.
  • Speaker: exposes NegotiatedVersion, captured during the handshake (previously discarded).
  • TunnelSupervisor: surfaces the tunnel's NegotiatedVersion through ITunnelSupervisor.
  • SystemResumeMonitor (new): event-based class raising Resumed from SystemEvents.PowerModeChanged; registered as a singleton.
  • Manager: subscribes to Resumed (mirroring the existing IManagerRpc.OnReceive wiring) and sends WakeRequest when the negotiated version is >= 1.3, with a 5s reply timeout. The send is fire-and-forget off the SystemEvents broadcast thread; SendWakeRequest logs and swallows all failures by construction, so nothing can fault the discarded task or affect the running tunnel.

Tests

  • SpeakerTest: negotiated version exposed after handshake.
  • RpcVersionTest: IsAtLeast ordering.
  • ManagerTest (new): wake request sent on the resume event; skipped when the tunnel isn't running or the version is too old; send failures are swallowed.
Implementation decisions
  1. 1.2's last_ping fields were already present in this repo's proto; only the version constant was never bumped, so Current goes straight to 1.3.
  2. Resume detection uses SystemEvents.PowerModeChanged (as suggested in the issue): works in both service and console mode, and SystemEvents runs its own broadcast window thread so no message pump is needed. The service-control-handler alternative (CanHandlePowerEvent/OnPowerEvent) requires subclassing WindowsServiceLifetime and doesn't fire in console/debug mode.
  3. Version gating uses standard ordering (IsAtLeast) rather than an exact-major match, so a future major protocol bump keeps sending wake requests.
  4. Wake is a unary RPC with a 5s timeout rather than pure fire-and-forget at the RPC layer, so unexpected replies can be logged.
  5. The wake gate relies on NegotiatedVersion == null to detect a stopped tunnel, keeping SendWakeRequest side-effect free and unit-testable with a fake ITunnelSupervisor.

This PR was generated with Coder Agents on behalf of @EhabY*.*

After the machine sleeps and wakes, the tunnel can stay unusable for
several minutes because a short, same-network wake often produces no
link-change event that would trigger recovery. The tunnel binary
(tunnel protocol 1.3) accepts a WakeRequest hint that forces network
path re-discovery.

Subscribe to SystemEvents.PowerModeChanged and, on resume, send a
WakeRequest over the existing tunnel RPC channel when the negotiated
protocol version supports it. Failures are logged and never affect the
running tunnel.

Fixes #172
@EhabY
EhabY marked this pull request as draft July 13, 2026 12:49
EhabY added 3 commits July 14, 2026 21:42
- Sync WakeResponse with upstream (success field was removed)
- Convert SystemResumeMonitor to a standard event-based class wired
  into Manager, instead of a hosted service calling into IManager
- Trim comments and condense tests
Rename SupportsFeature to IsAtLeast with standard version ordering so
a future major protocol bump keeps sending wake requests.
@EhabY EhabY self-assigned this Jul 15, 2026
@EhabY
EhabY marked this pull request as ready for review July 16, 2026 12:03
@EhabY
EhabY requested review from ibetitsmike and spikecurtis July 16, 2026 12:04
@EhabY

EhabY commented Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

I've tested this on Windows 11 and it does produce this event even if it's a short sleep or a long one (several hours)

@ibetitsmike

Copy link
Copy Markdown
Contributor

Tested the flow and it seems to improve the reconnection speed. Code LGTM

@matifali

Copy link
Copy Markdown
Member

We would also need to backport the upstream fix once verified to the stable and ESR channel.

@spikecurtis

Copy link
Copy Markdown
Collaborator

@matifali I don't believe such channels exist for Coder Desktop Windows

matifali commented Jul 20, 2026

Copy link
Copy Markdown
Member

I mean the upstream PR this depends on: coder/coder#26739
I may be mistaken, but my understanding is that this needs that PR in the Coder server.

@EhabY

EhabY commented Jul 20, 2026

Copy link
Copy Markdown
Contributor Author

Yes it needs that PR but this event is only emitted if the protocol matches (1.3), so if the server is old then this is a no-op

@EhabY
EhabY merged commit 5094b13 into main Jul 20, 2026
3 checks passed
@EhabY
EhabY deleted the feat/send-wake-request-on-system-resume branch July 20, 2026 13:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Send CoderVPN WakeRequest on system wake to recover tunnel paths

4 participants