Skip to content

Keepalive is a fixed ~1 Hz beacon that never backs off when idle #189

Description

@davvd

Both clients send a Ping frame roughly every 700-1300 ms for the entire life of the tunnel. The interval starts at one second (ios/APNExtension/APNProvider.swift:288, heartbeat.start(interval: 1); android/.../vpn/Tun.kt:96, hrt.start(1)) and the loop simply reschedules itself at jitter.millis(1s) -> a uniform 0.7-1.3x (ios/APNExtension/ICMPKeepAlive.swift:221; android/.../vpn/ICMPKeepAlive.kt:150). It never adapts to RTT, activity, or idleness. Android compounds this by holding a 24-hour PARTIAL_WAKE_LOCK for the whole session (android/.../vpn/VpnCore.kt:207), keeping the CPU warm about once a second no matter what.

This is wasteful because the node's idle read timeout is 60s (node/internal/server/phone.go:23, refreshed on every frame), so the client only needs to ping about once a minute to stay alive — today it pings roughly 60x more often than required while idle. That is a real battery and data cost (battery is a listed test area), and it is also a stealth liability: theories.md (Theory 2 residual) notes the idle steady state is a jittered but still periodic beacon, which is a classic flow-classifier signal, whereas Xray/Vision emits no heartbeat at all. WireGuard's passive keepalive is 10s and fires only after receiving data with nothing to send, and its persistent-keepalive defaults off (25s when used, purely to hold NAT).

Make the interval adaptive: keep ~1 Hz only while data is actively flowing (plus a short tail), then back off exponentially toward the node's 60s timeout (e.g. 25-45s) when idle, and release or shorten the Android wakelock while idle. The Pong carries lease/fleet state, but that tolerates 30-60s idle freshness, so backing off is safe; keep the existing jitter. Filing per a WireGuard comparison review.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions