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 }