Add support for use with android VPNService

This commit is contained in:
世界 2022-09-05 13:12:29 +08:00
parent f7bed32c6f
commit 8e7957d440
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
4 changed files with 25 additions and 11 deletions

View file

@ -20,7 +20,7 @@ type systemProxy struct {
isMixed bool isMixed bool
} }
func (p *systemProxy) update() error { func (p *systemProxy) update(event int) error {
newInterfaceName := p.monitor.DefaultInterfaceName(netip.IPv4Unspecified()) newInterfaceName := p.monitor.DefaultInterfaceName(netip.IPv4Unspecified())
if p.interfaceName == newInterfaceName { if p.interfaceName == newInterfaceName {
return nil return nil
@ -88,7 +88,7 @@ func SetSystemProxy(router adapter.Router, port uint16, isMixed bool) (func() er
port: port, port: port,
isMixed: isMixed, isMixed: isMixed,
} }
err := proxy.update() err := proxy.update(tun.EventInterfaceUpdate)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -86,6 +86,7 @@ func NewTun(ctx context.Context, router adapter.Router, logger log.ContextLogger
IncludeAndroidUser: options.IncludeAndroidUser, IncludeAndroidUser: options.IncludeAndroidUser,
IncludePackage: options.IncludePackage, IncludePackage: options.IncludePackage,
ExcludePackage: options.ExcludePackage, ExcludePackage: options.ExcludePackage,
InterfaceMonitor: router.InterfaceMonitor(),
}, },
endpointIndependentNat: options.EndpointIndependentNat, endpointIndependentNat: options.EndpointIndependentNat,
udpTimeout: udpTimeout, udpTimeout: udpTimeout,

View file

@ -16,6 +16,7 @@ type RouteOptions struct {
Final string `json:"final,omitempty"` Final string `json:"final,omitempty"`
FindProcess bool `json:"find_process,omitempty"` FindProcess bool `json:"find_process,omitempty"`
AutoDetectInterface bool `json:"auto_detect_interface,omitempty"` AutoDetectInterface bool `json:"auto_detect_interface,omitempty"`
OverrideAndroidVPN bool `json:"override_android_vpn,omitempty"`
DefaultInterface string `json:"default_interface,omitempty"` DefaultInterface string `json:"default_interface,omitempty"`
DefaultMark int `json:"default_mark,omitempty"` DefaultMark int `json:"default_mark,omitempty"`
} }

View file

@ -244,7 +244,7 @@ func NewRouter(ctx context.Context, logger log.ContextLogger, dnsLogger log.Cont
needInterfaceMonitor := options.AutoDetectInterface || needInterfaceMonitor := options.AutoDetectInterface ||
C.IsDarwin && common.Any(inbounds, func(inbound option.Inbound) bool { C.IsDarwin && common.Any(inbounds, func(inbound option.Inbound) bool {
return inbound.HTTPOptions.SetSystemProxy || inbound.MixedOptions.SetSystemProxy return inbound.HTTPOptions.SetSystemProxy || inbound.MixedOptions.SetSystemProxy || C.IsAndroid && inbound.TunOptions.AutoRoute
}) })
if router.interfaceBindManager != nil || needInterfaceMonitor { if router.interfaceBindManager != nil || needInterfaceMonitor {
@ -258,12 +258,24 @@ func NewRouter(ctx context.Context, logger log.ContextLogger, dnsLogger log.Cont
} }
if router.networkMonitor != nil && needInterfaceMonitor { if router.networkMonitor != nil && needInterfaceMonitor {
interfaceMonitor, err := tun.NewDefaultInterfaceMonitor(router.networkMonitor) interfaceMonitor, err := tun.NewDefaultInterfaceMonitor(router.networkMonitor, tun.DefaultInterfaceMonitorOptions{
OverrideAndroidVPN: options.OverrideAndroidVPN,
})
if err != nil { if err != nil {
return nil, E.New("auto_detect_interface unsupported on current platform") return nil, E.New("auto_detect_interface unsupported on current platform")
} }
interfaceMonitor.RegisterCallback(func() error { interfaceMonitor.RegisterCallback(func(event int) error {
router.logger.Info("updated default interface ", router.interfaceMonitor.DefaultInterfaceName(netip.IPv4Unspecified()), ", index ", router.interfaceMonitor.DefaultInterfaceIndex(netip.IPv4Unspecified())) if C.IsAndroid {
var vpnStatus string
if router.interfaceMonitor.AndroidVPNEnabled() {
vpnStatus = "enabled"
} else {
vpnStatus = "disabled"
}
router.logger.Info("updated default interface ", router.interfaceMonitor.DefaultInterfaceName(netip.IPv4Unspecified()), ", index ", router.interfaceMonitor.DefaultInterfaceIndex(netip.IPv4Unspecified()), ", vpn ", vpnStatus)
} else {
router.logger.Info("updated default interface ", router.interfaceMonitor.DefaultInterfaceName(netip.IPv4Unspecified()), ", index ", router.interfaceMonitor.DefaultInterfaceIndex(netip.IPv4Unspecified()))
}
return nil return nil
}) })
router.interfaceMonitor = interfaceMonitor router.interfaceMonitor = interfaceMonitor
@ -667,12 +679,12 @@ func (r *Router) match(ctx context.Context, metadata *adapter.InboundContext, de
} }
processInfo, err := process.FindProcessInfo(r.processSearcher, ctx, metadata.Network, metadata.Source.AddrPort(), originDestination) processInfo, err := process.FindProcessInfo(r.processSearcher, ctx, metadata.Network, metadata.Source.AddrPort(), originDestination)
if err != nil { if err != nil {
r.logger.DebugContext(ctx, "failed to search process: ", err) r.logger.InfoContext(ctx, "failed to search process: ", err)
} else { } else {
if processInfo.ProcessPath != "" { if processInfo.ProcessPath != "" {
r.logger.DebugContext(ctx, "found process path: ", processInfo.ProcessPath) r.logger.InfoContext(ctx, "found process path: ", processInfo.ProcessPath)
} else if processInfo.PackageName != "" { } else if processInfo.PackageName != "" {
r.logger.DebugContext(ctx, "found package name: ", processInfo.PackageName) r.logger.InfoContext(ctx, "found package name: ", processInfo.PackageName)
} else if processInfo.UserId != -1 { } else if processInfo.UserId != -1 {
if /*needUserName &&*/ true { if /*needUserName &&*/ true {
osUser, _ := user.LookupId(F.ToString(processInfo.UserId)) osUser, _ := user.LookupId(F.ToString(processInfo.UserId))
@ -681,9 +693,9 @@ func (r *Router) match(ctx context.Context, metadata *adapter.InboundContext, de
} }
} }
if processInfo.User != "" { if processInfo.User != "" {
r.logger.DebugContext(ctx, "found user: ", processInfo.User) r.logger.InfoContext(ctx, "found user: ", processInfo.User)
} else { } else {
r.logger.DebugContext(ctx, "found user id: ", processInfo.UserId) r.logger.InfoContext(ctx, "found user id: ", processInfo.UserId)
} }
} }
metadata.ProcessInfo = processInfo metadata.ProcessInfo = processInfo