diff --git a/go.mod b/go.mod index 1cf8d35a..fc2783f7 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/mdlayher/netlink v1.7.2-0.20221213171556-9881fafed8c7 github.com/metacubex/quic-go v0.33.3-0.20230322045857-901b636b4594 github.com/metacubex/sing-shadowsocks v0.2.2-0.20230417103204-e2bcd32a73cc - github.com/metacubex/sing-tun v0.1.4-0.20230417114323-ef78a871e13f + github.com/metacubex/sing-tun v0.1.4-0.20230417120711-05d852989e84 github.com/metacubex/sing-wireguard v0.0.0-20230413082948-e51777dcf025 github.com/miekg/dns v1.1.53 github.com/mroth/weightedrand/v2 v2.0.0 diff --git a/go.sum b/go.sum index 553498a8..f42dba4c 100644 --- a/go.sum +++ b/go.sum @@ -98,8 +98,8 @@ github.com/metacubex/quic-go v0.33.3-0.20230322045857-901b636b4594 h1:KD96JPdTIa github.com/metacubex/quic-go v0.33.3-0.20230322045857-901b636b4594/go.mod h1:9nOiGX6kqV3+ZbkDKdTNzdFD726QQHPH6WDb36jUSpA= github.com/metacubex/sing-shadowsocks v0.2.2-0.20230417103204-e2bcd32a73cc h1:ctwahnHNAgoicCUJqKrHNVcyjEeNIoK4Dqyjh5uIkEE= github.com/metacubex/sing-shadowsocks v0.2.2-0.20230417103204-e2bcd32a73cc/go.mod h1:4uQQReKMTU7KTfOykVBe/oGJ00pl38d+BYJ99+mx26s= -github.com/metacubex/sing-tun v0.1.4-0.20230417114323-ef78a871e13f h1:vS2bII9IjwpNaf311kWn9hi7p6WSzHM4dFdvmYECvEs= -github.com/metacubex/sing-tun v0.1.4-0.20230417114323-ef78a871e13f/go.mod h1:ifLPYzRpV/u8bLE39zGb4nuX1NuUqzzLZmF8iZvxjIA= +github.com/metacubex/sing-tun v0.1.4-0.20230417120711-05d852989e84 h1:3L4glttGciACRBYV1Z1eglcYFYWiXmTExWjTySgaGdM= +github.com/metacubex/sing-tun v0.1.4-0.20230417120711-05d852989e84/go.mod h1:kHkYHoRlYA4I12QPTt/ADyRGqy5YweLUfye1E1hC/q4= github.com/metacubex/sing-wireguard v0.0.0-20230413082948-e51777dcf025 h1:itjCqEeem+BKZFiBEhQmWHDHKK4FgTGvnYCFS0JOb3A= github.com/metacubex/sing-wireguard v0.0.0-20230413082948-e51777dcf025/go.mod h1:7mPG9qYln+CLKBcDt7Dk4c7b3S53VzEfexMVPe6T6FM= github.com/metacubex/uber-atomic v0.0.0-20230202125923-feb10b770370 h1:UkViS4DCESAUEYgbIEQdD02hyMacFt6Dny+1MOJtNIo= diff --git a/listener/sing_tun/server.go b/listener/sing_tun/server.go index ada9d1c2..5f691b44 100644 --- a/listener/sing_tun/server.go +++ b/listener/sing_tun/server.go @@ -229,8 +229,8 @@ func New(options LC.Tun, tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapte err = E.Cause(err, "configure tun interface") return } - l.tunIf = tunIf - l.tunStack, err = tun.NewStack(strings.ToLower(options.Stack.String()), tun.StackOptions{ + + stackOptions := tun.StackOptions{ Context: context.TODO(), Tun: tunIf, MTU: tunOptions.MTU, @@ -241,7 +241,16 @@ func New(options LC.Tun, tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapte UDPTimeout: udpTimeout, Handler: handler, Logger: log.SingLogger, - }) + } + + if options.FileDescriptor > 0 { + if tunName, err := getTunnelName(int32(options.FileDescriptor)); err != nil { + stackOptions.Name = tunName + stackOptions.UnderPlatform = true + } + } + l.tunIf = tunIf + l.tunStack, err = tun.NewStack(strings.ToLower(options.Stack.String()), stackOptions) if err != nil { return } diff --git a/listener/sing_tun/tun_name_darwin.go b/listener/sing_tun/tun_name_darwin.go new file mode 100644 index 00000000..5b4686ea --- /dev/null +++ b/listener/sing_tun/tun_name_darwin.go @@ -0,0 +1,11 @@ +package sing_tun + +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/listener/sing_tun/tun_name_linux.go b/listener/sing_tun/tun_name_linux.go new file mode 100644 index 00000000..9ae9800b --- /dev/null +++ b/listener/sing_tun/tun_name_linux.go @@ -0,0 +1,25 @@ +package sing_tun + +import ( + "fmt" + "golang.org/x/sys/unix" + "syscall" + "unsafe" +) + +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/listener/sing_tun/tun_name_other.go b/listener/sing_tun/tun_name_other.go new file mode 100644 index 00000000..c47c8cbe --- /dev/null +++ b/listener/sing_tun/tun_name_other.go @@ -0,0 +1,9 @@ +//go:build !(darwin || linux) + +package sing_tun + +import "os" + +func getTunnelName(fd int32) (string, error) { + return "", os.ErrInvalid +}