diff --git a/go.mod b/go.mod index 118e790..8c88c2a 100644 --- a/go.mod +++ b/go.mod @@ -3,12 +3,12 @@ module github.com/sagernet/sing-tun go 1.20 require ( - github.com/fsnotify/fsnotify v1.7.0 github.com/go-ole/go-ole v1.3.0 + github.com/sagernet/fswatch v0.1.1 github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a github.com/sagernet/nftables v0.3.0-beta.4 - github.com/sagernet/sing v0.5.0-alpha.10 + github.com/sagernet/sing v0.5.0-alpha.11.0.20240625144910-6bd878184516 go4.org/netipx v0.0.0-20231129151722-fdeea329fbba golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/net v0.26.0 @@ -16,6 +16,7 @@ require ( ) require ( + github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/google/btree v1.1.2 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/josharian/native v1.1.0 // indirect diff --git a/go.sum b/go.sum index 29b6826..3975fcf 100644 --- a/go.sum +++ b/go.sum @@ -14,14 +14,16 @@ github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U= github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +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/gvisor v0.0.0-20240428053021-e691de28565f h1:NkhuupzH5ch7b/Y/6ZHJWrnNLoiNnSJaow6DPb8VW2I= github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f/go.mod h1:KXmw+ouSJNOsuRpg4wgwwCQuunrGz4yoAqQjsLjc6N0= 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= github.com/sagernet/nftables v0.3.0-beta.4/go.mod h1:OQXAjvjNGGFxaTgVCSTRIhYB5/llyVDeapVoENYBDS8= -github.com/sagernet/sing v0.5.0-alpha.10 h1:kuHl10gpjbKQAdQfyogQU3u0CVnpqC3wrAHe/+BFaXc= -github.com/sagernet/sing v0.5.0-alpha.10/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak= +github.com/sagernet/sing v0.5.0-alpha.11.0.20240625144910-6bd878184516 h1:C5NYqSEQC2CcILDFhT31iZe5Kp5hFNEtdS9mnNWyW5c= +github.com/sagernet/sing v0.5.0-alpha.11.0.20240625144910-6bd878184516/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8= github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= diff --git a/packages.go b/packages.go index 58ffbda..3ec4654 100644 --- a/packages.go +++ b/packages.go @@ -1,6 +1,6 @@ package tun -import E "github.com/sagernet/sing/common/exceptions" +import "github.com/sagernet/sing/common/logger" type PackageManager interface { Start() error @@ -11,7 +11,14 @@ type PackageManager interface { SharedPackageByID(id uint32) (string, bool) } +type PackageManagerOptions struct { + Callback PackageManagerCallback + + // Logger is the logger to log errors + // optional + Logger logger.Logger +} + type PackageManagerCallback interface { OnPackagesUpdated(packages int, sharedUsers int) - E.Handler } diff --git a/packages_android.go b/packages_android.go index 15fa144..11de01f 100644 --- a/packages_android.go +++ b/packages_android.go @@ -2,30 +2,33 @@ package tun import ( "bytes" - "context" "encoding/xml" "io" "os" "strconv" + "github.com/sagernet/fswatch" "github.com/sagernet/sing/common" "github.com/sagernet/sing/common/abx" E "github.com/sagernet/sing/common/exceptions" - - "github.com/fsnotify/fsnotify" + "github.com/sagernet/sing/common/logger" ) type packageManager struct { callback PackageManagerCallback - watcher *fsnotify.Watcher + logger logger.Logger + watcher *fswatch.Watcher idByPackage map[string]uint32 sharedByPackage map[string]uint32 packageById map[uint32]string sharedById map[uint32]string } -func NewPackageManager(callback PackageManagerCallback) (PackageManager, error) { - return &packageManager{callback: callback}, nil +func NewPackageManager(options PackageManagerOptions) (PackageManager, error) { + return &packageManager{ + callback: options.Callback, + logger: options.Logger, + }, nil } func (m *packageManager) Start() error { @@ -35,42 +38,33 @@ func (m *packageManager) Start() error { } err = m.startWatcher() if err != nil { - m.callback.NewError(context.Background(), E.Cause(err, "create fsnotify watcher")) + m.logger.Error(E.Cause(err, "create watcher for packages list")) } return nil } func (m *packageManager) startWatcher() error { - watcher, err := fsnotify.NewWatcher() + watcher, err := fswatch.NewWatcher(fswatch.Options{ + Path: []string{"/data/system/packages.xml"}, + Direct: true, + Callback: m.packagesUpdated, + Logger: m.logger, + }) if err != nil { return err } - err = watcher.Add("/data/system/packages.xml") + err = watcher.Start() if err != nil { return err } m.watcher = watcher - go m.loopUpdate() return nil } -func (m *packageManager) loopUpdate() { - for { - select { - case _, ok := <-m.watcher.Events: - if !ok { - return - } - err := m.updatePackages() - if err != nil { - m.callback.NewError(context.Background(), E.Cause(err, "update packages")) - } - case err, ok := <-m.watcher.Errors: - if !ok { - return - } - m.callback.NewError(context.Background(), E.Cause(err, "fsnotify error")) - } +func (m *packageManager) packagesUpdated(path string) { + err := m.updatePackages() + if err != nil { + m.logger.Error(E.Cause(err, "update packages")) } } diff --git a/packages_stub.go b/packages_stub.go index 104454c..f6752d4 100644 --- a/packages_stub.go +++ b/packages_stub.go @@ -4,6 +4,6 @@ package tun import "os" -func NewPackageManager(callback PackageManagerCallback) (PackageManager, error) { +func NewPackageManager(options PackageManagerOptions) (PackageManager, error) { return nil, os.ErrInvalid } diff --git a/tun_linux.go b/tun_linux.go index d83ed45..6153abe 100644 --- a/tun_linux.go +++ b/tun_linux.go @@ -182,7 +182,7 @@ var controlPath string func init() { const defaultTunPath = "/dev/net/tun" const androidTunPath = "/dev/tun" - if rw.FileExists(androidTunPath) { + if rw.IsFile(androidTunPath) { controlPath = androidTunPath } else { controlPath = defaultTunPath