chore: apply find process mode in direct/global mode

This commit is contained in:
wwqgtxx
2025-06-12 00:27:51 +08:00
parent 9283cb0f5f
commit 082bcec281
2 changed files with 97 additions and 97 deletions

View File

@@ -12,6 +12,7 @@ import (
"sync"
"time"
"github.com/metacubex/mihomo/common/atomic"
N "github.com/metacubex/mihomo/common/net"
"github.com/metacubex/mihomo/common/utils"
"github.com/metacubex/mihomo/component/loopback"
@@ -58,7 +59,7 @@ var (
// default timeout for UDP session
udpTimeout = 60 * time.Second
findProcessMode P.FindProcessMode
findProcessMode = atomic.NewTypedValue(P.FindProcessStrict)
fakeIPRange netip.Prefix
@@ -273,13 +274,13 @@ func SetMode(m TunnelMode) {
}
func FindProcessMode() P.FindProcessMode {
return findProcessMode
return findProcessMode.Load()
}
// SetFindProcessMode replace SetAlwaysFindProcess
// always find process info if legacyAlways = true or mode.Always() = true, may be increase many memory
func SetFindProcessMode(mode P.FindProcessMode) {
findProcessMode = mode
findProcessMode.Store(mode)
}
func isHandle(t C.Type) bool {
@@ -337,6 +338,68 @@ func resolveMetadata(metadata *C.Metadata) (proxy C.Proxy, rule C.Rule, err erro
}
return
}
var (
resolved bool
attemptProcessLookup = metadata.Type != C.INNER
)
if node, ok := resolver.DefaultHosts.Search(metadata.Host, false); ok {
metadata.DstIP, _ = node.RandIP()
resolved = true
}
helper := C.RuleMatchHelper{
ResolveIP: func() {
if !resolved && metadata.Host != "" && !metadata.Resolved() {
ctx, cancel := context.WithTimeout(context.Background(), resolver.DefaultDNSTimeout)
defer cancel()
ip, err := resolver.ResolveIP(ctx, metadata.Host)
if err != nil {
log.Debugln("[DNS] resolve %s error: %s", metadata.Host, err.Error())
} else {
log.Debugln("[DNS] %s --> %s", metadata.Host, ip.String())
metadata.DstIP = ip
}
resolved = true
}
},
FindProcess: func() {
if attemptProcessLookup {
attemptProcessLookup = false
if !features.CMFA {
// normal check for process
uid, path, err := P.FindProcessName(metadata.NetWork.String(), metadata.SrcIP, int(metadata.SrcPort))
if err != nil {
log.Debugln("[Process] find process error for %s: %v", metadata.String(), err)
} else {
metadata.Process = filepath.Base(path)
metadata.ProcessPath = path
metadata.Uid = uid
if pkg, err := P.FindPackageName(metadata); err == nil { // for android (not CMFA) package names
metadata.Process = pkg
}
}
} else {
// check package names
pkg, err := P.FindPackageName(metadata)
if err != nil {
log.Debugln("[Process] find process error for %s: %v", metadata.String(), err)
} else {
metadata.Process = pkg
}
}
}
},
}
switch FindProcessMode() {
case P.FindProcessAlways:
helper.FindProcess()
helper.FindProcess = nil
case P.FindProcessOff:
helper.FindProcess = nil
}
switch mode {
case Direct:
@@ -345,7 +408,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, helper)
}
return
}
@@ -590,67 +653,9 @@ func logMetadata(metadata *C.Metadata, rule C.Rule, remoteConn C.Connection) {
}
}
func match(metadata *C.Metadata) (C.Proxy, C.Rule, error) {
func match(metadata *C.Metadata, helper C.RuleMatchHelper) (C.Proxy, C.Rule, error) {
configMux.RLock()
defer configMux.RUnlock()
var (
resolved bool
attemptProcessLookup = metadata.Type != C.INNER
)
if node, ok := resolver.DefaultHosts.Search(metadata.Host, false); ok {
metadata.DstIP, _ = node.RandIP()
resolved = true
}
helper := C.RuleMatchHelper{
ResolveIP: func() {
if !resolved && metadata.Host != "" && !metadata.Resolved() {
ctx, cancel := context.WithTimeout(context.Background(), resolver.DefaultDNSTimeout)
defer cancel()
ip, err := resolver.ResolveIP(ctx, metadata.Host)
if err != nil {
log.Debugln("[DNS] resolve %s error: %s", metadata.Host, err.Error())
} else {
log.Debugln("[DNS] %s --> %s", metadata.Host, ip.String())
metadata.DstIP = ip
}
resolved = true
}
},
FindProcess: func() {
if attemptProcessLookup && !findProcessMode.Off() {
attemptProcessLookup = false
if !features.CMFA {
// normal check for process
uid, path, err := P.FindProcessName(metadata.NetWork.String(), metadata.SrcIP, int(metadata.SrcPort))
if err != nil {
log.Debugln("[Process] find process error for %s: %v", metadata.String(), err)
} else {
metadata.Process = filepath.Base(path)
metadata.ProcessPath = path
metadata.Uid = uid
if pkg, err := P.FindPackageName(metadata); err == nil { // for android (not CMFA) package names
metadata.Process = pkg
}
}
} else {
// check package names
pkg, err := P.FindPackageName(metadata)
if err != nil {
log.Debugln("[Process] find process error for %s: %v", metadata.String(), err)
} else {
metadata.Process = pkg
}
}
}
},
}
if findProcessMode.Always() {
helper.FindProcess()
}
for _, rule := range getRules(metadata) {
if matched, ada := rule.Match(metadata, helper); matched {