Use new fswatcher to udpate android packages

This commit is contained in:
世界 2024-06-26 00:27:50 +08:00
parent c01b403a44
commit 7c4975c412
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
6 changed files with 39 additions and 35 deletions

5
go.mod
View file

@ -3,12 +3,12 @@ module github.com/sagernet/sing-tun
go 1.20 go 1.20
require ( require (
github.com/fsnotify/fsnotify v1.7.0
github.com/go-ole/go-ole v1.3.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/gvisor v0.0.0-20240428053021-e691de28565f
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a
github.com/sagernet/nftables v0.3.0-beta.4 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 go4.org/netipx v0.0.0-20231129151722-fdeea329fbba
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8
golang.org/x/net v0.26.0 golang.org/x/net v0.26.0
@ -16,6 +16,7 @@ require (
) )
require ( require (
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/google/btree v1.1.2 // indirect github.com/google/btree v1.1.2 // indirect
github.com/google/go-cmp v0.6.0 // indirect github.com/google/go-cmp v0.6.0 // indirect
github.com/josharian/native v1.1.0 // indirect github.com/josharian/native v1.1.0 // indirect

6
go.sum
View file

@ -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 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U=
github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA= 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/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 h1:NkhuupzH5ch7b/Y/6ZHJWrnNLoiNnSJaow6DPb8VW2I=
github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f/go.mod h1:KXmw+ouSJNOsuRpg4wgwwCQuunrGz4yoAqQjsLjc6N0= 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 h1:ObwtHN2VpqE0ZNjr6sGeT00J8uU7JF4cNUdb44/Duis=
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM= 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 h1:kbULlAwAC3jvdGAC1P5Fa3GSxVwQJibNenDW2zaXr8I=
github.com/sagernet/nftables v0.3.0-beta.4/go.mod h1:OQXAjvjNGGFxaTgVCSTRIhYB5/llyVDeapVoENYBDS8= 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.11.0.20240625144910-6bd878184516 h1:C5NYqSEQC2CcILDFhT31iZe5Kp5hFNEtdS9mnNWyW5c=
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/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= 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 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=

View file

@ -1,6 +1,6 @@
package tun package tun
import E "github.com/sagernet/sing/common/exceptions" import "github.com/sagernet/sing/common/logger"
type PackageManager interface { type PackageManager interface {
Start() error Start() error
@ -11,7 +11,14 @@ type PackageManager interface {
SharedPackageByID(id uint32) (string, bool) SharedPackageByID(id uint32) (string, bool)
} }
type PackageManagerOptions struct {
Callback PackageManagerCallback
// Logger is the logger to log errors
// optional
Logger logger.Logger
}
type PackageManagerCallback interface { type PackageManagerCallback interface {
OnPackagesUpdated(packages int, sharedUsers int) OnPackagesUpdated(packages int, sharedUsers int)
E.Handler
} }

View file

@ -2,30 +2,33 @@ package tun
import ( import (
"bytes" "bytes"
"context"
"encoding/xml" "encoding/xml"
"io" "io"
"os" "os"
"strconv" "strconv"
"github.com/sagernet/fswatch"
"github.com/sagernet/sing/common" "github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/abx" "github.com/sagernet/sing/common/abx"
E "github.com/sagernet/sing/common/exceptions" E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing/common/logger"
"github.com/fsnotify/fsnotify"
) )
type packageManager struct { type packageManager struct {
callback PackageManagerCallback callback PackageManagerCallback
watcher *fsnotify.Watcher logger logger.Logger
watcher *fswatch.Watcher
idByPackage map[string]uint32 idByPackage map[string]uint32
sharedByPackage map[string]uint32 sharedByPackage map[string]uint32
packageById map[uint32]string packageById map[uint32]string
sharedById map[uint32]string sharedById map[uint32]string
} }
func NewPackageManager(callback PackageManagerCallback) (PackageManager, error) { func NewPackageManager(options PackageManagerOptions) (PackageManager, error) {
return &packageManager{callback: callback}, nil return &packageManager{
callback: options.Callback,
logger: options.Logger,
}, nil
} }
func (m *packageManager) Start() error { func (m *packageManager) Start() error {
@ -35,42 +38,33 @@ func (m *packageManager) Start() error {
} }
err = m.startWatcher() err = m.startWatcher()
if err != nil { 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 return nil
} }
func (m *packageManager) startWatcher() error { 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 { if err != nil {
return err return err
} }
err = watcher.Add("/data/system/packages.xml") err = watcher.Start()
if err != nil { if err != nil {
return err return err
} }
m.watcher = watcher m.watcher = watcher
go m.loopUpdate()
return nil return nil
} }
func (m *packageManager) loopUpdate() { func (m *packageManager) packagesUpdated(path string) {
for { err := m.updatePackages()
select { if err != nil {
case _, ok := <-m.watcher.Events: m.logger.Error(E.Cause(err, "update packages"))
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"))
}
} }
} }

View file

@ -4,6 +4,6 @@ package tun
import "os" import "os"
func NewPackageManager(callback PackageManagerCallback) (PackageManager, error) { func NewPackageManager(options PackageManagerOptions) (PackageManager, error) {
return nil, os.ErrInvalid return nil, os.ErrInvalid
} }

View file

@ -182,7 +182,7 @@ var controlPath string
func init() { func init() {
const defaultTunPath = "/dev/net/tun" const defaultTunPath = "/dev/net/tun"
const androidTunPath = "/dev/tun" const androidTunPath = "/dev/tun"
if rw.FileExists(androidTunPath) { if rw.IsFile(androidTunPath) {
controlPath = androidTunPath controlPath = androidTunPath
} else { } else {
controlPath = defaultTunPath controlPath = defaultTunPath