mirror of
https://github.com/tailscale/tailscale.git
synced 2025-02-21 12:28:39 +00:00
net/dnsfallback: fix infinite loop and limit number of candidates
Updates #1455 (fixes the DNS spin part, but other things aren't ideal there) Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
63a9adeb6c
commit
d37b3b02cd
@ -30,26 +30,40 @@ func Lookup(ctx context.Context, host string) ([]netaddr.IP, error) {
|
||||
ip netaddr.IP
|
||||
}
|
||||
|
||||
var cands []nameIP
|
||||
dm := derpmap.Prod()
|
||||
var cands4, cands6 []nameIP
|
||||
for _, dr := range dm.Regions {
|
||||
for _, n := range dr.Nodes {
|
||||
if ip, err := netaddr.ParseIP(n.IPv4); err == nil {
|
||||
cands = append(cands, nameIP{n.HostName, ip})
|
||||
cands4 = append(cands4, nameIP{n.HostName, ip})
|
||||
}
|
||||
if ip, err := netaddr.ParseIP(n.IPv6); err == nil {
|
||||
cands = append(cands, nameIP{n.HostName, ip})
|
||||
cands6 = append(cands6, nameIP{n.HostName, ip})
|
||||
}
|
||||
}
|
||||
}
|
||||
rand.Shuffle(len(cands), func(i, j int) {
|
||||
cands[i], cands[j] = cands[j], cands[i]
|
||||
})
|
||||
rand.Shuffle(len(cands4), func(i, j int) { cands4[i], cands4[j] = cands4[j], cands4[i] })
|
||||
rand.Shuffle(len(cands6), func(i, j int) { cands6[i], cands6[j] = cands6[j], cands6[i] })
|
||||
|
||||
const maxCands = 6
|
||||
var cands []nameIP // up to maxCands alternating v4/v6 as long as we have both
|
||||
for (len(cands4) > 0 || len(cands6) > 0) && len(cands) < maxCands {
|
||||
if len(cands4) > 0 {
|
||||
cands = append(cands, cands4[0])
|
||||
cands4 = cands4[1:]
|
||||
}
|
||||
if len(cands6) > 0 {
|
||||
cands = append(cands, cands6[0])
|
||||
cands6 = cands6[1:]
|
||||
}
|
||||
}
|
||||
if len(cands) == 0 {
|
||||
return nil, fmt.Errorf("no DNS fallback options for %q", host)
|
||||
}
|
||||
for ctx.Err() == nil && len(cands) > 0 {
|
||||
cand := cands[0]
|
||||
for _, cand := range cands {
|
||||
if err := ctx.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Printf("trying bootstrapDNS(%q, %q) for %q ...", cand.dnsName, cand.ip, host)
|
||||
ctx, cancel := context.WithTimeout(ctx, 3*time.Second)
|
||||
defer cancel()
|
||||
|
Loading…
x
Reference in New Issue
Block a user