github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/app/tun/tun.go (about) 1 //go:build !confonly 2 // +build !confonly 3 4 package tun 5 6 import ( 7 "context" 8 9 "gvisor.dev/gvisor/pkg/tcpip/stack" 10 11 core "github.com/v2fly/v2ray-core/v5" 12 "github.com/v2fly/v2ray-core/v5/app/tun/device" 13 "github.com/v2fly/v2ray-core/v5/app/tun/device/gvisor" 14 "github.com/v2fly/v2ray-core/v5/app/tun/tunsorter" 15 "github.com/v2fly/v2ray-core/v5/common" 16 "github.com/v2fly/v2ray-core/v5/common/net/packetaddr" 17 "github.com/v2fly/v2ray-core/v5/features/policy" 18 "github.com/v2fly/v2ray-core/v5/features/routing" 19 ) 20 21 //go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen 22 23 type TUN struct { 24 ctx context.Context 25 dispatcher routing.Dispatcher 26 policyManager policy.Manager 27 config *Config 28 29 stack *stack.Stack 30 } 31 32 func (t *TUN) Type() interface{} { 33 return (*TUN)(nil) 34 } 35 36 func (t *TUN) Start() error { 37 DeviceConstructor := gvisor.New 38 tunDevice, err := DeviceConstructor(device.Options{ 39 Name: t.config.Name, 40 MTU: t.config.Mtu, 41 }) 42 if err != nil { 43 return newError("failed to create device").Base(err).AtError() 44 } 45 46 if t.config.PacketEncoding != packetaddr.PacketAddrType_None { 47 writer := device.NewLinkWriterToWriter(tunDevice) 48 sorter := tunsorter.NewTunSorter(writer, t.dispatcher, t.config.PacketEncoding, t.ctx) 49 tunDeviceLayered := NewDeviceWithSorter(tunDevice, sorter) 50 tunDevice = tunDeviceLayered 51 } 52 53 stack, err := t.CreateStack(tunDevice) 54 if err != nil { 55 return newError("failed to create stack").Base(err).AtError() 56 } 57 t.stack = stack 58 59 return nil 60 } 61 62 func (t *TUN) Close() error { 63 if t.stack != nil { 64 t.stack.Close() 65 t.stack.Wait() 66 } 67 return nil 68 } 69 70 func (t *TUN) Init(ctx context.Context, config *Config, dispatcher routing.Dispatcher, policyManager policy.Manager) error { 71 t.ctx = ctx 72 t.config = config 73 t.dispatcher = dispatcher 74 t.policyManager = policyManager 75 76 return nil 77 } 78 79 func init() { 80 common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { 81 tun := new(TUN) 82 err := core.RequireFeatures(ctx, func(d routing.Dispatcher, p policy.Manager) error { 83 return tun.Init(ctx, config.(*Config), d, p) 84 }) 85 return tun, err 86 })) 87 }