diff --git a/constant/metadata.go b/constant/metadata.go index 54362989..a7380857 100644 --- a/constant/metadata.go +++ b/constant/metadata.go @@ -156,7 +156,8 @@ type Metadata struct { RawSrcAddr net.Addr `json:"-"` RawDstAddr net.Addr `json:"-"` // Only domain rule - SniffHost string `json:"sniffHost"` + SniffHost string `json:"sniffHost"` + SniffDstIP netip.Addr `json:"sniffDestinationIP"` } func (m *Metadata) RemoteAddress() string { diff --git a/rules/common/ipcidr.go b/rules/common/ipcidr.go index 9c159502..1f02a5f5 100644 --- a/rules/common/ipcidr.go +++ b/rules/common/ipcidr.go @@ -37,10 +37,17 @@ func (i *IPCIDR) RuleType() C.RuleType { func (i *IPCIDR) Match(metadata *C.Metadata) (bool, string) { ip := metadata.DstIP + + var ipsValid bool = true + ips := metadata.SniffDstIP + if ips.IsValid() { + ipsValid = i.ipnet.Contains(ips.WithZone("")) + } + if i.isSourceIP { ip = metadata.SrcIP } - return ip.IsValid() && i.ipnet.Contains(ip.WithZone("")), i.adapter + return ip.IsValid() && i.ipnet.Contains(ip.WithZone("")) && ipsValid, i.adapter } func (i *IPCIDR) Adapter() string { diff --git a/tunnel/tunnel.go b/tunnel/tunnel.go index b1b4add5..a3c90db3 100644 --- a/tunnel/tunnel.go +++ b/tunnel/tunnel.go @@ -619,6 +619,20 @@ func match(metadata *C.Metadata) (C.Proxy, C.Rule, error) { }() } + if metadata.SniffHost != "" && !metadata.SniffDstIP.IsValid() && rule.ShouldResolveIP() { + func() { + ctx, cancel := context.WithTimeout(context.Background(), resolver.DefaultDNSTimeout) + defer cancel() + ip, err := resolver.ResolveIP(ctx, metadata.SniffHost) + if err != nil { + log.Debugln("[DNS] resolve sniffed host %s error: %s", metadata.SniffHost, err.Error()) + } else { + log.Debugln("[DNS] sniffed %s --> %s", metadata.SniffHost, ip.String()) + metadata.SniffDstIP = ip + } + }() + } + if attemptProcessLookup && !findProcessMode.Off() && (findProcessMode.Always() || rule.ShouldFindProcess()) { attemptProcessLookup = false if !features.CMFA {