Files
goodlink/netstack/setup_windows.go
kony c7bc4b9c4f u
2025-03-28 17:23:38 +08:00

190 lines
5.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//go:build windows
package netstack
import (
"crypto/tls"
"fmt"
"gogo"
"goodlink/winipcfg"
"io"
"net"
"net/http"
"net/netip"
"time"
"github.com/quic-go/quic-go"
"gvisor.dev/gvisor/pkg/tcpip"
"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
"gvisor.dev/gvisor/pkg/tcpip/stack"
"gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
)
func SetWinTunIP(wintunEP *Device, ip string, mask int, ip2r string, mask2r int) error {
var ipf netip.Prefix
var err error
// 将LUID转换为Windows网络接口标识
// LUID: 本地唯一接口标识符Local Unique Identifier
// 用于唯一标识网络接口,通常用于网络配置和管理
link := winipcfg.LUID((*wintunEP).(*TUN).GetNt().LUID())
// 将IP地址和掩码组合为CIDR格式如192.168.1.1/24
if ipf, err = netip.ParsePrefix(fmt.Sprintf("%s/%d", ip, mask)); err != nil {
return err
}
// 设置接口的主IP地址
if err = link.SetIPAddresses([]netip.Prefix{ipf}); err != nil {
return err
}
if ipf, err = netip.ParsePrefix(fmt.Sprintf("%s/%d", ip2r, mask2r)); err != nil {
return err
}
// 配置路由规则参数
routeData := &winipcfg.RouteData{
Destination: ipf, // 目标网络CIDR格式
NextHop: netip.MustParseAddr(ip), // 下一跳地址本机IP
Metric: 0, // 路由优先级(数值越小优先级越高)
}
// 应用路由配置到网络接口
if err = link.SetRoutes([]*winipcfg.RouteData{
routeData,
}); err != nil {
return err
}
return nil
}
func SetNetStackIP(s *stack.Stack, nicID tcpip.NICID, ip string, mask int, ip2r, mask2r string) error {
// 设置IP地址
// 配置网络接口的IPv4地址为192.168.3.3/24
protocolAddr := tcpip.ProtocolAddress{
Protocol: ipv4.ProtocolNumber,
AddressWithPrefix: tcpip.AddressWithPrefix{
Address: tcpip.AddrFromSlice(net.ParseIP(ip).To4()), // 设置IP地址
PrefixLen: mask, // 设置子网掩码长度
},
}
// 将IP地址添加到网络接口设置为静态配置的主端点
if err := s.AddProtocolAddress(nicID, protocolAddr, stack.AddressProperties{
PEB: stack.CanBePrimaryEndpoint, // 允许作为主端点
ConfigType: stack.AddressConfigStatic, // 使用静态配置
}); err != nil {
return fmt.Errorf("AddProtocolAddress failed: %v", err)
}
// 设置路由
// 配置默认路由将所有192.168.3.0/24网段的流量转发到该接口
subnet, err := tcpip.NewSubnet(
tcpip.AddrFromSlice(net.ParseIP(ip2r).To4()), // 设置目标网段
tcpip.MaskFromBytes(net.ParseIP(mask2r).To4()), // 设置子网掩码
)
if err != nil {
return fmt.Errorf("NewSubnet failed: %v", err)
}
// 设置路由表将指定网段的流量转发到NIC ID 1
s.SetRouteTable([]tcpip.Route{
{
Destination: subnet, // 目标网段
NIC: nicID, // 使用的网络接口
},
})
// 设置网络接口为混杂模式
// 允许接收所有网络数据包,用于网络数据包的转发
s.SetPromiscuousMode(nicID, true)
return nil
}
var (
init_stack_suss = false
netstack_stack *stack.Stack
)
func InitWintunDll() error {
if !gogo.Utils().FileExist("wintun.dll") {
var res []byte
var err error
var resp *http.Response
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true, // 跳过证书验证
},
},
Timeout: 3 * time.Second,
}
if resp, err = client.Get("https://gitee.com/konyshe/goodlink_conf/raw/master/wintun.dll"); err != nil {
return err
}
defer resp.Body.Close()
if res, err = io.ReadAll(resp.Body); err != nil {
return err
}
gogo.Utils().FileAppend("wintun.dll", res)
}
return nil
}
// setupNetstack 初始化并配置网络栈
// 该函数负责创建协议栈、设置网络接口、配置IP地址和路由表
// 返回:
// - *stack.Stack: 配置好的网络栈实例
// - error: 初始化过程中的错误信息
func Start() error {
InitWintunDll()
if init_stack_suss {
return nil
}
//Sudo()
// 创建协议栈
// 创建新的协议栈实例,配置网络层和传输层协议
netstack_stack = stack.New(stack.Options{
NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol}, // 配置IPv4协议
TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol}, // 配置TCP协议
})
// 使用Open函数创建TUN设备设备名称为"GoodLink"MTU为0表示使用系统默认值
wintunEP, err := Open("GoodLink", 1400) //因为要加自定义的头防止超出1500造成不必要的性能损耗
if err != nil {
return fmt.Errorf("请管理员权限运行")
}
SetWinTunIP(&wintunEP, "192.17.19.1", 32, "192.17.19.1", 32)
// 创建网络接口
// 将TUN设备注册到协议栈中使用NIC ID 1
nicID := tcpip.NICID(1)
if err := netstack_stack.CreateNIC(nicID, wintunEP); err != nil {
return fmt.Errorf("设备注册: %v", err)
}
SetNetStackIP(netstack_stack, nicID, "192.17.19.1", 32, "192.17.19.0", "255.255.255.0")
init_stack_suss = true
return nil
}
func SetForWarder(stun_quic_conn quic.Connection) {
// 设置TCP协议处理器
netstack_stack.SetTransportProtocolHandler(tcp.ProtocolNumber, NewTcpForwarder(netstack_stack, stun_quic_conn).HandlePacket)
}
func GetRemoteIP() string {
return "192.17.19.1"
}