Refactor: MainResolver
This commit is contained in:
parent
9bab2c504e
commit
4502776513
8 changed files with 128 additions and 75 deletions
|
@ -14,6 +14,7 @@ type Direct struct {
|
|||
|
||||
// DialContext implements C.ProxyAdapter
|
||||
func (d *Direct) DialContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.Conn, error) {
|
||||
opts = append(opts, dialer.WithDirect())
|
||||
c, err := dialer.DialContext(ctx, "tcp", metadata.RemoteAddress(), d.Base.DialOptions(opts...)...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -24,6 +25,7 @@ func (d *Direct) DialContext(ctx context.Context, metadata *C.Metadata, opts ...
|
|||
|
||||
// ListenPacketContext implements C.ProxyAdapter
|
||||
func (d *Direct) ListenPacketContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.PacketConn, error) {
|
||||
opts = append(opts, dialer.WithDirect())
|
||||
pc, err := dialer.ListenPacket(ctx, "udp", "", d.Base.DialOptions(opts...)...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -44,7 +44,7 @@ func resolveUDPAddr(network, address string) (*net.UDPAddr, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
ip, err := resolver.ResolveIP(host)
|
||||
ip, err := resolver.ResolveProxyServerHost(host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -32,14 +32,14 @@ func DialContext(ctx context.Context, network, address string, options ...Option
|
|||
var ip net.IP
|
||||
switch network {
|
||||
case "tcp4", "udp4":
|
||||
if opt.interfaceName != "" {
|
||||
ip, err = resolver.ResolveIPv4WithMain(host)
|
||||
if !opt.direct {
|
||||
ip, err = resolver.ResolveIPv4ProxyServerHost(host)
|
||||
} else {
|
||||
ip, err = resolver.ResolveIPv4(host)
|
||||
}
|
||||
default:
|
||||
if opt.interfaceName != "" {
|
||||
ip, err = resolver.ResolveIPv6WithMain(host)
|
||||
if !opt.direct {
|
||||
ip, err = resolver.ResolveIPv6ProxyServerHost(host)
|
||||
} else {
|
||||
ip, err = resolver.ResolveIPv6(host)
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ func dualStackDialContext(ctx context.Context, network, address string, opt *opt
|
|||
results := make(chan dialResult)
|
||||
var primary, fallback dialResult
|
||||
|
||||
startRacer := func(ctx context.Context, network, host string, ipv6 bool) {
|
||||
startRacer := func(ctx context.Context, network, host string, direct bool, ipv6 bool) {
|
||||
result := dialResult{ipv6: ipv6, done: true}
|
||||
defer func() {
|
||||
select {
|
||||
|
@ -135,14 +135,14 @@ func dualStackDialContext(ctx context.Context, network, address string, opt *opt
|
|||
|
||||
var ip net.IP
|
||||
if ipv6 {
|
||||
if opt.interfaceName != "" {
|
||||
ip, result.error = resolver.ResolveIPv6WithMain(host)
|
||||
if !direct {
|
||||
ip, result.error = resolver.ResolveIPv6ProxyServerHost(host)
|
||||
} else {
|
||||
ip, result.error = resolver.ResolveIPv6(host)
|
||||
}
|
||||
} else {
|
||||
if opt.interfaceName != "" {
|
||||
ip, result.error = resolver.ResolveIPv4WithMain(host)
|
||||
if !direct {
|
||||
ip, result.error = resolver.ResolveIPv4ProxyServerHost(host)
|
||||
} else {
|
||||
ip, result.error = resolver.ResolveIPv4(host)
|
||||
}
|
||||
|
@ -155,8 +155,8 @@ func dualStackDialContext(ctx context.Context, network, address string, opt *opt
|
|||
result.Conn, result.error = dialContext(ctx, network, ip, port, opt)
|
||||
}
|
||||
|
||||
go startRacer(ctx, network+"4", host, false)
|
||||
go startRacer(ctx, network+"6", host, true)
|
||||
go startRacer(ctx, network+"4", host, opt.direct, false)
|
||||
go startRacer(ctx, network+"6", host, opt.direct, true)
|
||||
|
||||
for res := range results {
|
||||
if res.error == nil {
|
||||
|
|
|
@ -12,6 +12,7 @@ type option struct {
|
|||
interfaceName string
|
||||
addrReuse bool
|
||||
routingMark int
|
||||
direct bool
|
||||
}
|
||||
|
||||
type Option func(opt *option)
|
||||
|
@ -33,3 +34,9 @@ func WithRoutingMark(mark int) Option {
|
|||
opt.routingMark = mark
|
||||
}
|
||||
}
|
||||
|
||||
func WithDirect() Option {
|
||||
return func(opt *option) {
|
||||
opt.direct = true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,8 +15,8 @@ var (
|
|||
// DefaultResolver aim to resolve ip
|
||||
DefaultResolver Resolver
|
||||
|
||||
// MainResolver resolve ip with main domain server
|
||||
MainResolver Resolver
|
||||
// ProxyServerHostResolver resolve ip to proxies server host
|
||||
ProxyServerHostResolver Resolver
|
||||
|
||||
// DisableIPv6 means don't resolve ipv6 host
|
||||
// default value is true
|
||||
|
@ -46,10 +46,6 @@ func ResolveIPv4(host string) (net.IP, error) {
|
|||
return ResolveIPv4WithResolver(host, DefaultResolver)
|
||||
}
|
||||
|
||||
func ResolveIPv4WithMain(host string) (net.IP, error) {
|
||||
return ResolveIPv4WithResolver(host, MainResolver)
|
||||
}
|
||||
|
||||
func ResolveIPv4WithResolver(host string, r Resolver) (net.IP, error) {
|
||||
if node := DefaultHosts.Search(host); node != nil {
|
||||
if ip := node.Data.(net.IP).To4(); ip != nil {
|
||||
|
@ -69,16 +65,20 @@ func ResolveIPv4WithResolver(host string, r Resolver) (net.IP, error) {
|
|||
return r.ResolveIPv4(host)
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), DefaultDNSTimeout)
|
||||
defer cancel()
|
||||
ipAddrs, err := net.DefaultResolver.LookupIP(ctx, "ip4", host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if len(ipAddrs) == 0 {
|
||||
return nil, ErrIPNotFound
|
||||
if DefaultResolver == nil {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), DefaultDNSTimeout)
|
||||
defer cancel()
|
||||
ipAddrs, err := net.DefaultResolver.LookupIP(ctx, "ip4", host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if len(ipAddrs) == 0 {
|
||||
return nil, ErrIPNotFound
|
||||
}
|
||||
|
||||
return ipAddrs[rand.Intn(len(ipAddrs))], nil
|
||||
}
|
||||
|
||||
return ipAddrs[rand.Intn(len(ipAddrs))], nil
|
||||
return nil, ErrIPNotFound
|
||||
}
|
||||
|
||||
// ResolveIPv6 with a host, return ipv6
|
||||
|
@ -86,10 +86,6 @@ func ResolveIPv6(host string) (net.IP, error) {
|
|||
return ResolveIPv6WithResolver(host, DefaultResolver)
|
||||
}
|
||||
|
||||
func ResolveIPv6WithMain(host string) (net.IP, error) {
|
||||
return ResolveIPv6WithResolver(host, MainResolver)
|
||||
}
|
||||
|
||||
func ResolveIPv6WithResolver(host string, r Resolver) (net.IP, error) {
|
||||
if DisableIPv6 {
|
||||
return nil, ErrIPv6Disabled
|
||||
|
@ -113,16 +109,20 @@ func ResolveIPv6WithResolver(host string, r Resolver) (net.IP, error) {
|
|||
return r.ResolveIPv6(host)
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), DefaultDNSTimeout)
|
||||
defer cancel()
|
||||
ipAddrs, err := net.DefaultResolver.LookupIP(ctx, "ip6", host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if len(ipAddrs) == 0 {
|
||||
return nil, ErrIPNotFound
|
||||
if DefaultResolver == nil {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), DefaultDNSTimeout)
|
||||
defer cancel()
|
||||
ipAddrs, err := net.DefaultResolver.LookupIP(ctx, "ip6", host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if len(ipAddrs) == 0 {
|
||||
return nil, ErrIPNotFound
|
||||
}
|
||||
|
||||
return ipAddrs[rand.Intn(len(ipAddrs))], nil
|
||||
}
|
||||
|
||||
return ipAddrs[rand.Intn(len(ipAddrs))], nil
|
||||
return nil, ErrIPNotFound
|
||||
}
|
||||
|
||||
// ResolveIPWithResolver same as ResolveIP, but with a resolver
|
||||
|
@ -145,12 +145,16 @@ func ResolveIPWithResolver(host string, r Resolver) (net.IP, error) {
|
|||
return ip, nil
|
||||
}
|
||||
|
||||
ipAddr, err := net.ResolveIPAddr("ip", host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if DefaultResolver == nil {
|
||||
ipAddr, err := net.ResolveIPAddr("ip", host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ipAddr.IP, nil
|
||||
}
|
||||
|
||||
return ipAddr.IP, nil
|
||||
return nil, ErrIPNotFound
|
||||
}
|
||||
|
||||
// ResolveIP with a host, return ip
|
||||
|
@ -158,7 +162,26 @@ func ResolveIP(host string) (net.IP, error) {
|
|||
return ResolveIPWithResolver(host, DefaultResolver)
|
||||
}
|
||||
|
||||
// ResolveIPWithMainResolver with a host, use main resolver, return ip
|
||||
func ResolveIPWithMainResolver(host string) (net.IP, error) {
|
||||
return ResolveIPWithResolver(host, MainResolver)
|
||||
// ResolveIPv4ProxyServerHost proxies server host only
|
||||
func ResolveIPv4ProxyServerHost(host string) (net.IP, error) {
|
||||
if ProxyServerHostResolver != nil {
|
||||
return ResolveIPv4WithResolver(host, ProxyServerHostResolver)
|
||||
}
|
||||
return ResolveIPv4(host)
|
||||
}
|
||||
|
||||
// ResolveIPv6ProxyServerHost proxies server host only
|
||||
func ResolveIPv6ProxyServerHost(host string) (net.IP, error) {
|
||||
if ProxyServerHostResolver != nil {
|
||||
return ResolveIPv6WithResolver(host, ProxyServerHostResolver)
|
||||
}
|
||||
return ResolveIPv6(host)
|
||||
}
|
||||
|
||||
// ResolveProxyServerHost proxies server host only
|
||||
func ResolveProxyServerHost(host string) (net.IP, error) {
|
||||
if ProxyServerHostResolver != nil {
|
||||
return ResolveIPWithResolver(host, ProxyServerHostResolver)
|
||||
}
|
||||
return ResolveIP(host)
|
||||
}
|
||||
|
|
|
@ -63,17 +63,18 @@ type Controller struct {
|
|||
|
||||
// DNS config
|
||||
type DNS struct {
|
||||
Enable bool `yaml:"enable"`
|
||||
IPv6 bool `yaml:"ipv6"`
|
||||
NameServer []dns.NameServer `yaml:"nameserver"`
|
||||
Fallback []dns.NameServer `yaml:"fallback"`
|
||||
FallbackFilter FallbackFilter `yaml:"fallback-filter"`
|
||||
Listen string `yaml:"listen"`
|
||||
EnhancedMode C.DNSMode `yaml:"enhanced-mode"`
|
||||
DefaultNameserver []dns.NameServer `yaml:"default-nameserver"`
|
||||
FakeIPRange *fakeip.Pool
|
||||
Hosts *trie.DomainTrie
|
||||
NameServerPolicy map[string]dns.NameServer
|
||||
Enable bool `yaml:"enable"`
|
||||
IPv6 bool `yaml:"ipv6"`
|
||||
NameServer []dns.NameServer `yaml:"nameserver"`
|
||||
Fallback []dns.NameServer `yaml:"fallback"`
|
||||
FallbackFilter FallbackFilter `yaml:"fallback-filter"`
|
||||
Listen string `yaml:"listen"`
|
||||
EnhancedMode C.DNSMode `yaml:"enhanced-mode"`
|
||||
DefaultNameserver []dns.NameServer `yaml:"default-nameserver"`
|
||||
FakeIPRange *fakeip.Pool
|
||||
Hosts *trie.DomainTrie
|
||||
NameServerPolicy map[string]dns.NameServer
|
||||
ProxyServerNameserver []dns.NameServer
|
||||
}
|
||||
|
||||
// FallbackFilter config
|
||||
|
@ -125,18 +126,19 @@ type Config struct {
|
|||
}
|
||||
|
||||
type RawDNS struct {
|
||||
Enable bool `yaml:"enable"`
|
||||
IPv6 bool `yaml:"ipv6"`
|
||||
UseHosts bool `yaml:"use-hosts"`
|
||||
NameServer []string `yaml:"nameserver"`
|
||||
Fallback []string `yaml:"fallback"`
|
||||
FallbackFilter RawFallbackFilter `yaml:"fallback-filter"`
|
||||
Listen string `yaml:"listen"`
|
||||
EnhancedMode C.DNSMode `yaml:"enhanced-mode"`
|
||||
FakeIPRange string `yaml:"fake-ip-range"`
|
||||
FakeIPFilter []string `yaml:"fake-ip-filter"`
|
||||
DefaultNameserver []string `yaml:"default-nameserver"`
|
||||
NameServerPolicy map[string]string `yaml:"nameserver-policy"`
|
||||
Enable bool `yaml:"enable"`
|
||||
IPv6 bool `yaml:"ipv6"`
|
||||
UseHosts bool `yaml:"use-hosts"`
|
||||
NameServer []string `yaml:"nameserver"`
|
||||
Fallback []string `yaml:"fallback"`
|
||||
FallbackFilter RawFallbackFilter `yaml:"fallback-filter"`
|
||||
Listen string `yaml:"listen"`
|
||||
EnhancedMode C.DNSMode `yaml:"enhanced-mode"`
|
||||
FakeIPRange string `yaml:"fake-ip-range"`
|
||||
FakeIPFilter []string `yaml:"fake-ip-filter"`
|
||||
DefaultNameserver []string `yaml:"default-nameserver"`
|
||||
NameServerPolicy map[string]string `yaml:"nameserver-policy"`
|
||||
ProxyServerNameserver []string `yaml:"proxy-server-nameserver"`
|
||||
}
|
||||
|
||||
type RawFallbackFilter struct {
|
||||
|
@ -679,6 +681,10 @@ func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie, rules []C.Rule) (*DNS,
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if dnsCfg.ProxyServerNameserver, err = parseNameServer(cfg.ProxyServerNameserver); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(cfg.DefaultNameserver) == 0 {
|
||||
return nil, errors.New("default nameserver should have at least one nameserver")
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ type Resolver struct {
|
|||
group singleflight.Group
|
||||
lruCache *cache.LruCache
|
||||
policy *trie.DomainTrie
|
||||
proxyServer []dnsClient
|
||||
}
|
||||
|
||||
// ResolveIP request with TypeA and TypeAAAA, priority return TypeA
|
||||
|
@ -301,6 +302,11 @@ func (r *Resolver) asyncExchange(ctx context.Context, client []dnsClient, msg *D
|
|||
return ch
|
||||
}
|
||||
|
||||
// HasProxyServer has proxy server dns client
|
||||
func (r *Resolver) HasProxyServer() bool {
|
||||
return len(r.main) > 0
|
||||
}
|
||||
|
||||
type NameServer struct {
|
||||
Net string
|
||||
Addr string
|
||||
|
@ -319,6 +325,7 @@ type FallbackFilter struct {
|
|||
type Config struct {
|
||||
Main, Fallback []NameServer
|
||||
Default []NameServer
|
||||
ProxyServer []NameServer
|
||||
IPv6 bool
|
||||
EnhancedMode C.DNSMode
|
||||
FallbackFilter FallbackFilter
|
||||
|
@ -344,6 +351,10 @@ func NewResolver(config Config) *Resolver {
|
|||
r.fallback = transform(config.Fallback, defaultResolver)
|
||||
}
|
||||
|
||||
if len(config.ProxyServer) != 0 {
|
||||
r.proxyServer = transform(config.ProxyServer, defaultResolver)
|
||||
}
|
||||
|
||||
if len(config.Policy) != 0 {
|
||||
r.policy = trie.New()
|
||||
for domain, nameserver := range config.Policy {
|
||||
|
@ -377,10 +388,10 @@ func NewResolver(config Config) *Resolver {
|
|||
return r
|
||||
}
|
||||
|
||||
func NewMainResolver(old *Resolver) *Resolver {
|
||||
func NewProxyServerHostResolver(old *Resolver) *Resolver {
|
||||
r := &Resolver{
|
||||
ipv6: old.ipv6,
|
||||
main: old.main,
|
||||
main: old.proxyServer,
|
||||
lruCache: old.lruCache,
|
||||
hosts: old.hosts,
|
||||
policy: old.policy,
|
||||
|
|
|
@ -130,12 +130,13 @@ func updateDNS(c *config.DNS, t *config.Tun) {
|
|||
Domain: c.FallbackFilter.Domain,
|
||||
GeoSite: c.FallbackFilter.GeoSite,
|
||||
},
|
||||
Default: c.DefaultNameserver,
|
||||
Policy: c.NameServerPolicy,
|
||||
Default: c.DefaultNameserver,
|
||||
Policy: c.NameServerPolicy,
|
||||
ProxyServer: c.ProxyServerNameserver,
|
||||
}
|
||||
|
||||
r := dns.NewResolver(cfg)
|
||||
mr := dns.NewMainResolver(r)
|
||||
pr := dns.NewProxyServerHostResolver(r)
|
||||
m := dns.NewEnhancer(cfg)
|
||||
|
||||
// reuse cache of old host mapper
|
||||
|
@ -144,9 +145,12 @@ func updateDNS(c *config.DNS, t *config.Tun) {
|
|||
}
|
||||
|
||||
resolver.DefaultResolver = r
|
||||
resolver.MainResolver = mr
|
||||
resolver.DefaultHostMapper = m
|
||||
|
||||
if pr.HasProxyServer() {
|
||||
resolver.ProxyServerHostResolver = pr
|
||||
}
|
||||
|
||||
if t.Enable {
|
||||
resolver.DefaultLocalServer = dns.NewLocalServer(r, m)
|
||||
}
|
||||
|
@ -156,9 +160,9 @@ func updateDNS(c *config.DNS, t *config.Tun) {
|
|||
} else {
|
||||
if !t.Enable {
|
||||
resolver.DefaultResolver = nil
|
||||
resolver.MainResolver = nil
|
||||
resolver.DefaultHostMapper = nil
|
||||
resolver.DefaultLocalServer = nil
|
||||
resolver.ProxyServerHostResolver = nil
|
||||
}
|
||||
dns.ReCreateServer("", nil, nil)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue