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>
pull/17806/head
Raj Singh 4 weeks ago committed by GitHub
parent d4c5b278b3
commit bab5e68d0a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -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)
}
}
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))
}
if rep.GlobalV6.IsValid() {
addrPorts.Add(rep.GlobalV6)
}
// 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
}

Loading…
Cancel
Save