diff --git a/component/resolver/resolver.go b/component/resolver/resolver.go index 356bc660..d10e39cb 100644 --- a/component/resolver/resolver.go +++ b/component/resolver/resolver.go @@ -3,6 +3,7 @@ package resolver import ( "context" "errors" + "math/rand" "net" "strings" "time" @@ -66,7 +67,7 @@ func ResolveIPv4(host string) (net.IP, error) { return nil, ErrIPNotFound } - return ipAddrs[0], nil + return ipAddrs[rand.Intn(len(ipAddrs))], nil } // ResolveIPv6 with a host, return ipv6 @@ -102,20 +103,20 @@ func ResolveIPv6(host string) (net.IP, error) { return nil, ErrIPNotFound } - return ipAddrs[0], nil + return ipAddrs[rand.Intn(len(ipAddrs))], nil } -// ResolveIP with a host, return ip -func ResolveIP(host string) (net.IP, error) { +// ResolveIPWithResolver same as ResolveIP, but with a resolver +func ResolveIPWithResolver(host string, r Resolver) (net.IP, error) { if node := DefaultHosts.Search(host); node != nil { return node.Data.(net.IP), nil } - if DefaultResolver != nil { + if r != nil { if DisableIPv6 { - return DefaultResolver.ResolveIPv4(host) + return r.ResolveIPv4(host) } - return DefaultResolver.ResolveIP(host) + return r.ResolveIP(host) } else if DisableIPv6 { return ResolveIPv4(host) } @@ -132,3 +133,8 @@ func ResolveIP(host string) (net.IP, error) { return ipAddr.IP, nil } + +// ResolveIP with a host, return ip +func ResolveIP(host string) (net.IP, error) { + return ResolveIPWithResolver(host, DefaultResolver) +} diff --git a/dns/client.go b/dns/client.go index 151bee24..405b3a98 100644 --- a/dns/client.go +++ b/dns/client.go @@ -7,6 +7,7 @@ import ( "strings" "github.com/Dreamacro/clash/component/dialer" + "github.com/Dreamacro/clash/component/resolver" D "github.com/miekg/dns" ) @@ -28,8 +29,7 @@ func (c *client) ExchangeContext(ctx context.Context, m *D.Msg) (msg *D.Msg, err // a default ip dns ip = net.ParseIP(c.host) } else { - var err error - if ip, err = c.r.ResolveIP(c.host); err != nil { + if ip, err = resolver.ResolveIPWithResolver(c.host, c.r); err != nil { return nil, fmt.Errorf("use default dns resolve failed: %w", err) } } diff --git a/dns/doh.go b/dns/doh.go index ee26e7c8..247e0704 100644 --- a/dns/doh.go +++ b/dns/doh.go @@ -9,6 +9,7 @@ import ( "net/http" "github.com/Dreamacro/clash/component/dialer" + "github.com/Dreamacro/clash/component/resolver" D "github.com/miekg/dns" ) @@ -83,12 +84,12 @@ func newDoHClient(url string, r *Resolver) *dohClient { return nil, err } - ip, err := r.ResolveIPv4(host) + ip, err := resolver.ResolveIPWithResolver(host, r) if err != nil { return nil, err } - return dialer.DialContext(ctx, "tcp4", net.JoinHostPort(ip.String(), port)) + return dialer.DialContext(ctx, "tcp", net.JoinHostPort(ip.String(), port)) }, }, }