2023-05-28 00:18:58 -04:00
|
|
|
//go:build !confonly
|
|
|
|
// +build !confonly
|
|
|
|
|
|
|
|
package tun
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2023-10-22 20:44:36 -04:00
|
|
|
|
|
|
|
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
|
|
|
|
2023-05-28 00:18:58 -04:00
|
|
|
core "github.com/v2fly/v2ray-core/v5"
|
|
|
|
"github.com/v2fly/v2ray-core/v5/app/tun/device"
|
2023-05-28 20:34:33 -04:00
|
|
|
"github.com/v2fly/v2ray-core/v5/app/tun/device/gvisor"
|
2023-10-22 20:11:41 -04:00
|
|
|
"github.com/v2fly/v2ray-core/v5/app/tun/tunsorter"
|
2023-05-28 00:18:58 -04:00
|
|
|
"github.com/v2fly/v2ray-core/v5/common"
|
2023-10-22 20:11:41 -04:00
|
|
|
"github.com/v2fly/v2ray-core/v5/common/net/packetaddr"
|
2023-05-28 00:18:58 -04:00
|
|
|
"github.com/v2fly/v2ray-core/v5/features/policy"
|
|
|
|
"github.com/v2fly/v2ray-core/v5/features/routing"
|
|
|
|
)
|
|
|
|
|
|
|
|
//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen
|
|
|
|
|
|
|
|
type TUN struct {
|
|
|
|
ctx context.Context
|
|
|
|
dispatcher routing.Dispatcher
|
|
|
|
policyManager policy.Manager
|
|
|
|
config *Config
|
|
|
|
|
|
|
|
stack *stack.Stack
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *TUN) Type() interface{} {
|
|
|
|
return (*TUN)(nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *TUN) Start() error {
|
2023-05-28 20:34:33 -04:00
|
|
|
DeviceConstructor := gvisor.New
|
2023-10-22 20:11:41 -04:00
|
|
|
tunDevice, err := DeviceConstructor(device.Options{
|
2023-05-28 00:18:58 -04:00
|
|
|
Name: t.config.Name,
|
|
|
|
MTU: t.config.Mtu,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return newError("failed to create device").Base(err).AtError()
|
|
|
|
}
|
|
|
|
|
2023-10-22 20:11:41 -04:00
|
|
|
if t.config.PacketEncoding != packetaddr.PacketAddrType_None {
|
|
|
|
writer := device.NewLinkWriterToWriter(tunDevice)
|
|
|
|
sorter := tunsorter.NewTunSorter(writer, t.dispatcher, t.config.PacketEncoding, t.ctx)
|
|
|
|
tunDeviceLayered := NewDeviceWithSorter(tunDevice, sorter)
|
|
|
|
tunDevice = tunDeviceLayered
|
|
|
|
}
|
|
|
|
|
|
|
|
stack, err := t.CreateStack(tunDevice)
|
2023-05-28 00:18:58 -04:00
|
|
|
if err != nil {
|
|
|
|
return newError("failed to create stack").Base(err).AtError()
|
|
|
|
}
|
|
|
|
t.stack = stack
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *TUN) Close() error {
|
|
|
|
if t.stack != nil {
|
|
|
|
t.stack.Close()
|
|
|
|
t.stack.Wait()
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-05-28 08:21:46 -04:00
|
|
|
func (t *TUN) Init(ctx context.Context, config *Config, dispatcher routing.Dispatcher, policyManager policy.Manager) error {
|
|
|
|
t.ctx = ctx
|
|
|
|
t.config = config
|
|
|
|
t.dispatcher = dispatcher
|
|
|
|
t.policyManager = policyManager
|
|
|
|
|
|
|
|
return nil
|
2023-05-28 00:18:58 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
|
2023-05-28 08:21:46 -04:00
|
|
|
tun := new(TUN)
|
|
|
|
err := core.RequireFeatures(ctx, func(d routing.Dispatcher, p policy.Manager) error {
|
|
|
|
return tun.Init(ctx, config.(*Config), d, p)
|
2023-05-28 00:18:58 -04:00
|
|
|
})
|
2023-05-28 08:21:46 -04:00
|
|
|
return tun, err
|
2023-05-28 00:18:58 -04:00
|
|
|
}))
|
|
|
|
}
|