aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
authorJason A. Donenfeld <Jason@zx2c4.com>2021-09-14 12:23:07 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2021-09-14 12:24:17 +0200
commiteca2bc860abefa580c32f6452bc6598799106db6 (patch)
tree7660537a8a627ec5f7387660e7484d4c349cb4e3
parentversion: bump (diff)
downloadwireguard-windows-eca2bc860abefa580c32f6452bc6598799106db6.tar.xz
wireguard-windows-eca2bc860abefa580c32f6452bc6598799106db6.zip
tunnel: reinitialize configuration after PnP flaps driver on <10
On older Windows, PnP will unload the driver and reload it. This makes multiple tunnels impossible, as we knew. But this also happens when various adapter settings change, like ICS, which is maybe a bigger issue. Solve this by reloading the configuration after these flaps. Reported-by: Harland Coles <harland.coles@energy-x.com> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-rw-r--r--manager/ipc_server.go3
-rw-r--r--tunnel/interfacewatcher.go20
-rw-r--r--tunnel/service.go4
3 files changed, 21 insertions, 6 deletions
diff --git a/manager/ipc_server.go b/manager/ipc_server.go
index de97ffb1..48db057e 100644
--- a/manager/ipc_server.go
+++ b/manager/ipc_server.go
@@ -113,14 +113,13 @@ func (s *ManagerService) Start(tunnelName string) error {
return err
}
- maj, _, _ := windows.RtlGetNtVersionNumbers()
// Figure out which tunnels have intersecting addresses/routes and stop those.
trackedTunnelsLock.Lock()
tt := make([]string, 0, len(trackedTunnels))
var inTransition string
for t, state := range trackedTunnels {
c2, err := conf.LoadFromName(t)
- if maj >= 10 && (err != nil || !c.IntersectsWith(c2)) {
+ if err != nil || !c.IntersectsWith(c2) {
// If we can't get the config, assume it doesn't intersect.
continue
}
diff --git a/tunnel/interfacewatcher.go b/tunnel/interfacewatcher.go
index 1abc021d..4e28a6a2 100644
--- a/tunnel/interfacewatcher.go
+++ b/tunnel/interfacewatcher.go
@@ -11,6 +11,7 @@ import (
"sync"
"golang.org/x/sys/windows"
+ "golang.zx2c4.com/wireguard/windows/driver"
"golang.zx2c4.com/wireguard/conn"
"golang.zx2c4.com/wireguard/windows/conf"
@@ -33,6 +34,7 @@ type interfaceWatcher struct {
binder conn.BindSocketToInterface
clamper mtuClamper
conf *conf.Config
+ adapter *driver.Adapter
luid winipcfg.LUID
setupMutex sync.Mutex
@@ -144,6 +146,20 @@ func watchInterface() (*interfaceWatcher, error) {
return
}
iw.setup(iface.Family)
+
+ if iw.adapter != nil {
+ if state, err := iw.adapter.AdapterState(); err == nil && state == driver.AdapterStateDown {
+ log.Println("Reinitializing adapter configuration")
+ err = iw.adapter.SetConfiguration(iw.conf.ToDriverConfiguration())
+ if err != nil {
+ log.Println(fmt.Errorf("%v: %w", services.ErrorDeviceSetConfig, err))
+ }
+ err = iw.adapter.SetAdapterState(driver.AdapterStateUp)
+ if err != nil {
+ log.Println(fmt.Errorf("%v: %w", services.ErrorDeviceBringUp, err))
+ }
+ }
+ }
})
if err != nil {
return nil, fmt.Errorf("unable to register interface change callback: %w", err)
@@ -151,11 +167,11 @@ func watchInterface() (*interfaceWatcher, error) {
return iw, nil
}
-func (iw *interfaceWatcher) Configure(binder conn.BindSocketToInterface, clamper mtuClamper, conf *conf.Config, luid winipcfg.LUID) {
+func (iw *interfaceWatcher) Configure(binder conn.BindSocketToInterface, clamper mtuClamper, adapter *driver.Adapter, conf *conf.Config, luid winipcfg.LUID) {
iw.setupMutex.Lock()
defer iw.setupMutex.Unlock()
- iw.binder, iw.clamper, iw.conf, iw.luid = binder, clamper, conf, luid
+ iw.binder, iw.clamper, iw.adapter, iw.conf, iw.luid = binder, clamper, adapter, conf, luid
for _, event := range iw.storedEvents {
if event.luid == luid {
iw.setup(event.family)
diff --git a/tunnel/service.go b/tunnel/service.go
index 9df4fecc..decfb571 100644
--- a/tunnel/service.go
+++ b/tunnel/service.go
@@ -276,7 +276,7 @@ func (service *tunnelService) Execute(args []string, r <-chan svc.ChangeRequest,
var clamper mtuClamper
clamper = nativeTun
- watcher.Configure(bind.(conn.BindSocketToInterface), clamper, config, luid)
+ watcher.Configure(bind.(conn.BindSocketToInterface), clamper, nil, config, luid)
log.Println("Listening for UAPI requests")
go func() {
@@ -298,7 +298,7 @@ func (service *tunnelService) Execute(args []string, r <-chan svc.ChangeRequest,
if err != nil {
serviceError = services.ErrorDeviceBringUp
}
- watcher.Configure(nil, nil, config, luid)
+ watcher.Configure(nil, nil, adapter, config, luid)
}
err = runScriptCommand(config.Interface.PostUp, config.Name)