From 591d91e9d1e33b58d2c00a7425f2a12f9f282888 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Mon, 17 Apr 2023 20:04:23 +0800 Subject: [PATCH] Fix system 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 | 2 +- go.sum | 4 ++-- inbound/tun.go | 2 +- 9 files changed, 58 insertions(+), 8 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 bee1b450..9c80b948 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,7 @@ require ( github.com/sagernet/sing-dns v0.1.5-0.20230415085626-111ecf799dfc github.com/sagernet/sing-shadowsocks v0.2.2-0.20230417102954-f77257340507 github.com/sagernet/sing-shadowtls v0.1.2-0.20230417103049-4f682e05f19b - github.com/sagernet/sing-tun v0.1.4-0.20230417112313-499c0aed67bc + github.com/sagernet/sing-tun v0.1.4-0.20230417120210-d880656b527e github.com/sagernet/sing-vmess v0.1.5-0.20230417103030-8c3070ae3fb3 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 10444588..45b7afd8 100644 --- a/go.sum +++ b/go.sum @@ -119,8 +119,8 @@ github.com/sagernet/sing-shadowsocks v0.2.2-0.20230417102954-f77257340507 h1:bAH github.com/sagernet/sing-shadowsocks v0.2.2-0.20230417102954-f77257340507/go.mod h1:UJjvQGw0lyYaDGIDvUraL16fwaAEH1WFw1Y6sUcMPog= github.com/sagernet/sing-shadowtls v0.1.2-0.20230417103049-4f682e05f19b h1:ouW/6IDCrxkBe19YSbdCd7buHix7b+UZ6BM4Zz74XF4= github.com/sagernet/sing-shadowtls v0.1.2-0.20230417103049-4f682e05f19b/go.mod h1:oG8bPerYI6cZ74KquY3DvA7ynECyrILPBnce6wtBqeI= -github.com/sagernet/sing-tun v0.1.4-0.20230417112313-499c0aed67bc h1:TGnS4hLAjOQjgshQcwCW5R66VkKJ8qgSCI8fPxXTs3M= -github.com/sagernet/sing-tun v0.1.4-0.20230417112313-499c0aed67bc/go.mod h1:4YxIDEkkCjGXDOTMPw1SXpLmCQUFAWuaQN250oo+928= +github.com/sagernet/sing-tun v0.1.4-0.20230417120210-d880656b527e h1:KlV8aWhMKnYcb9qHHbaCjGpz/u8EOETIwG+oOrX8Fxk= +github.com/sagernet/sing-tun v0.1.4-0.20230417120210-d880656b527e/go.mod h1:4YxIDEkkCjGXDOTMPw1SXpLmCQUFAWuaQN250oo+928= github.com/sagernet/sing-vmess v0.1.5-0.20230417103030-8c3070ae3fb3 h1:BHOnxrbC929JonuKqFdJ7ZbDp7zs4oTlH5KFvKtWu9U= github.com/sagernet/sing-vmess v0.1.5-0.20230417103030-8c3070ae3fb3/go.mod h1:yKrAr+dqZd64DxBXCHWrYicp+n4qbqO73mtwv3dck8U= 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 f18c61d2..480642fb 100644 --- a/inbound/tun.go +++ b/inbound/tun.go @@ -152,7 +152,7 @@ func (t *Tun) Start() error { ) t.logger.Trace("opening interface") 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) }