Refine DNS strategies

This commit is contained in:
JimhHan 2021-04-09 23:36:36 +08:00
parent f4a048aa0c
commit 726a722019
No known key found for this signature in database
GPG key ID: 48D5D7CF95157AC5
21 changed files with 255 additions and 208 deletions

View file

@ -22,6 +22,9 @@ type Client interface {
// LookupIP returns IP address for the given domain. IPs may contain IPv4 and/or IPv6 addresses.
LookupIP(domain string) ([]net.IP, error)
// LookupOptions query IP address for domain with IPOption.
LookupOptions(domain string, opt IPOption) ([]net.IP, error)
}
// IPv4Lookup is an optional feature for querying IPv4 addresses only.
@ -38,20 +41,6 @@ type IPv6Lookup interface {
LookupIPv6(domain string) ([]net.IP, error)
}
// ClientWithIPOption is an optional feature for querying DNS information.
//
// xray:api:beta
type ClientWithIPOption interface {
// GetIPOption returns IPOption for the DNS client.
GetIPOption() *IPOption
// SetQueryOption sets IPv4Enable and IPv6Enable for the DNS client.
SetQueryOption(isIPv4Enable, isIPv6Enable bool)
// SetFakeDNSOption sets FakeEnable option for DNS client.
SetFakeDNSOption(isFakeEnable bool)
}
// ClientType returns the type of Client interface. Can be used for implementing common.HasType.
//
// xray:api:beta
@ -78,3 +67,11 @@ func RCodeFromError(err error) uint16 {
}
return 0
}
var (
LookupIPv4 = IPOption{IPv4Enable: true}
LookupIPv6 = IPOption{IPv6Enable: true}
LookupIP = IPOption{IPv4Enable: true, IPv6Enable: true}
LookupFake = IPOption{FakeEnable: true}
LookupAll = IPOption{true, true, true}
)

View file

@ -38,6 +38,11 @@ func (*Client) LookupIP(host string) ([]net.IP, error) {
return parsedIPs, nil
}
// LookupOptions implements Client.
func (c *Client) LookupOptions(host string, _ dns.IPOption) ([]net.IP, error) {
return c.LookupIP(host)
}
// LookupIPv4 implements IPv4Lookup.
func (c *Client) LookupIPv4(host string) ([]net.IP, error) {
ips, err := c.LookupIP(host)

View file

@ -26,40 +26,12 @@ func (ctx *ResolvableContext) GetTargetIPs() []net.IP {
}
if domain := ctx.GetTargetDomain(); len(domain) != 0 {
var lookupFunc func(string) ([]net.IP, error) = ctx.dnsClient.LookupIP
ipOption := &dns.IPOption{
IPv4Enable: true,
IPv6Enable: true,
}
if c, ok := ctx.dnsClient.(dns.ClientWithIPOption); ok {
ipOption = c.GetIPOption()
c.SetFakeDNSOption(false) // Skip FakeDNS.
} else {
newError("ctx.dnsClient doesn't implement ClientWithIPOption").AtDebug().WriteToLog()
}
switch {
case ipOption.IPv4Enable && !ipOption.IPv6Enable:
if lookupIPv4, ok := ctx.dnsClient.(dns.IPv4Lookup); ok {
lookupFunc = lookupIPv4.LookupIPv4
} else {
newError("ctx.dnsClient doesn't implement IPv4Lookup. Use LookupIP instead.").AtDebug().WriteToLog()
}
case !ipOption.IPv4Enable && ipOption.IPv6Enable:
if lookupIPv6, ok := ctx.dnsClient.(dns.IPv6Lookup); ok {
lookupFunc = lookupIPv6.LookupIPv6
} else {
newError("ctx.dnsClient doesn't implement IPv6Lookup. Use LookupIP instead.").AtDebug().WriteToLog()
}
}
ips, err := lookupFunc(domain)
ips, err := ctx.dnsClient.LookupIP(domain)
if err == nil {
ctx.resolvedIPs = ips
return ips
}
newError("resolve ip for ", domain).Base(err).WriteToLog()
newError("failed to resolve ip for ", domain).Base(err).WriteToLog()
}
return nil