Skip to content

ts_dataplane, ts_tunnel: fix reserved_zeroes check in could_be_wireguard - #415

Merged
dylan-tailscale merged 1 commit into
mainfrom
dylan/wg-hdr-size
Sep 16, 2026
Merged

dylan-tailscale merged 1 commit into
mainfrom
dylan/wg-hdr-size

Conversation

@dylan-tailscale

@dylan-tailscale dylan-tailscale commented Sep 16, 2026

Copy link
Copy Markdown
Collaborator

Split into two commits; first commit is the bugfix, second is a potential minor improvement.

could_be_wireguard() was expecting four bytes of zeroes in valid WireGuard packets starting at idx 1; the reserved_zeroes field in every WireGuard packet is three bytes of zeroes, starting at idx 1. This was misclassifying any WireGuard packet with a non-zero byte at idx 4 (top byte of the receiver/sender index field, depending on message type) as not WireGuard. Impact was non-existent, as we currently process PacketType::Unknown and PacketType::WireGuard identically anyway in DataPlane::process_inbound(). Also increases the min packet size to 16 bytes, since no valid WireGuard packet will be smaller.

The second commit adds tighter length-based checks to could_be_wireguard() by moving it to ts_tunnel and checking minimum WireGuard packet lengths per-message-type; may or may not be worth the extra ~2-4 branches on the hot path, thus the separate commit.

Updates #cleanup.

@npry npry left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to not fragment the packet_ident module? In my mental model could_be_wireguard doesn't really have to do with ts_tunnel, it's about exterior packet identification, where ts_tunnel is about the protocol internals. If you feel strongly though no worries

Regardless, the fix lgtm, ty!

@dylan-tailscale

Copy link
Copy Markdown
Collaborator Author

I'd prefer to not fragment the packet_ident module? In my mental model could_be_wireguard doesn't really have to do with ts_tunnel, it's about exterior packet identification, where ts_tunnel is about the protocol internals. If you feel strongly though no worries

Yep, 100% agree...the move was to avoid making ts_tunnel::messages{::<various structs>} public, exporting a bunch of size_of::<message>() consts from ts_tunnel, or defining size consts in ts_dataplane that weren't tied to the actual structs in ts_tunnel, which all felt messy. Regardless, you're right, it belongs in packet_ident.

Regardless, the fix lgtm, ty!

Reverted the second commit and kept the first commit with the fix, ty!

…kt len

`could_be_wireguard()` was expecting four bytes of zeroes in valid WireGuard packets starting at idx 1; the `reserved_zeroes` field in every WireGuard packet is _three_ bytes of zeroes, starting at idx 1. This was misclassifying any WireGuard packet with a non-zero byte at idx 4 (top byte of the receiver/sender index field, depending on message type) as not WireGuard. Impact was minimal, as we currently process `PacketType::Unknown` and `PacketType::WireGuard` identically anyway in `DataPlane::process_inbound()`.

Also increases the min packet size to 16 bytes, since no valid WireGuard packet will be smaller.

Signed-off-by: Dylan Bargatze <dylan@tailscale.com>
@dylan-tailscale
dylan-tailscale enabled auto-merge (squash) September 16, 2026 18:39
@dylan-tailscale
dylan-tailscale merged commit 792d345 into main Sep 16, 2026
23 checks passed
@dylan-tailscale
dylan-tailscale deleted the dylan/wg-hdr-size branch September 16, 2026 18:50
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.

2 participants