Files
firezone/swift
Mariusz Klochowicz bdffa3a697 fix(apple): prevent utun increments from IPC calls (#10855)
On macOS, IPC calls to the network extension can wake it whilst not
connected, causing the system to create a utun device.
If startTunnel() is not subsequently called, these devices
persist and accumulate over time.

The existing dryStartStopCycle() mechanism was introduced to wake the
extension after upgrades, but other IPC operations (log management
functions) could also wake the extension without proper cleanup.

Solution
--------

Add wrapper functions in IPCClient that automatically handle wake-up
and cleanup lifecycle for IPC calls made whilst disconnected:

- Check VPN connection status
- If connected: execute IPC operation directly (utun already exists)
- If disconnected: wake extension → wait 500ms → execute IPC → cleanup

Implementation
--------------

For async IPC operations (clearLogs, getLogFolderSize):
  Created free functions in IPCClient that wrap low-level IPC calls
  with wrapIPCCallIfNeeded():
  - clearLogsWithCleanup(store:session:)
  - getLogFolderSizeWithCleanup(store:session:)

For callback-based exportLogs:
  We cannot use wrapper because exportLogs returns immediately and uses
  callbacks for streaming chunks. Wrapper would call stop() before
  export finishes, killing the extension mid-stream.

  Solution: Manual wake-up/cleanup in LogExporter where we already have
  continuation that waits for chunk.done signal:
  1. Check if extension needs waking (vpnStatus != .connected)
  2. If yes: wake extension, wait 500ms
  3. Start export with callbacks
  4. When chunk.done=true: cleanup utun device, then resume continuation
  5. On error: cleanup utun device, then resume with error
  
  
  Fixes #10580

---------

Co-authored-by: Jamil Bou Kheir <jamilbk@users.noreply.github.com>
2025-11-13 22:01:22 +00:00
..