@@ -12,6 +12,7 @@ import (
1212 "sync"
1313 "time"
1414
15+ "github.com/metacubex/mihomo/common/atomic"
1516 N "github.com/metacubex/mihomo/common/net"
1617 "github.com/metacubex/mihomo/common/utils"
1718 "github.com/metacubex/mihomo/component/loopback"
5859 // default timeout for UDP session
5960 udpTimeout = 60 * time .Second
6061
61- findProcessMode P. FindProcessMode
62+ findProcessMode = atomic . NewTypedValue ( P . FindProcessStrict )
6263
6364 fakeIPRange netip.Prefix
6465
@@ -273,13 +274,13 @@ func SetMode(m TunnelMode) {
273274}
274275
275276func FindProcessMode () P.FindProcessMode {
276- return findProcessMode
277+ return findProcessMode . Load ()
277278}
278279
279280// SetFindProcessMode replace SetAlwaysFindProcess
280281// always find process info if legacyAlways = true or mode.Always() = true, may be increase many memory
281282func SetFindProcessMode (mode P.FindProcessMode ) {
282- findProcessMode = mode
283+ findProcessMode . Store ( mode )
283284}
284285
285286func isHandle (t C.Type ) bool {
@@ -337,6 +338,68 @@ func resolveMetadata(metadata *C.Metadata) (proxy C.Proxy, rule C.Rule, err erro
337338 }
338339 return
339340 }
341+ var (
342+ resolved bool
343+ attemptProcessLookup = metadata .Type != C .INNER
344+ )
345+
346+ if node , ok := resolver .DefaultHosts .Search (metadata .Host , false ); ok {
347+ metadata .DstIP , _ = node .RandIP ()
348+ resolved = true
349+ }
350+
351+ helper := C.RuleMatchHelper {
352+ ResolveIP : func () {
353+ if ! resolved && metadata .Host != "" && ! metadata .Resolved () {
354+ ctx , cancel := context .WithTimeout (context .Background (), resolver .DefaultDNSTimeout )
355+ defer cancel ()
356+ ip , err := resolver .ResolveIP (ctx , metadata .Host )
357+ if err != nil {
358+ log .Debugln ("[DNS] resolve %s error: %s" , metadata .Host , err .Error ())
359+ } else {
360+ log .Debugln ("[DNS] %s --> %s" , metadata .Host , ip .String ())
361+ metadata .DstIP = ip
362+ }
363+ resolved = true
364+ }
365+ },
366+ FindProcess : func () {
367+ if attemptProcessLookup {
368+ attemptProcessLookup = false
369+ if ! features .CMFA {
370+ // normal check for process
371+ uid , path , err := P .FindProcessName (metadata .NetWork .String (), metadata .SrcIP , int (metadata .SrcPort ))
372+ if err != nil {
373+ log .Debugln ("[Process] find process error for %s: %v" , metadata .String (), err )
374+ } else {
375+ metadata .Process = filepath .Base (path )
376+ metadata .ProcessPath = path
377+ metadata .Uid = uid
378+
379+ if pkg , err := P .FindPackageName (metadata ); err == nil { // for android (not CMFA) package names
380+ metadata .Process = pkg
381+ }
382+ }
383+ } else {
384+ // check package names
385+ pkg , err := P .FindPackageName (metadata )
386+ if err != nil {
387+ log .Debugln ("[Process] find process error for %s: %v" , metadata .String (), err )
388+ } else {
389+ metadata .Process = pkg
390+ }
391+ }
392+ }
393+ },
394+ }
395+
396+ switch FindProcessMode () {
397+ case P .FindProcessAlways :
398+ helper .FindProcess ()
399+ helper .FindProcess = nil
400+ case P .FindProcessOff :
401+ helper .FindProcess = nil
402+ }
340403
341404 switch mode {
342405 case Direct :
@@ -345,7 +408,7 @@ func resolveMetadata(metadata *C.Metadata) (proxy C.Proxy, rule C.Rule, err erro
345408 proxy = proxies ["GLOBAL" ]
346409 // Rule
347410 default :
348- proxy , rule , err = match (metadata )
411+ proxy , rule , err = match (metadata , helper )
349412 }
350413 return
351414}
@@ -590,67 +653,9 @@ func logMetadata(metadata *C.Metadata, rule C.Rule, remoteConn C.Connection) {
590653 }
591654}
592655
593- func match (metadata * C.Metadata ) (C.Proxy , C.Rule , error ) {
656+ func match (metadata * C.Metadata , helper C. RuleMatchHelper ) (C.Proxy , C.Rule , error ) {
594657 configMux .RLock ()
595658 defer configMux .RUnlock ()
596- var (
597- resolved bool
598- attemptProcessLookup = metadata .Type != C .INNER
599- )
600-
601- if node , ok := resolver .DefaultHosts .Search (metadata .Host , false ); ok {
602- metadata .DstIP , _ = node .RandIP ()
603- resolved = true
604- }
605-
606- helper := C.RuleMatchHelper {
607- ResolveIP : func () {
608- if ! resolved && metadata .Host != "" && ! metadata .Resolved () {
609- ctx , cancel := context .WithTimeout (context .Background (), resolver .DefaultDNSTimeout )
610- defer cancel ()
611- ip , err := resolver .ResolveIP (ctx , metadata .Host )
612- if err != nil {
613- log .Debugln ("[DNS] resolve %s error: %s" , metadata .Host , err .Error ())
614- } else {
615- log .Debugln ("[DNS] %s --> %s" , metadata .Host , ip .String ())
616- metadata .DstIP = ip
617- }
618- resolved = true
619- }
620- },
621- FindProcess : func () {
622- if attemptProcessLookup && ! findProcessMode .Off () {
623- attemptProcessLookup = false
624- if ! features .CMFA {
625- // normal check for process
626- uid , path , err := P .FindProcessName (metadata .NetWork .String (), metadata .SrcIP , int (metadata .SrcPort ))
627- if err != nil {
628- log .Debugln ("[Process] find process error for %s: %v" , metadata .String (), err )
629- } else {
630- metadata .Process = filepath .Base (path )
631- metadata .ProcessPath = path
632- metadata .Uid = uid
633-
634- if pkg , err := P .FindPackageName (metadata ); err == nil { // for android (not CMFA) package names
635- metadata .Process = pkg
636- }
637- }
638- } else {
639- // check package names
640- pkg , err := P .FindPackageName (metadata )
641- if err != nil {
642- log .Debugln ("[Process] find process error for %s: %v" , metadata .String (), err )
643- } else {
644- metadata .Process = pkg
645- }
646- }
647- }
648- },
649- }
650-
651- if findProcessMode .Always () {
652- helper .FindProcess ()
653- }
654659
655660 for _ , rule := range getRules (metadata ) {
656661 if matched , ada := rule .Match (metadata , helper ); matched {
0 commit comments