From 842730707c03d3477a2aa1d4a4d6d94c0b57e889 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Sun, 26 Feb 2023 19:16:28 +0800 Subject: [PATCH] Update TUN creation --- cmd/internal/build_libbox/main.go | 4 ++-- experimental/libbox/log_client.go | 2 +- experimental/libbox/log_server.go | 2 +- experimental/libbox/platform.go | 2 +- experimental/libbox/service.go | 12 +++------- experimental/libbox/tun.go | 33 ++++++++++----------------- experimental/libbox/tun_darwin.go | 34 ++++++++++++++++++++++++++++ experimental/libbox/tun_gvisor.go | 19 ---------------- go.mod | 2 +- go.sum | 4 ++-- inbound/tun.go | 2 +- log/default.go | 2 +- log/observable.go | 6 +++-- transport/wireguard/device_system.go | 2 +- 14 files changed, 64 insertions(+), 62 deletions(-) create mode 100644 experimental/libbox/tun_darwin.go delete mode 100644 experimental/libbox/tun_gvisor.go diff --git a/cmd/internal/build_libbox/main.go b/cmd/internal/build_libbox/main.go index 7bc76cd2..9166f9d6 100644 --- a/cmd/internal/build_libbox/main.go +++ b/cmd/internal/build_libbox/main.go @@ -85,10 +85,10 @@ func buildiOS() { } if !debugEnabled { args = append(args, - "-trimpath", "-ldflags=-s -w -buildid=", + "-trimpath", "-ldflags=-s -w -buildid=", "-tags", "with_gvisor,with_clash_api", ) } else { - args = append(args, "-tags", "debug") + args = append(args, "-tags", "with_gvisor,with_clash_api,debug") } args = append(args, "./experimental/libbox") diff --git a/experimental/libbox/log_client.go b/experimental/libbox/log_client.go index f503e57c..6efb21fb 100644 --- a/experimental/libbox/log_client.go +++ b/experimental/libbox/log_client.go @@ -1,4 +1,4 @@ -//go:build ios +//go:build darwin package libbox diff --git a/experimental/libbox/log_server.go b/experimental/libbox/log_server.go index af80a635..1e0eb0a1 100644 --- a/experimental/libbox/log_server.go +++ b/experimental/libbox/log_server.go @@ -1,4 +1,4 @@ -//go:build ios +//go:build darwin package libbox diff --git a/experimental/libbox/platform.go b/experimental/libbox/platform.go index c494c598..527ee737 100644 --- a/experimental/libbox/platform.go +++ b/experimental/libbox/platform.go @@ -2,7 +2,7 @@ package libbox type PlatformInterface interface { AutoDetectInterfaceControl(fd int32) error - OpenTun(options TunOptions) (TunInterface, error) + OpenTun(options TunOptions) (int32, error) WriteLog(message string) UseProcFS() bool FindConnectionOwner(ipProtocol int32, sourceAddress string, sourcePort int32, destinationAddress string, destinationPort int32) (int32, error) diff --git a/experimental/libbox/service.go b/experimental/libbox/service.go index a08e9b7d..1c89fd69 100644 --- a/experimental/libbox/service.go +++ b/experimental/libbox/service.go @@ -3,7 +3,6 @@ package libbox import ( "context" "net/netip" - "os" "runtime" "syscall" @@ -76,17 +75,12 @@ func (w *platformInterfaceWrapper) OpenTun(options tun.Options) (tun.Tun, error) } optionsWrapper := tunOptions(options) - tunInterface, err := w.iif.OpenTun(&optionsWrapper) + tunFd, err := w.iif.OpenTun(&optionsWrapper) if err != nil { return nil, err } - tunFd := tunInterface.FileDescriptor() - return &nativeTun{ - tunFd: int(tunFd), - tunFile: os.NewFile(uintptr(tunFd), "tun"), - tunMTU: options.MTU, - closer: tunInterface, - }, nil + options.FileDescriptor = int(tunFd) + 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 27912bb9..d9013e59 100644 --- a/experimental/libbox/tun.go +++ b/experimental/libbox/tun.go @@ -1,13 +1,13 @@ package libbox import ( - "io" + "net" "net/netip" - "os" "github.com/sagernet/sing-tun" "github.com/sagernet/sing/common" E "github.com/sagernet/sing/common/exceptions" + M "github.com/sagernet/sing/common/metadata" ) type TunOptions interface { @@ -28,6 +28,16 @@ type RoutePrefix struct { Prefix int32 } +func (p *RoutePrefix) Mask() string { + var bits int + if M.ParseSocksaddr(p.Address).Addr.Is6() { + bits = 128 + } else { + bits = 32 + } + return net.IP(net.CIDRMask(int(p.Prefix), bits)).String() +} + type RoutePrefixIterator interface { Next() *RoutePrefix HasNext() bool @@ -88,22 +98,3 @@ func (o *tunOptions) GetIncludePackage() StringIterator { func (o *tunOptions) GetExcludePackage() StringIterator { return newIterator(o.ExcludePackage) } - -type nativeTun struct { - tunFd int - tunFile *os.File - tunMTU uint32 - closer io.Closer -} - -func (t *nativeTun) Read(p []byte) (n int, err error) { - return t.tunFile.Read(p) -} - -func (t *nativeTun) Write(p []byte) (n int, err error) { - return t.tunFile.Write(p) -} - -func (t *nativeTun) Close() error { - return t.closer.Close() -} diff --git a/experimental/libbox/tun_darwin.go b/experimental/libbox/tun_darwin.go new file mode 100644 index 00000000..e312cb91 --- /dev/null +++ b/experimental/libbox/tun_darwin.go @@ -0,0 +1,34 @@ +package libbox + +import ( + "golang.org/x/sys/unix" +) + +// kanged from wireauard-apple + +const utunControlName = "com.apple.net.utun_control" + +func GetTunnelFileDescriptor() int32 { + ctlInfo := &unix.CtlInfo{} + copy(ctlInfo.Name[:], utunControlName) + for fd := 0; fd < 1024; fd++ { + addr, err := unix.Getpeername(fd) + if err != nil { + continue + } + addrCTL, loaded := addr.(*unix.SockaddrCtl) + if !loaded { + continue + } + if ctlInfo.Id == 0 { + err = unix.IoctlCtlInfo(fd, ctlInfo) + if err != nil { + continue + } + } + if addrCTL.ID == ctlInfo.Id { + return int32(fd) + } + } + return -1 +} diff --git a/experimental/libbox/tun_gvisor.go b/experimental/libbox/tun_gvisor.go deleted file mode 100644 index 97b807ee..00000000 --- a/experimental/libbox/tun_gvisor.go +++ /dev/null @@ -1,19 +0,0 @@ -//go:build with_gvisor && linux - -package libbox - -import ( - "github.com/sagernet/sing-tun" - - "gvisor.dev/gvisor/pkg/tcpip/link/fdbased" - "gvisor.dev/gvisor/pkg/tcpip/stack" -) - -var _ tun.GVisorTun = (*nativeTun)(nil) - -func (t *nativeTun) NewEndpoint() (stack.LinkEndpoint, error) { - return fdbased.New(&fdbased.Options{ - FDs: []int{t.tunFd}, - MTU: t.tunMTU, - }) -} diff --git a/go.mod b/go.mod index 646c6366..2de507bb 100644 --- a/go.mod +++ b/go.mod @@ -28,7 +28,7 @@ require ( github.com/sagernet/sing-dns v0.1.4 github.com/sagernet/sing-shadowsocks v0.1.2-0.20230221080503-769c01d6bba9 github.com/sagernet/sing-shadowtls v0.0.0-20230221123345-78e50cd7b587 - github.com/sagernet/sing-tun v0.1.1 + github.com/sagernet/sing-tun v0.1.2-0.20230226091124-0cdb0eed74d9 github.com/sagernet/sing-vmess v0.1.2 github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195 github.com/sagernet/tfo-go v0.0.0-20230207095944-549363a7327d diff --git a/go.sum b/go.sum index 6e3d522f..c96926b6 100644 --- a/go.sum +++ b/go.sum @@ -137,8 +137,8 @@ github.com/sagernet/sing-shadowsocks v0.1.2-0.20230221080503-769c01d6bba9 h1:qS3 github.com/sagernet/sing-shadowsocks v0.1.2-0.20230221080503-769c01d6bba9/go.mod h1:f3mHTy5shnVM9l8UocMlJgC/1G/zdj5FuEuVXhDinGU= github.com/sagernet/sing-shadowtls v0.0.0-20230221123345-78e50cd7b587 h1:OjIXlHT2bblZfp+ciupM4xY9+Ccpj9FsuHRtKRBv+Pg= github.com/sagernet/sing-shadowtls v0.0.0-20230221123345-78e50cd7b587/go.mod h1:Kn1VUIprdkwCgkS6SXYaLmIpKzQbqBIKJBMY+RvBhYc= -github.com/sagernet/sing-tun v0.1.1 h1:2Hg3GAyJWzQ7Ua1j74dE+mI06vaqSBO9yD4tkTjggn4= -github.com/sagernet/sing-tun v0.1.1/go.mod h1:WzW/SkT+Nh9uJn/FIYUE2YJHYuPwfbh8sATOzU9QDGw= +github.com/sagernet/sing-tun v0.1.2-0.20230226091124-0cdb0eed74d9 h1:tq1kc0HFj/jfhLfVC1NJI6lex2g6w2W+gVsFu6H2Kis= +github.com/sagernet/sing-tun v0.1.2-0.20230226091124-0cdb0eed74d9/go.mod h1:KnRkwaDHbb06zgeNPu0LQ8A+vA9myMxKEgHN1brCPHg= github.com/sagernet/sing-vmess v0.1.2 h1:RbOZNAId2LrCai8epMoQXlf0XTrou0bfcw08hNBg6lM= github.com/sagernet/sing-vmess v0.1.2/go.mod h1:9NSj8mZTx1JIY/HF9LaYRppUsVkysIN5tEFpNZujXxY= github.com/sagernet/smux v0.0.0-20220831015742-e0f1988e3195 h1:5VBIbVw9q7aKbrFdT83mjkyvQ+VaRsQ6yflTepfln38= diff --git a/inbound/tun.go b/inbound/tun.go index 374c3767..c292ba91 100644 --- a/inbound/tun.go +++ b/inbound/tun.go @@ -150,7 +150,7 @@ func (t *Tun) Start() error { if t.platformInterface != nil { tunInterface, err = t.platformInterface.OpenTun(t.tunOptions) } else { - tunInterface, err = tun.Open(t.tunOptions) + tunInterface, err = tun.New(t.tunOptions) } if err != nil { return E.Cause(err, "configure tun interface") diff --git a/log/default.go b/log/default.go index e8db489a..b469c07a 100644 --- a/log/default.go +++ b/log/default.go @@ -25,7 +25,7 @@ func NewFactory(formatter Formatter, writer io.Writer, platformWriter io.Writer) formatter: formatter, platformFormatter: Formatter{ BaseTime: formatter.BaseTime, - DisableColors: C.IsIos, + DisableColors: C.IsDarwin || C.IsIos, }, writer: writer, platformWriter: platformWriter, diff --git a/log/observable.go b/log/observable.go index b2c87412..7d873e0e 100644 --- a/log/observable.go +++ b/log/observable.go @@ -6,6 +6,7 @@ import ( "os" "time" + C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing/common" F "github.com/sagernet/sing/common/format" "github.com/sagernet/sing/common/observable" @@ -27,7 +28,8 @@ func NewObservableFactory(formatter Formatter, writer io.Writer, platformWriter factory := &observableFactory{ formatter: formatter, platformFormatter: Formatter{ - BaseTime: formatter.BaseTime, + BaseTime: formatter.BaseTime, + DisableColors: C.IsDarwin || C.IsIos, }, writer: writer, platformWriter: platformWriter, @@ -91,7 +93,7 @@ func (l *observableLogger) Log(ctx context.Context, level Level, args []any) { } l.subscriber.Emit(Entry{level, messageSimple}) if l.platformWriter != nil { - l.platformWriter.Write([]byte(l.formatter.Format(ctx, level, l.tag, F.ToString(args...), nowTime))) + l.platformWriter.Write([]byte(l.platformFormatter.Format(ctx, level, l.tag, F.ToString(args...), nowTime))) } } diff --git a/transport/wireguard/device_system.go b/transport/wireguard/device_system.go index b5bde2fd..d4316422 100644 --- a/transport/wireguard/device_system.go +++ b/transport/wireguard/device_system.go @@ -46,7 +46,7 @@ func NewSystemDevice(router adapter.Router, interfaceName string, localPrefixes if interfaceName == "" { interfaceName = tun.CalculateInterfaceName("wg") } - tunInterface, err := tun.Open(tun.Options{ + tunInterface, err := tun.New(tun.Options{ Name: interfaceName, Inet4Address: inet4Addresses, Inet6Address: inet6Addresses,