github anton48/vk-turn-proxy-ios v1.0-build86
v1.0-build86 — Path-change resilience + grower cold-start state machine

latest releases: v1.0-build347, v1.0-build314, v1.0-build311...
3 months ago

Combines builds 85→86 (six commits since v1.0-build85). Two themes:
faster recovery from edge-case iOS path events, and smarter cred pool
ramp-up that spreads expirations even better than build 85 did.

Path-change resilience

• iface=other PathMonitor events now extend pause-acquire 5s without
triggering smart-pause re-marking. iOS fires brief "satisfied
iface=other" events (~3s) during physical interface transitions,
where its os-default points at our own TUN device — recursive
routing fallback. Previous code ran smart-pause logic on these
events, which was no-op for marking but the 500ms pause expired
before the new real interface arrived, allowing conns to acquire
fresh slots that would then fail / 486 cascade. Observed in
vpn.over24h.log 2026-05-13 15:26 outage (10-minute pool dead).

• activeAllocationsWindow bumped 10m → 12m. VK TURN allocation
lifetime is 600s from last refresh. Pion refreshes every ~5min,
so worst-case allocation expiry post-conn-death is conn-death + 10m.
Previous threshold of 10m exactly matched VK's lifetime with zero
safety margin → slots whose lastUsedAt was just past 10m got
classified as "ghost expired" by smart-pause and skipped, while VK
could still hold active allocations, leading to 486 cascade. Same
15:26 outage observation — slots 3/4/5 were smart-pause-skipped at
event 1 then 486-cascaded after the path settled.

Grower cold-start state machine

• Cold-start target now scales with NumConns instead of pool ratio.
NumConns=30 → 3 fast-fill slots (was 6 at 50% of pool=12). Saves
user a few seconds at startup AND doubles the staggered portion of
the pool, smoothing expirations 8h later.

• Stagger window 60-240s → 120-300s for wider expiry spread (~3.5min
average gap between maintenance fills, was ~2.5min).

• Two-mode state machine with abort guard inside tryFill at TWO
checkpoints (before fetch + after fetch / before commit). The
post-fetch checkpoint catches the race where conn-driven fetches
in get() complete during the grower's 5-10s PoW window — without
it, grower systematically over-shot cold-start by 1-2 slots
(observed wifi.4.log: 0 → 5 instead of 0 → 3 for NumConns=30).

DNS empirical clarifications

• The "DNS doesn't work in extension" docstring was inherited from a
historical claim that nobody had actually tested. Probed in
pkg/proxy/dns_probe.go (since reverted) at both pre- and
post-bootstrap: cgo getaddrinfo via mDNSResponder XPC works fine
in BOTH windows. Pure-Go resolver fails universally (no usable
/etc/resolv.conf). vk_host_ips pre-resolution is now correctly
framed as latency optimization + defense-in-depth, NOT a hard
requirement. No code change to vk_host_ips path itself; just
docstring updates.

UI / diagnostic

• Connect / Disconnect button presses now log via NSLog +
SharedLogger. Helps distinguish iOS-side stops (NEProviderStopReason
.userInitiated fires for non-user reasons sometimes) from actual
user-initiated disconnects.

Don't miss a new vk-turn-proxy-ios release

NewReleases is sending notifications on new releases.