3
3
* Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved.
4
4
*/
5
5
6
- package manager
6
+ package tunnel
7
7
8
8
import (
9
9
"log"
@@ -12,15 +12,24 @@ import (
12
12
13
13
"golang.org/x/sys/windows"
14
14
"golang.org/x/sys/windows/svc/mgr"
15
+ "golang.zx2c4.com/go118/netip"
16
+ "golang.zx2c4.com/wireguard/windows/conf"
17
+ "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
15
18
)
16
19
17
- func checkForPitfalls () {
20
+ func evaluateStaticPitfalls () {
18
21
go func () {
19
22
pitfallDnsCacheDisabled ()
20
23
pitfallVirtioNetworkDriver ()
21
24
}()
22
25
}
23
26
27
+ func evaluateDynamicPitfalls (family winipcfg.AddressFamily , conf * conf.Config , luid winipcfg.LUID ) {
28
+ go func () {
29
+ pitfallWeakHostSend (family , conf , luid )
30
+ }()
31
+ }
32
+
24
33
func pitfallDnsCacheDisabled () {
25
34
scm , err := mgr .Connect ()
26
35
if err != nil {
@@ -92,3 +101,80 @@ func pitfallVirtioNetworkDriver() {
92
101
return
93
102
}
94
103
}
104
+
105
+ func pitfallWeakHostSend (family winipcfg.AddressFamily , conf * conf.Config , ourLUID winipcfg.LUID ) {
106
+ routingTable , err := winipcfg .GetIPForwardTable2 (family )
107
+ if err != nil {
108
+ return
109
+ }
110
+ type endpointRoute struct {
111
+ addr netip.Addr
112
+ name string
113
+ lowestMetric uint32
114
+ highestCIDR uint8
115
+ weakHostSend bool
116
+ finalIsOurs bool
117
+ }
118
+ endpoints := make ([]endpointRoute , 0 , len (conf .Peers ))
119
+ for _ , peer := range conf .Peers {
120
+ addr , err := netip .ParseAddr (peer .Endpoint .Host )
121
+ if err != nil {
122
+ continue
123
+ }
124
+ endpoints = append (endpoints , endpointRoute {addr : addr , lowestMetric : ^ uint32 (0 )})
125
+ }
126
+ for i := range routingTable {
127
+ var (
128
+ ifrow * winipcfg.MibIfRow2
129
+ ifacerow * winipcfg.MibIPInterfaceRow
130
+ metric uint32
131
+ )
132
+ for j := range endpoints {
133
+ r , e := & routingTable [i ], & endpoints [j ]
134
+ if (e .addr .Is4 () && family != windows .AF_INET ) || (e .addr .Is6 () && family != windows .AF_INET6 ) {
135
+ continue
136
+ }
137
+ if r .DestinationPrefix .PrefixLength < e .highestCIDR {
138
+ continue
139
+ }
140
+ if ! r .DestinationPrefix .Prefix ().Contains (e .addr ) {
141
+ continue
142
+ }
143
+ if ifrow == nil {
144
+ ifrow , err = r .InterfaceLUID .Interface ()
145
+ if err != nil {
146
+ continue
147
+ }
148
+ }
149
+ if ifrow .OperStatus != winipcfg .IfOperStatusUp {
150
+ continue
151
+ }
152
+ if ifacerow == nil {
153
+ ifacerow , err = r .InterfaceLUID .IPInterface (family )
154
+ if err != nil {
155
+ continue
156
+ }
157
+ metric = r .Metric + ifacerow .Metric
158
+ }
159
+ if r .DestinationPrefix .PrefixLength == e .highestCIDR && metric > e .lowestMetric {
160
+ continue
161
+ }
162
+ e .lowestMetric = metric
163
+ e .highestCIDR = r .DestinationPrefix .PrefixLength
164
+ e .finalIsOurs = r .InterfaceLUID == ourLUID
165
+ if ! e .finalIsOurs {
166
+ e .name = ifrow .Alias ()
167
+ e .weakHostSend = ifacerow .ForwardingEnabled || ifacerow .WeakHostSend
168
+ }
169
+ }
170
+ }
171
+ problematicInterfaces := make (map [string ]bool , len (endpoints ))
172
+ for _ , e := range endpoints {
173
+ if e .weakHostSend && e .finalIsOurs {
174
+ problematicInterfaces [e .name ] = true
175
+ }
176
+ }
177
+ for iface := range problematicInterfaces {
178
+ log .Printf ("Warning: the %q interface has Forwarding/WeakHostSend enabled, which will cause routing loops" , iface )
179
+ }
180
+ }
0 commit comments