Skip to content

ml_wg_mgr: don't pre-install unvalidated peer endpoints — DERP until DISCO validates - #21

Open
snowpaper wants to merge 1 commit into
CamM2325:mainfrom
snowpaper:fix/no-unvalidated-endpoints
Open

ml_wg_mgr: don't pre-install unvalidated peer endpoints — DERP until DISCO validates#21
snowpaper wants to merge 1 commit into
CamM2325:mainfrom
snowpaper:fix/no-unvalidated-endpoints

Conversation

@snowpaper

Copy link
Copy Markdown

Fixes #18.

At peer-add, the peer's advertised endpoints[0] from the MapResponse was installed as the WireGuard endpoint before any path validation, and wireguardif's output path treats any non-zero endpoint as a working direct path. For a CGNAT peer (cellular hotspot) that address is unreachable — no hole was ever punched — so the tunnel went one-way: inbound arrived via DERP while every outbound data packet went direct-UDP into a black hole (device trace: inbound via_derp=1, DERP TX carried zero hdr=04 data frames).

Fix follows Tailscale's own semantics — data via DERP until a direct path is validated by a DISCO pong: leave the endpoint blank at peer-add. The only endpoint installs are now the already-correctly-gated ones (process_disco_pong on a direct pong, and the handshake path gated on best_ip). Same-LAN peers still upgrade to direct within seconds because the direct pong validates immediately.

Verified on hardware (ESP32-S3 N16R8, ESP-IDF v5.3): a CGNAT peer that previously could never reach a TCP service on the node (ping timeout, connect fail, despite the node showing active) gets ping replies over DERP, TCP connects, and bulk transfers complete end-to-end. Same-LAN direct path validated unaffected the same day. CRLF line endings preserved.

@snowpaper
snowpaper force-pushed the fix/no-unvalidated-endpoints branch from d8258bc to 1397fcf Compare July 9, 2026 04:56
…DISCO validates

At peer-add, the peer's advertised endpoints[0] from the MapResponse was
installed as the WireGuard endpoint before any path validation, and
wireguardif's output path treats any non-zero endpoint as a working
direct path. For a CGNAT peer (e.g. cellular hotspot) that address is
unreachable, so the tunnel went one-way: inbound arrived via DERP while
every outbound data packet was sent direct-UDP into a black hole.

Tailscale semantics: data flows via DERP until a direct path is
validated by a DISCO pong. Leave the endpoint blank at peer-add; the
only endpoint installs are the already-gated ones (process_disco_pong on
a direct pong, and the handshake path gated on best_ip). Same-LAN peers
still upgrade to direct within seconds.

Verified on ESP32-S3 (ESP-IDF v5.3): a CGNAT peer that previously could
never reach a TCP service on the node (ping timeout, connect fail)
gets ping replies over DERP, TCP connects, and bulk transfers complete.
Same-LAN direct path unaffected.

Fixes CamM2325#18
@snowpaper
snowpaper force-pushed the fix/no-unvalidated-endpoints branch from 1397fcf to da55beb Compare July 9, 2026 04:57
fudio101 referenced this pull request in fugo101/microlink Aug 14, 2026
Absorb upstream #21: don't pre-install unvalidated peer endpoints
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unvalidated advertised endpoints installed at peer-add — one-way tunnel with CGNAT peers

1 participant