mirror of
https://gitee.com/konyshe/goodlink.git
synced 2025-09-26 20:51:22 +08:00
167 lines
6.0 KiB
Go
167 lines
6.0 KiB
Go
//go:build windows
|
||
|
||
// Package netstack 提供了基于 WireGuard TUN 设备的网络栈实现
|
||
// 该包实现了虚拟网络接口,允许在用户空间处理网络数据包
|
||
// 主要用于实现 VPN 和网络代理功能
|
||
package netstack
|
||
|
||
import (
|
||
"fmt"
|
||
"sync"
|
||
|
||
"golang.zx2c4.com/wireguard/tun"
|
||
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||
)
|
||
|
||
// Device is the interface that implemented by network layer devices (e.g. tun),
|
||
// and easy to use as stack.LinkEndpoint.
|
||
type Device interface {
|
||
stack.LinkEndpoint
|
||
|
||
// Name returns the current name of the device.
|
||
Name() string
|
||
|
||
// Type returns the driver type of the device.
|
||
Type() string
|
||
}
|
||
|
||
// 常量定义
|
||
const (
|
||
offset = 0 // 数据包偏移量,用于处理TUN_PI头,0表示不使用TUN_PI
|
||
defaultMTU = 0 // 默认MTU值,0表示使用系统自动配置的MTU
|
||
)
|
||
|
||
// TUN 结构体实现了 TUN 设备的核心功能
|
||
// 它封装了 WireGuard 的 TUN 接口和基本的 I/O 操作
|
||
// 该结构体实现了 Device 接口,提供了与网络栈交互的能力
|
||
type TUN struct {
|
||
*Endpoint // 嵌入Endpoint接口,提供网络栈接口功能,实现数据包的收发
|
||
|
||
nt *tun.NativeTun // 原生的 TUN 设备接口,用于与系统TUN设备交互
|
||
mtu uint32 // 最大传输单元,限制单个数据包的最大大小
|
||
name string // TUN 设备名称,用于系统识别
|
||
offset int // 数据包偏移量,用于处理TUN_PI头
|
||
|
||
rSizes []int // 读取数据包大小数组,用于存储每个数据包的实际大小
|
||
rBuffs [][]byte // 读取缓冲区数组,用于存储接收到的数据包
|
||
wBuffs [][]byte // 写入缓冲区数组,用于存储待发送的数据包
|
||
rMutex sync.Mutex // 读取互斥锁,保护并发读取操作
|
||
wMutex sync.Mutex // 写入互斥锁,保护并发写入操作
|
||
}
|
||
|
||
// Open 创建一个新的 TUN 设备
|
||
// 该函数负责初始化TUN设备,设置MTU,并创建必要的端点
|
||
// 参数:
|
||
// - name: TUN 设备名称,用于系统识别
|
||
// - mtu: 最大传输单元大小,如果为 0 则使用系统默认值
|
||
//
|
||
// 返回:
|
||
// - Device: 实现了Device接口的TUN设备
|
||
// - error: 创建过程中的错误信息
|
||
func Open(name string, mtu uint32) (_ Device, err error) {
|
||
// 使用defer和recover处理可能的panic,确保错误被正确捕获和包装
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
err = fmt.Errorf("open tun: %v", r)
|
||
}
|
||
}()
|
||
|
||
// 初始化 TUN 结构体,设置基本参数
|
||
t := &TUN{
|
||
name: name, // 设置设备名称
|
||
mtu: mtu, // 设置MTU值
|
||
offset: offset, // 设置数据包偏移量
|
||
rSizes: make([]int, 1), // 初始化大小为1的数组,用于存储单个数据包大小
|
||
rBuffs: make([][]byte, 1), // 初始化大小为1的数组,用于存储单个接收缓冲区
|
||
wBuffs: make([][]byte, 1), // 初始化大小为1的数组,用于存储单个发送缓冲区
|
||
}
|
||
|
||
// 设置 MTU,如果指定了MTU则使用指定值,否则使用系统默认值
|
||
forcedMTU := defaultMTU
|
||
if t.mtu > 0 {
|
||
forcedMTU = int(t.mtu)
|
||
}
|
||
|
||
// 创建 TUN 设备,使用WireGuard的tun包创建原生TUN接口
|
||
nt, err := tun.CreateTUN(t.name, forcedMTU)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("create tun: %w", err)
|
||
}
|
||
t.nt = nt.(*tun.NativeTun) // 类型断言,确保使用NativeTun实现
|
||
|
||
// 获取实际的 MTU 值,从系统获取TUN设备的实际MTU
|
||
tunMTU, err := nt.MTU()
|
||
if err != nil {
|
||
return nil, fmt.Errorf("get mtu: %w", err)
|
||
}
|
||
t.mtu = uint32(tunMTU) // 更新为系统实际的MTU值
|
||
|
||
// 创建 I/O 端点,用于处理数据包的收发
|
||
ep, err := NewEndpoint(t, t.mtu, offset)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("create endpoint: %w", err)
|
||
}
|
||
t.Endpoint = ep // 设置端点,使TUN设备能够与网络栈交互
|
||
|
||
return t, nil
|
||
}
|
||
|
||
// Read 从 TUN 设备读取数据包
|
||
// 该方法实现了io.Reader接口,用于从TUN设备读取网络数据包
|
||
// 参数:
|
||
// - packet: 用于存储读取到的数据包的缓冲区
|
||
//
|
||
// 返回:
|
||
// - int: 读取的字节数
|
||
// - error: 读取过程中的错误信息
|
||
func (t *TUN) Read(packet []byte) (int, error) {
|
||
t.rMutex.Lock() // 加锁保护并发读取
|
||
defer t.rMutex.Unlock()
|
||
t.rBuffs[0] = packet // 设置接收缓冲区,将传入的缓冲区设置为读取目标
|
||
_, err := t.nt.Read(t.rBuffs, t.rSizes, t.offset) // 从TUN设备读取数据,rSizes[0]将被设置为实际读取的字节数
|
||
return t.rSizes[0], err // 返回读取的字节数和错误
|
||
}
|
||
|
||
// Name 返回 TUN 设备的名称
|
||
// 该方法实现了Device接口的Name方法
|
||
// 返回:
|
||
// - string: TUN设备的名称
|
||
func (t *TUN) Name() string {
|
||
name, _ := t.nt.Name() // 忽略错误,因为设备名称获取失败不影响主要功能
|
||
return name
|
||
}
|
||
|
||
// Close 关闭 TUN 设备
|
||
// 该方法负责清理资源,确保TUN设备和相关端点被正确关闭
|
||
func (t *TUN) Close() {
|
||
defer t.Endpoint.Close() // 确保端点被正确关闭,使用defer确保即使后续操作失败也能关闭端点
|
||
t.nt.Close() // 关闭TUN设备
|
||
}
|
||
|
||
// Write 向 TUN 设备写入数据包
|
||
// 该方法实现了io.Writer接口,用于向TUN设备写入网络数据包
|
||
// 参数:
|
||
// - packet: 要发送的数据包
|
||
//
|
||
// 返回:
|
||
// - int: 写入的字节数
|
||
// - error: 写入过程中的错误信息
|
||
func (t *TUN) Write(packet []byte) (int, error) {
|
||
t.wMutex.Lock() // 加锁保护并发写入
|
||
defer t.wMutex.Unlock()
|
||
t.wBuffs[0] = packet // 设置发送缓冲区,将待发送的数据包放入缓冲区
|
||
return t.nt.Write(t.wBuffs, t.offset) // 向TUN设备写入数据,offset用于处理TUN_PI头
|
||
}
|
||
|
||
// Type 返回设备类型,用于标识这是一个TUN设备
|
||
// 该方法实现了Device接口的Type方法
|
||
// 返回:
|
||
// - string: 设备类型标识符
|
||
func (t *TUN) Type() string {
|
||
return "tun" // 返回固定的设备类型标识符
|
||
}
|
||
|
||
func (t *TUN) GetNt() *tun.NativeTun {
|
||
return t.nt
|
||
}
|