aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/tunnel/interfacewatcher.go
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2019-10-21 13:32:13 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2019-10-21 13:39:41 +0200
commitab2518f77c565a93bfaa9f5c8179cad0408471cb (patch)
treeb6247ab117c344b33854b206074ae7ec5785a923 /tunnel/interfacewatcher.go
parentbuild: update to go 1.13.3 and remove patcher (diff)
downloadwireguard-windows-ab2518f77c565a93bfaa9f5c8179cad0408471cb.tar.xz
wireguard-windows-ab2518f77c565a93bfaa9f5c8179cad0408471cb.zip
tunnel: blackhole sockets when there's going to be a sure routing loop
This prevents against common mishaps when changing from a wifi network that supports v6 to one that doesn't. Reported-by: Jonathan Tooker <jonathan.tooker@netprotect.com>
Diffstat (limited to 'tunnel/interfacewatcher.go')
-rw-r--r--tunnel/interfacewatcher.go41
1 files changed, 40 insertions, 1 deletions
diff --git a/tunnel/interfacewatcher.go b/tunnel/interfacewatcher.go
index 92d08e90..1f632725 100644
--- a/tunnel/interfacewatcher.go
+++ b/tunnel/interfacewatcher.go
@@ -10,6 +10,7 @@ import (
"sync"
"golang.org/x/sys/windows"
+
"golang.zx2c4.com/wireguard/device"
"golang.zx2c4.com/wireguard/tun"
@@ -41,6 +42,44 @@ type interfaceWatcher struct {
storedEvents []interfaceWatcherEvent
}
+func hasDefaultRoute(family winipcfg.AddressFamily, peers []conf.Peer) bool {
+ var (
+ foundV401 bool
+ foundV41281 bool
+ foundV600001 bool
+ foundV680001 bool
+ foundV400 bool
+ foundV600 bool
+ v40 = [4]byte{}
+ v60 = [16]byte{}
+ v48 = [4]byte{0x80}
+ v68 = [16]byte{0x80}
+ )
+ for _, peer := range peers {
+ for _, allowedip := range peer.AllowedIPs {
+ if allowedip.Cidr == 1 && len(allowedip.IP) == 16 && allowedip.IP.Equal(v60[:]) {
+ foundV600001 = true
+ } else if allowedip.Cidr == 1 && len(allowedip.IP) == 16 && allowedip.IP.Equal(v68[:]) {
+ foundV680001 = true
+ } else if allowedip.Cidr == 1 && len(allowedip.IP) == 4 && allowedip.IP.Equal(v40[:]) {
+ foundV401 = true
+ } else if allowedip.Cidr == 1 && len(allowedip.IP) == 4 && allowedip.IP.Equal(v48[:]) {
+ foundV41281 = true
+ } else if allowedip.Cidr == 0 && len(allowedip.IP) == 16 && allowedip.IP.Equal(v60[:]) {
+ foundV600 = true
+ } else if allowedip.Cidr == 0 && len(allowedip.IP) == 4 && allowedip.IP.Equal(v40[:]) {
+ foundV400 = true
+ }
+ }
+ }
+ if family == windows.AF_INET {
+ return foundV400 || (foundV401 && foundV41281)
+ } else if family == windows.AF_INET6 {
+ return foundV600 || (foundV600001 && foundV680001)
+ }
+ return false
+}
+
func (iw *interfaceWatcher) setup(family winipcfg.AddressFamily) {
var changeCallbacks *[]winipcfg.ChangeCallback
var ipversion string
@@ -62,7 +101,7 @@ func (iw *interfaceWatcher) setup(family winipcfg.AddressFamily) {
var err error
log.Printf("Monitoring default %s routes", ipversion)
- *changeCallbacks, err = monitorDefaultRoutes(family, iw.device, iw.conf.Interface.MTU == 0, iw.tun)
+ *changeCallbacks, err = monitorDefaultRoutes(family, iw.device, iw.conf.Interface.MTU == 0, hasDefaultRoute(family, iw.conf.Peers), iw.tun)
if err != nil {
iw.errors <- interfaceWatcherError{services.ErrorBindSocketsToDefaultRoutes, err}
return