github anton48/vk-turn-proxy-ios v1.0-build16
v1.0 Build 16 — Silent degradation detection + filter hardening

latest releases: v1.0-build408, v1.0-build385, v1.0-build380...
5 months ago

Changes from Build 13

Detect silent VK TURN degradation

Adds a third watchdog condition to runWatchdog. It catches the "silent partial death" scenario where VK starts rejecting 8 of 10 pion clients with 400 Bad Request on CreatePermission refresh: the surviving 2 clients keep lastRecvTime fresh, so condition 1 never fires, while throughput quietly collapses to 1/5 of normal. UI shows conns 10/10 and 0 reconnects but nothing actually works.

The new condition counts pion Errorf/Warnf messages that match the whitelist "error response" — which is the substring pion includes in real STUN error response stringifications (CreatePermission error response (error N: ...), unexpected response type ChannelBind error response). When the counter ≥ 10 AND the first error is at least 90 seconds old, the watchdog forces a full reconnect.

The whitelist cleanly excludes local-side noise that would false-positive:

  • transaction closed — from client.Close() during our own ForceReconnect
  • all retransmissions failed — network-level STUN drops
  • use of closed network connection — teardown writes after socket close

Fix lastRecvTime stale-after-reconnect bug

ForceReconnect now resets lastRecvTime to now() so the new session gets a fair 2-minute window before watchdog condition 1 can fire again. Previously the stale lastRecv from before the reconnect (which is exactly why condition 1 had triggered) would re-fire the watchdog on the very next 30-second tick and kill the new session before it had a chance to deliver packets.

Log source-interface address in TURN allocation

The "TURN relay allocated" log now includes the local address of the underlying UDP socket (local=IP:port), which tells us which iOS Network Extension interface was picked — cellular CGNAT 10.x.x.x vs WiFi LAN 192.168.x.x. Used this to rule out a "mixed interface" hypothesis: in practice all 10 sockets always pick the same interface per allocation batch.

Keep diagnostic logging from Build 13

Goroutine exit paths in runDTLSSession and runTURN, plus pion Failed to read / Exiting loop debug messages. Costs nothing in steady state and has helped identify multiple bugs already.

Test results

  • 72 min LTE sleep: 2 reconnects, no false-positive condition 3 pairs (vs ~50% false positives in build 14)
  • 40 min WiFi-only: 0 reconnects, 0 errors, 1 lost ping out of 1794
  • LTE + WiFi auto-join + 30 min sleep: 0 errors, nonce rotation handled cleanly
  • Home WiFi today: no 400 Bad Request cascades (the degradation seen in earlier tests appears to have been transient VK anti-abuse state)

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

NewReleases is sending notifications on new releases.