mirror of
https://github.com/SagerNet/sing-box.git
synced 2024-11-25 10:01:30 +00:00
Add android package rules support in tun routing
This commit is contained in:
parent
3157593b6b
commit
cd5e7055d2
|
@ -37,6 +37,7 @@ type Router interface {
|
||||||
DefaultMark() int
|
DefaultMark() int
|
||||||
NetworkMonitor() tun.NetworkUpdateMonitor
|
NetworkMonitor() tun.NetworkUpdateMonitor
|
||||||
InterfaceMonitor() tun.DefaultInterfaceMonitor
|
InterfaceMonitor() tun.DefaultInterfaceMonitor
|
||||||
|
PackageManager() tun.PackageManager
|
||||||
Rules() []Rule
|
Rules() []Rule
|
||||||
SetTrafficController(controller TrafficController)
|
SetTrafficController(controller TrafficController)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
|
||||||
|
"github.com/sagernet/sing-box/log"
|
||||||
|
"github.com/sagernet/sing-tun"
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -13,6 +15,11 @@ type Searcher interface {
|
||||||
|
|
||||||
var ErrNotFound = E.New("process not found")
|
var ErrNotFound = E.New("process not found")
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
Logger log.ContextLogger
|
||||||
|
PackageManager tun.PackageManager
|
||||||
|
}
|
||||||
|
|
||||||
type Info struct {
|
type Info struct {
|
||||||
ProcessPath string
|
ProcessPath string
|
||||||
PackageName string
|
PackageName string
|
||||||
|
|
|
@ -2,81 +2,19 @@ package process
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/xml"
|
|
||||||
"io"
|
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/log"
|
tun "github.com/sagernet/sing-tun"
|
||||||
"github.com/sagernet/sing/common"
|
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
|
||||||
|
|
||||||
"github.com/fsnotify/fsnotify"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ Searcher = (*androidSearcher)(nil)
|
var _ Searcher = (*androidSearcher)(nil)
|
||||||
|
|
||||||
type androidSearcher struct {
|
type androidSearcher struct {
|
||||||
logger log.ContextLogger
|
packageManager tun.PackageManager
|
||||||
watcher *fsnotify.Watcher
|
|
||||||
userMap map[string]int32
|
|
||||||
packageMap map[int32]string
|
|
||||||
sharedUserMap map[int32]string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSearcher(logger log.ContextLogger) (Searcher, error) {
|
func NewSearcher(config Config) (Searcher, error) {
|
||||||
return &androidSearcher{logger: logger}, nil
|
return &androidSearcher{config.PackageManager}, nil
|
||||||
}
|
|
||||||
|
|
||||||
func (s *androidSearcher) Start() error {
|
|
||||||
err := s.updatePackages()
|
|
||||||
if err != nil {
|
|
||||||
return E.Cause(err, "read packages list")
|
|
||||||
}
|
|
||||||
err = s.startWatcher()
|
|
||||||
if err != nil {
|
|
||||||
s.logger.Warn("create fsnotify watcher: ", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *androidSearcher) startWatcher() error {
|
|
||||||
watcher, err := fsnotify.NewWatcher()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = watcher.Add("/data/system/packages.xml")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
s.watcher = watcher
|
|
||||||
go s.loopUpdate()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *androidSearcher) loopUpdate() {
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case _, ok := <-s.watcher.Events:
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err := s.updatePackages()
|
|
||||||
if err != nil {
|
|
||||||
s.logger.Error(E.Cause(err, "update packages list"))
|
|
||||||
}
|
|
||||||
case err, ok := <-s.watcher.Errors:
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
s.logger.Error(E.Cause(err, "fsnotify error"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *androidSearcher) Close() error {
|
|
||||||
return common.Close(common.PtrOrNil(s.watcher))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *androidSearcher) FindProcessInfo(ctx context.Context, network string, srcIP netip.Addr, srcPort int) (*Info, error) {
|
func (s *androidSearcher) FindProcessInfo(ctx context.Context, network string, srcIP netip.Addr, srcPort int) (*Info, error) {
|
||||||
|
@ -84,13 +22,13 @@ func (s *androidSearcher) FindProcessInfo(ctx context.Context, network string, s
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if sharedUser, loaded := s.sharedUserMap[uid]; loaded {
|
if sharedPackage, loaded := s.packageManager.SharedPackageByID(uint32(uid)); loaded {
|
||||||
return &Info{
|
return &Info{
|
||||||
UserId: uid,
|
UserId: uid,
|
||||||
PackageName: sharedUser,
|
PackageName: sharedPackage,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
if packageName, loaded := s.packageMap[uid]; loaded {
|
if packageName, loaded := s.packageManager.PackageByID(uint32(uid)); loaded {
|
||||||
return &Info{
|
return &Info{
|
||||||
UserId: uid,
|
UserId: uid,
|
||||||
PackageName: packageName,
|
PackageName: packageName,
|
||||||
|
@ -98,74 +36,3 @@ func (s *androidSearcher) FindProcessInfo(ctx context.Context, network string, s
|
||||||
}
|
}
|
||||||
return &Info{UserId: uid}, nil
|
return &Info{UserId: uid}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *androidSearcher) updatePackages() error {
|
|
||||||
userMap := make(map[string]int32)
|
|
||||||
packageMap := make(map[int32]string)
|
|
||||||
sharedUserMap := make(map[int32]string)
|
|
||||||
packagesData, err := os.Open("/data/system/packages.xml")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
decoder := xml.NewDecoder(packagesData)
|
|
||||||
var token xml.Token
|
|
||||||
for {
|
|
||||||
token, err = decoder.Token()
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
} else if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
element, isStart := token.(xml.StartElement)
|
|
||||||
if !isStart {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
switch element.Name.Local {
|
|
||||||
case "package":
|
|
||||||
var name string
|
|
||||||
var userID int64
|
|
||||||
for _, attr := range element.Attr {
|
|
||||||
switch attr.Name.Local {
|
|
||||||
case "name":
|
|
||||||
name = attr.Value
|
|
||||||
case "userId", "sharedUserId":
|
|
||||||
userID, err = strconv.ParseInt(attr.Value, 10, 32)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if userID == 0 && name == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
userMap[name] = int32(userID)
|
|
||||||
packageMap[int32(userID)] = name
|
|
||||||
case "shared-user":
|
|
||||||
var name string
|
|
||||||
var userID int64
|
|
||||||
for _, attr := range element.Attr {
|
|
||||||
switch attr.Name.Local {
|
|
||||||
case "name":
|
|
||||||
name = attr.Value
|
|
||||||
case "userId":
|
|
||||||
userID, err = strconv.ParseInt(attr.Value, 10, 32)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
packageMap[int32(userID)] = name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if userID == 0 && name == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
sharedUserMap[int32(userID)] = name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s.logger.Info("updated packages list: ", len(packageMap), " packages, ", len(sharedUserMap), " shared users")
|
|
||||||
s.userMap = userMap
|
|
||||||
s.packageMap = packageMap
|
|
||||||
s.sharedUserMap = sharedUserMap
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/log"
|
|
||||||
N "github.com/sagernet/sing/common/network"
|
N "github.com/sagernet/sing/common/network"
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
|
@ -18,7 +17,7 @@ var _ Searcher = (*darwinSearcher)(nil)
|
||||||
|
|
||||||
type darwinSearcher struct{}
|
type darwinSearcher struct{}
|
||||||
|
|
||||||
func NewSearcher(logger log.ContextLogger) (Searcher, error) {
|
func NewSearcher(_ Config) (Searcher, error) {
|
||||||
return &darwinSearcher{}, nil
|
return &darwinSearcher{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,8 @@ type linuxSearcher struct {
|
||||||
logger log.ContextLogger
|
logger log.ContextLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSearcher(logger log.ContextLogger) (Searcher, error) {
|
func NewSearcher(config Config) (Searcher, error) {
|
||||||
return &linuxSearcher{logger}, nil
|
return &linuxSearcher{config.Logger}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *linuxSearcher) FindProcessInfo(ctx context.Context, network string, srcIP netip.Addr, srcPort int) (*Info, error) {
|
func (s *linuxSearcher) FindProcessInfo(ctx context.Context, network string, srcIP netip.Addr, srcPort int) (*Info, error) {
|
||||||
|
|
|
@ -4,10 +4,8 @@ package process
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/log"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewSearcher(logger log.ContextLogger) (Searcher, error) {
|
func NewSearcher(_ Config) (Searcher, error) {
|
||||||
return nil, os.ErrInvalid
|
return nil, os.ErrInvalid
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/sagernet/sing-box/log"
|
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
N "github.com/sagernet/sing/common/network"
|
N "github.com/sagernet/sing/common/network"
|
||||||
|
|
||||||
|
@ -19,7 +18,7 @@ var _ Searcher = (*windowsSearcher)(nil)
|
||||||
|
|
||||||
type windowsSearcher struct{}
|
type windowsSearcher struct{}
|
||||||
|
|
||||||
func NewSearcher(logger log.ContextLogger) (Searcher, error) {
|
func NewSearcher(_ Config) (Searcher, error) {
|
||||||
err := initWin32API()
|
err := initWin32API()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, E.Cause(err, "init win32 api")
|
return nil, E.Cause(err, "init win32 api")
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#### 2022/08/15
|
#### 2022/08/15
|
||||||
|
|
||||||
* Add uid and android user rules support in [Tun](/configuration/inbound/tun) routing.
|
* Add uid, android user and package rules support in [Tun](/configuration/inbound/tun) routing.
|
||||||
|
|
||||||
#### 2022/08/13
|
#### 2022/08/13
|
||||||
|
|
||||||
|
|
|
@ -28,10 +28,6 @@
|
||||||
99999
|
99999
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
"include_android_user": [
|
|
||||||
0,
|
|
||||||
10
|
|
||||||
],
|
|
||||||
"exclude_uid": [
|
"exclude_uid": [
|
||||||
1000
|
1000
|
||||||
],
|
],
|
||||||
|
@ -39,6 +35,16 @@
|
||||||
1000,
|
1000,
|
||||||
99999
|
99999
|
||||||
],
|
],
|
||||||
|
"include_android_user": [
|
||||||
|
0,
|
||||||
|
10
|
||||||
|
],
|
||||||
|
"include_package": [
|
||||||
|
"com.android.chrome"
|
||||||
|
],
|
||||||
|
"exclude_package": [
|
||||||
|
"com.android.captiveportallogin"
|
||||||
|
],
|
||||||
|
|
||||||
"sniff": true,
|
"sniff": true,
|
||||||
"sniff_override_destination": false,
|
"sniff_override_destination": false,
|
||||||
|
@ -111,7 +117,7 @@ TCP/IP stack.
|
||||||
|
|
||||||
!!! error ""
|
!!! error ""
|
||||||
|
|
||||||
UID and android user rules are only supported on Linux and require auto_route.
|
UID rules are only supported on Linux and require auto_route.
|
||||||
|
|
||||||
Limit users in route. Not limited by default.
|
Limit users in route. Not limited by default.
|
||||||
|
|
||||||
|
@ -119,19 +125,6 @@ Limit users in route. Not limited by default.
|
||||||
|
|
||||||
Limit users in route, but in range.
|
Limit users in route, but in range.
|
||||||
|
|
||||||
#### include_android_user
|
|
||||||
|
|
||||||
!!! warning ""
|
|
||||||
|
|
||||||
Only supported on Android
|
|
||||||
|
|
||||||
Limit android users in route.
|
|
||||||
|
|
||||||
| Common user | ID |
|
|
||||||
|--------------|-----|
|
|
||||||
| Main | 0 |
|
|
||||||
| Work Profile | 10 |
|
|
||||||
|
|
||||||
#### exclude_uid
|
#### exclude_uid
|
||||||
|
|
||||||
Exclude users in route.
|
Exclude users in route.
|
||||||
|
@ -140,6 +133,27 @@ Exclude users in route.
|
||||||
|
|
||||||
Exclude users in route, but in range.
|
Exclude users in route, but in range.
|
||||||
|
|
||||||
|
#### include_android_user
|
||||||
|
|
||||||
|
!!! error ""
|
||||||
|
|
||||||
|
Android user and package rules are only supported on Android and require auto_route.
|
||||||
|
|
||||||
|
Limit android users in route.
|
||||||
|
|
||||||
|
| Common user | ID |
|
||||||
|
|--------------|-----|
|
||||||
|
| Main | 0 |
|
||||||
|
| Work Profile | 10 |
|
||||||
|
|
||||||
|
#### include_package
|
||||||
|
|
||||||
|
Limit android packages in route.
|
||||||
|
|
||||||
|
#### exclude_package
|
||||||
|
|
||||||
|
Exclude android packages in route.
|
||||||
|
|
||||||
### Listen Fields
|
### Listen Fields
|
||||||
|
|
||||||
#### sniff
|
#### sniff
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -18,7 +18,7 @@ require (
|
||||||
github.com/sagernet/sing v0.0.0-20220814164830-4f2b872a8cbf
|
github.com/sagernet/sing v0.0.0-20220814164830-4f2b872a8cbf
|
||||||
github.com/sagernet/sing-dns v0.0.0-20220813025814-e656c9dbf3ae
|
github.com/sagernet/sing-dns v0.0.0-20220813025814-e656c9dbf3ae
|
||||||
github.com/sagernet/sing-shadowsocks v0.0.0-20220812082714-484a11603b48
|
github.com/sagernet/sing-shadowsocks v0.0.0-20220812082714-484a11603b48
|
||||||
github.com/sagernet/sing-tun v0.0.0-20220815014658-b828f0164333
|
github.com/sagernet/sing-tun v0.0.0-20220815033412-1407eae46bd7
|
||||||
github.com/sagernet/sing-vmess v0.0.0-20220811135656-4f3f07acf9c4
|
github.com/sagernet/sing-vmess v0.0.0-20220811135656-4f3f07acf9c4
|
||||||
github.com/sagernet/smux v0.0.0-20220812084127-e2d085ee3939
|
github.com/sagernet/smux v0.0.0-20220812084127-e2d085ee3939
|
||||||
github.com/spf13/cobra v1.5.0
|
github.com/spf13/cobra v1.5.0
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -159,8 +159,8 @@ github.com/sagernet/sing-dns v0.0.0-20220813025814-e656c9dbf3ae h1:xOpbvgizvIbKK
|
||||||
github.com/sagernet/sing-dns v0.0.0-20220813025814-e656c9dbf3ae/go.mod h1:T77zZdE2Cm6VqnFumrpwsq+kxYsbq+vWDhmjtdSl/oM=
|
github.com/sagernet/sing-dns v0.0.0-20220813025814-e656c9dbf3ae/go.mod h1:T77zZdE2Cm6VqnFumrpwsq+kxYsbq+vWDhmjtdSl/oM=
|
||||||
github.com/sagernet/sing-shadowsocks v0.0.0-20220812082714-484a11603b48 h1:NlcTFKldteZvYBDyr+V9MjZEI0rAWCSFCyLgPvc5n/Y=
|
github.com/sagernet/sing-shadowsocks v0.0.0-20220812082714-484a11603b48 h1:NlcTFKldteZvYBDyr+V9MjZEI0rAWCSFCyLgPvc5n/Y=
|
||||||
github.com/sagernet/sing-shadowsocks v0.0.0-20220812082714-484a11603b48/go.mod h1:EX3RbZvrwAkPI2nuGa78T2iQXmrkT+/VQtskjou42xM=
|
github.com/sagernet/sing-shadowsocks v0.0.0-20220812082714-484a11603b48/go.mod h1:EX3RbZvrwAkPI2nuGa78T2iQXmrkT+/VQtskjou42xM=
|
||||||
github.com/sagernet/sing-tun v0.0.0-20220815014658-b828f0164333 h1:fJj7jCPkGkbhY/UNwebi7kKq8Yxc6qeD3Jzh9Wk9tPw=
|
github.com/sagernet/sing-tun v0.0.0-20220815033412-1407eae46bd7 h1:KwUTQUPvdcJtrZR3WImygB0fINaGIr4X42TnDIDJ9sU=
|
||||||
github.com/sagernet/sing-tun v0.0.0-20220815014658-b828f0164333/go.mod h1:+JztVFWrBR8bbf1fWPCyc4KJ/a1bPejmmoEBj9rI6HQ=
|
github.com/sagernet/sing-tun v0.0.0-20220815033412-1407eae46bd7/go.mod h1:+mJ/s6hO3CZyD7CpHbEuZmIVyRkTYLRl4iTr5a57mG0=
|
||||||
github.com/sagernet/sing-vmess v0.0.0-20220811135656-4f3f07acf9c4 h1:2hLETh97+S4WnfMR27XyC7QVU1SH7FTNoCznP229YJU=
|
github.com/sagernet/sing-vmess v0.0.0-20220811135656-4f3f07acf9c4 h1:2hLETh97+S4WnfMR27XyC7QVU1SH7FTNoCznP229YJU=
|
||||||
github.com/sagernet/sing-vmess v0.0.0-20220811135656-4f3f07acf9c4/go.mod h1:82O6gzbxLha/W/jxSVQbsqf2lVdRTjMIgyLug0lpJps=
|
github.com/sagernet/sing-vmess v0.0.0-20220811135656-4f3f07acf9c4/go.mod h1:82O6gzbxLha/W/jxSVQbsqf2lVdRTjMIgyLug0lpJps=
|
||||||
github.com/sagernet/smux v0.0.0-20220812084127-e2d085ee3939 h1:pB1Dh1NbwVrLhQhotr4O4Hs3yhiBzmg3AvnUyYjL4x4=
|
github.com/sagernet/smux v0.0.0-20220812084127-e2d085ee3939 h1:pB1Dh1NbwVrLhQhotr4O4Hs3yhiBzmg3AvnUyYjL4x4=
|
||||||
|
|
|
@ -81,8 +81,10 @@ func NewTun(ctx context.Context, router adapter.Router, logger log.ContextLogger
|
||||||
Inet6Address: options.Inet6Address.Build(),
|
Inet6Address: options.Inet6Address.Build(),
|
||||||
AutoRoute: options.AutoRoute,
|
AutoRoute: options.AutoRoute,
|
||||||
IncludeUID: includeUID,
|
IncludeUID: includeUID,
|
||||||
IncludeAndroidUser: options.IncludeAndroidUser,
|
|
||||||
ExcludeUID: excludeUID,
|
ExcludeUID: excludeUID,
|
||||||
|
IncludeAndroidUser: options.IncludeAndroidUser,
|
||||||
|
IncludePackage: options.IncludePackage,
|
||||||
|
ExcludePackage: options.ExcludePackage,
|
||||||
},
|
},
|
||||||
endpointIndependentNat: options.EndpointIndependentNat,
|
endpointIndependentNat: options.EndpointIndependentNat,
|
||||||
udpTimeout: udpTimeout,
|
udpTimeout: udpTimeout,
|
||||||
|
@ -131,6 +133,9 @@ func (t *Tun) Tag() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Tun) Start() error {
|
func (t *Tun) Start() error {
|
||||||
|
if C.IsAndroid {
|
||||||
|
t.tunOptions.BuildAndroidRules(t.router.PackageManager(), t)
|
||||||
|
}
|
||||||
tunIf, err := tun.Open(t.tunOptions)
|
tunIf, err := tun.Open(t.tunOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return E.Cause(err, "configure tun interface")
|
return E.Cause(err, "configure tun interface")
|
||||||
|
|
|
@ -11,6 +11,8 @@ type TunInboundOptions struct {
|
||||||
ExcludeUID Listable[uint32] `json:"exclude_uid,omitempty"`
|
ExcludeUID Listable[uint32] `json:"exclude_uid,omitempty"`
|
||||||
ExcludeUIDRange Listable[string] `json:"exclude_uid_range,omitempty"`
|
ExcludeUIDRange Listable[string] `json:"exclude_uid_range,omitempty"`
|
||||||
IncludeAndroidUser Listable[int] `json:"android_user,omitempty"`
|
IncludeAndroidUser Listable[int] `json:"android_user,omitempty"`
|
||||||
|
IncludePackage Listable[string] `json:"include_package,omitempty"`
|
||||||
|
ExcludePackage Listable[string] `json:"exclude_package,omitempty"`
|
||||||
EndpointIndependentNat bool `json:"endpoint_independent_nat,omitempty"`
|
EndpointIndependentNat bool `json:"endpoint_independent_nat,omitempty"`
|
||||||
UDPTimeout int64 `json:"udp_timeout,omitempty"`
|
UDPTimeout int64 `json:"udp_timeout,omitempty"`
|
||||||
Stack string `json:"stack,omitempty"`
|
Stack string `json:"stack,omitempty"`
|
||||||
|
|
|
@ -90,6 +90,7 @@ type Router struct {
|
||||||
defaultMark int
|
defaultMark int
|
||||||
networkMonitor tun.NetworkUpdateMonitor
|
networkMonitor tun.NetworkUpdateMonitor
|
||||||
interfaceMonitor tun.DefaultInterfaceMonitor
|
interfaceMonitor tun.DefaultInterfaceMonitor
|
||||||
|
packageManager tun.PackageManager
|
||||||
trafficController adapter.TrafficController
|
trafficController adapter.TrafficController
|
||||||
processSearcher process.Searcher
|
processSearcher process.Searcher
|
||||||
}
|
}
|
||||||
|
@ -260,8 +261,22 @@ func NewRouter(ctx context.Context, logger log.ContextLogger, dnsLogger log.Cont
|
||||||
router.interfaceMonitor = interfaceMonitor
|
router.interfaceMonitor = interfaceMonitor
|
||||||
}
|
}
|
||||||
|
|
||||||
if hasRule(options.Rules, isProcessRule) || hasDNSRule(dnsOptions.Rules, isProcessDNSRule) || options.FindProcess {
|
needFindProcess := hasRule(options.Rules, isProcessRule) || hasDNSRule(dnsOptions.Rules, isProcessDNSRule) || options.FindProcess
|
||||||
searcher, err := process.NewSearcher(logger)
|
needPackageManager := C.IsAndroid && (needFindProcess || common.Any(inbounds, func(inbound option.Inbound) bool {
|
||||||
|
return len(inbound.TunOptions.IncludePackage) > 0 || len(inbound.TunOptions.ExcludePackage) > 0
|
||||||
|
}))
|
||||||
|
if needPackageManager {
|
||||||
|
packageManager, err := tun.NewPackageManager(router)
|
||||||
|
if err != nil {
|
||||||
|
return nil, E.Cause(err, "create package manager")
|
||||||
|
}
|
||||||
|
router.packageManager = packageManager
|
||||||
|
}
|
||||||
|
if needFindProcess {
|
||||||
|
searcher, err := process.NewSearcher(process.Config{
|
||||||
|
Logger: logger,
|
||||||
|
PackageManager: router.packageManager,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err != os.ErrInvalid {
|
if err != os.ErrInvalid {
|
||||||
logger.Warn(E.Cause(err, "create process searcher"))
|
logger.Warn(E.Cause(err, "create process searcher"))
|
||||||
|
@ -425,13 +440,10 @@ func (r *Router) Start() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if r.processSearcher != nil {
|
if r.packageManager != nil {
|
||||||
if starter, isStarter := r.processSearcher.(common.Starter); isStarter {
|
err := r.packageManager.Start()
|
||||||
err := starter.Start()
|
if err != nil {
|
||||||
if err != nil {
|
return err
|
||||||
r.logger.Error(E.Cause(err, "initialize process searcher"))
|
|
||||||
r.processSearcher = nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -454,7 +466,7 @@ func (r *Router) Close() error {
|
||||||
common.PtrOrNil(r.geoIPReader),
|
common.PtrOrNil(r.geoIPReader),
|
||||||
r.interfaceMonitor,
|
r.interfaceMonitor,
|
||||||
r.networkMonitor,
|
r.networkMonitor,
|
||||||
r.processSearcher,
|
r.packageManager,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -679,6 +691,10 @@ func (r *Router) InterfaceMonitor() tun.DefaultInterfaceMonitor {
|
||||||
return r.interfaceMonitor
|
return r.interfaceMonitor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Router) PackageManager() tun.PackageManager {
|
||||||
|
return r.packageManager
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Router) SetTrafficController(controller adapter.TrafficController) {
|
func (r *Router) SetTrafficController(controller adapter.TrafficController) {
|
||||||
r.trafficController = controller
|
r.trafficController = controller
|
||||||
}
|
}
|
||||||
|
@ -912,6 +928,10 @@ func (r *Router) downloadGeositeDatabase(savePath string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Router) OnPackagesUpdated(packages int, sharedUsers int) {
|
||||||
|
r.logger.Info("updated packages list: ", packages, " packages, ", sharedUsers, " shared users")
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Router) NewError(ctx context.Context, err error) {
|
func (r *Router) NewError(ctx context.Context, err error) {
|
||||||
common.Close(err)
|
common.Close(err)
|
||||||
if E.IsClosedOrCanceled(err) {
|
if E.IsClosedOrCanceled(err) {
|
||||||
|
|
|
@ -14,7 +14,7 @@ require (
|
||||||
github.com/sagernet/sing-shadowsocks v0.0.0-20220812082714-484a11603b48
|
github.com/sagernet/sing-shadowsocks v0.0.0-20220812082714-484a11603b48
|
||||||
github.com/spyzhov/ajson v0.7.1
|
github.com/spyzhov/ajson v0.7.1
|
||||||
github.com/stretchr/testify v1.8.0
|
github.com/stretchr/testify v1.8.0
|
||||||
golang.org/x/net v0.0.0-20220811182439-13a9a731de15
|
golang.org/x/net v0.0.0-20220812174116-3211cb980234
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
@ -54,7 +54,7 @@ require (
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/sagernet/netlink v0.0.0-20220803045538-bdac49abf805 // indirect
|
github.com/sagernet/netlink v0.0.0-20220803045538-bdac49abf805 // indirect
|
||||||
github.com/sagernet/sing-dns v0.0.0-20220813025814-e656c9dbf3ae // indirect
|
github.com/sagernet/sing-dns v0.0.0-20220813025814-e656c9dbf3ae // indirect
|
||||||
github.com/sagernet/sing-tun v0.0.0-20220815014658-b828f0164333 // indirect
|
github.com/sagernet/sing-tun v0.0.0-20220815033412-1407eae46bd7 // indirect
|
||||||
github.com/sagernet/sing-vmess v0.0.0-20220811135656-4f3f07acf9c4 // indirect
|
github.com/sagernet/sing-vmess v0.0.0-20220811135656-4f3f07acf9c4 // indirect
|
||||||
github.com/sagernet/smux v0.0.0-20220812084127-e2d085ee3939 // indirect
|
github.com/sagernet/smux v0.0.0-20220812084127-e2d085ee3939 // indirect
|
||||||
github.com/sirupsen/logrus v1.8.1 // indirect
|
github.com/sirupsen/logrus v1.8.1 // indirect
|
||||||
|
|
|
@ -181,8 +181,8 @@ github.com/sagernet/sing-dns v0.0.0-20220813025814-e656c9dbf3ae h1:xOpbvgizvIbKK
|
||||||
github.com/sagernet/sing-dns v0.0.0-20220813025814-e656c9dbf3ae/go.mod h1:T77zZdE2Cm6VqnFumrpwsq+kxYsbq+vWDhmjtdSl/oM=
|
github.com/sagernet/sing-dns v0.0.0-20220813025814-e656c9dbf3ae/go.mod h1:T77zZdE2Cm6VqnFumrpwsq+kxYsbq+vWDhmjtdSl/oM=
|
||||||
github.com/sagernet/sing-shadowsocks v0.0.0-20220812082714-484a11603b48 h1:NlcTFKldteZvYBDyr+V9MjZEI0rAWCSFCyLgPvc5n/Y=
|
github.com/sagernet/sing-shadowsocks v0.0.0-20220812082714-484a11603b48 h1:NlcTFKldteZvYBDyr+V9MjZEI0rAWCSFCyLgPvc5n/Y=
|
||||||
github.com/sagernet/sing-shadowsocks v0.0.0-20220812082714-484a11603b48/go.mod h1:EX3RbZvrwAkPI2nuGa78T2iQXmrkT+/VQtskjou42xM=
|
github.com/sagernet/sing-shadowsocks v0.0.0-20220812082714-484a11603b48/go.mod h1:EX3RbZvrwAkPI2nuGa78T2iQXmrkT+/VQtskjou42xM=
|
||||||
github.com/sagernet/sing-tun v0.0.0-20220815014658-b828f0164333 h1:fJj7jCPkGkbhY/UNwebi7kKq8Yxc6qeD3Jzh9Wk9tPw=
|
github.com/sagernet/sing-tun v0.0.0-20220815033412-1407eae46bd7 h1:KwUTQUPvdcJtrZR3WImygB0fINaGIr4X42TnDIDJ9sU=
|
||||||
github.com/sagernet/sing-tun v0.0.0-20220815014658-b828f0164333/go.mod h1:+JztVFWrBR8bbf1fWPCyc4KJ/a1bPejmmoEBj9rI6HQ=
|
github.com/sagernet/sing-tun v0.0.0-20220815033412-1407eae46bd7/go.mod h1:+mJ/s6hO3CZyD7CpHbEuZmIVyRkTYLRl4iTr5a57mG0=
|
||||||
github.com/sagernet/sing-vmess v0.0.0-20220811135656-4f3f07acf9c4 h1:2hLETh97+S4WnfMR27XyC7QVU1SH7FTNoCznP229YJU=
|
github.com/sagernet/sing-vmess v0.0.0-20220811135656-4f3f07acf9c4 h1:2hLETh97+S4WnfMR27XyC7QVU1SH7FTNoCznP229YJU=
|
||||||
github.com/sagernet/sing-vmess v0.0.0-20220811135656-4f3f07acf9c4/go.mod h1:82O6gzbxLha/W/jxSVQbsqf2lVdRTjMIgyLug0lpJps=
|
github.com/sagernet/sing-vmess v0.0.0-20220811135656-4f3f07acf9c4/go.mod h1:82O6gzbxLha/W/jxSVQbsqf2lVdRTjMIgyLug0lpJps=
|
||||||
github.com/sagernet/smux v0.0.0-20220812084127-e2d085ee3939 h1:pB1Dh1NbwVrLhQhotr4O4Hs3yhiBzmg3AvnUyYjL4x4=
|
github.com/sagernet/smux v0.0.0-20220812084127-e2d085ee3939 h1:pB1Dh1NbwVrLhQhotr4O4Hs3yhiBzmg3AvnUyYjL4x4=
|
||||||
|
@ -275,8 +275,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||||
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.0.0-20220811182439-13a9a731de15 h1:cik0bxZUSJVDyaHf1hZPSDsU8SZHGQZQMeueXCE7yBQ=
|
golang.org/x/net v0.0.0-20220812174116-3211cb980234 h1:RDqmgfe7SvlMWoqC3xwQ2blLO3fcWcxMa3eBLRdRW7E=
|
||||||
golang.org/x/net v0.0.0-20220811182439-13a9a731de15/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
|
|
Loading…
Reference in a new issue