wgtunnel: client MTU 1420 → 1280 (S3.1, resolve §4.3 open decision)
The 2026-07-04 CGNAT smoke test found MTU 1420 silently black-holes bulk TCP on sub-~1480 paths (mobile ~1400, DS-Lite ~1452): handshake+ping stay healthy, PBS TLS page (and at S4 the backup itself) drops. Set a fleet-wide, permanent, family-agnostic client MTU of 1280 (RFC 8200 IPv6-minimum floor; outer 1340 v4 / 1360 v6 fits every realistic path). Client-only by construction — interface MTU caps box→PBS, advertised MSS caps PBS→box; the endpoint's wg0 is untouched (zero live-endpoint risk). New const clientMTU=1280 as the single home; golden pins exact "MTU = 1280" (red-proofed against a 1420 flip). Stale report.go comment updated. No wire/JSON change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
This commit is contained in:
@@ -140,8 +140,16 @@ func validKeyB64(s string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// clientMTU is the offsite tunnel's interface MTU — the IPv6-minimum floor (RFC 8200 guarantees
|
||||
// every path carries ≥1280). Chosen fleet-wide + family-agnostic so bulk TCP never black-holes on
|
||||
// a constrained path: outer = 1280+60 (v4) / 1280+80 (v6), both fit the mobile ~1400, DS-Lite
|
||||
// ~1452, PPPoE 1492 and clean 1500 cases. Client-only bounds both directions (interface MTU caps
|
||||
// box→PBS; advertised MSS = MTU−40 caps PBS→box), so the endpoint's wg0 stays untouched. Was 1420
|
||||
// (silently black-holed sub-~1480 paths — CGNAT smoke test 2026-07-04). See doc 06 §4.3.
|
||||
const clientMTU = 1280
|
||||
|
||||
// renderConf builds the wg-felhom.conf content from the hub block + the local private key.
|
||||
// Client-side constants per doc 06 §4: MTU 1420, AllowedIPs = pbs_tunnel_ip/32 (the tunnel
|
||||
// Client-side constants per doc 06 §4: MTU 1280, AllowedIPs = pbs_tunnel_ip/32 (the tunnel
|
||||
// carries ONLY box→PBS traffic), PersistentKeepalive 25. All inputs validated — nothing
|
||||
// user-controlled is interpolatable (strict charsets, netip parses).
|
||||
func renderConf(block *hub.WireWireguard, privB64 string) (string, error) {
|
||||
@@ -171,7 +179,7 @@ func renderConf(block *hub.WireWireguard, privB64 string) (string, error) {
|
||||
b.WriteString("[Interface]\n")
|
||||
fmt.Fprintf(&b, "PrivateKey = %s\n", privB64)
|
||||
fmt.Fprintf(&b, "Address = %s\n", block.AssignedIP)
|
||||
b.WriteString("MTU = 1420\n\n")
|
||||
fmt.Fprintf(&b, "MTU = %d\n\n", clientMTU)
|
||||
b.WriteString("[Peer]\n")
|
||||
fmt.Fprintf(&b, "PublicKey = %s\n", block.Endpoint.ServerPubkey)
|
||||
fmt.Fprintf(&b, "Endpoint = %s:%d\n", block.Endpoint.DNSName, block.Endpoint.WGPort)
|
||||
|
||||
Reference in New Issue
Block a user