#495·boringtun

0.7.1 regression: sessions go one-way deaf ~15-30s after handshake (0.6.0 stable)

Author: onnimonniCreated Aug 29, 2026Updated Aug 29, 2026

Summary

With 0.7.1 (Tunn as a library, no tun device), established sessions go one-way deaf ~15–30 s after each handshake: the peer (ProtonVPN server) stops sending transport packets entirely, while handshake initiations still get responses within ~30 ms. Traffic recovers only when the KEEPALIVE + REKEY_TIMEOUT timer fires a new handshake ~15 s later. Result: ~15 % of client requests time out, cycle repeats every ~30 s.

Pinning boringtun = "0.6.0" with otherwise identical code fixes it completely.

Environment

  • boringtun 0.7.1 vs 0.6.0, default-features = false, Tunn API only (onetun-style: smoltcp virtual stack, single UDP socket, update_timers every 250 ms)
  • macOS 15 (arm64), server: ProtonVPN (multiple servers, same result), keepalive 25 s

Evidence

  • 40 TCP fetches through the tunnel, one every 3 s: 0.7.1 → 34/40 ok, 0.6.0 → 40/40 ok; onetun 0.3.10 (boringtun 0.6) on the same server/network → 40/40.
  • During a deaf window: zero datagrams arrive on the UDP socket (kernel Recv-Q stays 0, no decapsulate errors), yet a handshake initiation sent mid-window is answered in ~30 ms → path and server fine, session state is not.
  • WARN HANDSHAKE(KEEPALIVE + REKEY_TIMEOUT) every ~30 s in logs; each new session repeats the pattern.
  • Ruled out: endpoint roaming (server source never changes), local socket buffer drops, DNS (raw TCP-by-IP shows it too).

Repro sketch

Drive Tunn directly against a WireGuard server (ProtonVPN reproduces reliably): handshake, send steady TCP traffic through it, watch inbound stop ~15–30 s after session establishment while handshakes keep working.

Happy to run diagnostics/bisect builds if useful.