Skip to content

fix: send wake request to tunnel on system wake#262

Draft
EhabY wants to merge 4 commits into
mainfrom
fix/send-wake-request-on-system-wake
Draft

fix: send wake request to tunnel on system wake#262
EhabY wants to merge 4 commits into
mainfrom
fix/send-wake-request-on-system-wake

Conversation

@EhabY

@EhabY EhabY commented Jul 13, 2026

Copy link
Copy Markdown

After macOS sleep/wake, Coder Connect can stay unusable for minutes: a short same-network sleep often produces no link-change event, so the tunnel never re-homes its paths until a periodic re-STUN fires (coder/coder#26736).

The daemon-side hook merged in coder/coder#26739 (WakeRequest/WakeResponse, tunnel protocol 1.3). This PR makes Coder Desktop emit it:

  • The helper daemon registers for system power events via IORegisterForSystemPower and reacts only to kIOMessageSystemHasPoweredOn, which is not delivered on dark wake (same semantics as NSWorkspace.didWakeNotification, but deliverable to a daemon, so it works even when the GUI app isn't running).
  • Speaker now advertises protocol 1.3 and records the negotiated version.
  • On wake, the manager sends WakeRequest over the existing tunnel RPC channel, gated on negotiated version >= 1.3 so older daemons are never sent a message they don't understand. Failures and WakeResponse.success are logged; nothing is torn down.
  • vpn.proto synced with the wake messages and vpn.pb.swift regenerated with protoc-gen-swift 1.28.2 (matching the pinned SwiftProtobuf version).

Tests

  • ProtoVersion comparison (Comparable).
  • Handshake exposes the negotiated version (both 1.1 and 1.3 peers).
  • Speaker.wake() round-trip over an in-memory pipe.
  • Speaker.wake() is a no-op against a 1.1 peer.
Decision log
  • Wake source: IORegisterForSystemPower in the helper daemon instead of NSWorkspace.didWakeNotification in the GUI app. kIOMessageSystemHasPoweredOn is only delivered on full wake (not dark wake, per https://developer.apple.com/forums/thread/770517), matching didWakeNotification semantics, and the helper owns the tunnel lifecycle regardless of GUI state. Sleep-related power messages are acknowledged with IOAllowPowerChange to avoid delaying sleep.
  • Version gating: Speaker.handshake() previously discarded the negotiated version; it now stores it, and the wake RPC lives in a Speaker extension typed to the manager role, keeping the gate unit-testable and Manager under the lint size limit.
  • Proto sync: applied only the wake additions instead of a full upstream file sync; upstream reformatted to tabs and added Windows-only StartProgress messages, both of which would add noise. Generated bindings are additive only.
  • Debounce: none client-side; the daemon already debounces wake-triggered rebinds (5s) per fix: add VPN wake rebind hook coder#26739.

Closes #260


Generated by Coder Agents on behalf of @EhabY.

@EhabY EhabY marked this pull request as draft July 13, 2026 14:36
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

1 participant