chore: add fswatch

This commit is contained in:
wwqgtxx 2024-07-24 13:59:10 +08:00
parent 4b9fdacbad
commit 313493cc94
8 changed files with 106 additions and 80 deletions

View File

@ -3,6 +3,8 @@ package process
import (
"errors"
"net/netip"
C "github.com/metacubex/mihomo/constant"
)
var (
@ -19,3 +21,18 @@ const (
func FindProcessName(network string, srcIP netip.Addr, srcPort int) (uint32, string, error) {
return findProcessName(network, srcIP, srcPort)
}
// PackageNameResolver
// never change type traits because it's used in CFMA
type PackageNameResolver func(metadata *C.Metadata) (string, error)
// DefaultPackageNameResolver
// never change type traits because it's used in CFMA
var DefaultPackageNameResolver PackageNameResolver
func FindPackageName(metadata *C.Metadata) (string, error) {
if resolver := DefaultPackageNameResolver; resolver != nil {
return resolver(metadata)
}
return "", ErrPlatformNotSupport
}

View File

@ -1,16 +0,0 @@
//go:build android && cmfa
package process
import "github.com/metacubex/mihomo/constant"
type PackageNameResolver func(metadata *constant.Metadata) (string, error)
var DefaultPackageNameResolver PackageNameResolver
func FindPackageName(metadata *constant.Metadata) (string, error) {
if resolver := DefaultPackageNameResolver; resolver != nil {
return resolver(metadata)
}
return "", ErrPlatformNotSupport
}

View File

@ -1,9 +0,0 @@
//go:build !(android && cmfa)
package process
import "github.com/metacubex/mihomo/constant"
func FindPackageName(metadata *constant.Metadata) (string, error) {
return "", nil
}

View File

@ -2,23 +2,19 @@ package process
import (
"bytes"
"context"
"encoding/binary"
"fmt"
"net/netip"
"os"
"path"
"path/filepath"
"runtime"
"strings"
"sync"
"syscall"
"unicode"
"unsafe"
"github.com/metacubex/mihomo/log"
"github.com/mdlayher/netlink"
tun "github.com/metacubex/sing-tun"
"golang.org/x/sys/unix"
)
@ -63,25 +59,11 @@ type inetDiagResponse struct {
INode uint32
}
type MyCallback struct{}
var (
packageManager tun.PackageManager
once sync.Once
)
func (cb *MyCallback) OnPackagesUpdated(packageCount int, sharedCount int) {}
func (cb *MyCallback) NewError(ctx context.Context, err error) {
log.Warnln("%s", err)
}
func findProcessName(network string, ip netip.Addr, srcPort int) (uint32, string, error) {
uid, inode, err := resolveSocketByNetlink(network, ip, srcPort)
if err != nil {
return 0, "", err
}
pp, err := resolveProcessNameByProcSearch(inode, uid)
return uid, pp, err
}
@ -177,44 +159,38 @@ func resolveProcessNameByProcSearch(inode, uid uint32) (string, error) {
if err != nil {
continue
}
if runtime.GOOS == "android" {
if bytes.Equal(buffer[:n], socket) {
return findPackageName(uid), nil
cmdline, err := os.ReadFile(path.Join(processPath, "cmdline"))
if err != nil {
return "", err
}
return splitCmdline(cmdline), nil
}
} else {
if bytes.Equal(buffer[:n], socket) {
return os.Readlink(filepath.Join(processPath, "exe"))
}
}
}
}
return "", fmt.Errorf("process of uid(%d),inode(%d) not found", uid, inode)
}
func findPackageName(uid uint32) string {
once.Do(func() {
callback := &MyCallback{}
var err error
packageManager, err = tun.NewPackageManager(callback)
if err != nil {
log.Warnln("%s", err)
}
err = packageManager.Start()
if err != nil {
log.Warnln("%s", err)
return
}
func splitCmdline(cmdline []byte) string {
cmdline = bytes.Trim(cmdline, " ")
idx := bytes.IndexFunc(cmdline, func(r rune) bool {
return unicode.IsControl(r) || unicode.IsSpace(r)
})
if sharedPackage, loaded := packageManager.SharedPackageByID(uid % 100000); loaded {
return sharedPackage
if idx == -1 {
return filepath.Base(string(cmdline))
}
if packageName, loaded := packageManager.PackageByID(uid % 100000); loaded {
return packageName
}
return ""
return filepath.Base(string(cmdline[:idx]))
}
func isPid(s string) bool {

7
go.mod
View File

@ -24,7 +24,7 @@ require (
github.com/metacubex/sing-quic v0.0.0-20240518034124-7696d3f7da72
github.com/metacubex/sing-shadowsocks v0.2.7
github.com/metacubex/sing-shadowsocks2 v0.2.1
github.com/metacubex/sing-tun v0.2.7-0.20240719141828-5710f5d19a55
github.com/metacubex/sing-tun v0.2.7-0.20240719141246-19c49ac9589d
github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9
github.com/metacubex/sing-wireguard v0.0.0-20240618022557-a6efaa37127a
github.com/metacubex/tfo-go v0.0.0-20240228025757-be1269474a66
@ -36,7 +36,7 @@ require (
github.com/puzpuzpuz/xsync/v3 v3.2.0
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a
github.com/sagernet/sing v0.5.0-alpha.10
github.com/sagernet/sing v0.5.0-alpha.13
github.com/sagernet/sing-mux v0.2.1-0.20240124034317-9bfb33698bb6
github.com/sagernet/sing-shadowtls v0.1.4
github.com/sagernet/wireguard-go v0.0.0-20231209092712-9a439356a62e
@ -93,6 +93,7 @@ require (
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/quic-go/qpack v0.4.0 // indirect
github.com/quic-go/qtls-go1-20 v0.4.1 // indirect
github.com/sagernet/fswatch v0.1.1 // indirect
github.com/sagernet/nftables v0.3.0-beta.4 // indirect
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
@ -112,4 +113,4 @@ require (
golang.org/x/tools v0.22.0 // indirect
)
replace github.com/sagernet/sing => github.com/metacubex/sing v0.0.0-20240617013425-3e3bd9dab6a2
replace github.com/sagernet/sing => github.com/metacubex/sing v0.0.0-20240724044459-6f3cf5896297

10
go.sum
View File

@ -107,16 +107,16 @@ github.com/metacubex/quic-go v0.45.1-0.20240610004319-163fee60637e h1:bLYn3GuRvW
github.com/metacubex/quic-go v0.45.1-0.20240610004319-163fee60637e/go.mod h1:Yza2H7Ax1rxWPUcJx0vW+oAt9EsPuSiyQFhFabUPzwU=
github.com/metacubex/randv2 v0.2.0 h1:uP38uBvV2SxYfLj53kuvAjbND4RUDfFJjwr4UigMiLs=
github.com/metacubex/randv2 v0.2.0/go.mod h1:kFi2SzrQ5WuneuoLLCMkABtiBu6VRrMrWFqSPyj2cxY=
github.com/metacubex/sing v0.0.0-20240617013425-3e3bd9dab6a2 h1:N5tidgg/FRmkgPw/AjRwhLUinKDx/ODCSbvv9xqRoLM=
github.com/metacubex/sing v0.0.0-20240617013425-3e3bd9dab6a2/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
github.com/metacubex/sing v0.0.0-20240724044459-6f3cf5896297 h1:YG/JkwGPbca5rUtEMHIu8ZuqzR7BSVm1iqY8hNoMeMA=
github.com/metacubex/sing v0.0.0-20240724044459-6f3cf5896297/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
github.com/metacubex/sing-quic v0.0.0-20240518034124-7696d3f7da72 h1:Wr4g1HCb5Z/QIFwFiVNjO2qL+dRu25+Mdn9xtAZZ+ew=
github.com/metacubex/sing-quic v0.0.0-20240518034124-7696d3f7da72/go.mod h1:g7Mxj7b7zm7YVqD975mk/hSmrb0A0G4bVvIMr2MMzn8=
github.com/metacubex/sing-shadowsocks v0.2.7 h1:9f3Dt2+71TNp0e202llA2ug5h/rkWs2EZxQ5IMpf+9g=
github.com/metacubex/sing-shadowsocks v0.2.7/go.mod h1:X3x88XtJpBxG0W0/ECOJL6Ib0SJ3xdniAkU/6/RMWU0=
github.com/metacubex/sing-shadowsocks2 v0.2.1 h1:XIZBXlazp8EEoPp1S0DViAhLkJakjQ2f+AOwwdKKNYg=
github.com/metacubex/sing-shadowsocks2 v0.2.1/go.mod h1:BhOug03a/RbI7y6hp6q+6ITM1dXjnLTmeWBHSTwvv2Q=
github.com/metacubex/sing-tun v0.2.7-0.20240719141828-5710f5d19a55 h1:q7RhLYjTNTmO9aTFCRlKJE3endUHBQNzc7KDFfvTHj8=
github.com/metacubex/sing-tun v0.2.7-0.20240719141828-5710f5d19a55/go.mod h1:WwJGbCx7bQcBzuQXiDOJvZH27R0kIjKNNlISIWsL6kM=
github.com/metacubex/sing-tun v0.2.7-0.20240719141246-19c49ac9589d h1:iYlepjRCYlPXtELupDL+pQjGqkCnQz4KQOfKImP9sog=
github.com/metacubex/sing-tun v0.2.7-0.20240719141246-19c49ac9589d/go.mod h1:olbEx9yVcaw5tHTNlRamRoxmMKcvDvcVS1YLnQGzvWE=
github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9 h1:OAXiCosqY8xKDp3pqTW3qbrCprZ1l6WkrXSFSCwyY4I=
github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9/go.mod h1:olVkD4FChQ5gKMHG4ZzuD7+fMkJY1G8vwOKpRehjrmY=
github.com/metacubex/sing-wireguard v0.0.0-20240618022557-a6efaa37127a h1:NpSGclHJUYndUwBmyIpFBSoBVg8PoVX7QQKhYg0DjM0=
@ -158,6 +158,8 @@ github.com/quic-go/qtls-go1-20 v0.4.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a h1:+NkI2670SQpQWvkkD2QgdTuzQG263YZ+2emfpeyGqW0=
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a/go.mod h1:63s7jpZqcDAIpj8oI/1v4Izok+npJOHACFCU6+huCkM=
github.com/sagernet/fswatch v0.1.1 h1:YqID+93B7VRfqIH3PArW/XpJv5H4OLEVWDfProGoRQs=
github.com/sagernet/fswatch v0.1.1/go.mod h1:nz85laH0mkQqJfaOrqPpkwtU1znMFNVTpT/5oRsVz/o=
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a h1:ObwtHN2VpqE0ZNjr6sGeT00J8uU7JF4cNUdb44/Duis=
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
github.com/sagernet/nftables v0.3.0-beta.4 h1:kbULlAwAC3jvdGAC1P5Fa3GSxVwQJibNenDW2zaXr8I=

View File

@ -1,29 +1,80 @@
package sing_tun
import (
"errors"
"runtime"
"sync"
"github.com/metacubex/mihomo/component/process"
"github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/constant/features"
"github.com/metacubex/mihomo/log"
tun "github.com/metacubex/sing-tun"
"github.com/metacubex/sing-tun"
"github.com/sagernet/netlink"
"golang.org/x/sys/unix"
"runtime"
)
func (l *Listener) buildAndroidRules(tunOptions *tun.Options) error {
packageManager, err := tun.NewPackageManager(l.handler)
type packageManagerCallback struct{}
func (cb *packageManagerCallback) OnPackagesUpdated(packageCount int, sharedCount int) {}
func newPackageManager() (tun.PackageManager, error) {
packageManager, err := tun.NewPackageManager(tun.PackageManagerOptions{
Callback: &packageManagerCallback{},
Logger: log.SingLogger,
})
if err != nil {
return err
return nil, err
}
err = packageManager.Start()
if err != nil {
return nil, err
}
return packageManager, nil
}
var (
globalPM tun.PackageManager
pmOnce sync.Once
pmErr error
)
func getPackageManager() (tun.PackageManager, error) {
pmOnce.Do(func() {
globalPM, pmErr = newPackageManager()
})
return globalPM, pmErr
}
func (l *Listener) buildAndroidRules(tunOptions *tun.Options) error {
packageManager, err := getPackageManager()
if err != nil {
return err
}
l.packageManager = packageManager
tunOptions.BuildAndroidRules(packageManager, l.handler)
return nil
}
func (h *ListenerHandler) OnPackagesUpdated(packages int, sharedUsers int) {
return
func findPackageName(metadata *constant.Metadata) (string, error) {
packageManager, err := getPackageManager()
if err != nil {
return "", err
}
uid := metadata.Uid
if sharedPackage, loaded := packageManager.SharedPackageByID(uid % 100000); loaded {
return sharedPackage, nil
}
if packageName, loaded := packageManager.PackageByID(uid % 100000); loaded {
return packageName, nil
}
return "", errors.New("package not found")
}
func init() {
if !features.CMFA {
process.DefaultPackageNameResolver = findPackageName
}
}
func (l *Listener) openAndroidHotspot(tunOptions tun.Options) {

View File

@ -622,6 +622,10 @@ func match(metadata *C.Metadata) (C.Proxy, C.Rule, error) {
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