Skip to content

Commit

Permalink
add direct-nameserver and direct-nameserver-follow-policy in `dns…
Browse files Browse the repository at this point in the history
…` section
  • Loading branch information
wwqgtxx committed Oct 4, 2024
1 parent b95e228 commit e489544
Show file tree
Hide file tree
Showing 9 changed files with 106 additions and 102 deletions.
4 changes: 2 additions & 2 deletions adapter/outbound/direct.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type DirectOption 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.WithResolver(resolver.ProxyServerHostResolver))
opts = append(opts, dialer.WithResolver(resolver.DirectHostResolver))
c, err := dialer.DialContext(ctx, "tcp", metadata.RemoteAddress(), d.Base.DialOptions(opts...)...)
if err != nil {
return nil, err
Expand All @@ -32,7 +32,7 @@ func (d *Direct) DialContext(ctx context.Context, metadata *C.Metadata, opts ...
func (d *Direct) ListenPacketContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.PacketConn, error) {
// net.UDPConn.WriteTo only working with *net.UDPAddr, so we need a net.UDPAddr
if !metadata.Resolved() {
ip, err := resolver.ResolveIPWithResolver(ctx, metadata.Host, resolver.ProxyServerHostResolver)
ip, err := resolver.ResolveIPWithResolver(ctx, metadata.Host, resolver.DirectHostResolver)
if err != nil {
return nil, errors.New("can't resolve ip")
}
Expand Down
10 changes: 5 additions & 5 deletions adapter/outbound/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func resolveUDPAddr(ctx context.Context, network, address string) (*net.UDPAddr,
return nil, err
}

ip, err := resolver.ResolveProxyServerHost(ctx, host)
ip, err := resolver.ResolveIPWithResolver(ctx, host, resolver.ProxyServerHostResolver)
if err != nil {
return nil, err
}
Expand All @@ -57,12 +57,12 @@ func resolveUDPAddrWithPrefer(ctx context.Context, network, address string, pref
var fallback netip.Addr
switch prefer {
case C.IPv4Only:
ip, err = resolver.ResolveIPv4ProxyServerHost(ctx, host)
ip, err = resolver.ResolveIPv4WithResolver(ctx, host, resolver.ProxyServerHostResolver)
case C.IPv6Only:
ip, err = resolver.ResolveIPv6ProxyServerHost(ctx, host)
ip, err = resolver.ResolveIPv6WithResolver(ctx, host, resolver.ProxyServerHostResolver)
case C.IPv6Prefer:
var ips []netip.Addr
ips, err = resolver.LookupIPProxyServerHost(ctx, host)
ips, err = resolver.LookupIPWithResolver(ctx, host, resolver.ProxyServerHostResolver)
if err == nil {
for _, addr := range ips {
if addr.Is6() {
Expand All @@ -78,7 +78,7 @@ func resolveUDPAddrWithPrefer(ctx context.Context, network, address string, pref
default:
// C.IPv4Prefer, C.DualStack and other
var ips []netip.Addr
ips, err = resolver.LookupIPProxyServerHost(ctx, host)
ips, err = resolver.LookupIPWithResolver(ctx, host, resolver.ProxyServerHostResolver)
if err == nil {
for _, addr := range ips {
if addr.Is4() {
Expand Down
4 changes: 2 additions & 2 deletions adapter/outbound/wireguard.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ type WireGuard struct {
device wireguardGoDevice
tunDevice wireguard.Device
dialer proxydialer.SingDialer
resolver *dns.Resolver
resolver resolver.Resolver
refP *refProxyAdapter

initOk atomic.Bool
Expand Down Expand Up @@ -295,7 +295,7 @@ func NewWireGuard(option WireGuardOption) (*WireGuard, error) {
for i := range nss {
nss[i].ProxyAdapter = refP
}
outbound.resolver, _ = dns.NewResolver(dns.Config{
outbound.resolver = dns.NewResolver(dns.Config{
Main: nss,
IPv6: has6,
})
Expand Down
22 changes: 7 additions & 15 deletions component/dialer/dialer.go
Original file line number Diff line number Diff line change
Expand Up @@ -334,26 +334,18 @@ func parseAddr(ctx context.Context, network, address string, preferResolver reso
return nil, "-1", err
}

if preferResolver == nil {
preferResolver = resolver.ProxyServerHostResolver
}

var ips []netip.Addr
switch network {
case "tcp4", "udp4":
if preferResolver == nil {
ips, err = resolver.LookupIPv4ProxyServerHost(ctx, host)
} else {
ips, err = resolver.LookupIPv4WithResolver(ctx, host, preferResolver)
}
ips, err = resolver.LookupIPv4WithResolver(ctx, host, preferResolver)
case "tcp6", "udp6":
if preferResolver == nil {
ips, err = resolver.LookupIPv6ProxyServerHost(ctx, host)
} else {
ips, err = resolver.LookupIPv6WithResolver(ctx, host, preferResolver)
}
ips, err = resolver.LookupIPv6WithResolver(ctx, host, preferResolver)
default:
if preferResolver == nil {
ips, err = resolver.LookupIPProxyServerHost(ctx, host)
} else {
ips, err = resolver.LookupIPWithResolver(ctx, host, preferResolver)
}
ips, err = resolver.LookupIPWithResolver(ctx, host, preferResolver)
}
if err != nil {
return nil, "-1", fmt.Errorf("dns resolve failed: %w", err)
Expand Down
53 changes: 4 additions & 49 deletions component/resolver/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@ var (
// DefaultResolver aim to resolve ip
DefaultResolver Resolver

// ProxyServerHostResolver resolve ip to proxies server host
// ProxyServerHostResolver resolve ip for proxies server host, only nil when DefaultResolver is nil
ProxyServerHostResolver Resolver

// DirectHostResolver resolve ip for direct outbound host, only nil when DefaultResolver is nil
DirectHostResolver Resolver

// SystemResolver always using system dns, and was init in dns module
SystemResolver Resolver

Expand Down Expand Up @@ -187,58 +190,10 @@ func ResolveIP(ctx context.Context, host string) (netip.Addr, error) {
return ResolveIPWithResolver(ctx, host, DefaultResolver)
}

// ResolveIPv4ProxyServerHost proxies server host only
func ResolveIPv4ProxyServerHost(ctx context.Context, host string) (netip.Addr, error) {
if ProxyServerHostResolver != nil {
return ResolveIPv4WithResolver(ctx, host, ProxyServerHostResolver)
}
return ResolveIPv4(ctx, host)
}

// ResolveIPv6ProxyServerHost proxies server host only
func ResolveIPv6ProxyServerHost(ctx context.Context, host string) (netip.Addr, error) {
if ProxyServerHostResolver != nil {
return ResolveIPv6WithResolver(ctx, host, ProxyServerHostResolver)
}
return ResolveIPv6(ctx, host)
}

// ResolveProxyServerHost proxies server host only
func ResolveProxyServerHost(ctx context.Context, host string) (netip.Addr, error) {
if ProxyServerHostResolver != nil {
return ResolveIPWithResolver(ctx, host, ProxyServerHostResolver)
}
return ResolveIP(ctx, host)
}

func LookupIPv6ProxyServerHost(ctx context.Context, host string) ([]netip.Addr, error) {
if ProxyServerHostResolver != nil {
return LookupIPv6WithResolver(ctx, host, ProxyServerHostResolver)
}
return LookupIPv6(ctx, host)
}

func LookupIPv4ProxyServerHost(ctx context.Context, host string) ([]netip.Addr, error) {
if ProxyServerHostResolver != nil {
return LookupIPv4WithResolver(ctx, host, ProxyServerHostResolver)
}
return LookupIPv4(ctx, host)
}

func LookupIPProxyServerHost(ctx context.Context, host string) ([]netip.Addr, error) {
if ProxyServerHostResolver != nil {
return LookupIPWithResolver(ctx, host, ProxyServerHostResolver)
}
return LookupIP(ctx, host)
}

func ResetConnection() {
if DefaultResolver != nil {
go DefaultResolver.ResetConnection()
}
if ProxyServerHostResolver != nil {
go ProxyServerHostResolver.ResetConnection()
}
}

func SortationAddr(ips []netip.Addr) (ipv4s, ipv6s []netip.Addr) {
Expand Down
46 changes: 28 additions & 18 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ type DNS struct {
Hosts *trie.DomainTrie[netip.Addr]
NameServerPolicy []dns.Policy
ProxyServerNameserver []dns.NameServer
DirectNameServer []dns.NameServer
DirectFollowPolicy bool
SearchDomains []string
}

Expand Down Expand Up @@ -163,24 +165,26 @@ type RawCors struct {
}

type RawDNS struct {
Enable bool `yaml:"enable" json:"enable"`
IPv6 bool `yaml:"ipv6" json:"ipv6"`
UseHosts bool `yaml:"use-hosts" json:"use-hosts"`
UseSystemHosts bool `yaml:"use-system-hosts" json:"use-system-hosts"`
RespectRules bool `yaml:"respect-rules" json:"respect-rules"`
NameServer []string `yaml:"nameserver" json:"nameserver"`
Fallback []string `yaml:"fallback" json:"fallback"`
FallbackFilter RawFallbackFilter `yaml:"fallback-filter" json:"fallback-filter"`
Listen string `yaml:"listen" json:"listen"`
EnhancedMode C.DNSMode `yaml:"enhanced-mode" json:"enhanced-mode"`
FakeIPRange string `yaml:"fake-ip-range" json:"fake-ip-range"`
FakeIPFilter []string `yaml:"fake-ip-filter" json:"fake-ip-filter"`
FakeIPFilterMode C.FilterMode `yaml:"fake-ip-filter-mode" json:"fake-ip-filter-mode"`
DefaultNameserver []string `yaml:"default-nameserver" json:"default-nameserver"`
CacheAlgorithm string `yaml:"cache-algorithm" json:"cache-algorithm"`
NameServerPolicy *orderedmap.OrderedMap[string, any] `yaml:"nameserver-policy" json:"nameserver-policy"`
ProxyServerNameserver []string `yaml:"proxy-server-nameserver" json:"proxy-server-nameserver"`
SearchDomains []string `yaml:"search-domains" json:"search-domains"`
Enable bool `yaml:"enable" json:"enable"`
IPv6 bool `yaml:"ipv6" json:"ipv6"`
UseHosts bool `yaml:"use-hosts" json:"use-hosts"`
UseSystemHosts bool `yaml:"use-system-hosts" json:"use-system-hosts"`
RespectRules bool `yaml:"respect-rules" json:"respect-rules"`
NameServer []string `yaml:"nameserver" json:"nameserver"`
Fallback []string `yaml:"fallback" json:"fallback"`
FallbackFilter RawFallbackFilter `yaml:"fallback-filter" json:"fallback-filter"`
Listen string `yaml:"listen" json:"listen"`
EnhancedMode C.DNSMode `yaml:"enhanced-mode" json:"enhanced-mode"`
FakeIPRange string `yaml:"fake-ip-range" json:"fake-ip-range"`
FakeIPFilter []string `yaml:"fake-ip-filter" json:"fake-ip-filter"`
FakeIPFilterMode C.FilterMode `yaml:"fake-ip-filter-mode" json:"fake-ip-filter-mode"`
DefaultNameserver []string `yaml:"default-nameserver" json:"default-nameserver"`
CacheAlgorithm string `yaml:"cache-algorithm" json:"cache-algorithm"`
NameServerPolicy *orderedmap.OrderedMap[string, any] `yaml:"nameserver-policy" json:"nameserver-policy"`
ProxyServerNameserver []string `yaml:"proxy-server-nameserver" json:"proxy-server-nameserver"`
DirectNameServer []string `yaml:"direct-nameserver" json:"direct-nameserver"`
DirectNameServerFollowPolicy bool `yaml:"direct-nameserver-follow-policy" json:"direct-nameserver-follow-policy"`
SearchDomains []string `yaml:"search-domains" json:"search-domains"`
}

type RawFallbackFilter struct {
Expand Down Expand Up @@ -394,6 +398,7 @@ func DefaultRawConfig() *RawConfig {
}
rawCfg.DNS.RespectRules = true
rawCfg.DNS.ProxyServerNameserver = rawCfg.DNS.DefaultNameserver
rawCfg.DNS.DirectNameServer = rawCfg.DNS.DefaultNameserver
return rawCfg
}

Expand Down Expand Up @@ -1142,6 +1147,11 @@ func parseDNS(rawCfg *RawConfig, hosts *trie.DomainTrie[netip.Addr], ruleProvide
return nil, err
}

if dnsCfg.DirectNameServer, err = parseNameServer(cfg.DirectNameServer, false); err != nil {
return nil, err
}
dnsCfg.DirectFollowPolicy = cfg.DirectNameServerFollowPolicy

if len(cfg.DefaultNameserver) == 0 {
return nil, errors.New("default nameserver should have at least one nameserver")
}
Expand Down
45 changes: 40 additions & 5 deletions dns/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,8 @@ type Config struct {
Main, Fallback []NameServer
Default []NameServer
ProxyServer []NameServer
DirectServer []NameServer
DirectFollowPolicy bool
IPv6 bool
EnhancedMode C.DNSMode
FallbackIPFilter []C.IpMatcher
Expand All @@ -474,7 +476,25 @@ func (config Config) newCache() dnsCache {
}
}

func NewResolver(config Config) (r *Resolver, pr *Resolver) {
type Resolvers struct {
*Resolver
ProxyResolver *Resolver
DirectResolver *Resolver
}

func (rs Resolvers) ClearCache() {
rs.Resolver.ClearCache()
rs.ProxyResolver.ClearCache()
rs.DirectResolver.ClearCache()
}

func (rs Resolvers) ResetConnection() {
rs.Resolver.ResetConnection()
rs.ProxyResolver.ResetConnection()
rs.DirectResolver.ResetConnection()
}

func NewResolver(config Config) (rs Resolvers) {
defaultResolver := &Resolver{
main: transform(config.Default, nil),
cache: config.newCache(),
Expand Down Expand Up @@ -507,17 +527,18 @@ func NewResolver(config Config) (r *Resolver, pr *Resolver) {
return
}

r = &Resolver{
r := &Resolver{
ipv6: config.IPv6,
main: cacheTransform(config.Main),
cache: config.newCache(),
hosts: config.Hosts,
searchDomains: config.SearchDomains,
}
r.defaultResolver = defaultResolver
rs.Resolver = r

if len(config.ProxyServer) != 0 {
pr = &Resolver{
rs.ProxyResolver = &Resolver{
ipv6: config.IPv6,
main: cacheTransform(config.ProxyServer),
cache: config.newCache(),
Expand All @@ -526,8 +547,20 @@ func NewResolver(config Config) (r *Resolver, pr *Resolver) {
}
}

if len(config.DirectServer) != 0 {
rs.DirectResolver = &Resolver{
ipv6: config.IPv6,
main: cacheTransform(config.DirectServer),
cache: config.newCache(),
hosts: config.Hosts,
searchDomains: config.SearchDomains,
}
}

if len(config.Fallback) != 0 {
r.fallback = cacheTransform(config.Fallback)
r.fallbackIPFilters = config.FallbackIPFilter
r.fallbackDomainFilters = config.FallbackDomainFilter
}

if len(config.Policy) != 0 {
Expand Down Expand Up @@ -556,9 +589,11 @@ func NewResolver(config Config) (r *Resolver, pr *Resolver) {
}
}
insertPolicy(nil)

if rs.DirectResolver != nil && config.DirectFollowPolicy {
rs.DirectResolver.policy = r.policy
}
}
r.fallbackIPFilters = config.FallbackIPFilter
r.fallbackDomainFilters = config.FallbackDomainFilter

return
}
Expand Down
2 changes: 1 addition & 1 deletion dns/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func newSystemClient() *systemClient {
}

func init() {
r, _ := NewResolver(Config{})
r := NewResolver(Config{})
c := newSystemClient()
c.defaultNS = transform([]NameServer{{Addr: "114.114.114.114:53"}, {Addr: "8.8.8.8:53"}}, nil)
r.main = []dnsClient{c}
Expand Down
Loading

0 comments on commit e489544

Please sign in to comment.