Skip to content

Commit 082bcec

Browse files
committed
chore: apply find process mode in direct/global mode
1 parent 9283cb0 commit 082bcec

File tree

2 files changed

+96
-96
lines changed

2 files changed

+96
-96
lines changed
Lines changed: 28 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,52 @@
11
package process
22

33
import (
4-
"encoding/json"
54
"errors"
65
"strings"
76
)
87

98
const (
10-
FindProcessAlways = "always"
11-
FindProcessStrict = "strict"
12-
FindProcessOff = "off"
9+
FindProcessStrict FindProcessMode = iota
10+
FindProcessAlways
11+
FindProcessOff
1312
)
1413

1514
var (
16-
validModes = map[string]struct{}{
17-
FindProcessAlways: {},
18-
FindProcessOff: {},
19-
FindProcessStrict: {},
15+
validModes = map[string]FindProcessMode{
16+
FindProcessStrict.String(): FindProcessStrict,
17+
FindProcessAlways.String(): FindProcessAlways,
18+
FindProcessOff.String(): FindProcessOff,
2019
}
2120
)
2221

23-
type FindProcessMode string
22+
type FindProcessMode int
2423

25-
func (m FindProcessMode) Always() bool {
26-
return m == FindProcessAlways
24+
// UnmarshalText unserialize FindProcessMode
25+
func (m *FindProcessMode) UnmarshalText(data []byte) error {
26+
return m.Set(string(data))
2727
}
2828

29-
func (m FindProcessMode) Off() bool {
30-
return m == FindProcessOff
31-
}
32-
33-
func (m *FindProcessMode) UnmarshalYAML(unmarshal func(any) error) error {
34-
var tp string
35-
if err := unmarshal(&tp); err != nil {
36-
return err
29+
func (m *FindProcessMode) Set(value string) error {
30+
mode, exist := validModes[strings.ToLower(value)]
31+
if !exist {
32+
return errors.New("invalid find process mode")
3733
}
38-
return m.Set(tp)
34+
*m = mode
35+
return nil
3936
}
4037

41-
func (m *FindProcessMode) UnmarshalJSON(data []byte) error {
42-
var tp string
43-
if err := json.Unmarshal(data, &tp); err != nil {
44-
return err
45-
}
46-
return m.Set(tp)
38+
// MarshalText serialize FindProcessMode
39+
func (m FindProcessMode) MarshalText() ([]byte, error) {
40+
return []byte(m.String()), nil
4741
}
4842

49-
func (m *FindProcessMode) Set(value string) error {
50-
mode := strings.ToLower(value)
51-
_, exist := validModes[mode]
52-
if !exist {
53-
return errors.New("invalid find process mode")
43+
func (m FindProcessMode) String() string {
44+
switch m {
45+
case FindProcessAlways:
46+
return "always"
47+
case FindProcessOff:
48+
return "off"
49+
default:
50+
return "strict"
5451
}
55-
*m = FindProcessMode(mode)
56-
return nil
5752
}

tunnel/tunnel.go

Lines changed: 68 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -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"
@@ -58,7 +59,7 @@ var (
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

275276
func 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
281282
func SetFindProcessMode(mode P.FindProcessMode) {
282-
findProcessMode = mode
283+
findProcessMode.Store(mode)
283284
}
284285

285286
func 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

Comments
 (0)