diff --git a/listener/tun/device/fdbased/open_linux.go b/listener/tun/device/fdbased/open_linux.go index c19b1491..0df81ff3 100644 --- a/listener/tun/device/fdbased/open_linux.go +++ b/listener/tun/device/fdbased/open_linux.go @@ -1,12 +1,7 @@ package fdbased import ( - "fmt" - "github.com/Dreamacro/clash/listener/tun/device" - - "gvisor.dev/gvisor/pkg/tcpip/link/fdbased" - "gvisor.dev/gvisor/pkg/tcpip/link/rawfile" ) func open(fd int, mtu uint32) (device.Device, error) { @@ -16,17 +11,7 @@ func open(fd int, mtu uint32) (device.Device, error) { } func (f *FD) useEndpoint() error { - ep, err := fdbased.New(&fdbased.Options{ - FDs: []int{f.fd}, - MTU: f.mtu, - // TUN only, ignore ethernet header. - EthernetHeader: false, - }) - if err != nil { - return fmt.Errorf("create endpoint: %w", err) - } - f.LinkEndpoint = ep - return nil + return f.newLinuxEp() } func (f *FD) useIOBased() error { @@ -34,23 +19,9 @@ func (f *FD) useIOBased() error { } func (f *FD) Read(packet []byte) (int, error) { - n, gvErr := rawfile.BlockingRead(f.fd, packet) - if gvErr != nil { - return 0, fmt.Errorf("read error: %s", gvErr.String()) - } - - return n, nil + return f.read(packet) } func (f *FD) Write(packet []byte) (int, error) { - n := len(packet) - if n == 0 { - return 0, nil - } - - gvErr := rawfile.NonBlockingWrite(f.fd, packet) - if gvErr != nil { - return 0, fmt.Errorf("write error: %s", gvErr.String()) - } - return n, nil + return f.write(packet) } diff --git a/listener/tun/device/fdbased/open_linux_gvisor.go b/listener/tun/device/fdbased/open_linux_gvisor.go new file mode 100644 index 00000000..dc250692 --- /dev/null +++ b/listener/tun/device/fdbased/open_linux_gvisor.go @@ -0,0 +1,45 @@ +//go:build !no_gvisor && (linux || android) + +package fdbased + +import ( + "fmt" + "gvisor.dev/gvisor/pkg/tcpip/link/fdbased" + "gvisor.dev/gvisor/pkg/tcpip/link/rawfile" +) + +func (f *FD) newLinuxEp() error { + ep, err := fdbased.New(&fdbased.Options{ + FDs: []int{f.fd}, + MTU: f.mtu, + // TUN only, ignore ethernet header. + EthernetHeader: false, + }) + if err != nil { + return fmt.Errorf("create endpoint: %w", err) + } + f.LinkEndpoint = ep + return nil +} + +func (f *FD) read(packet []byte) (int, error) { + n, gvErr := rawfile.BlockingRead(f.fd, packet) + if gvErr != nil { + return 0, fmt.Errorf("read error: %s", gvErr.String()) + } + + return n, nil +} + +func (f *FD) write(packet []byte) (int, error) { + n := len(packet) + if n == 0 { + return 0, nil + } + + gvErr := rawfile.NonBlockingWrite(f.fd, packet) + if gvErr != nil { + return 0, fmt.Errorf("write error: %s", gvErr.String()) + } + return n, nil +} diff --git a/listener/tun/device/fdbased/open_linux_no_gvisor.go b/listener/tun/device/fdbased/open_linux_no_gvisor.go new file mode 100644 index 00000000..ec76d991 --- /dev/null +++ b/listener/tun/device/fdbased/open_linux_no_gvisor.go @@ -0,0 +1,19 @@ +//go:build no_gvisor + +package fdbased + +import ( + "fmt" +) + +func (f *FD) newLinuxEp() error { + return fmt.Errorf("unsupported gvisor on the build") +} + +func (f *FD) read(packet []byte) (int, error) { + return 0, fmt.Errorf("unsupported gvisor on the build") +} + +func (f *FD) write(packet []byte) (int, error) { + return 0, fmt.Errorf("unsupported gvisor on the build") +} diff --git a/listener/tun/device/fdbased/open_others.go b/listener/tun/device/fdbased/open_others.go index a4d4687a..e5c98276 100644 --- a/listener/tun/device/fdbased/open_others.go +++ b/listener/tun/device/fdbased/open_others.go @@ -16,7 +16,7 @@ func open(fd int, mtu uint32) (device.Device, error) { } func (f *FD) useEndpoint() error { - return newEp(f) + return f.newEpOther() } func (f *FD) useIOBased() error { diff --git a/listener/tun/device/fdbased/open_others_gvisor.go b/listener/tun/device/fdbased/open_others_gvisor.go index 7f7249eb..9cb00511 100644 --- a/listener/tun/device/fdbased/open_others_gvisor.go +++ b/listener/tun/device/fdbased/open_others_gvisor.go @@ -9,7 +9,7 @@ import ( "github.com/Dreamacro/clash/listener/tun/device/iobased" ) -func newEp(f *FD) error { +func (f *FD) newEpOther() error { ep, err := iobased.New(os.NewFile(uintptr(f.fd), f.Name()), f.mtu, 0) if err != nil { return fmt.Errorf("create endpoint: %w", err) diff --git a/listener/tun/device/fdbased/open_others_no_gvisor.go b/listener/tun/device/fdbased/open_others_no_gvisor.go index 559881b4..ed616f76 100644 --- a/listener/tun/device/fdbased/open_others_no_gvisor.go +++ b/listener/tun/device/fdbased/open_others_no_gvisor.go @@ -6,6 +6,6 @@ import ( "fmt" ) -func newEp(f *FD) error { +func (f *FD) newEpOther() error { return fmt.Errorf("unsupported gvisor on the build") }