github.com/Asutorufa/yuhaiin@v0.3.6-0.20240502055049-7984da7023a0/pkg/net/netlink/route_windows.go (about)

     1  package netlink
     2  
     3  import (
     4  	"fmt"
     5  	"log/slog"
     6  	"net/netip"
     7  
     8  	"github.com/Asutorufa/yuhaiin/pkg/log"
     9  	wun "github.com/tailscale/wireguard-go/tun"
    10  	"golang.org/x/sys/windows"
    11  	"golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
    12  )
    13  
    14  func Route(opt *Options) error {
    15  	var device wun.Device
    16  
    17  	if opt.Writer == nil && opt.Endpoint != nil {
    18  		if w, ok := opt.Endpoint.(interface{ Writer() Tun }); ok {
    19  			opt.Writer = w.Writer()
    20  		}
    21  	}
    22  
    23  	if opt.Writer != nil {
    24  		device = opt.Writer.Tun()
    25  	}
    26  
    27  	tt, ok := device.(*wun.NativeTun)
    28  	if !ok {
    29  		return fmt.Errorf("not a native tun device")
    30  	}
    31  
    32  	luid := winipcfg.LUID(tt.LUID())
    33  
    34  	V4Address := opt.V4Address()
    35  	if V4Address.IsValid() {
    36  		if err := setAddress(luid, winipcfg.AddressFamily(windows.AF_INET), V4Address, opt.MTU); err != nil {
    37  			log.Error("set ipv4 address failed", slog.Any("err", err))
    38  		}
    39  	}
    40  
    41  	v6Address := opt.V6Address()
    42  	if v6Address.IsValid() {
    43  		if err := setAddress(luid, winipcfg.AddressFamily(windows.AF_INET6), v6Address, opt.MTU); err != nil {
    44  			log.Error("set ipv6 address failed", slog.Any("err", err))
    45  		}
    46  	}
    47  
    48  	var err error
    49  	for _, v := range opt.Routes {
    50  		if v.Addr().Is4() && opt.V4Address().IsValid() {
    51  			err = luid.AddRoute(v, V4Address.Addr(), 1)
    52  		} else if opt.V6Address().IsValid() {
    53  			err = luid.AddRoute(v, v6Address.Addr(), 1)
    54  		}
    55  		if err != nil {
    56  			log.Error("add route failed", slog.Any("err", err))
    57  		}
    58  	}
    59  
    60  	return nil
    61  }
    62  
    63  func setAddress(luid winipcfg.LUID, family winipcfg.AddressFamily, address netip.Prefix, mtu int) error {
    64  	err := luid.SetIPAddressesForFamily(family, []netip.Prefix{address})
    65  	if err != nil {
    66  		return err
    67  	}
    68  
    69  	err = luid.SetDNS(family, []netip.Addr{address.Addr().Next()}, nil)
    70  	if err != nil {
    71  		return err
    72  	}
    73  
    74  	inetIf, err := luid.IPInterface(family)
    75  	if err != nil {
    76  		return err
    77  	}
    78  
    79  	err = setInetIf(inetIf, mtu)
    80  	if err != nil {
    81  		return err
    82  	}
    83  	return nil
    84  }
    85  
    86  func setInetIf(inetIf *winipcfg.MibIPInterfaceRow, mtu int) error {
    87  	inetIf.ForwardingEnabled = true
    88  	inetIf.RouterDiscoveryBehavior = winipcfg.RouterDiscoveryDisabled
    89  	inetIf.DadTransmits = 0
    90  	inetIf.ManagedAddressConfigurationSupported = false
    91  	inetIf.OtherStatefulConfigurationSupported = false
    92  	inetIf.NLMTU = uint32(mtu)
    93  	inetIf.UseAutomaticMetric = false
    94  	inetIf.Metric = 0
    95  	return inetIf.Set()
    96  }