From e0cca2ddd9a1c8f1171d2ec6ae7f603b39a2558e Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Wed, 28 Aug 2019 10:47:19 +0200 Subject: manager: clean stale adapters on startup Signed-off-by: Simon Rozman --- manager/adapters.go | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++ manager/service.go | 1 + 2 files changed, 70 insertions(+) create mode 100644 manager/adapters.go diff --git a/manager/adapters.go b/manager/adapters.go new file mode 100644 index 00000000..5ac16465 --- /dev/null +++ b/manager/adapters.go @@ -0,0 +1,69 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (C) 2019 WireGuard LLC. All Rights Reserved. + */ + +package manager + +import ( + "log" + + "golang.org/x/sys/windows" + "golang.org/x/sys/windows/svc" + "golang.org/x/sys/windows/svc/mgr" + + "golang.zx2c4.com/wireguard/tun/wintun" + "golang.zx2c4.com/wireguard/windows/services" +) + +func cleanStaleAdapters() { + defer printPanic() + + m, err := mgr.Connect() + if err != nil { + log.Printf("Error connecting to Service Control Manager: %v", err) + return + } + defer m.Disconnect() + + wintun.DeleteMatchingInterfaces(func(wintun *wintun.Wintun) bool { + interfaceName, err := wintun.InterfaceName() + if err != nil { + log.Printf("Removing Wintun interface %s because determining interface name failed: %v", wintun.GUID().String(), err) + return true + } + serviceName, err := services.ServiceNameOfTunnel(interfaceName) + if err != nil { + log.Printf("Removing Wintun interface %s because determining tunnel service name failed: %v", interfaceName, err) + return true + } + service, err := m.OpenService(serviceName) + if err == windows.ERROR_SERVICE_DOES_NOT_EXIST { + log.Printf("Removing orphaned Wintun interface %s", interfaceName) + return true + } + if err != nil { + log.Printf("Error opening service %s: %v", serviceName, err) + return false + } + defer service.Close() + config, err := service.Config() + if err != nil { + log.Printf("Error getting service %s configuration: %v", serviceName, err) + return false + } + if config.StartType == mgr.StartAutomatic { + return false + } + status, err := service.Query() + if err != nil { + log.Printf("Error getting service %s status: %v", serviceName, err) + return false + } + if status.State == svc.Stopped { + log.Printf("Removing unused Wintun interface %s", interfaceName) + return true + } + return false + }) +} diff --git a/manager/service.go b/manager/service.go index 3b71bbff..7ab3db16 100644 --- a/manager/service.go +++ b/manager/service.go @@ -247,6 +247,7 @@ func (service *managerService) Execute(args []string, r <-chan svc.ChangeRequest }() } + go cleanStaleAdapters() go checkForUpdates() var sessionsPointer *windows.WTS_SESSION_INFO -- cgit v1.2.3-59-g8ed1b