From ec8974673b90d25d1a59675928e6e092aee2d626 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Mon, 17 Apr 2023 19:05:02 +0800 Subject: [PATCH] Fix platform interface monitor & Fix system tun stack for ios --- experimental/libbox/platform/interface.go | 2 +- experimental/libbox/service.go | 8 +++++-- experimental/libbox/tun.go | 2 +- experimental/libbox/tun_name_darwin.go | 11 ++++++++++ experimental/libbox/tun_name_linux.go | 26 +++++++++++++++++++++++ experimental/libbox/tun_name_other.go | 9 ++++++++ go.mod | 4 ++-- go.sum | 8 +++---- inbound/tun.go | 2 +- route/router.go | 9 ++++++-- 10 files changed, 68 insertions(+), 13 deletions(-) create mode 100644 experimental/libbox/tun_name_darwin.go create mode 100644 experimental/libbox/tun_name_linux.go create mode 100644 experimental/libbox/tun_name_other.go diff --git a/experimental/libbox/platform/interface.go b/experimental/libbox/platform/interface.go index 760b9587..a16297f8 100644 --- a/experimental/libbox/platform/interface.go +++ b/experimental/libbox/platform/interface.go @@ -11,7 +11,7 @@ import ( type Interface interface { AutoDetectInterfaceControl() control.Func - OpenTun(options tun.Options, platformOptions option.TunPlatformOptions) (tun.Tun, error) + OpenTun(options *tun.Options, platformOptions option.TunPlatformOptions) (tun.Tun, error) process.Searcher io.Writer } diff --git a/experimental/libbox/service.go b/experimental/libbox/service.go index 5a66852c..e6510170 100644 --- a/experimental/libbox/service.go +++ b/experimental/libbox/service.go @@ -68,7 +68,7 @@ func (w *platformInterfaceWrapper) AutoDetectInterfaceControl() control.Func { } } -func (w *platformInterfaceWrapper) OpenTun(options tun.Options, platformOptions option.TunPlatformOptions) (tun.Tun, error) { +func (w *platformInterfaceWrapper) OpenTun(options *tun.Options, platformOptions option.TunPlatformOptions) (tun.Tun, error) { if len(options.IncludeUID) > 0 || len(options.ExcludeUID) > 0 { return nil, E.New("android: unsupported uid options") } @@ -79,12 +79,16 @@ func (w *platformInterfaceWrapper) OpenTun(options tun.Options, platformOptions if err != nil { return nil, err } + options.Name, err = getTunnelName(tunFd) + if err != nil { + return nil, E.Cause(err, "query tun name") + } dupFd, err := dup(int(tunFd)) if err != nil { return nil, E.Cause(err, "dup tun file descriptor") } options.FileDescriptor = dupFd - return tun.New(options) + return tun.New(*options) } func (w *platformInterfaceWrapper) Write(p []byte) (n int, err error) { diff --git a/experimental/libbox/tun.go b/experimental/libbox/tun.go index e7db249c..e692a5d6 100644 --- a/experimental/libbox/tun.go +++ b/experimental/libbox/tun.go @@ -59,7 +59,7 @@ func mapRoutePrefix(prefixes []netip.Prefix) RoutePrefixIterator { var _ TunOptions = (*tunOptions)(nil) type tunOptions struct { - tun.Options + *tun.Options option.TunPlatformOptions } diff --git a/experimental/libbox/tun_name_darwin.go b/experimental/libbox/tun_name_darwin.go new file mode 100644 index 00000000..ff8c9dcc --- /dev/null +++ b/experimental/libbox/tun_name_darwin.go @@ -0,0 +1,11 @@ +package libbox + +import "golang.org/x/sys/unix" + +func getTunnelName(fd int32) (string, error) { + return unix.GetsockoptString( + int(fd), + 2, /* #define SYSPROTO_CONTROL 2 */ + 2, /* #define UTUN_OPT_IFNAME 2 */ + ) +} diff --git a/experimental/libbox/tun_name_linux.go b/experimental/libbox/tun_name_linux.go new file mode 100644 index 00000000..bf2f4f07 --- /dev/null +++ b/experimental/libbox/tun_name_linux.go @@ -0,0 +1,26 @@ +package libbox + +import ( + "fmt" + "syscall" + "unsafe" + + "golang.org/x/sys/unix" +) + +const ifReqSize = unix.IFNAMSIZ + 64 + +func getTunnelName(fd int32) (string, error) { + var ifr [ifReqSize]byte + var errno syscall.Errno + _, _, errno = unix.Syscall( + unix.SYS_IOCTL, + uintptr(fd), + uintptr(unix.TUNGETIFF), + uintptr(unsafe.Pointer(&ifr[0])), + ) + if errno != 0 { + return "", fmt.Errorf("failed to get name of TUN device: %w", errno) + } + return unix.ByteSliceToString(ifr[:]), nil +} diff --git a/experimental/libbox/tun_name_other.go b/experimental/libbox/tun_name_other.go new file mode 100644 index 00000000..94a08afa --- /dev/null +++ b/experimental/libbox/tun_name_other.go @@ -0,0 +1,9 @@ +//go:build !(darwin || linux) + +package libbox + +import "os" + +func getTunnelName(fd int32) (string, error) { + return "", os.ErrInvalid +} diff --git a/go.mod b/go.mod index 7f663b74..a5bbb926 100644 --- a/go.mod +++ b/go.mod @@ -26,11 +26,11 @@ require ( github.com/sagernet/gomobile v0.0.0-20230413023804-244d7ff07035 github.com/sagernet/quic-go v0.0.0-20230202071646-a8c8afb18b32 github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 - github.com/sagernet/sing v0.2.3 + github.com/sagernet/sing v0.2.4-0.20230418025125-f196b4303e31 github.com/sagernet/sing-dns v0.1.5-0.20230415085626-111ecf799dfc github.com/sagernet/sing-shadowsocks v0.2.0 github.com/sagernet/sing-shadowtls v0.1.0 - github.com/sagernet/sing-tun v0.1.4-0.20230326080954-8848c0e4cbab + github.com/sagernet/sing-tun v0.1.4-0.20230419061614-d744d03d9302 github.com/sagernet/sing-vmess v0.1.3 github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 github.com/sagernet/tfo-go v0.0.0-20230303015439-ffcfd8c41cf9 diff --git a/go.sum b/go.sum index 7f51d33c..989bcf8f 100644 --- a/go.sum +++ b/go.sum @@ -113,16 +113,16 @@ github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byL github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU= github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY= github.com/sagernet/sing v0.1.8/go.mod h1:jt1w2u7lJQFFSGLiRrRIs5YWmx4kAPfWuOejuDW9qMk= -github.com/sagernet/sing v0.2.3 h1:V50MvZ4c3Iij2lYFWPlzL1PyipwSzjGeN9x+Ox89vpk= -github.com/sagernet/sing v0.2.3/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w= +github.com/sagernet/sing v0.2.4-0.20230418025125-f196b4303e31 h1:qgq8jeY/rbnY9NwYXByO//AP0ByIxnsKUxQx1tOB3W0= +github.com/sagernet/sing v0.2.4-0.20230418025125-f196b4303e31/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w= github.com/sagernet/sing-dns v0.1.5-0.20230415085626-111ecf799dfc h1:hmbuqKv48SAjiKPoqtJGvS5pEHVPZjTHq9CPwQY2cZ4= github.com/sagernet/sing-dns v0.1.5-0.20230415085626-111ecf799dfc/go.mod h1:ZKuuqgsHRxDahYrzgSgy4vIAGGuKPlIf4hLcNzYzLkY= github.com/sagernet/sing-shadowsocks v0.2.0 h1:ILDWL7pwWfkPLEbviE/MyCgfjaBmJY/JVVY+5jhSb58= github.com/sagernet/sing-shadowsocks v0.2.0/go.mod h1:ysYzszRLpNzJSorvlWRMuzU6Vchsp7sd52q+JNY4axw= github.com/sagernet/sing-shadowtls v0.1.0 h1:05MYce8aR5xfKIn+y7xRFsdKhKt44QZTSEQW+lG5IWQ= github.com/sagernet/sing-shadowtls v0.1.0/go.mod h1:Kn1VUIprdkwCgkS6SXYaLmIpKzQbqBIKJBMY+RvBhYc= -github.com/sagernet/sing-tun v0.1.4-0.20230326080954-8848c0e4cbab h1:a9oeWuPBuIZ70qMhIIH6RrYhp886xN9jJIwsuu4ZFUo= -github.com/sagernet/sing-tun v0.1.4-0.20230326080954-8848c0e4cbab/go.mod h1:4YxIDEkkCjGXDOTMPw1SXpLmCQUFAWuaQN250oo+928= +github.com/sagernet/sing-tun v0.1.4-0.20230419061614-d744d03d9302 h1:aPb0T2HQRTG2t7fEwLvFLZSXmhmnBh+SMs2NufhmrsI= +github.com/sagernet/sing-tun v0.1.4-0.20230419061614-d744d03d9302/go.mod h1:bvcVzlf9q9dgxt8qKluW+zOXCFoN1+SpBG3sHTq8/9Q= github.com/sagernet/sing-vmess v0.1.3 h1:q/+tsF46dvvapL6CpQBgPHJ6nQrDUZqEtLHCbsjO7iM= github.com/sagernet/sing-vmess v0.1.3/go.mod h1:GVXqAHwe9U21uS+Voh4YBIrADQyE4F9v0ayGSixSQAE= github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 h1:HuE6xSwco/Xed8ajZ+coeYLmioq0Qp1/Z2zczFaV8as= diff --git a/inbound/tun.go b/inbound/tun.go index 8ea7b384..9e287c74 100644 --- a/inbound/tun.go +++ b/inbound/tun.go @@ -148,7 +148,7 @@ func (t *Tun) Start() error { err error ) if t.platformInterface != nil { - tunInterface, err = t.platformInterface.OpenTun(t.tunOptions, t.platformOptions) + tunInterface, err = t.platformInterface.OpenTun(&t.tunOptions, t.platformOptions) } else { tunInterface, err = tun.New(t.tunOptions) } diff --git a/route/router.go b/route/router.go index 71b2ef3f..6547c4a7 100644 --- a/route/router.go +++ b/route/router.go @@ -15,6 +15,7 @@ import ( "github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/common/dialer" + "github.com/sagernet/sing-box/common/dialer/conntrack" "github.com/sagernet/sing-box/common/geoip" "github.com/sagernet/sing-box/common/geosite" "github.com/sagernet/sing-box/common/mux" @@ -268,9 +269,9 @@ func NewRouter( router.transportMap = transportMap router.transportDomainStrategy = transportDomainStrategy - needInterfaceMonitor := platformInterface == nil && (options.AutoDetectInterface || common.Any(inbounds, func(inbound option.Inbound) bool { + needInterfaceMonitor := options.AutoDetectInterface || common.Any(inbounds, func(inbound option.Inbound) bool { return inbound.HTTPOptions.SetSystemProxy || inbound.MixedOptions.SetSystemProxy || inbound.TunOptions.AutoRoute - })) + }) if needInterfaceMonitor { networkMonitor, err := tun.NewNetworkUpdateMonitor(router) @@ -1157,5 +1158,9 @@ func (r *Router) notifyNetworkUpdate(int) error { } } } + + if conntrack.Enabled { + conntrack.Close() + } return nil }