wireguard源码分析(六)

这段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"
)

分析

  • fmtlogtime 是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地址、路由的设置,以及防火墙规则的启用。它使用了重试机制,以应对系统启动后的特殊情况,并通过清理断开连接的接口上的旧地址,确保配置的准确性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值