|
@@ -22,6 +22,7 @@ import (
|
|
"github.com/sagernet/sing-box/common/sniff"
|
|
"github.com/sagernet/sing-box/common/sniff"
|
|
"github.com/sagernet/sing-box/common/warning"
|
|
"github.com/sagernet/sing-box/common/warning"
|
|
C "github.com/sagernet/sing-box/constant"
|
|
C "github.com/sagernet/sing-box/constant"
|
|
|
|
+ "github.com/sagernet/sing-box/experimental/libbox/platform"
|
|
"github.com/sagernet/sing-box/log"
|
|
"github.com/sagernet/sing-box/log"
|
|
"github.com/sagernet/sing-box/option"
|
|
"github.com/sagernet/sing-box/option"
|
|
"github.com/sagernet/sing-dns"
|
|
"github.com/sagernet/sing-dns"
|
|
@@ -97,9 +98,10 @@ type Router struct {
|
|
processSearcher process.Searcher
|
|
processSearcher process.Searcher
|
|
clashServer adapter.ClashServer
|
|
clashServer adapter.ClashServer
|
|
v2rayServer adapter.V2RayServer
|
|
v2rayServer adapter.V2RayServer
|
|
|
|
+ platformInterface platform.Interface
|
|
}
|
|
}
|
|
|
|
|
|
-func NewRouter(ctx context.Context, logFactory log.Factory, options option.RouteOptions, dnsOptions option.DNSOptions, inbounds []option.Inbound) (*Router, error) {
|
|
|
|
|
|
+func NewRouter(ctx context.Context, logFactory log.Factory, options option.RouteOptions, dnsOptions option.DNSOptions, inbounds []option.Inbound, platformInterface platform.Interface) (*Router, error) {
|
|
if options.DefaultInterface != "" {
|
|
if options.DefaultInterface != "" {
|
|
warnDefaultInterfaceOnUnsupportedPlatform.Check()
|
|
warnDefaultInterfaceOnUnsupportedPlatform.Check()
|
|
}
|
|
}
|
|
@@ -127,6 +129,7 @@ func NewRouter(ctx context.Context, logFactory log.Factory, options option.Route
|
|
autoDetectInterface: options.AutoDetectInterface,
|
|
autoDetectInterface: options.AutoDetectInterface,
|
|
defaultInterface: options.DefaultInterface,
|
|
defaultInterface: options.DefaultInterface,
|
|
defaultMark: options.DefaultMark,
|
|
defaultMark: options.DefaultMark,
|
|
|
|
+ platformInterface: platformInterface,
|
|
}
|
|
}
|
|
router.dnsClient = dns.NewClient(dnsOptions.DNSClientOptions.DisableCache, dnsOptions.DNSClientOptions.DisableExpire, router.dnsLogger)
|
|
router.dnsClient = dns.NewClient(dnsOptions.DNSClientOptions.DisableCache, dnsOptions.DNSClientOptions.DisableExpire, router.dnsLogger)
|
|
for i, ruleOptions := range options.Rules {
|
|
for i, ruleOptions := range options.Rules {
|
|
@@ -248,9 +251,9 @@ func NewRouter(ctx context.Context, logFactory log.Factory, options option.Route
|
|
router.transportMap = transportMap
|
|
router.transportMap = transportMap
|
|
router.transportDomainStrategy = transportDomainStrategy
|
|
router.transportDomainStrategy = transportDomainStrategy
|
|
|
|
|
|
- needInterfaceMonitor := options.AutoDetectInterface || common.Any(inbounds, func(inbound option.Inbound) bool {
|
|
|
|
|
|
+ needInterfaceMonitor := platformInterface == nil && (options.AutoDetectInterface || common.Any(inbounds, func(inbound option.Inbound) bool {
|
|
return inbound.HTTPOptions.SetSystemProxy || inbound.MixedOptions.SetSystemProxy || inbound.TunOptions.AutoRoute
|
|
return inbound.HTTPOptions.SetSystemProxy || inbound.MixedOptions.SetSystemProxy || inbound.TunOptions.AutoRoute
|
|
- })
|
|
|
|
|
|
+ }))
|
|
|
|
|
|
if needInterfaceMonitor {
|
|
if needInterfaceMonitor {
|
|
networkMonitor, err := tun.NewNetworkUpdateMonitor(router)
|
|
networkMonitor, err := tun.NewNetworkUpdateMonitor(router)
|
|
@@ -272,7 +275,7 @@ func NewRouter(ctx context.Context, logFactory log.Factory, options option.Route
|
|
}
|
|
}
|
|
|
|
|
|
needFindProcess := hasRule(options.Rules, isProcessRule) || hasDNSRule(dnsOptions.Rules, isProcessDNSRule) || options.FindProcess
|
|
needFindProcess := hasRule(options.Rules, isProcessRule) || hasDNSRule(dnsOptions.Rules, isProcessDNSRule) || options.FindProcess
|
|
- needPackageManager := C.IsAndroid && (needFindProcess || common.Any(inbounds, func(inbound option.Inbound) bool {
|
|
|
|
|
|
+ needPackageManager := C.IsAndroid && platformInterface == nil && (needFindProcess || common.Any(inbounds, func(inbound option.Inbound) bool {
|
|
return len(inbound.TunOptions.IncludePackage) > 0 || len(inbound.TunOptions.ExcludePackage) > 0
|
|
return len(inbound.TunOptions.IncludePackage) > 0 || len(inbound.TunOptions.ExcludePackage) > 0
|
|
}))
|
|
}))
|
|
if needPackageManager {
|
|
if needPackageManager {
|
|
@@ -283,16 +286,20 @@ func NewRouter(ctx context.Context, logFactory log.Factory, options option.Route
|
|
router.packageManager = packageManager
|
|
router.packageManager = packageManager
|
|
}
|
|
}
|
|
if needFindProcess {
|
|
if needFindProcess {
|
|
- searcher, err := process.NewSearcher(process.Config{
|
|
|
|
- Logger: logFactory.NewLogger("router/process"),
|
|
|
|
- PackageManager: router.packageManager,
|
|
|
|
- })
|
|
|
|
- if err != nil {
|
|
|
|
- if err != os.ErrInvalid {
|
|
|
|
- router.logger.Warn(E.Cause(err, "create process searcher"))
|
|
|
|
- }
|
|
|
|
|
|
+ if platformInterface != nil {
|
|
|
|
+ router.processSearcher = platformInterface
|
|
} else {
|
|
} else {
|
|
- router.processSearcher = searcher
|
|
|
|
|
|
+ searcher, err := process.NewSearcher(process.Config{
|
|
|
|
+ Logger: logFactory.NewLogger("router/process"),
|
|
|
|
+ PackageManager: router.packageManager,
|
|
|
|
+ })
|
|
|
|
+ if err != nil {
|
|
|
|
+ if err != os.ErrInvalid {
|
|
|
|
+ router.logger.Warn(E.Cause(err, "create process searcher"))
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ router.processSearcher = searcher
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return router, nil
|
|
return router, nil
|
|
@@ -737,6 +744,21 @@ func (r *Router) AutoDetectInterface() bool {
|
|
return r.autoDetectInterface
|
|
return r.autoDetectInterface
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+func (r *Router) AutoDetectInterfaceFunc() control.Func {
|
|
|
|
+ if r.platformInterface != nil {
|
|
|
|
+ return r.platformInterface.AutoDetectInterfaceControl()
|
|
|
|
+ } else {
|
|
|
|
+ return control.BindToInterfaceFunc(r.InterfaceFinder(), func(network string, address string) (interfaceName string, interfaceIndex int) {
|
|
|
|
+ remoteAddr := M.ParseSocksaddr(address).Addr
|
|
|
|
+ if C.IsLinux {
|
|
|
|
+ return r.InterfaceMonitor().DefaultInterfaceName(remoteAddr), -1
|
|
|
|
+ } else {
|
|
|
|
+ return "", r.InterfaceMonitor().DefaultInterfaceIndex(remoteAddr)
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
func (r *Router) DefaultInterface() string {
|
|
func (r *Router) DefaultInterface() string {
|
|
return r.defaultInterface
|
|
return r.defaultInterface
|
|
}
|
|
}
|
|
@@ -849,6 +871,8 @@ func (r *Router) prepareGeoIPDatabase() error {
|
|
geoPath = "geoip.db"
|
|
geoPath = "geoip.db"
|
|
if foundPath, loaded := C.FindPath(geoPath); loaded {
|
|
if foundPath, loaded := C.FindPath(geoPath); loaded {
|
|
geoPath = foundPath
|
|
geoPath = foundPath
|
|
|
|
+ } else {
|
|
|
|
+ geoPath = C.BasePath(geoPath)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if !rw.FileExists(geoPath) {
|
|
if !rw.FileExists(geoPath) {
|
|
@@ -861,7 +885,7 @@ func (r *Router) prepareGeoIPDatabase() error {
|
|
}
|
|
}
|
|
r.logger.Error("download geoip database: ", err)
|
|
r.logger.Error("download geoip database: ", err)
|
|
os.Remove(geoPath)
|
|
os.Remove(geoPath)
|
|
- time.Sleep(10 * time.Second)
|
|
|
|
|
|
+ // time.Sleep(10 * time.Second)
|
|
}
|
|
}
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
@@ -884,6 +908,8 @@ func (r *Router) prepareGeositeDatabase() error {
|
|
geoPath = "geosite.db"
|
|
geoPath = "geosite.db"
|
|
if foundPath, loaded := C.FindPath(geoPath); loaded {
|
|
if foundPath, loaded := C.FindPath(geoPath); loaded {
|
|
geoPath = foundPath
|
|
geoPath = foundPath
|
|
|
|
+ } else {
|
|
|
|
+ geoPath = C.BasePath(geoPath)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if !rw.FileExists(geoPath) {
|
|
if !rw.FileExists(geoPath) {
|
|
@@ -896,7 +922,7 @@ func (r *Router) prepareGeositeDatabase() error {
|
|
}
|
|
}
|
|
r.logger.Error("download geosite database: ", err)
|
|
r.logger.Error("download geosite database: ", err)
|
|
os.Remove(geoPath)
|
|
os.Remove(geoPath)
|
|
- time.Sleep(10 * time.Second)
|
|
|
|
|
|
+ // time.Sleep(10 * time.Second)
|
|
}
|
|
}
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
@@ -950,6 +976,7 @@ func (r *Router) downloadGeoIPDatabase(savePath string) error {
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
+ defer httpClient.CloseIdleConnections()
|
|
response, err := httpClient.Get(downloadURL)
|
|
response, err := httpClient.Get(downloadURL)
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|
|
@@ -997,6 +1024,7 @@ func (r *Router) downloadGeositeDatabase(savePath string) error {
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
+ defer httpClient.CloseIdleConnections()
|
|
response, err := httpClient.Get(downloadURL)
|
|
response, err := httpClient.Get(downloadURL)
|
|
if err != nil {
|
|
if err != nil {
|
|
return err
|
|
return err
|