From d7ca483df1c45d2e725c495ffa5c53d322118ea9 Mon Sep 17 00:00:00 2001 From: bt90 Date: Tue, 8 Apr 2025 14:23:57 +0200 Subject: [PATCH] chore(config): resolve primary STUN servers via SRV record (fixes #10029) (#10031) ### Purpose Fixes #10029 ### Testing ``` [3JPXJ] 2025/04/03 14:36:44.601454 stun.go:146: DEBUG: Running stun for Stun@udp://[::]:22000 via fyc5mja4mz5s0vmz1txx.syncthing.net:9999 [3JPXJ] 2025/04/03 14:36:54.185157 stun.go:170: DEBUG: Stun@udp://[::]:22000 stun discovery on fyc5mja4mz5s0vmz1txx.syncthing.net:9999 resulted in no address [3JPXJ] 2025/04/03 14:36:54.185204 stun.go:146: DEBUG: Running stun for Stun@udp://[::]:22000 via stun.internetcalls.com:3478 ``` ### Documentation https://github.com/syncthing/docs/pull/904 --- lib/config/config.go | 10 +++------- lib/config/optionsconfiguration.go | 25 +++++++++++++++++-------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/lib/config/config.go b/lib/config/config.go index 6805a15eb..e3d9f11c9 100644 --- a/lib/config/config.go +++ b/lib/config/config.go @@ -68,13 +68,9 @@ var ( DefaultTheme = "default" // Default stun servers should be substituted when the configuration // contains default. - - // DefaultPrimaryStunServers are servers provided by us (to avoid causing the public servers burden) - DefaultPrimaryStunServers = []string{ - // Discontinued because of misuse. See https://forum.syncthing.net/t/stun-server-misuse/23319 - //"stun.syncthing.net:3478", - } - DefaultSecondaryStunServers = []string{ + // The primary stun servers are provided by us and are resolved via an SRV record + // The fallback stun servers are used if the primary ones can't be resolved or are down. + DefaultFallbackStunServers = []string{ "stun.counterpath.com:3478", "stun.counterpath.net:3478", "stun.ekiga.net:3478", diff --git a/lib/config/optionsconfiguration.go b/lib/config/optionsconfiguration.go index eecf34dda..32e1b4891 100644 --- a/lib/config/optionsconfiguration.go +++ b/lib/config/optionsconfiguration.go @@ -8,8 +8,10 @@ package config import ( "fmt" + "net" "runtime" "slices" + "strings" "github.com/syncthing/syncthing/lib/protocol" "github.com/syncthing/syncthing/lib/rand" @@ -184,15 +186,22 @@ func (opts OptionsConfiguration) StunServers() []string { for _, addr := range opts.RawStunServers { switch addr { case "default": - defaultPrimaryAddresses := make([]string, len(DefaultPrimaryStunServers)) - copy(defaultPrimaryAddresses, DefaultPrimaryStunServers) - rand.Shuffle(defaultPrimaryAddresses) - addresses = append(addresses, defaultPrimaryAddresses...) + _, records, err := net.LookupSRV("stun", "udp", "syncthing.net") + if err != nil { + l.Warnln("Unable to resolve primary STUN servers via DNS:", err) + } - defaultSecondaryAddresses := make([]string, len(DefaultSecondaryStunServers)) - copy(defaultSecondaryAddresses, DefaultSecondaryStunServers) - rand.Shuffle(defaultSecondaryAddresses) - addresses = append(addresses, defaultSecondaryAddresses...) + for _, record := range records { + priority := record.Priority + target := strings.TrimSuffix(record.Target, ".") + address := fmt.Sprintf("%s:%d", target, record.Port) + l.Debugf("Resolved primary STUN server %s with priority %d", address, priority) + addresses = append(addresses, address) + } + + fallbackAddresses := slices.Clone(DefaultFallbackStunServers) + rand.Shuffle(fallbackAddresses) + addresses = append(addresses, fallbackAddresses...) default: addresses = append(addresses, addr) }