diff --git a/dnscrypt-proxy/sources.go b/dnscrypt-proxy/sources.go index d08b89b9..0e28e274 100644 --- a/dnscrypt-proxy/sources.go +++ b/dnscrypt-proxy/sources.go @@ -4,6 +4,7 @@ import ( "bytes" "fmt" "io/ioutil" + "math/rand" "net/url" "os" "path/filepath" @@ -14,6 +15,7 @@ import ( "github.com/dchest/safefile" "github.com/jedisct1/dlog" + "github.com/jedisct1/go-dnsstamps" stamps "github.com/jedisct1/go-dnsstamps" "github.com/jedisct1/go-minisign" ) @@ -244,7 +246,6 @@ func (source *Source) parseV2(prefix string) ([]RegisteredServer, error) { return registeredServers, fmt.Errorf("Invalid format for source at [%v]", source.urls) } parts = parts[1:] -PartsLoop: for _, part := range parts { part = strings.TrimFunc(part, unicode.IsSpace) subparts := strings.Split(part, "\n") @@ -258,14 +259,11 @@ PartsLoop: subparts = subparts[1:] name = prefix + name var stampStr, description string + stampStrs := make([]string, 0) for _, subpart := range subparts { subpart = strings.TrimFunc(subpart, unicode.IsSpace) - if strings.HasPrefix(subpart, "sdns:") { - if len(stampStr) > 0 { - appendStampErr("Multiple stamps for server [%s]", name) - continue PartsLoop - } - stampStr = subpart + if strings.HasPrefix(subpart, "sdns:") && len(subpart) >= 6 { + stampStrs = append(stampStrs, subpart) continue } else if len(subpart) == 0 || strings.HasPrefix(subpart, "//") { continue @@ -275,13 +273,23 @@ PartsLoop: } description += subpart } - if len(stampStr) < 6 { + stampStrsLen := len(stampStrs) + if stampStrsLen <= 0 { appendStampErr("Missing stamp for server [%s]", name) continue + } else if stampStrsLen > 1 { + rand.Shuffle(stampStrsLen, func(i, j int) { stampStrs[i], stampStrs[j] = stampStrs[j], stampStrs[i] }) } - stamp, err := stamps.NewServerStampFromString(stampStr) - if err != nil { + var stamp dnsstamps.ServerStamp + var err error + for _, stampStr = range stampStrs { + stamp, err = stamps.NewServerStampFromString(stampStr) + if err == nil { + break + } appendStampErr("Invalid or unsupported stamp [%v]: %s", stampStr, err.Error()) + } + if err != nil { continue } registeredServer := RegisteredServer{