wgengine/magicsock: make endpoint.bestAddr Geneve-aware (#16195)

This commit adds a new type to magicsock, epAddr, which largely ends up
replacing netip.AddrPort in packet I/O paths throughout, enabling
Geneve encapsulation over UDP awareness.

The conn.ReceiveFunc for UDP has been revamped to fix and more clearly
distinguish the different classes of packets we expect to receive: naked
STUN binding messages, naked disco, naked WireGuard, Geneve-encapsulated
disco, and Geneve-encapsulated WireGuard.

Prior to this commit, STUN matching logic in the RX path could swallow
a naked WireGuard packet if the keypair index, which is randomly
generated, happened to overlap with a subset of the STUN magic cookie.

Updates tailscale/corp#27502
Updates tailscale/corp#29326

Signed-off-by: Jordan Whited <jordan@tailscale.com>
This commit is contained in:
Jordan Whited
2025-06-06 09:46:29 -07:00
committed by GitHub
parent 3f7a9f82e3
commit 66ae8737f4
14 changed files with 604 additions and 386 deletions
+19 -3
View File
@@ -5,6 +5,7 @@ package magicsock
import (
"errors"
"fmt"
"net"
"net/netip"
"sync"
@@ -13,6 +14,7 @@ import (
"golang.org/x/net/ipv6"
"tailscale.com/net/netaddr"
"tailscale.com/net/packet"
"tailscale.com/types/nettype"
)
@@ -71,14 +73,28 @@ func (c *RebindingUDPConn) ReadFromUDPAddrPort(b []byte) (int, netip.AddrPort, e
}
// WriteBatchTo writes buffs to addr.
func (c *RebindingUDPConn) WriteBatchTo(buffs [][]byte, addr netip.AddrPort, offset int) error {
func (c *RebindingUDPConn) WriteBatchTo(buffs [][]byte, addr epAddr, offset int) error {
if offset != packet.GeneveFixedHeaderLength {
return fmt.Errorf("RebindingUDPConn.WriteBatchTo: [unexpected] offset (%d) != Geneve header length (%d)", offset, packet.GeneveFixedHeaderLength)
}
for {
pconn := *c.pconnAtomic.Load()
b, ok := pconn.(batchingConn)
if !ok {
vniIsSet := addr.vni.isSet()
var gh packet.GeneveHeader
if vniIsSet {
gh = packet.GeneveHeader{
VNI: addr.vni.get(),
}
}
for _, buf := range buffs {
buf = buf[offset:]
_, err := c.writeToUDPAddrPortWithInitPconn(pconn, buf, addr)
if vniIsSet {
gh.Encode(buf)
} else {
buf = buf[offset:]
}
_, err := c.writeToUDPAddrPortWithInitPconn(pconn, buf, addr.ap)
if err != nil {
return err
}