net/udprelay: use GetGlobalAddrs and add local port endpoint (#17797)

Use GetGlobalAddrs() to discover all STUN endpoints, handling bad NATs
that create multiple mappings. When MappingVariesByDestIP is true, also
add the first STUN IPv4 address with the relay's local port for static
port mapping scenarios.

Updates #17796

Signed-off-by: Raj Singh <raj@tailscale.com>
This commit is contained in:
Raj Singh 2025-11-07 18:38:49 -05:00 committed by GitHub
parent d4c5b278b3
commit bab5e68d0a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -393,14 +393,29 @@ func (s *Server) addrDiscoveryLoop() {
if err != nil {
return nil, err
}
if rep.GlobalV4.IsValid() {
addrPorts.Add(rep.GlobalV4)
// Add STUN-discovered endpoints with their observed ports.
v4Addrs, v6Addrs := rep.GetGlobalAddrs()
for _, addr := range v4Addrs {
if addr.IsValid() {
addrPorts.Add(addr)
}
}
if rep.GlobalV6.IsValid() {
addrPorts.Add(rep.GlobalV6)
for _, addr := range v6Addrs {
if addr.IsValid() {
addrPorts.Add(addr)
}
}
if len(v4Addrs) >= 1 && v4Addrs[0].IsValid() {
// If they're behind a hard NAT and are using a fixed
// port locally, assume they might've added a static
// port mapping on their router to the same explicit
// port that the relay is running with. Worst case
// it's an invalid candidate mapping.
if rep.MappingVariesByDestIP.EqualBool(true) && s.uc4Port != 0 {
addrPorts.Add(netip.AddrPortFrom(v4Addrs[0].Addr(), s.uc4Port))
}
}
// TODO(jwhited): consider logging if rep.MappingVariesByDestIP as
// that's a hint we are not well-positioned to operate as a UDP relay.
return addrPorts.Slice(), nil
}