chore: Refine process code

This commit is contained in:
metacubex 2023-01-14 02:23:30 +08:00
parent 804cff8c55
commit f96bf65557
8 changed files with 41 additions and 66 deletions

View file

@ -16,14 +16,6 @@ const (
UDP = "udp" UDP = "udp"
) )
func FindProcessName(network string, srcIP netip.Addr, srcPort int) (*uint32, string, error) { func FindProcessName(network string, srcIP netip.Addr, srcPort int) (uint32, string, error) {
return findProcessName(network, srcIP, srcPort) return findProcessName(network, srcIP, srcPort)
} }
func FindUid(network string, srcIP netip.Addr, srcPort int) (*uint32, error) {
_, uid, err := resolveSocketByNetlink(network, srcIP, srcPort)
if err != nil {
return nil, err
}
return &uid, nil
}

View file

@ -33,11 +33,7 @@ var structSize = func() int {
} }
}() }()
func resolveSocketByNetlink(network string, ip netip.Addr, srcPort int) (uint32, uint32, error) { func findProcessName(network string, ip netip.Addr, port int) (uint32, string, error) {
return 0, 0, ErrPlatformNotSupport
}
func findProcessName(network string, ip netip.Addr, port int) (*uint32, string, error) {
var spath string var spath string
switch network { switch network {
case TCP: case TCP:
@ -45,14 +41,14 @@ func findProcessName(network string, ip netip.Addr, port int) (*uint32, string,
case UDP: case UDP:
spath = "net.inet.udp.pcblist_n" spath = "net.inet.udp.pcblist_n"
default: default:
return nil, "", ErrInvalidNetwork return 0, "", ErrInvalidNetwork
} }
isIPv4 := ip.Is4() isIPv4 := ip.Is4()
value, err := syscall.Sysctl(spath) value, err := syscall.Sysctl(spath)
if err != nil { if err != nil {
return nil, "", err return 0, "", err
} }
buf := []byte(value) buf := []byte(value)
@ -96,7 +92,7 @@ func findProcessName(network string, ip netip.Addr, port int) (*uint32, string,
// xsocket_n.so_last_pid // xsocket_n.so_last_pid
pid := readNativeUint32(buf[so+68 : so+72]) pid := readNativeUint32(buf[so+68 : so+72])
pp, err := getExecPathFromPID(pid) pp, err := getExecPathFromPID(pid)
return nil, pp, err return 0, pp, err
} }
// udp packet connection may be not equal with srcIP // udp packet connection may be not equal with srcIP
@ -106,10 +102,10 @@ func findProcessName(network string, ip netip.Addr, port int) (*uint32, string,
} }
if network == UDP && fallbackUDPProcess != "" { if network == UDP && fallbackUDPProcess != "" {
return nil, fallbackUDPProcess, nil return 0, fallbackUDPProcess, nil
} }
return nil, "", ErrNotFound return 0, "", ErrNotFound
} }
func getExecPathFromPID(pid uint32) (string, error) { func getExecPathFromPID(pid uint32) (string, error) {

View file

@ -21,11 +21,7 @@ var (
once sync.Once once sync.Once
) )
func resolveSocketByNetlink(network string, ip netip.Addr, srcPort int) (uint32, uint32, error) { func findProcessName(network string, ip netip.Addr, srcPort int) (uint32, string, error) {
return 0, 0, ErrPlatformNotSupport
}
func findProcessName(network string, ip netip.Addr, srcPort int) (*uint32, string, error) {
once.Do(func() { once.Do(func() {
if err := initSearcher(); err != nil { if err := initSearcher(); err != nil {
log.Errorln("Initialize PROCESS-NAME failed: %s", err.Error()) log.Errorln("Initialize PROCESS-NAME failed: %s", err.Error())
@ -35,7 +31,7 @@ func findProcessName(network string, ip netip.Addr, srcPort int) (*uint32, strin
}) })
if defaultSearcher == nil { if defaultSearcher == nil {
return nil, "", ErrPlatformNotSupport return 0, "", ErrPlatformNotSupport
} }
var spath string var spath string
@ -46,22 +42,22 @@ func findProcessName(network string, ip netip.Addr, srcPort int) (*uint32, strin
case UDP: case UDP:
spath = "net.inet.udp.pcblist" spath = "net.inet.udp.pcblist"
default: default:
return nil, "", ErrInvalidNetwork return 0, "", ErrInvalidNetwork
} }
value, err := syscall.Sysctl(spath) value, err := syscall.Sysctl(spath)
if err != nil { if err != nil {
return nil, "", err return 0, "", err
} }
buf := []byte(value) buf := []byte(value)
pid, err := defaultSearcher.Search(buf, ip, uint16(srcPort), isTCP) pid, err := defaultSearcher.Search(buf, ip, uint16(srcPort), isTCP)
if err != nil { if err != nil {
return nil, "", err return 0, "", err
} }
pp, err := getExecPathFromPID(pid) pp, err := getExecPathFromPID(pid)
return nil, pp, err return 0, pp, err
} }
func getExecPathFromPID(pid uint32) (string, error) { func getExecPathFromPID(pid uint32) (string, error) {

View file

@ -59,14 +59,14 @@ type inetDiagResponse struct {
INode uint32 INode uint32
} }
func findProcessName(network string, ip netip.Addr, srcPort int) (*uint32, string, error) { func findProcessName(network string, ip netip.Addr, srcPort int) (uint32, string, error) {
inode, uid, err := resolveSocketByNetlink(network, ip, srcPort) uid, inode, err := resolveSocketByNetlink(network, ip, srcPort)
if err != nil { if err != nil {
return nil, "", err return 0, "", err
} }
pp, err := resolveProcessNameByProcSearch(inode, uid) pp, err := resolveProcessNameByProcSearch(inode, uid)
return &uid, pp, err return uid, pp, err
} }
func resolveSocketByNetlink(network string, ip netip.Addr, srcPort int) (uint32, uint32, error) { func resolveSocketByNetlink(network string, ip netip.Addr, srcPort int) (uint32, uint32, error) {
@ -119,7 +119,7 @@ func resolveSocketByNetlink(network string, ip netip.Addr, srcPort int) (uint32,
response := (*inetDiagResponse)(unsafe.Pointer(&msg.Data[0])) response := (*inetDiagResponse)(unsafe.Pointer(&msg.Data[0]))
return response.INode, response.UID, nil return response.UID, response.INode, nil
} }
return 0, 0, ErrNotFound return 0, 0, ErrNotFound

View file

@ -4,8 +4,8 @@ package process
import "net/netip" import "net/netip"
func findProcessName(network string, ip netip.Addr, srcPort int) (*uint32, string, error) { func findProcessName(network string, ip netip.Addr, srcPort int) (uint32, string, error) {
return nil, "", ErrPlatformNotSupport return 0, "", ErrPlatformNotSupport
} }
func resolveSocketByNetlink(network string, ip netip.Addr, srcPort int) (uint32, uint32, error) { func resolveSocketByNetlink(network string, ip netip.Addr, srcPort int) (uint32, uint32, error) {

View file

@ -62,7 +62,7 @@ func initWin32API() error {
return nil return nil
} }
func findProcessName(network string, ip netip.Addr, srcPort int) (*uint32, string, error) { func findProcessName(network string, ip netip.Addr, srcPort int) (uint32, string, error) {
once.Do(func() { once.Do(func() {
err := initWin32API() err := initWin32API()
if err != nil { if err != nil {
@ -86,22 +86,22 @@ func findProcessName(network string, ip netip.Addr, srcPort int) (*uint32, strin
fn = getExUDPTable fn = getExUDPTable
class = udpTablePid class = udpTablePid
default: default:
return nil, "", ErrInvalidNetwork return 0, "", ErrInvalidNetwork
} }
buf, err := getTransportTable(fn, family, class) buf, err := getTransportTable(fn, family, class)
if err != nil { if err != nil {
return nil, "", err return 0, "", err
} }
s := newSearcher(family == windows.AF_INET, network == TCP) s := newSearcher(family == windows.AF_INET, network == TCP)
pid, err := s.Search(buf, ip, uint16(srcPort)) pid, err := s.Search(buf, ip, uint16(srcPort))
if err != nil { if err != nil {
return nil, "", err return 0, "", err
} }
pp, err := getExecPathFromPID(pid) pp, err := getExecPathFromPID(pid)
return nil, pp, err return 0, pp, err
} }
type searcher struct { type searcher struct {

View file

@ -128,7 +128,7 @@ type Metadata struct {
InName string `json:"inboundName"` InName string `json:"inboundName"`
Host string `json:"host"` Host string `json:"host"`
DNSMode DNSMode `json:"dnsMode"` DNSMode DNSMode `json:"dnsMode"`
Uid *uint32 `json:"uid"` Uid uint32 `json:"uid"`
Process string `json:"process"` Process string `json:"process"`
ProcessPath string `json:"processPath"` ProcessPath string `json:"processPath"`
SpecialProxy string `json:"specialProxy"` SpecialProxy string `json:"specialProxy"`
@ -149,13 +149,14 @@ func (m *Metadata) SourceDetail() string {
return fmt.Sprintf("[%s]", ClashName) return fmt.Sprintf("[%s]", ClashName)
} }
if m.Process != "" && m.Uid != nil { switch {
return fmt.Sprintf("%s(%s, uid=%d)", m.SourceAddress(), m.Process, *m.Uid) case m.Process != "" && m.Uid != 0:
} else if m.Uid != nil { return fmt.Sprintf("%s(%s, uid=%d)", m.SourceAddress(), m.Process, m.Uid)
return fmt.Sprintf("%s(uid=%d)", m.SourceAddress(), *m.Uid) case m.Uid != 0:
} else if m.Process != "" { return fmt.Sprintf("%s(uid=%d)", m.SourceAddress(), m.Uid)
case m.Process != "":
return fmt.Sprintf("%s(%s)", m.SourceAddress(), m.Process) return fmt.Sprintf("%s(%s)", m.SourceAddress(), m.Process)
} else { default:
return fmt.Sprintf("%s", m.SourceAddress()) return fmt.Sprintf("%s", m.SourceAddress())
} }
} }

View file

@ -3,7 +3,6 @@ package common
import ( import (
"fmt" "fmt"
"github.com/Dreamacro/clash/common/utils" "github.com/Dreamacro/clash/common/utils"
"github.com/Dreamacro/clash/component/process"
C "github.com/Dreamacro/clash/constant" C "github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/log" "github.com/Dreamacro/clash/log"
"runtime" "runtime"
@ -72,27 +71,14 @@ func (u *Uid) RuleType() C.RuleType {
} }
func (u *Uid) Match(metadata *C.Metadata) (bool, string) { func (u *Uid) Match(metadata *C.Metadata) (bool, string) {
srcPort, err := strconv.ParseUint(metadata.SrcPort, 10, 16) if metadata.Uid != 0 {
if err != nil { for _, uid := range u.uids {
return false, "" if uid.Contains(metadata.Uid) {
}
var uid *uint32
if metadata.Uid != nil {
uid = metadata.Uid
} else if uid, err = process.FindUid(metadata.NetWork.String(), metadata.SrcIP, int(srcPort)); err == nil {
metadata.Uid = uid
} else {
log.Warnln("[UID] could not get uid from %s", metadata.String())
return false, ""
}
if uid != nil {
for _, _uid := range u.uids {
if _uid.Contains(*uid) {
return true, u.adapter return true, u.adapter
} }
} }
} }
log.Warnln("[UID] could not get uid from %s", metadata.String())
return false, "" return false, ""
} }
@ -103,3 +89,7 @@ func (u *Uid) Adapter() string {
func (u *Uid) Payload() string { func (u *Uid) Payload() string {
return u.oUid return u.oUid
} }
func (u *Uid) ShouldFindProcess() bool {
return true
}