a974abdaa2
The v3.4.2 fix injected the server-IP bypass into `SplitRoutes::direct_hosts` but the macOS apply plan emitted the bypass commands AFTER the two half-Internet routes. There's a ~tens-of-ms race window during which: 1. `route add -net 0.0.0.0/1 -interface utunN` ← installed 2. `route add -net 128.0.0.0/1 -interface utunN` ← installed; 187.77.67.17 now matches `128.0.0.0/1` and routes to utunN 3. *kernel re-resolves routes for the live TCP socket Aura is using to talk to 187.77.67.17* — packets briefly enter utunN → infinite recursion → the socket sees a stall and the inner data plane collapses 4. `route add -host 187.77.67.17 192.168.1.254` ← finally bypasses, but too late — TCP is already in a bad state This matches the user's "Aura умирает через пару секунд после подключения" symptom verbatim. Server side saw `rx_packets` grow once (a few frames from the cover-traffic loop) and then `tx_packets` flatline at zero — exactly what happens when the upstream is dead. Fix: reorder `macos_apply_plan` for `DefaultAction::Vpn` so all bypasses (direct_cidrs + direct_hosts) install FIRST. When the half-Internet routes finally land, the kernel's longest-prefix-match already has the /32 bypass for the server IP ready, so the in-flight TCP socket keeps egressing via en0 throughout. Test updated to assert the new plan order: [0] direct CIDR via gateway [1] direct host via gateway (-host) [2] 0.0.0.0/1 via -interface utun [3] 128.0.0.0/1 via -interface utun 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>