wireguard源码分析(二)

这个代码片段是 WireGuard VPN 在 Windows 平台上的一部分,主要实现了两个功能:一个是启动 WireGuard 隧道服务,另一个是生成密钥对。

导入部分

import (
	"C"
	"crypto/rand"
	"log"
	"path/filepath"
	"unsafe"

	"golang.org/x/crypto/curve25519"
	"golang.org/x/sys/windows"

	"golang.zx2c4.com/wireguard/windows/conf"
	"golang.zx2c4.com/wireguard/windows/tunnel"
)
  • C 是为了使用 cgo(允许 Go 代码与 C 代码互操作)。
  • crypto/rand 用于生成加密随机数。
  • log 提供日志记录功能。
  • path/filepath 处理文件路径。
  • unsafe 用于不安全的指针操作。
  • golang.org/x/crypto/curve25519 是 Go 的 curve25519 库,用于密钥生成和椭圆曲线计算。
  • golang.org/x/sys/windows 包含与 Windows 系统调用和操作相关的函数。
  • golang.zx2c4.com/wireguard/windows/confgolang.zx2c4.com/wireguard/windows/tunnel 是 WireGuard 在 Windows 上的配置和隧道管理模块。

WireGuardTunnelService 函数

//export WireGuardTunnelService
func WireGuardTunnelService(confFile16 *uint16) bool {
	confFile := windows.UTF16PtrToString(confFile16)
	conf.PresetRootDirectory(filepath.Dir(confFile))
	tunnel.UseFixedGUIDInsteadOfDeterministic = true
	err := tunnel.Run(confFile)
	if err != nil {
		log.Printf("Service run error: %v", err)
	}
	return err == nil
}
  • 函数功能:启动 WireGuard 隧道服务。
  • 参数confFile16 是一个指向 UTF-16 编码的配置文件路径的指针。
  • 步骤解析
    1. windows.UTF16PtrToString(confFile16) 将 UTF-16 编码的指针转换为 Go 字符串。
    2. conf.PresetRootDirectory(filepath.Dir(confFile)) 将配置文件所在目录设置为 WireGuard 的根目录。
    3. tunnel.UseFixedGUIDInsteadOfDeterministic = true 强制使用固定的 GUID(全局唯一标识符),而不是基于配置文件内容的确定性 GUID。
    4. tunnel.Run(confFile) 启动 WireGuard 隧道服务,并传入配置文件路径。
    5. 如果运行过程中出现错误,记录错误日志。
    6. 返回 truefalse,表示服务是否成功运行。

WireGuardGenerateKeypair 函数

//export WireGuardGenerateKeypair
func WireGuardGenerateKeypair(publicKey, privateKey *byte) {
	publicKeyArray := (*[32]byte)(unsafe.Pointer(publicKey))
	privateKeyArray := (*[32]byte)(unsafe.Pointer(privateKey))
	n, err := rand.Read(privateKeyArray[:])
	if err != nil || n != len(privateKeyArray) {
		panic("Unable to generate random bytes")
	}
	privateKeyArray[0] &= 248
	privateKeyArray[31] = (privateKeyArray[31] & 127) | 64

	curve25519.ScalarBaseMult(publicKeyArray, privateKeyArray)
}
  • 函数功能:生成一对公私钥。
  • 参数publicKeyprivateKey 是指向字节数组的指针,用于存储生成的公钥和私钥。
  • 步骤解析
    1. publicKeyprivateKey 转换为 [32]byte 数组的指针,以便后续操作。
    2. 使用 rand.Read 生成 32 字节的加密随机数作为私钥。
    3. 如果随机数生成失败,抛出一个 panic。
    4. 对私钥的第一个字节进行 &= 248 操作,确保私钥符合 curve25519 的要求。
    5. 对私钥的最后一个字节进行位运算,确保密钥符合 curve25519 的规范。
    6. 使用 curve25519.ScalarBaseMult 生成对应的公钥。

main 函数

func main() {}
  • 功能:这是一个空的 main 函数。对于 Go 程序来说,main 函数是程序的入口点,但在这个情况下,因为这是一个动态库(通过 cgo 暴露函数),所以 main 函数是空的。

总结

这个代码片段是 WireGuard 在 Windows 平台上的实现。它提供了启动 WireGuard 隧道服务和生成密钥对的功能。通过使用 Windows 特定的系统调用和 WireGuard 的库函数,代码实现了这些功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值