@@ -5,10 +5,12 @@ package tun
55import (
66 "crypto/md5"
77 "errors"
8+ "net/netip"
89 "unsafe"
910
1011 "golang.org/x/sys/windows"
1112 "golang.zx2c4.com/wintun"
13+ "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
1214 "gvisor.dev/gvisor/pkg/buffer"
1315 "gvisor.dev/gvisor/pkg/tcpip"
1416 "gvisor.dev/gvisor/pkg/tcpip/stack"
@@ -70,20 +72,79 @@ func open(name string) (*wintun.Adapter, error) {
7072 // generate a deterministic GUID from the adapter name
7173 id := md5 .Sum ([]byte (name ))
7274 guid := (* windows .GUID )(unsafe .Pointer (& id [0 ]))
73- // try to open existing adapter by name
74- adapter , err := wintun .OpenAdapter (name )
75- if err == nil {
76- return adapter , nil
77- }
7875 // try to create adapter anew
79- adapter , err = wintun .CreateAdapter (name , "Xray" , guid )
76+ adapter , err : = wintun .CreateAdapter (name , "Xray" , guid )
8077 if err == nil {
8178 return adapter , nil
8279 }
8380 return nil , err
8481}
8582
8683func (t * WindowsTun ) Start () error {
84+ var has4 , has6 bool
85+ allowedIPs := make ([]netip.Prefix , 0 , len (t .options .WinRoute ))
86+ for _ , route := range t .options .WinRoute {
87+ allowedIPs = append (allowedIPs , netip .MustParsePrefix (route ))
88+ }
89+ routesMap := make (map [winipcfg.RouteData ]struct {})
90+ for _ , ip := range allowedIPs {
91+ route := winipcfg.RouteData {
92+ Destination : ip .Masked (),
93+ Metric : 0 ,
94+ }
95+ if ip .Addr ().Is4 () {
96+ has4 = true
97+ route .NextHop = netip .IPv4Unspecified ()
98+ } else {
99+ has6 = true
100+ route .NextHop = netip .IPv6Unspecified ()
101+ }
102+ routesMap [route ] = struct {}{}
103+ }
104+ routesData := make ([]* winipcfg.RouteData , 0 , len (routesMap ))
105+ for route := range routesMap {
106+ r := route
107+ routesData = append (routesData , & r )
108+ }
109+ luid := winipcfg .LUID (t .adapter .LUID ())
110+ err := luid .SetRoutes (routesData )
111+ if err != nil {
112+ return err
113+ }
114+ if has4 {
115+ ipif , err := luid .IPInterface (windows .AF_INET )
116+ if err != nil {
117+ return err
118+ }
119+ ipif .RouterDiscoveryBehavior = winipcfg .RouterDiscoveryDisabled
120+ ipif .DadTransmits = 0
121+ ipif .ManagedAddressConfigurationSupported = false
122+ ipif .OtherStatefulConfigurationSupported = false
123+ ipif .NLMTU = t .options .MTU
124+ ipif .UseAutomaticMetric = false
125+ ipif .Metric = 0
126+ err = ipif .Set ()
127+ if err != nil {
128+ return err
129+ }
130+ }
131+ if has6 {
132+ ipif , err := luid .IPInterface (windows .AF_INET6 )
133+ if err != nil {
134+ return err
135+ }
136+ ipif .RouterDiscoveryBehavior = winipcfg .RouterDiscoveryDisabled
137+ ipif .DadTransmits = 0
138+ ipif .ManagedAddressConfigurationSupported = false
139+ ipif .OtherStatefulConfigurationSupported = false
140+ ipif .NLMTU = t .options .MTU
141+ ipif .UseAutomaticMetric = false
142+ ipif .Metric = 0
143+ err = ipif .Set ()
144+ if err != nil {
145+ return err
146+ }
147+ }
87148 return nil
88149}
89150
0 commit comments