fix #322: add option general.find-process-mode, user can turn off findProcess feature in router
findProcess slow down connection due to repeat call to FindProcessName in router environment this option has 3 values: always, strict, off - always, equal to enable-process: true. Just try to merge all process related option into one - strict, as default value, behavior remains unchanged - off, turn off findProcess, useful in router environment
This commit is contained in:
parent
fd48c6df8a
commit
b4503908df
4 changed files with 137 additions and 70 deletions
57
component/process/find_process_mode.go
Normal file
57
component/process/find_process_mode.go
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
package process
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
FindProcessAlways = "always"
|
||||||
|
FindProcessStrict = "strict"
|
||||||
|
FindProcessOff = "off"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
validModes = map[string]struct{}{
|
||||||
|
FindProcessAlways: {},
|
||||||
|
FindProcessOff: {},
|
||||||
|
FindProcessStrict: {},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
type FindProcessMode string
|
||||||
|
|
||||||
|
func (m FindProcessMode) Always() bool {
|
||||||
|
return m == FindProcessAlways
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m FindProcessMode) Off() bool {
|
||||||
|
return m == FindProcessOff
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *FindProcessMode) UnmarshalYAML(unmarshal func(any) error) error {
|
||||||
|
var tp string
|
||||||
|
if err := unmarshal(&tp); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return m.Set(tp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *FindProcessMode) UnmarshalJSON(data []byte) error {
|
||||||
|
var tp string
|
||||||
|
if err := json.Unmarshal(data, &tp); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return m.Set(tp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *FindProcessMode) Set(value string) error {
|
||||||
|
mode := strings.ToLower(value)
|
||||||
|
_, exist := validModes[mode]
|
||||||
|
if !exist {
|
||||||
|
return errors.New("invalid find process mode")
|
||||||
|
}
|
||||||
|
*m = FindProcessMode(mode)
|
||||||
|
return nil
|
||||||
|
}
|
133
config/config.go
133
config/config.go
|
@ -4,6 +4,7 @@ import (
|
||||||
"container/list"
|
"container/list"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
P "github.com/Dreamacro/clash/component/process"
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
@ -42,18 +43,19 @@ import (
|
||||||
type General struct {
|
type General struct {
|
||||||
Inbound
|
Inbound
|
||||||
Controller
|
Controller
|
||||||
Mode T.TunnelMode `json:"mode"`
|
Mode T.TunnelMode `json:"mode"`
|
||||||
UnifiedDelay bool
|
UnifiedDelay bool
|
||||||
LogLevel log.LogLevel `json:"log-level"`
|
LogLevel log.LogLevel `json:"log-level"`
|
||||||
IPv6 bool `json:"ipv6"`
|
IPv6 bool `json:"ipv6"`
|
||||||
Interface string `json:"interface-name"`
|
Interface string `json:"interface-name"`
|
||||||
RoutingMark int `json:"-"`
|
RoutingMark int `json:"-"`
|
||||||
GeodataMode bool `json:"geodata-mode"`
|
GeodataMode bool `json:"geodata-mode"`
|
||||||
GeodataLoader string `json:"geodata-loader"`
|
GeodataLoader string `json:"geodata-loader"`
|
||||||
TCPConcurrent bool `json:"tcp-concurrent"`
|
TCPConcurrent bool `json:"tcp-concurrent"`
|
||||||
EnableProcess bool `json:"enable-process"`
|
EnableProcess bool `json:"enable-process"`
|
||||||
Sniffing bool `json:"sniffing"`
|
FindProcessMode P.FindProcessMode `json:"find-process-mode"`
|
||||||
EBpf EBpf `json:"-"`
|
Sniffing bool `json:"sniffing"`
|
||||||
|
EBpf EBpf `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inbound config
|
// Inbound config
|
||||||
|
@ -226,32 +228,33 @@ type RawTuicServer struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type RawConfig struct {
|
type RawConfig struct {
|
||||||
Port int `yaml:"port"`
|
Port int `yaml:"port"`
|
||||||
SocksPort int `yaml:"socks-port"`
|
SocksPort int `yaml:"socks-port"`
|
||||||
RedirPort int `yaml:"redir-port"`
|
RedirPort int `yaml:"redir-port"`
|
||||||
TProxyPort int `yaml:"tproxy-port"`
|
TProxyPort int `yaml:"tproxy-port"`
|
||||||
MixedPort int `yaml:"mixed-port"`
|
MixedPort int `yaml:"mixed-port"`
|
||||||
ShadowSocksConfig string `yaml:"ss-config"`
|
ShadowSocksConfig string `yaml:"ss-config"`
|
||||||
VmessConfig string `yaml:"vmess-config"`
|
VmessConfig string `yaml:"vmess-config"`
|
||||||
InboundTfo bool `yaml:"inbound-tfo"`
|
InboundTfo bool `yaml:"inbound-tfo"`
|
||||||
Authentication []string `yaml:"authentication"`
|
Authentication []string `yaml:"authentication"`
|
||||||
AllowLan bool `yaml:"allow-lan"`
|
AllowLan bool `yaml:"allow-lan"`
|
||||||
BindAddress string `yaml:"bind-address"`
|
BindAddress string `yaml:"bind-address"`
|
||||||
Mode T.TunnelMode `yaml:"mode"`
|
Mode T.TunnelMode `yaml:"mode"`
|
||||||
UnifiedDelay bool `yaml:"unified-delay"`
|
UnifiedDelay bool `yaml:"unified-delay"`
|
||||||
LogLevel log.LogLevel `yaml:"log-level"`
|
LogLevel log.LogLevel `yaml:"log-level"`
|
||||||
IPv6 bool `yaml:"ipv6"`
|
IPv6 bool `yaml:"ipv6"`
|
||||||
ExternalController string `yaml:"external-controller"`
|
ExternalController string `yaml:"external-controller"`
|
||||||
ExternalControllerTLS string `yaml:"external-controller-tls"`
|
ExternalControllerTLS string `yaml:"external-controller-tls"`
|
||||||
ExternalUI string `yaml:"external-ui"`
|
ExternalUI string `yaml:"external-ui"`
|
||||||
Secret string `yaml:"secret"`
|
Secret string `yaml:"secret"`
|
||||||
Interface string `yaml:"interface-name"`
|
Interface string `yaml:"interface-name"`
|
||||||
RoutingMark int `yaml:"routing-mark"`
|
RoutingMark int `yaml:"routing-mark"`
|
||||||
Tunnels []LC.Tunnel `yaml:"tunnels"`
|
Tunnels []LC.Tunnel `yaml:"tunnels"`
|
||||||
GeodataMode bool `yaml:"geodata-mode"`
|
GeodataMode bool `yaml:"geodata-mode"`
|
||||||
GeodataLoader string `yaml:"geodata-loader"`
|
GeodataLoader string `yaml:"geodata-loader"`
|
||||||
TCPConcurrent bool `yaml:"tcp-concurrent" json:"tcp-concurrent"`
|
TCPConcurrent bool `yaml:"tcp-concurrent" json:"tcp-concurrent"`
|
||||||
EnableProcess bool `yaml:"enable-process" json:"enable-process"`
|
EnableProcess bool `yaml:"enable-process" json:"enable-process"`
|
||||||
|
FindProcessMode P.FindProcessMode `yaml:"find-process-mode" json:"find-process-mode"`
|
||||||
|
|
||||||
Sniffer RawSniffer `yaml:"sniffer"`
|
Sniffer RawSniffer `yaml:"sniffer"`
|
||||||
ProxyProvider map[string]map[string]any `yaml:"proxy-providers"`
|
ProxyProvider map[string]map[string]any `yaml:"proxy-providers"`
|
||||||
|
@ -314,21 +317,22 @@ func Parse(buf []byte) (*Config, error) {
|
||||||
func UnmarshalRawConfig(buf []byte) (*RawConfig, error) {
|
func UnmarshalRawConfig(buf []byte) (*RawConfig, error) {
|
||||||
// config with default value
|
// config with default value
|
||||||
rawCfg := &RawConfig{
|
rawCfg := &RawConfig{
|
||||||
AllowLan: false,
|
AllowLan: false,
|
||||||
BindAddress: "*",
|
BindAddress: "*",
|
||||||
IPv6: true,
|
IPv6: true,
|
||||||
Mode: T.Rule,
|
Mode: T.Rule,
|
||||||
GeodataMode: C.GeodataMode,
|
GeodataMode: C.GeodataMode,
|
||||||
GeodataLoader: "memconservative",
|
GeodataLoader: "memconservative",
|
||||||
UnifiedDelay: false,
|
UnifiedDelay: false,
|
||||||
Authentication: []string{},
|
Authentication: []string{},
|
||||||
LogLevel: log.INFO,
|
LogLevel: log.INFO,
|
||||||
Hosts: map[string]string{},
|
Hosts: map[string]string{},
|
||||||
Rule: []string{},
|
Rule: []string{},
|
||||||
Proxy: []map[string]any{},
|
Proxy: []map[string]any{},
|
||||||
ProxyGroup: []map[string]any{},
|
ProxyGroup: []map[string]any{},
|
||||||
TCPConcurrent: false,
|
TCPConcurrent: false,
|
||||||
EnableProcess: false,
|
EnableProcess: false,
|
||||||
|
FindProcessMode: P.FindProcessStrict,
|
||||||
Tun: RawTun{
|
Tun: RawTun{
|
||||||
Enable: false,
|
Enable: false,
|
||||||
Device: "",
|
Device: "",
|
||||||
|
@ -536,17 +540,18 @@ func parseGeneral(cfg *RawConfig) (*General, error) {
|
||||||
Secret: cfg.Secret,
|
Secret: cfg.Secret,
|
||||||
ExternalControllerTLS: cfg.ExternalControllerTLS,
|
ExternalControllerTLS: cfg.ExternalControllerTLS,
|
||||||
},
|
},
|
||||||
UnifiedDelay: cfg.UnifiedDelay,
|
UnifiedDelay: cfg.UnifiedDelay,
|
||||||
Mode: cfg.Mode,
|
Mode: cfg.Mode,
|
||||||
LogLevel: cfg.LogLevel,
|
LogLevel: cfg.LogLevel,
|
||||||
IPv6: cfg.IPv6,
|
IPv6: cfg.IPv6,
|
||||||
Interface: cfg.Interface,
|
Interface: cfg.Interface,
|
||||||
RoutingMark: cfg.RoutingMark,
|
RoutingMark: cfg.RoutingMark,
|
||||||
GeodataMode: cfg.GeodataMode,
|
GeodataMode: cfg.GeodataMode,
|
||||||
GeodataLoader: cfg.GeodataLoader,
|
GeodataLoader: cfg.GeodataLoader,
|
||||||
TCPConcurrent: cfg.TCPConcurrent,
|
TCPConcurrent: cfg.TCPConcurrent,
|
||||||
EnableProcess: cfg.EnableProcess,
|
EnableProcess: cfg.EnableProcess,
|
||||||
EBpf: cfg.EBpf,
|
FindProcessMode: cfg.FindProcessMode,
|
||||||
|
EBpf: cfg.EBpf,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -309,7 +309,7 @@ func updateTunnels(tunnels []LC.Tunnel) {
|
||||||
|
|
||||||
func updateGeneral(general *config.General, force bool) {
|
func updateGeneral(general *config.General, force bool) {
|
||||||
tunnel.SetMode(general.Mode)
|
tunnel.SetMode(general.Mode)
|
||||||
tunnel.SetAlwaysFindProcess(general.EnableProcess)
|
tunnel.SetFindProcessMode(general.EnableProcess, general.FindProcessMode)
|
||||||
dialer.DisableIPv6 = !general.IPv6
|
dialer.DisableIPv6 = !general.IPv6
|
||||||
if !dialer.DisableIPv6 {
|
if !dialer.DisableIPv6 {
|
||||||
log.Infoln("Use IPv6")
|
log.Infoln("Use IPv6")
|
||||||
|
|
|
@ -43,7 +43,7 @@ var (
|
||||||
// default timeout for UDP session
|
// default timeout for UDP session
|
||||||
udpTimeout = 60 * time.Second
|
udpTimeout = 60 * time.Second
|
||||||
|
|
||||||
alwaysFindProcess = false
|
findProcessMode P.FindProcessMode
|
||||||
|
|
||||||
fakeIPRange netip.Prefix
|
fakeIPRange netip.Prefix
|
||||||
)
|
)
|
||||||
|
@ -146,9 +146,14 @@ func SetMode(m TunnelMode) {
|
||||||
mode = m
|
mode = m
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetAlwaysFindProcess set always find process info, may be increase many memory
|
// SetFindProcessMode replace SetAlwaysFindProcess
|
||||||
func SetAlwaysFindProcess(findProcess bool) {
|
// always find process info if legacyAlways = true or mode.Always() = true, may be increase many memory
|
||||||
alwaysFindProcess = findProcess
|
func SetFindProcessMode(legacyAlways bool, mode P.FindProcessMode) {
|
||||||
|
if legacyAlways {
|
||||||
|
findProcessMode = P.FindProcessAlways
|
||||||
|
} else {
|
||||||
|
findProcessMode = mode
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// processUDP starts a loop to handle udp packet
|
// processUDP starts a loop to handle udp packet
|
||||||
|
@ -463,7 +468,7 @@ func match(metadata *C.Metadata) (C.Proxy, C.Rule, error) {
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
if !processFound && (alwaysFindProcess || rule.ShouldFindProcess()) {
|
if !findProcessMode.Off() && !processFound && (findProcessMode.Always() || rule.ShouldFindProcess()) {
|
||||||
srcPort, err := strconv.ParseUint(metadata.SrcPort, 10, 16)
|
srcPort, err := strconv.ParseUint(metadata.SrcPort, 10, 16)
|
||||||
uid, path, err := P.FindProcessName(metadata.NetWork.String(), metadata.SrcIP, int(srcPort))
|
uid, path, err := P.FindProcessName(metadata.NetWork.String(), metadata.SrcIP, int(srcPort))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in a new issue