|
|
|
@ -243,7 +243,16 @@ func (f *forwarder) getDoHClient(ip netaddr.IP) (urlBase string, c *http.Client,
|
|
|
|
if !strings.HasPrefix(netw, "tcp") {
|
|
|
|
if !strings.HasPrefix(netw, "tcp") {
|
|
|
|
return nil, fmt.Errorf("unexpected network %q", netw)
|
|
|
|
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{}
|
|
|
|
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() {
|
|
|
|
func init() {
|
|
|
|
// Cloudflare
|
|
|
|
// Cloudflare
|
|
|
|
|