Our tunnel carries IP packets inside a single TLS-over-TCP connection on :443, and there is no UDP path anywhere in the stack. The node opens one TCP listener (node/cmd/server/main.go, tunnel.New(subnet, subnet6, 1420)), and both clients hand-roll TLS 1.3 over a raw TCP socket (ios/APNExtension/TLSWire.swift, SwiftNIO ClientBootstrap; android/src/main/java/tech/apn/vpn/TLSWire.kt, SocketChannel). Every inner flow shares one reliable ordered byte stream.
This is the classic TCP-over-TCP problem: because inner TCP rides an outer reliable stream, a single lost or dropped outer segment stalls all inner flows until it is retransmitted (head-of-line blocking). WireGuard is UDP-based precisely to avoid this (general VPN design principle). The MSS clamp in node/internal/tunnel/tunnel.go and the 1280 client MTU only limit fragmentation; they do not address meltdown. Worse, theories.md (PROOF #2) shows Russia's TSPU implements its freeze as a surgical retransmit black-hole — it drops one segment and every retransmission of it, wedging a permanent head-of-line hole while the socket still looks alive — which our single-TCP design is maximally exposed to. theories.md itself lists "leave the TCP-TLS bucket (QUIC / non-TLS)" as an escape lever.
Add an optional QUIC / HTTP-3 masquerade transport alongside the existing TLS-over-TCP one: QUIC on :443/UDP is legitimate modern HTTPS (keeps the cover story), gives independent streams (no cross-flow head-of-line blocking), and its connection migration lets a session survive an IP/port change without re-handshaking (which also cuts our roaming/reconnect cost). Concrete first step: a node-side QUIC listener behind an env flag (e.g. APN_QUIC), advertised to clients through the existing Peer/Property SNI+port fields in pong.proto, with TLS-over-TCP kept as the fallback for UDP-blocked networks. This is an enhancement, not a defect; filing per a WireGuard comparison review.
Our tunnel carries IP packets inside a single TLS-over-TCP connection on :443, and there is no UDP path anywhere in the stack. The node opens one TCP listener (
node/cmd/server/main.go,tunnel.New(subnet, subnet6, 1420)), and both clients hand-roll TLS 1.3 over a raw TCP socket (ios/APNExtension/TLSWire.swift, SwiftNIOClientBootstrap;android/src/main/java/tech/apn/vpn/TLSWire.kt,SocketChannel). Every inner flow shares one reliable ordered byte stream.This is the classic TCP-over-TCP problem: because inner TCP rides an outer reliable stream, a single lost or dropped outer segment stalls all inner flows until it is retransmitted (head-of-line blocking). WireGuard is UDP-based precisely to avoid this (general VPN design principle). The MSS clamp in
node/internal/tunnel/tunnel.goand the 1280 client MTU only limit fragmentation; they do not address meltdown. Worse,theories.md(PROOF #2) shows Russia's TSPU implements its freeze as a surgical retransmit black-hole — it drops one segment and every retransmission of it, wedging a permanent head-of-line hole while the socket still looks alive — which our single-TCP design is maximally exposed to.theories.mditself lists "leave the TCP-TLS bucket (QUIC / non-TLS)" as an escape lever.Add an optional QUIC / HTTP-3 masquerade transport alongside the existing TLS-over-TCP one: QUIC on :443/UDP is legitimate modern HTTPS (keeps the cover story), gives independent streams (no cross-flow head-of-line blocking), and its connection migration lets a session survive an IP/port change without re-handshaking (which also cuts our roaming/reconnect cost). Concrete first step: a node-side QUIC listener behind an env flag (e.g.
APN_QUIC), advertised to clients through the existingPeer/PropertySNI+port fields inpong.proto, with TLS-over-TCP kept as the fallback for UDP-blocked networks. This is an enhancement, not a defect; filing per a WireGuard comparison review.