From 94a5b1a6790f0c56cb182f823cda285181b09ec3 Mon Sep 17 00:00:00 2001 From: qianlongzt <18493471+qianlongzt@users.noreply.github.com> Date: Sun, 16 Mar 2025 22:58:41 +0800 Subject: [PATCH] refactor(dns): use option to avoid dns resolve --- config/dns_policy_rule.go | 7 ++++--- tunnel/dns_dialer.go | 4 ++-- tunnel/tunnel.go | 16 ++++++++++------ 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/config/dns_policy_rule.go b/config/dns_policy_rule.go index ff73d0d2..2d5b2b07 100644 --- a/config/dns_policy_rule.go +++ b/config/dns_policy_rule.go @@ -2,7 +2,6 @@ package config import ( "errors" - "net/netip" "strings" "github.com/metacubex/mihomo/common/lru" @@ -28,9 +27,8 @@ func (r *ruleMatcher) MatchDomain(domain string) bool { NetWork: C.TCP, Type: C.INNER, // avoid process lookup Host: domain, - DstIP: netip.AddrFrom4([4]byte{}), // avoid dns lookup } - p, _, err := tunnel.ResolveMetadata(meta) + p, r, err := tunnel.ResolveMetadata(meta, &tunnel.ResolveOption{SkipResolveIP: true}) if err != nil { log.Warnln("[DNS] ruleMatcher: match(%s) got err %v", domain, err.Error()) return false @@ -45,6 +43,9 @@ func (r *ruleMatcher) MatchDomain(domain string) bool { break } } + log.Debugln("[DNS] ruleMatcher: domain(%s, %s) rule(%s)", + domain, typ.String(), r) + typ = adapter.Type() cache.Set(domain, typ) } diff --git a/tunnel/dns_dialer.go b/tunnel/dns_dialer.go index 8f1b904e..6f4aec02 100644 --- a/tunnel/dns_dialer.go +++ b/tunnel/dns_dialer.go @@ -64,7 +64,7 @@ func (d *DNSDialer) DialContext(ctx context.Context, network, addr string) (net. } metadata.DstIP = dstIP } - proxyAdapter, rule, err = ResolveMetadata(metadata) + proxyAdapter, rule, err = ResolveMetadata(metadata, &ResolveOption{SkipResolveIP: true}) if err != nil { return nil, err } @@ -151,7 +151,7 @@ func (d *DNSDialer) ListenPacket(ctx context.Context, network, addr string) (net var rule C.Rule if proxyAdapter == nil { if proxyName == DnsRespectRules { - proxyAdapter, rule, err = ResolveMetadata(metadata) + proxyAdapter, rule, err = ResolveMetadata(metadata, &ResolveOption{SkipResolveIP: true}) if err != nil { return nil, err } diff --git a/tunnel/tunnel.go b/tunnel/tunnel.go index 4b6f7d96..c206800a 100644 --- a/tunnel/tunnel.go +++ b/tunnel/tunnel.go @@ -324,7 +324,11 @@ func preHandleMetadata(metadata *C.Metadata) error { return nil } -func ResolveMetadata(metadata *C.Metadata) (proxy C.Proxy, rule C.Rule, err error) { +type ResolveOption struct { + SkipResolveIP bool +} + +func ResolveMetadata(metadata *C.Metadata, option *ResolveOption) (proxy C.Proxy, rule C.Rule, err error) { if metadata.SpecialProxy != "" { var exist bool proxy, exist = proxies[metadata.SpecialProxy] @@ -341,7 +345,7 @@ func ResolveMetadata(metadata *C.Metadata) (proxy C.Proxy, rule C.Rule, err erro proxy = proxies["GLOBAL"] // Rule default: - proxy, rule, err = match(metadata) + proxy, rule, err = match(metadata, option) } return } @@ -393,7 +397,7 @@ func handleUDPConn(packet C.PacketAdapter) { return nil, nil, err } - proxy, rule, err := ResolveMetadata(metadata) + proxy, rule, err := ResolveMetadata(metadata, &ResolveOption{}) if err != nil { log.Warnln("[UDP] Parse metadata failed: %s", err.Error()) return nil, nil, err @@ -489,7 +493,7 @@ func handleTCPConn(connCtx C.ConnContext) { }() } - proxy, rule, err := ResolveMetadata(metadata) + proxy, rule, err := ResolveMetadata(metadata, &ResolveOption{}) if err != nil { log.Warnln("[Metadata] parse failed: %s", err.Error()) return @@ -592,7 +596,7 @@ func shouldResolveIP(rule C.Rule, metadata *C.Metadata) bool { return rule.ShouldResolveIP() && metadata.Host != "" && !metadata.DstIP.IsValid() } -func match(metadata *C.Metadata) (C.Proxy, C.Rule, error) { +func match(metadata *C.Metadata, option *ResolveOption) (C.Proxy, C.Rule, error) { configMux.RLock() defer configMux.RUnlock() var ( @@ -606,7 +610,7 @@ func match(metadata *C.Metadata) (C.Proxy, C.Rule, error) { } for _, rule := range getRules(metadata) { - if !resolved && shouldResolveIP(rule, metadata) { + if !resolved && !option.SkipResolveIP && shouldResolveIP(rule, metadata) { func() { ctx, cancel := context.WithTimeout(context.Background(), resolver.DefaultDNSTimeout) defer cancel()