mirror of
https://github.com/tailscale/tailscale.git
synced 2025-01-05 14:57:49 +00:00
net/dns/resolver: fall back to IPv6 for well-known DoH servers if v4 fails
Should help with IPv6-only environments when the tailnet admin only specified IPv4 DNS IPs. See https://github.com/tailscale/tailscale/issues/2447#issuecomment-884188562 Co-Author: Adrian Dewhurst <adrian@tailscale.com> Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
74eee4de1c
commit
3daf27eaad
@ -81,3 +81,16 @@ func TestDoH(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDoHV6Fallback(t *testing.T) {
|
||||
for ip, base := range knownDoH {
|
||||
if ip.Is4() {
|
||||
ip6, ok := dohV6(base)
|
||||
if !ok {
|
||||
t.Errorf("no v6 DoH known for %v", ip)
|
||||
} else if !ip6.Is6() {
|
||||
t.Errorf("dohV6(%q) returned non-v6 address %v", base, ip6)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -243,7 +243,16 @@ func (f *forwarder) getDoHClient(ip netaddr.IP) (urlBase string, c *http.Client,
|
||||
if !strings.HasPrefix(netw, "tcp") {
|
||||
return nil, fmt.Errorf("unexpected network %q", netw)
|
||||
}
|
||||
return nsDialer.DialContext(ctx, "tcp", net.JoinHostPort(ip.String(), "443"))
|
||||
c, err := nsDialer.DialContext(ctx, "tcp", net.JoinHostPort(ip.String(), "443"))
|
||||
// If v4 failed, try an equivalent v6 also in the time remaining.
|
||||
if err != nil && ctx.Err() == nil {
|
||||
if ip6, ok := dohV6(urlBase); ok && ip.Is4() {
|
||||
if c6, err := nsDialer.DialContext(ctx, "tcp", net.JoinHostPort(ip6.String(), "443")); err == nil {
|
||||
return c6, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return c, err
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -509,7 +518,22 @@ func (p *closePool) Close() error {
|
||||
|
||||
var knownDoH = map[netaddr.IP]string{}
|
||||
|
||||
func addDoH(ip, base string) { knownDoH[netaddr.MustParseIP(ip)] = base }
|
||||
var dohIPsOfBase = map[string][]netaddr.IP{}
|
||||
|
||||
func addDoH(ipStr, base string) {
|
||||
ip := netaddr.MustParseIP(ipStr)
|
||||
knownDoH[ip] = base
|
||||
dohIPsOfBase[base] = append(dohIPsOfBase[base], ip)
|
||||
}
|
||||
|
||||
func dohV6(base string) (ip netaddr.IP, ok bool) {
|
||||
for _, ip := range dohIPsOfBase[base] {
|
||||
if ip.Is6() {
|
||||
return ip, true
|
||||
}
|
||||
}
|
||||
return ip, false
|
||||
}
|
||||
|
||||
func init() {
|
||||
// Cloudflare
|
||||
|
Loading…
x
Reference in New Issue
Block a user