这段Go代码主要用于配置和管理Windows系统上的网络接口,包括IP地址和路由的设置,并启用防火墙规则。下面逐块分析每个部分的作用:
1. 导入包
import (
"fmt"
"log"
"net/netip"
"time"
"golang.org/x/sys/windows"
"golang.zx2c4.com/wireguard/windows/conf"
"golang.zx2c4.com/wireguard/windows/services"
"golang.zx2c4.com/wireguard/windows/tunnel/firewall"
"golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
)
分析:
fmt
、log
和time
是Go标准库,分别用于格式化字符串、日志记录和时间操作。net/netip
提供IP地址和前缀处理功能。windows
提供与Windows操作系统交互的功能。- 其他包 (
conf
,services
,firewall
,winipcfg
) 是WireGuard项目的相关模块,用于配置网络、管理服务、防火墙规则等。
2. cleanupAddressesOnDisconnectedInterfaces
函数
func cleanupAddressesOnDisconnectedInterfaces(family winipcfg.AddressFamily, addresses []netip.Prefix) {
if len(addresses) == 0 {
return
}
addrHash := make(map[netip.Addr]bool, len(addresses))
for i := range addresses {
addrHash[addresses[i].Addr()] = true
}
interfaces, err := winipcfg.GetAdaptersAddresses(family, winipcfg.GAAFlagDefault)
if err != nil {
return
}
for _, iface := range interfaces {
if iface.OperStatus == winipcfg.IfOperStatusUp {
continue
}
for address := iface.FirstUnicastAddress; address != nil; address = address.Next {
if ip, _ := netip.AddrFromSlice(address.Address.IP()); addrHash[ip] {
prefix := netip.PrefixFrom(ip, int(address.OnLinkPrefixLength))
log.Printf("Cleaning up stale address %s from interface '%s'", prefix.String(), iface.FriendlyName())
iface.LUID.DeleteIPAddress(prefix)
}
}
}
}
分析:
- 此函数用于清理在断开连接的网络接口上存在的旧IP地址。
- 首先创建一个哈希表,存储传入的IP地址。
- 然后获取系统中所有网络接口的地址信息。
- 对于每个断开的接口,如果发现其IP地址在哈希表中存在,则认为是旧地址,并将其删除。
3. configureInterface
函数
func configureInterface(family winipcfg.AddressFamily, conf *conf.Config, luid winipcfg.LUID) error {
retryOnFailure := services.StartedAtBoot()
tryTimes := 0
startOver:
var err error
if tryTimes > 0 {
log.Printf("Retrying interface configuration after failure because system just booted (T+%v): %v", windows.DurationSinceBoot(), err)
time.Sleep(time.Second)
retryOnFailure = retryOnFailure && tryTimes < 15
}
tryTimes++
// ... (略去部分代码)
分析:
- 该函数用于配置指定的网络接口,包括IP地址和路由。
retryOnFailure
判断系统是否在启动时执行,可能需要重试配置。- 通过
startOver
标签实现配置失败后的重试机制。 - 使用循环遍历
conf.Peers
来估算路由数量,并生成路由数据。 - 如果没有关闭路由表的功能,尝试配置路由。
- 处理IP地址配置,遇到已经存在的对象时,会先清理断开连接的接口上的旧地址,再重试配置。
- 还包括配置接口的MTU、路由发现行为、DNS等。
4. enableFirewall
函数
func enableFirewall(conf *conf.Config, luid winipcfg.LUID) error {
doNotRestrict := true
if len(conf.Peers) == 1 && !conf.Interface.TableOff {
for _, allowedip := range conf.Peers[0].AllowedIPs {
if allowedip.Bits() == 0 && allowedip == allowedip.Masked() {
doNotRestrict = false
break
}
}
}
log.Println("Enabling firewall rules")
return firewall.EnableFirewall(uint64(luid), doNotRestrict, conf.Interface.DNS)
}
分析:
- 此函数用于启用防火墙规则。
- 如果配置中只有一个
peer
且没有关闭路由表,则检查是否有允许的IP覆盖整个地址空间(allowedip.Bits() == 0
),若是,则不限制防火墙规则。 - 通过调用
firewall.EnableFirewall
启用防火墙规则。
总结
这段代码的核心是配置和管理Windows系统上的网络接口,主要包括IP地址、路由的设置,以及防火墙规则的启用。它使用了重试机制,以应对系统启动后的特殊情况,并通过清理断开连接的接口上的旧地址,确保配置的准确性。