Add set system proxy support for macOS

This commit is contained in:
世界 2022-08-04 22:01:20 +08:00
parent 64dbac8138
commit f691bd5ce1
No known key found for this signature in database
GPG Key ID: CD109927C34A63C4
21 changed files with 225 additions and 174 deletions

View File

@ -7,6 +7,7 @@ import (
"github.com/sagernet/sing-box/common/geoip"
"github.com/sagernet/sing-dns"
"github.com/sagernet/sing-tun"
"github.com/sagernet/sing/common/control"
N "github.com/sagernet/sing/common/network"
@ -33,10 +34,9 @@ type Router interface {
InterfaceBindManager() control.BindManager
DefaultInterface() string
AutoDetectInterface() bool
AutoDetectInterfaceName() string
AutoDetectInterfaceIndex() int
DefaultMark() int
NetworkMonitor() tun.NetworkUpdateMonitor
InterfaceMonitor() tun.DefaultInterfaceMonitor
Rules() []Rule
SetTrafficController(controller TrafficController)
}

1
box.go
View File

@ -90,6 +90,7 @@ func New(ctx context.Context, options option.Options) (*Box, error) {
logFactory.NewLogger("dns"),
common.PtrValueOrDefault(options.Route),
common.PtrValueOrDefault(options.DNS),
options.Inbounds,
)
if err != nil {
return nil, E.Cause(err, "parse route options")

View File

@ -61,27 +61,27 @@ func NewDefault(router adapter.Router, options option.DialerOptions) *DefaultDia
var listener net.ListenConfig
if options.BindInterface != "" {
warnBindInterfaceOnUnsupportedPlatform.Check()
dialer.Control = control.Append(dialer.Control, control.BindToInterface(router.InterfaceBindManager(), options.BindInterface))
listener.Control = control.Append(listener.Control, control.BindToInterface(router.InterfaceBindManager(), options.BindInterface))
bindFunc := control.BindToInterface(router.InterfaceBindManager(), options.BindInterface)
dialer.Control = control.Append(dialer.Control, bindFunc)
listener.Control = control.Append(listener.Control, bindFunc)
} else if router.AutoDetectInterface() {
if C.IsWindows {
dialer.Control = control.Append(dialer.Control, control.BindToInterfaceIndexFunc(func() int {
return router.AutoDetectInterfaceIndex()
}))
listener.Control = control.Append(listener.Control, control.BindToInterfaceIndexFunc(func() int {
return router.AutoDetectInterfaceIndex()
}))
bindFunc := control.BindToInterfaceIndexFunc(func() int {
return router.InterfaceMonitor().DefaultInterfaceIndex()
})
dialer.Control = control.Append(dialer.Control, bindFunc)
listener.Control = control.Append(listener.Control, bindFunc)
} else {
dialer.Control = control.Append(dialer.Control, control.BindToInterfaceFunc(router.InterfaceBindManager(), func() string {
return router.AutoDetectInterfaceName()
}))
listener.Control = control.Append(listener.Control, control.BindToInterfaceFunc(router.InterfaceBindManager(), func() string {
return router.AutoDetectInterfaceName()
}))
bindFunc := control.BindToInterfaceFunc(router.InterfaceBindManager(), func() string {
return router.InterfaceMonitor().DefaultInterfaceName()
})
dialer.Control = control.Append(dialer.Control, bindFunc)
listener.Control = control.Append(listener.Control, bindFunc)
}
} else if router.DefaultInterface() != "" {
dialer.Control = control.Append(dialer.Control, control.BindToInterface(router.InterfaceBindManager(), router.DefaultInterface()))
listener.Control = control.Append(listener.Control, control.BindToInterface(router.InterfaceBindManager(), router.DefaultInterface()))
bindFunc := control.BindToInterface(router.InterfaceBindManager(), router.DefaultInterface())
dialer.Control = control.Append(dialer.Control, bindFunc)
listener.Control = control.Append(listener.Control, bindFunc)
}
if options.RoutingMark != 0 {
warnRoutingMarkOnUnsupportedPlatform.Check()

View File

@ -13,3 +13,9 @@ func runCommand(name string, args ...string) error {
command.Stderr = os.Stderr
return command.Run()
}
func readCommand(name string, args ...string) ([]byte, error) {
command := exec.Command(name, args...)
command.Env = os.Environ()
return command.CombinedOutput()
}

View File

@ -4,6 +4,7 @@ import (
"os"
"strings"
"github.com/sagernet/sing-box/adapter"
C "github.com/sagernet/sing-box/constant"
F "github.com/sagernet/sing/common/format"
)
@ -30,10 +31,12 @@ func runAndroidShell(name string, args ...string) error {
}
}
func ClearSystemProxy() error {
return runAndroidShell("settings", "put", "global", "http_proxy", ":0")
}
func SetSystemProxy(port uint16, mixed bool) error {
return runAndroidShell("settings", "put", "global", "http_proxy", F.ToString("127.0.0.1:", port))
func SetSystemProxy(router adapter.Router, port uint16, isMixed bool) (func() error, error) {
err := runAndroidShell("settings", "put", "global", "http_proxy", F.ToString("127.0.0.1:", port))
if err != nil {
return nil, err
}
return func() error {
return runAndroidShell("settings", "put", "global", "http_proxy", ":0")
}, nil
}

View File

@ -0,0 +1,98 @@
package settings
import (
"strings"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-tun"
E "github.com/sagernet/sing/common/exceptions"
F "github.com/sagernet/sing/common/format"
"github.com/sagernet/sing/common/x/list"
)
type systemProxy struct {
monitor tun.DefaultInterfaceMonitor
interfaceName string
element *list.Element[tun.DefaultInterfaceUpdateCallback]
port uint16
isMixed bool
}
func (p *systemProxy) update() error {
newInterfaceName := p.monitor.DefaultInterfaceName()
if p.interfaceName == newInterfaceName {
return nil
}
if p.interfaceName != "" {
_ = p.unset()
}
p.interfaceName = newInterfaceName
interfaceDisplayName, err := getInterfaceDisplayName(p.interfaceName)
if err != nil {
return err
}
if p.isMixed {
err = runCommand("networksetup", "-setsocksfirewallproxy", interfaceDisplayName, "127.0.0.1", F.ToString(p.port))
}
if err == nil {
err = runCommand("networksetup", "-setwebproxy", interfaceDisplayName, "127.0.0.1", F.ToString(p.port))
}
if err == nil {
err = runCommand("networksetup", "-setsecurewebproxy", interfaceDisplayName, "127.0.0.1", F.ToString(p.port))
}
return err
}
func (p *systemProxy) unset() error {
interfaceDisplayName, err := getInterfaceDisplayName(p.interfaceName)
if err != nil {
return err
}
if p.isMixed {
err = runCommand("networksetup", "-setsocksfirewallproxystate", interfaceDisplayName, "off")
}
if err == nil {
err = runCommand("networksetup", "-setwebproxystate", interfaceDisplayName, "off")
}
if err == nil {
err = runCommand("networksetup", "-setsecurewebproxystate", interfaceDisplayName, "off")
}
return err
}
func getInterfaceDisplayName(name string) (string, error) {
content, err := readCommand("networksetup", "-listallhardwareports")
if err != nil {
return "", err
}
for _, deviceSpan := range strings.Split(string(content), "Ethernet Address") {
if strings.Contains(deviceSpan, "Device: "+name) {
substr := "Hardware Port: "
deviceSpan = deviceSpan[strings.Index(deviceSpan, substr)+len(substr):]
deviceSpan = deviceSpan[:strings.Index(deviceSpan, "\n")]
return deviceSpan, nil
}
}
return "", E.New(name, " not found in networksetup -listallhardwareports")
}
func SetSystemProxy(router adapter.Router, port uint16, isMixed bool) (func() error, error) {
interfaceMonitor := router.InterfaceMonitor()
if interfaceMonitor == nil {
return nil, E.New("missing interface monitor")
}
proxy := &systemProxy{
monitor: interfaceMonitor,
port: port,
isMixed: isMixed,
}
err := proxy.update()
if err != nil {
return nil, err
}
proxy.element = interfaceMonitor.RegisterCallback(proxy.update)
return func() error {
interfaceMonitor.UnregisterCallback(proxy.element)
return proxy.unset()
}, nil
}

View File

@ -7,7 +7,7 @@ import (
"os/exec"
"strings"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions"
F "github.com/sagernet/sing/common/format"
@ -35,42 +35,33 @@ func runAsUser(name string, args ...string) error {
}
}
func ClearSystemProxy() error {
if hasGSettings {
return runAsUser("gsettings", "set", "org.gnome.system.proxy", "mode", "none")
func SetSystemProxy(router adapter.Router, port uint16, isMixed bool) (func() error, error) {
if !hasGSettings {
return nil, E.New("unsupported desktop environment")
}
return nil
}
func SetSystemProxy(port uint16, mixed bool) error {
if hasGSettings {
err := runAsUser("gsettings", "set", "org.gnome.system.proxy.http", "enabled", "true")
if err != nil {
return err
}
if mixed {
err = setGnomeProxy(port, "ftp", "http", "https", "socks")
if err != nil {
return err
}
} else {
err = setGnomeProxy(port, "http", "https")
if err != nil {
return err
}
}
err = runAsUser("gsettings", "set", "org.gnome.system.proxy", "use-same-proxy", F.ToString(mixed))
if err != nil {
return err
}
err = runAsUser("gsettings", "set", "org.gnome.system.proxy", "mode", "manual")
if err != nil {
return err
}
err := runAsUser("gsettings", "set", "org.gnome.system.proxy.http", "enabled", "true")
if err != nil {
return nil, err
}
if isMixed {
err = setGnomeProxy(port, "ftp", "http", "https", "socks")
} else {
log.Warn("set system proxy: unsupported desktop environment")
err = setGnomeProxy(port, "http", "https")
}
return nil
if err != nil {
return nil, err
}
err = runAsUser("gsettings", "set", "org.gnome.system.proxy", "use-same-proxy", F.ToString(isMixed))
if err != nil {
return nil, err
}
err = runAsUser("gsettings", "set", "org.gnome.system.proxy", "mode", "manual")
if err != nil {
return nil, err
}
return func() error {
return runAsUser("gsettings", "set", "org.gnome.system.proxy", "mode", "none")
}, nil
}
func setGnomeProxy(port uint16, proxyTypes ...string) error {

View File

@ -1,14 +1,13 @@
//go:build !windows && !linux
//go:build !(windows || linux || darwin)
package settings
import "github.com/sagernet/sing-box/log"
import (
"os"
func ClearSystemProxy() error {
return nil
}
"github.com/sagernet/sing-box/adapter"
)
func SetSystemProxy(port uint16, mixed bool) error {
log.Warn("set system proxy: unsupported operating system")
return nil
func SetSystemProxy(router adapter.Router, port uint16, isMixed bool) (func() error, error) {
return nil, os.ErrInvalid
}

View File

@ -1,14 +1,17 @@
package settings
import (
"github.com/sagernet/sing-box/adapter"
F "github.com/sagernet/sing/common/format"
"github.com/sagernet/sing/common/wininet"
)
func ClearSystemProxy() error {
return wininet.ClearSystemProxy()
}
func SetSystemProxy(port uint16, mixed bool) error {
return wininet.SetSystemProxy(F.ToString("http://127.0.0.1:", port), "local")
func SetSystemProxy(router adapter.Router, port uint16, isMixed bool) (func() error, error) {
err := wininet.SetSystemProxy(F.ToString("http://127.0.0.1:", port), "local")
if err != nil {
return nil, err
}
return func() error {
return wininet.ClearSystemProxy()
}, nil
}

View File

@ -71,7 +71,7 @@ If `sniff_override_destination` is in effect, its value will be taken as a fallb
!!! error ""
Windows only
Only supported on Linux, Android, Windows, and macOS.
Automatically set system proxy configuration when start and clean up when stop.

View File

@ -71,7 +71,7 @@ If `sniff_override_destination` is in effect, its value will be taken as a fallb
!!! error ""
Windows only
Only supported on Linux, Android, Windows, and macOS.
Automatically set system proxy configuration when start and clean up when stop.

View File

@ -30,7 +30,7 @@ Default outbound tag. the first outbound will be used if empty.
!!! error ""
Linux and Windows only
Only supported on Linux and Windows.
Bind outbound connections to the default NIC by default to prevent routing loops under Tun.
@ -40,7 +40,7 @@ Takes no effect if `outbound.bind_interface` is set.
!!! error ""
Linux and Windows only
Only supported on Linux and Windows.
Bind outbound connections to the specified NIC by default to prevent routing loops under Tun.
@ -50,7 +50,7 @@ Takes no effect if `auto_detect_interface` is set.
!!! error ""
Linux only
Only supported on Linux.
Set iptables routing mark by default.

4
go.mod
View File

@ -16,7 +16,7 @@ require (
github.com/sagernet/sing v0.0.0-20220804023557-9c64b40e7050
github.com/sagernet/sing-dns v0.0.0-20220803121532-9e1ffb850d91
github.com/sagernet/sing-shadowsocks v0.0.0-20220801112336-a91eacdd01e1
github.com/sagernet/sing-tun v0.0.0-20220803112223-a8fd6450d4ed
github.com/sagernet/sing-tun v0.0.0-20220804154459-7ee0d19103d2
github.com/sagernet/sing-vmess v0.0.0-20220804023624-e829b41c84c2
github.com/spf13/cobra v1.5.0
github.com/stretchr/testify v1.8.0
@ -24,7 +24,7 @@ require (
go.uber.org/atomic v1.9.0
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa
golang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b
golang.org/x/sys v0.0.0-20220731174439-a90be440212d
golang.org/x/sys v0.0.0-20220803195053-6e608f9ce704
)
require (

8
go.sum
View File

@ -155,8 +155,8 @@ github.com/sagernet/sing-dns v0.0.0-20220803121532-9e1ffb850d91 h1:jxt2PYixIkK2i
github.com/sagernet/sing-dns v0.0.0-20220803121532-9e1ffb850d91/go.mod h1:T77zZdE2Cm6VqnFumrpwsq+kxYsbq+vWDhmjtdSl/oM=
github.com/sagernet/sing-shadowsocks v0.0.0-20220801112336-a91eacdd01e1 h1:RYvOc69eSNMN0dwVugrDts41Nn7Ar/C/n/fvytvFcp4=
github.com/sagernet/sing-shadowsocks v0.0.0-20220801112336-a91eacdd01e1/go.mod h1:NqZjiXszgVCMQ4gVDa2V+drhS8NMfGqUqDF86EacEFc=
github.com/sagernet/sing-tun v0.0.0-20220803112223-a8fd6450d4ed h1:28qeqeuHLZEkzdcZjYwcCn8y4ckyKimaP+L4P25dqUo=
github.com/sagernet/sing-tun v0.0.0-20220803112223-a8fd6450d4ed/go.mod h1:jNlPidQzZYkpmpQJ+sDN2YGrPsL4QImoqBpuauId9po=
github.com/sagernet/sing-tun v0.0.0-20220804154459-7ee0d19103d2 h1:har8hmVNhGxp14zLNAoGrgfzgxZQn0KTYJDfJudj0RU=
github.com/sagernet/sing-tun v0.0.0-20220804154459-7ee0d19103d2/go.mod h1:K1Hfxaa/1zsxZix3ats3k1TJftVwK0l4OoRnUjjhi0g=
github.com/sagernet/sing-vmess v0.0.0-20220804023624-e829b41c84c2 h1:C8sc2MYiNx0O7uQ0nieJWq5qYeIHj20XHFWPlcgoQeY=
github.com/sagernet/sing-vmess v0.0.0-20220804023624-e829b41c84c2/go.mod h1:bNXBqSWYaG3ePl6u0xQY5zneE+ZKa3683ZpuE8S1M1w=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
@ -279,8 +279,8 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220731174439-a90be440212d h1:Sv5ogFZatcgIMMtBSTTAgMYsicp25MXBubjXNDKwm80=
golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220803195053-6e608f9ce704 h1:Y7NOhdqIOU8kYI7BxsgL38d0ot0raxvcW+EMQU2QrT4=
golang.org/x/sys v0.0.0-20220803195053-6e608f9ce704/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

View File

@ -40,7 +40,8 @@ type myInboundAdapter struct {
// http mixed
setSystemProxy bool
setSystemProxy bool
clearSystemProxy func() error
// internal
@ -60,10 +61,10 @@ func (a *myInboundAdapter) Tag() string {
}
func (a *myInboundAdapter) Start() error {
var err error
bindAddr := M.SocksaddrFrom(netip.Addr(a.listenOptions.Listen), a.listenOptions.ListenPort)
if common.Contains(a.network, N.NetworkTCP) {
var tcpListener *net.TCPListener
var err error
if !a.listenOptions.TCPFastOpen {
tcpListener, err = net.ListenTCP(M.NetworkFromNetAddr(N.NetworkTCP, bindAddr.Addr), bindAddr.TCPAddr())
} else {
@ -77,7 +78,8 @@ func (a *myInboundAdapter) Start() error {
a.logger.Info("tcp server started at ", tcpListener.Addr())
}
if common.Contains(a.network, N.NetworkUDP) {
udpConn, err := net.ListenUDP(M.NetworkFromNetAddr(N.NetworkUDP, bindAddr.Addr), bindAddr.UDPAddr())
var udpConn *net.UDPConn
udpConn, err = net.ListenUDP(M.NetworkFromNetAddr(N.NetworkUDP, bindAddr.Addr), bindAddr.UDPAddr())
if err != nil {
return err
}
@ -101,7 +103,7 @@ func (a *myInboundAdapter) Start() error {
a.logger.Info("udp server started at ", udpConn.LocalAddr())
}
if a.setSystemProxy {
err := settings.SetSystemProxy(M.SocksaddrFromNet(a.tcpListener.Addr()).Port, a.protocol == C.TypeMixed)
a.clearSystemProxy, err = settings.SetSystemProxy(a.router, M.SocksaddrFromNet(a.tcpListener.Addr()).Port, a.protocol == C.TypeMixed)
if err != nil {
return E.Cause(err, "set system proxy")
}
@ -111,8 +113,8 @@ func (a *myInboundAdapter) Start() error {
func (a *myInboundAdapter) Close() error {
var err error
if a.setSystemProxy {
err = settings.ClearSystemProxy()
if a.clearSystemProxy != nil {
err = a.clearSystemProxy()
}
return E.Errors(err, common.Close(
common.PtrOrNil(a.tcpListener),

View File

@ -1,22 +0,0 @@
package route
import "github.com/sagernet/sing/common/x/list"
type (
NetworkUpdateCallback = func() error
DefaultInterfaceUpdateCallback = func()
)
type NetworkUpdateMonitor interface {
Start() error
Close() error
RegisterCallback(callback NetworkUpdateCallback) *list.Element[NetworkUpdateCallback]
UnregisterCallback(element *list.Element[NetworkUpdateCallback])
}
type DefaultInterfaceMonitor interface {
Start() error
Close() error
DefaultInterfaceName() string
DefaultInterfaceIndex() int
}

View File

@ -1,17 +0,0 @@
//go:build !(linux || windows) || no_gvisor
package route
import (
"os"
E "github.com/sagernet/sing/common/exceptions"
)
func NewNetworkUpdateMonitor(errorHandler E.Handler) (NetworkUpdateMonitor, error) {
return nil, os.ErrInvalid
}
func NewDefaultInterfaceMonitor(networkMonitor NetworkUpdateMonitor, callback DefaultInterfaceUpdateCallback) (DefaultInterfaceMonitor, error) {
return nil, os.ErrInvalid
}

View File

@ -1,16 +0,0 @@
//go:build (linux || windows) && !no_gvisor
package route
import (
"github.com/sagernet/sing-tun"
E "github.com/sagernet/sing/common/exceptions"
)
func NewNetworkUpdateMonitor(errorHandler E.Handler) (NetworkUpdateMonitor, error) {
return tun.NewNetworkUpdateMonitor(errorHandler)
}
func NewDefaultInterfaceMonitor(networkMonitor NetworkUpdateMonitor, callback DefaultInterfaceUpdateCallback) (DefaultInterfaceMonitor, error) {
return tun.NewDefaultInterfaceMonitor(networkMonitor, callback)
}

View File

@ -25,6 +25,7 @@ import (
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing-dns"
"github.com/sagernet/sing-tun"
"github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/buf"
"github.com/sagernet/sing/common/bufio"
@ -83,16 +84,16 @@ type Router struct {
transports []dns.Transport
transportMap map[string]dns.Transport
interfaceBindManager control.BindManager
networkMonitor NetworkUpdateMonitor
autoDetectInterface bool
defaultInterface string
interfaceMonitor DefaultInterfaceMonitor
defaultMark int
networkMonitor tun.NetworkUpdateMonitor
interfaceMonitor tun.DefaultInterfaceMonitor
trafficController adapter.TrafficController
processSearcher process.Searcher
}
func NewRouter(ctx context.Context, logger log.ContextLogger, dnsLogger log.ContextLogger, options option.RouteOptions, dnsOptions option.DNSOptions) (*Router, error) {
func NewRouter(ctx context.Context, logger log.ContextLogger, dnsLogger log.ContextLogger, options option.RouteOptions, dnsOptions option.DNSOptions, inbounds []option.Inbound) (*Router, error) {
if options.DefaultInterface != "" {
warnDefaultInterfaceOnUnsupportedPlatform.Check()
}
@ -231,8 +232,13 @@ func NewRouter(ctx context.Context, logger log.ContextLogger, dnsLogger log.Cont
router.transports = transports
router.transportMap = transportMap
if router.interfaceBindManager != nil || options.AutoDetectInterface {
networkMonitor, err := NewNetworkUpdateMonitor(router)
needInterfaceMonitor := options.AutoDetectInterface ||
C.IsDarwin && common.Any(inbounds, func(inbound option.Inbound) bool {
return inbound.HTTPOptions.SetSystemProxy || inbound.MixedOptions.SetSystemProxy
})
if router.interfaceBindManager != nil || needInterfaceMonitor {
networkMonitor, err := tun.NewNetworkUpdateMonitor(router)
if err == nil {
router.networkMonitor = networkMonitor
if router.interfaceBindManager != nil {
@ -241,15 +247,18 @@ func NewRouter(ctx context.Context, logger log.ContextLogger, dnsLogger log.Cont
}
}
if router.networkMonitor != nil && options.AutoDetectInterface {
interfaceMonitor, err := NewDefaultInterfaceMonitor(router.networkMonitor, func() {
router.logger.Info("updated default interface ", router.interfaceMonitor.DefaultInterfaceName(), ", index ", router.interfaceMonitor.DefaultInterfaceIndex())
})
if router.networkMonitor != nil && needInterfaceMonitor {
interfaceMonitor, err := tun.NewDefaultInterfaceMonitor(router.networkMonitor)
if err != nil {
return nil, E.New("auto_detect_interface unsupported on current platform")
}
interfaceMonitor.RegisterCallback(func() error {
router.logger.Info("updated default interface ", router.interfaceMonitor.DefaultInterfaceName(), ", index ", router.interfaceMonitor.DefaultInterfaceIndex())
return nil
})
router.interfaceMonitor = interfaceMonitor
}
if hasRule(options.Rules, isProcessRule) || hasDNSRule(dnsOptions.Rules, isProcessDNSRule) || options.FindProcess {
searcher, err := process.NewSearcher(logger)
if err != nil {
@ -648,20 +657,6 @@ func (r *Router) DefaultInterface() string {
return r.defaultInterface
}
func (r *Router) AutoDetectInterfaceName() string {
if r.interfaceMonitor == nil {
return ""
}
return r.interfaceMonitor.DefaultInterfaceName()
}
func (r *Router) AutoDetectInterfaceIndex() int {
if r.interfaceMonitor == nil {
return -1
}
return r.interfaceMonitor.DefaultInterfaceIndex()
}
func (r *Router) DefaultMark() int {
return r.defaultMark
}
@ -670,6 +665,14 @@ func (r *Router) Rules() []adapter.Rule {
return r.rules
}
func (r *Router) NetworkMonitor() tun.NetworkUpdateMonitor {
return r.networkMonitor
}
func (r *Router) InterfaceMonitor() tun.DefaultInterfaceMonitor {
return r.interfaceMonitor
}
func (r *Router) SetTrafficController(controller adapter.TrafficController) {
r.trafficController = controller
}

View File

@ -54,7 +54,7 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/sagernet/netlink v0.0.0-20220803045538-bdac49abf805 // indirect
github.com/sagernet/sing-dns v0.0.0-20220803121532-9e1ffb850d91 // indirect
github.com/sagernet/sing-tun v0.0.0-20220803112223-a8fd6450d4ed // indirect
github.com/sagernet/sing-tun v0.0.0-20220804154459-7ee0d19103d2 // indirect
github.com/sagernet/sing-vmess v0.0.0-20220804023624-e829b41c84c2 // indirect
github.com/sirupsen/logrus v1.8.1 // indirect
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect
@ -62,7 +62,7 @@ require (
go.uber.org/atomic v1.9.0 // indirect
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect
golang.org/x/mod v0.5.1 // indirect
golang.org/x/sys v0.0.0-20220731174439-a90be440212d // indirect
golang.org/x/sys v0.0.0-20220803195053-6e608f9ce704 // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect
golang.org/x/tools v0.1.9 // indirect

View File

@ -180,8 +180,8 @@ github.com/sagernet/sing-dns v0.0.0-20220803121532-9e1ffb850d91 h1:jxt2PYixIkK2i
github.com/sagernet/sing-dns v0.0.0-20220803121532-9e1ffb850d91/go.mod h1:T77zZdE2Cm6VqnFumrpwsq+kxYsbq+vWDhmjtdSl/oM=
github.com/sagernet/sing-shadowsocks v0.0.0-20220801112336-a91eacdd01e1 h1:RYvOc69eSNMN0dwVugrDts41Nn7Ar/C/n/fvytvFcp4=
github.com/sagernet/sing-shadowsocks v0.0.0-20220801112336-a91eacdd01e1/go.mod h1:NqZjiXszgVCMQ4gVDa2V+drhS8NMfGqUqDF86EacEFc=
github.com/sagernet/sing-tun v0.0.0-20220803112223-a8fd6450d4ed h1:28qeqeuHLZEkzdcZjYwcCn8y4ckyKimaP+L4P25dqUo=
github.com/sagernet/sing-tun v0.0.0-20220803112223-a8fd6450d4ed/go.mod h1:jNlPidQzZYkpmpQJ+sDN2YGrPsL4QImoqBpuauId9po=
github.com/sagernet/sing-tun v0.0.0-20220804154459-7ee0d19103d2 h1:har8hmVNhGxp14zLNAoGrgfzgxZQn0KTYJDfJudj0RU=
github.com/sagernet/sing-tun v0.0.0-20220804154459-7ee0d19103d2/go.mod h1:K1Hfxaa/1zsxZix3ats3k1TJftVwK0l4OoRnUjjhi0g=
github.com/sagernet/sing-vmess v0.0.0-20220804023624-e829b41c84c2 h1:C8sc2MYiNx0O7uQ0nieJWq5qYeIHj20XHFWPlcgoQeY=
github.com/sagernet/sing-vmess v0.0.0-20220804023624-e829b41c84c2/go.mod h1:bNXBqSWYaG3ePl6u0xQY5zneE+ZKa3683ZpuE8S1M1w=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
@ -314,8 +314,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220731174439-a90be440212d h1:Sv5ogFZatcgIMMtBSTTAgMYsicp25MXBubjXNDKwm80=
golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220803195053-6e608f9ce704 h1:Y7NOhdqIOU8kYI7BxsgL38d0ot0raxvcW+EMQU2QrT4=
golang.org/x/sys v0.0.0-20220803195053-6e608f9ce704/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=