wireguardif.h sets
#define WIREGUARDIF_MTU (1420)
which is WireGuard's own default. Tailscale uses 1280 for its tunnel, and MicroLink is a Tailscale client, so the netif advertises an MSS that peers cannot actually deliver.
What it looks like on the wire
tcpdump on a Linux peer (tailscale0, MTU 1280), connecting to a TCP listener on the node:
peer > node: Flags [S], win 64480, options [mss 1240,sackOK,TS ...,wscale 10]
node > peer: Flags [S.], win 32768, options [mss 1380]
The peer correctly offers 1240 (1280 − 40). The node offers 1380 (1420 − 40). So anything the peer sends towards the node is built into 1380-byte segments, 1420 bytes on the wire, into a 1280-byte tunnel.
Downloads from the node are unaffected, because the node honours the peer's 1240. Anything pushing data to the node — an upload, a POST body, a proxied request — hits it. That is why it can sit unnoticed for a long time on a telemetry-shaped workload.
Suggested fix
Not sending a PR for this one, because wireguard_lwip is a general-purpose WireGuard implementation and 1420 is the right default there — it is only wrong in MicroLink's Tailscale-specific context. Two reasonable shapes:
- A Kconfig option, defaulting to 1280 for MicroLink, so plain-WireGuard users of the vendored
wireguard_lwip keep 1420.
- Set
netif->mtu = 1280 in wg_init_interface() after wireguardif_init(), leaving the library's default alone.
Happy to send whichever you prefer.
For what it's worth, changing it to 1280 locally makes the node advertise mss 1240 and the two sides match.
Found while debugging #17 on an ESP32-S3; unrelated to that bug, but it turned up in the same packet captures.
wireguardif.hsetswhich is WireGuard's own default. Tailscale uses 1280 for its tunnel, and MicroLink is a Tailscale client, so the netif advertises an MSS that peers cannot actually deliver.
What it looks like on the wire
tcpdumpon a Linux peer (tailscale0, MTU 1280), connecting to a TCP listener on the node:The peer correctly offers 1240 (1280 − 40). The node offers 1380 (1420 − 40). So anything the peer sends towards the node is built into 1380-byte segments, 1420 bytes on the wire, into a 1280-byte tunnel.
Downloads from the node are unaffected, because the node honours the peer's 1240. Anything pushing data to the node — an upload, a POST body, a proxied request — hits it. That is why it can sit unnoticed for a long time on a telemetry-shaped workload.
Suggested fix
Not sending a PR for this one, because
wireguard_lwipis a general-purpose WireGuard implementation and 1420 is the right default there — it is only wrong in MicroLink's Tailscale-specific context. Two reasonable shapes:wireguard_lwipkeep 1420.netif->mtu = 1280inwg_init_interface()afterwireguardif_init(), leaving the library's default alone.Happy to send whichever you prefer.
For what it's worth, changing it to 1280 locally makes the node advertise
mss 1240and the two sides match.Found while debugging #17 on an ESP32-S3; unrelated to that bug, but it turned up in the same packet captures.