aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--docs/enterprise.md8
-rw-r--r--driver/driver_windows.go150
-rw-r--r--installer/customactions.c2
-rw-r--r--main.go12
-rw-r--r--manager/interfacecleanup.go33
-rw-r--r--manager/ipc_driver.go2
-rw-r--r--manager/ipc_server.go10
-rw-r--r--manager/service.go4
-rw-r--r--tunnel/service.go15
9 files changed, 54 insertions, 182 deletions
diff --git a/docs/enterprise.md b/docs/enterprise.md
index fbbbc13a..ce35d7d4 100644
--- a/docs/enterprise.md
+++ b/docs/enterprise.md
@@ -89,16 +89,16 @@ One could have Task Scheduler run it daily at 3am:
> schtasks /create /f /ru SYSTEM /sc daily /tn "WireGuard Update" /tr "%PROGRAMFILES%\WireGuard\wireguard.exe /update" /st 03:00
```
-### Network Adapters
+### Driver Removal
-The tunnel service creates a network adapter at startup and destroys it at shutdown. It may be desirable, however, to remove all network adapters created in WireGuard's pool and uninstall the driver if no other applications are using our network adapters. This can be accomplished using the command:
+The tunnel service creates a network adapter at startup and destroys it at shutdown. If there are no more network adapters, the driver may be removed with:
```text
-> wireguard /removealladapters
+> wireguard /removedriver
```
Or, to log the status of that command:
```text
-> wireguard /removealladapters 2> C:\path\to\removal\log.txt
+> wireguard /removedriver 2> C:\path\to\removal\log.txt
```
diff --git a/driver/driver_windows.go b/driver/driver_windows.go
index 749fb3e8..3bc838bf 100644
--- a/driver/driver_windows.go
+++ b/driver/driver_windows.go
@@ -6,7 +6,6 @@
package driver
import (
- "errors"
"log"
"runtime"
"syscall"
@@ -25,12 +24,8 @@ const (
logErr
)
-const (
- PoolNameMax = 256
- AdapterNameMax = 128
-)
+const AdapterNameMax = 128
-type Pool [PoolNameMax]uint16
type Adapter struct {
handle uintptr
lastGetGuessSize uint32
@@ -38,17 +33,12 @@ type Adapter struct {
var (
modwireguard = newLazyDLL("wireguard.dll", setupLogger)
-
procWireGuardCreateAdapter = modwireguard.NewProc("WireGuardCreateAdapter")
- procWireGuardDeleteAdapter = modwireguard.NewProc("WireGuardDeleteAdapter")
- procWireGuardDeletePoolDriver = modwireguard.NewProc("WireGuardDeletePoolDriver")
- procWireGuardEnumAdapters = modwireguard.NewProc("WireGuardEnumAdapters")
- procWireGuardFreeAdapter = modwireguard.NewProc("WireGuardFreeAdapter")
procWireGuardOpenAdapter = modwireguard.NewProc("WireGuardOpenAdapter")
+ procWireGuardCloseAdapter = modwireguard.NewProc("WireGuardCloseAdapter")
+ procWireGuardDeleteDriver = modwireguard.NewProc("WireGuardDeleteDriver")
procWireGuardGetAdapterLUID = modwireguard.NewProc("WireGuardGetAdapterLUID")
- procWireGuardGetAdapterName = modwireguard.NewProc("WireGuardGetAdapterName")
procWireGuardGetRunningDriverVersion = modwireguard.NewProc("WireGuardGetRunningDriverVersion")
- procWireGuardSetAdapterName = modwireguard.NewProc("WireGuardSetAdapterName")
procWireGuardSetAdapterLogging = modwireguard.NewProc("WireGuardSetAdapterLogging")
)
@@ -75,129 +65,66 @@ func setupLogger(dll *lazyDLL) {
syscall.Syscall(dll.NewProc("WireGuardSetLogger").Addr(), 1, callback, 0, 0)
}
-var DefaultPool, _ = MakePool("WireGuard")
+func closeAdapter(wireguard *Adapter) {
+ syscall.Syscall(procWireGuardCloseAdapter.Addr(), 1, wireguard.handle, 0, 0)
+}
-// MakePool creates a driver pool for creating adapters.
-func MakePool(poolName string) (pool *Pool, err error) {
- poolName16, err := windows.UTF16FromString(poolName)
+// CreateAdapter creates a WireGuard adapter. name is the cosmetic name of the adapter.
+// tunnelType represents the type of adapter and should be "WireGuard". requestedGUID is
+// the GUID of the created network adapter, which then influences NLA generation
+// deterministically. If it is set to nil, the GUID is chosen by the system at random,
+// and hence a new NLA entry is created for each new adapter.
+func CreateAdapter(name string, tunnelType string, requestedGUID *windows.GUID) (wireguard *Adapter, err error) {
+ var name16 *uint16
+ name16, err = windows.UTF16PtrFromString(name)
if err != nil {
return
}
- if len(poolName16) > PoolNameMax {
- err = errors.New("Pool name too long")
- return
- }
- pool = &Pool{}
- copy(pool[:], poolName16)
- return
-}
-
-// String returns the name of the pool.
-func (pool *Pool) String() string {
- return windows.UTF16ToString(pool[:])
-}
-
-func freeAdapter(wireguard *Adapter) {
- syscall.Syscall(procWireGuardFreeAdapter.Addr(), 1, wireguard.handle, 0, 0)
-}
-
-// OpenAdapter finds a WireGuard adapter by its name. This function returns the adapter if found, or
-// windows.ERROR_FILE_NOT_FOUND otherwise. If the adapter is found but not a WireGuard-class or a
-// member of the pool, this function returns windows.ERROR_ALREADY_EXISTS. The adapter must be
-// released after use.
-func (pool *Pool) OpenAdapter(ifname string) (wireguard *Adapter, err error) {
- ifname16, err := windows.UTF16PtrFromString(ifname)
+ var tunnelType16 *uint16
+ tunnelType16, err = windows.UTF16PtrFromString(tunnelType)
if err != nil {
- return nil, err
+ return
}
- r0, _, e1 := syscall.Syscall(procWireGuardOpenAdapter.Addr(), 2, uintptr(unsafe.Pointer(pool)), uintptr(unsafe.Pointer(ifname16)), 0)
+ r0, _, e1 := syscall.Syscall(procWireGuardCreateAdapter.Addr(), 3, uintptr(unsafe.Pointer(name16)), uintptr(unsafe.Pointer(tunnelType16)), uintptr(unsafe.Pointer(requestedGUID)))
if r0 == 0 {
err = e1
return
}
wireguard = &Adapter{handle: r0}
- runtime.SetFinalizer(wireguard, freeAdapter)
+ runtime.SetFinalizer(wireguard, closeAdapter)
return
}
-// CreateAdapter creates a WireGuard adapter. ifname is the requested name of the adapter, while
-// requestedGUID is the GUID of the created network adapter, which then influences NLA generation
-// deterministically. If it is set to nil, the GUID is chosen by the system at random, and hence a
-// new NLA entry is created for each new adapter. It is called "requested" GUID because the API it
-// uses is completely undocumented, and so there could be minor interesting complications with its
-// usage. This function returns the network adapter ID and a flag if reboot is required.
-func (pool *Pool) CreateAdapter(ifname string, requestedGUID *windows.GUID) (wireguard *Adapter, rebootRequired bool, err error) {
- var ifname16 *uint16
- ifname16, err = windows.UTF16PtrFromString(ifname)
+// OpenAdapter opens an existing WireGuard adapter by name.
+func OpenAdapter(name string) (wireguard *Adapter, err error) {
+ var name16 *uint16
+ name16, err = windows.UTF16PtrFromString(name)
if err != nil {
return
}
- var _p0 uint32
- r0, _, e1 := syscall.Syscall6(procWireGuardCreateAdapter.Addr(), 4, uintptr(unsafe.Pointer(pool)), uintptr(unsafe.Pointer(ifname16)), uintptr(unsafe.Pointer(requestedGUID)), uintptr(unsafe.Pointer(&_p0)), 0, 0)
- rebootRequired = _p0 != 0
+ r0, _, e1 := syscall.Syscall(procWireGuardOpenAdapter.Addr(), 1, uintptr(unsafe.Pointer(name16)), 0, 0)
if r0 == 0 {
err = e1
return
}
wireguard = &Adapter{handle: r0}
- runtime.SetFinalizer(wireguard, freeAdapter)
+ runtime.SetFinalizer(wireguard, closeAdapter)
return
}
-// Delete deletes a WireGuard adapter. This function succeeds if the adapter was not found. It returns
-// a bool indicating whether a reboot is required.
-func (wireguard *Adapter) Delete() (rebootRequired bool, err error) {
- var _p0 uint32
- r1, _, e1 := syscall.Syscall(procWireGuardDeleteAdapter.Addr(), 2, wireguard.handle, uintptr(unsafe.Pointer(&_p0)), 0)
- rebootRequired = _p0 != 0
+// Close closes a WireGuard adapter.
+func (wireguard *Adapter) Close() (err error) {
+ runtime.SetFinalizer(wireguard, nil)
+ r1, _, e1 := syscall.Syscall(procWireGuardCloseAdapter.Addr(), 1, wireguard.handle, 0, 0)
if r1 == 0 {
err = e1
}
return
}
-// DeleteMatchingAdapters deletes all WireGuard adapters, which match
-// given criteria, and returns which ones it deleted, whether a reboot
-// is required after, and which errors occurred during the process.
-func (pool *Pool) DeleteMatchingAdapters(matches func(adapter *Adapter) bool) (rebootRequired bool, errors []error) {
- cb := func(handle uintptr, _ uintptr) int {
- adapter := &Adapter{handle: handle}
- if !matches(adapter) {
- return 1
- }
- rebootRequired2, err := adapter.Delete()
- if err != nil {
- errors = append(errors, err)
- return 1
- }
- rebootRequired = rebootRequired || rebootRequired2
- return 1
- }
- r1, _, e1 := syscall.Syscall(procWireGuardEnumAdapters.Addr(), 3, uintptr(unsafe.Pointer(pool)), uintptr(windows.NewCallback(cb)), 0)
- if r1 == 0 {
- errors = append(errors, e1)
- }
- return
-}
-
-// Name returns the name of the WireGuard adapter.
-func (wireguard *Adapter) Name() (ifname string, err error) {
- var ifname16 [AdapterNameMax]uint16
- r1, _, e1 := syscall.Syscall(procWireGuardGetAdapterName.Addr(), 2, wireguard.handle, uintptr(unsafe.Pointer(&ifname16[0])), 0)
- if r1 == 0 {
- err = e1
- return
- }
- ifname = windows.UTF16ToString(ifname16[:])
- return
-}
-
-// DeleteDriver deletes all WireGuard adapters in a pool and if there are no more adapters in any other
-// pools, also removes WireGuard from the driver store, usually called by uninstallers.
-func (pool *Pool) DeleteDriver() (rebootRequired bool, err error) {
- var _p0 uint32
- r1, _, e1 := syscall.Syscall(procWireGuardDeletePoolDriver.Addr(), 2, uintptr(unsafe.Pointer(pool)), uintptr(unsafe.Pointer(&_p0)), 0)
- rebootRequired = _p0 != 0
+// Uninstall removes the driver from the system if no drivers are currently in use.
+func Uninstall() (err error) {
+ r1, _, e1 := syscall.Syscall(procWireGuardDeleteDriver.Addr(), 0, 0, 0, 0)
if r1 == 0 {
err = e1
}
@@ -205,19 +132,6 @@ func (pool *Pool) DeleteDriver() (rebootRequired bool, err error) {
}
-// SetName sets name of the WireGuard adapter.
-func (wireguard *Adapter) SetName(ifname string) (err error) {
- ifname16, err := windows.UTF16FromString(ifname)
- if err != nil {
- return err
- }
- r1, _, e1 := syscall.Syscall(procWireGuardSetAdapterName.Addr(), 2, wireguard.handle, uintptr(unsafe.Pointer(&ifname16[0])), 0)
- if r1 == 0 {
- err = e1
- }
- return
-}
-
type AdapterLogState uint32
const (
diff --git a/installer/customactions.c b/installer/customactions.c
index 7c6a528e..b16e9aa4 100644
--- a/installer/customactions.c
+++ b/installer/customactions.c
@@ -519,7 +519,7 @@ __declspec(dllexport) UINT __stdcall RemoveAdapters(MSIHANDLE installer)
log_errorf(installer, LOG_LEVEL_WARN, GetLastError(), TEXT("SetHandleInformation failed"));
goto cleanup_pipe_w;
}
- if (!CreateProcess(path, TEXT("wireguard /removealladapters"), NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
+ if (!CreateProcess(path, TEXT("wireguard /removedriver"), NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
log_errorf(installer, LOG_LEVEL_WARN, GetLastError(), TEXT("Failed to create \"%1\" process"), path);
goto cleanup_pipe_w;
}
diff --git a/main.go b/main.go
index 6eb5c428..b9936c44 100644
--- a/main.go
+++ b/main.go
@@ -75,7 +75,7 @@ func usage() {
"/ui CMD_READ_HANDLE CMD_WRITE_HANDLE CMD_EVENT_HANDLE LOG_MAPPING_HANDLE",
"/dumplog",
"/update",
- "/removealladapters",
+ "/removedriver",
}
builder := strings.Builder{}
for _, flag := range flags {
@@ -315,23 +315,19 @@ func main() {
}
}
return
- case "/removealladapters":
+ case "/removedriver":
if len(os.Args) != 2 {
usage()
}
- var rebootRequiredDriver, rebootRequiredWintun bool
var err error
- rebootRequiredDriver, err = driver.DefaultPool.DeleteDriver()
+ err = driver.Uninstall()
if err != nil {
fatal(err)
}
- rebootRequiredWintun, err = tun.WintunPool.DeleteDriver()
+ _, err = tun.WintunPool.DeleteDriver()
if err != nil {
fatal(err)
}
- if rebootRequiredWintun || rebootRequiredDriver {
- log.Println("A reboot may be required")
- }
return
}
usage()
diff --git a/manager/interfacecleanup.go b/manager/interfacecleanup.go
index 007c94d7..96c4aad6 100644
--- a/manager/interfacecleanup.go
+++ b/manager/interfacecleanup.go
@@ -13,47 +13,16 @@ import (
"golang.org/x/sys/windows/svc/mgr"
"golang.zx2c4.com/wireguard/tun"
"golang.zx2c4.com/wireguard/tun/wintun"
- "golang.zx2c4.com/wireguard/windows/driver"
"golang.zx2c4.com/wireguard/windows/services"
)
-func cleanupStaleNetworkInterfaces() {
+func cleanupStaleWintunInterfaces() {
m, err := mgr.Connect()
if err != nil {
return
}
defer m.Disconnect()
- driver.DefaultPool.DeleteMatchingAdapters(func(wintun *driver.Adapter) bool {
- interfaceName, err := wintun.Name()
- if err != nil {
- log.Printf("Removing network adapter because determining interface name failed: %v", err)
- return true
- }
- serviceName, err := services.ServiceNameOfTunnel(interfaceName)
- if err != nil {
- log.Printf("Removing network adapter ‘%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 network adapter ‘%s’ because no service for it exists", interfaceName)
- return true
- } else if err != nil {
- return false
- }
- defer service.Close()
- status, err := service.Query()
- if err != nil {
- return false
- }
- if status.State == svc.Stopped {
- log.Printf("Removing network adapter ‘%s’ because its service is stopped", interfaceName)
- return true
- }
- return false
- })
-
tun.WintunPool.DeleteMatchingAdapters(func(adapter *wintun.Adapter) bool {
interfaceName, err := adapter.Name()
if err != nil {
diff --git a/manager/ipc_driver.go b/manager/ipc_driver.go
index dae213de..2155207b 100644
--- a/manager/ipc_driver.go
+++ b/manager/ipc_driver.go
@@ -37,7 +37,7 @@ func findDriverAdapter(tunnelName string) (*lockedDriverAdapter, error) {
}
driverAdapter = &lockedDriverAdapter{}
var err error
- driverAdapter.Adapter, err = driver.DefaultPool.OpenAdapter(tunnelName)
+ driverAdapter.Adapter, err = driver.OpenAdapter(tunnelName)
if err != nil {
return nil, err
}
diff --git a/manager/ipc_server.go b/manager/ipc_server.go
index 48db057e..a8c8064b 100644
--- a/manager/ipc_server.go
+++ b/manager/ipc_server.go
@@ -148,8 +148,9 @@ func (s *ManagerService) Start(tunnelName string) error {
}
}
}()
- time.AfterFunc(time.Second*10, cleanupStaleNetworkInterfaces)
-
+ if conf.AdminBool("UseUserspaceImplementation") {
+ time.AfterFunc(time.Second*10, cleanupStaleWintunInterfaces)
+ }
// After the stop process has begun, but before it's finished, we install the new one.
path, err := c.Path()
if err != nil {
@@ -159,8 +160,9 @@ func (s *ManagerService) Start(tunnelName string) error {
}
func (s *ManagerService) Stop(tunnelName string) error {
- time.AfterFunc(time.Second*10, cleanupStaleNetworkInterfaces)
-
+ if conf.AdminBool("UseUserspaceImplementation") {
+ time.AfterFunc(time.Second*10, cleanupStaleWintunInterfaces)
+ }
err := UninstallTunnel(tunnelName)
if err == windows.ERROR_SERVICE_DOES_NOT_EXIST {
_, notExistsError := conf.LoadFromName(tunnelName)
diff --git a/manager/service.go b/manager/service.go
index 1deb50a4..2b553793 100644
--- a/manager/service.go
+++ b/manager/service.go
@@ -261,7 +261,9 @@ func (service *managerService) Execute(args []string, r <-chan svc.ChangeRequest
}()
}
- time.AfterFunc(time.Second*10, cleanupStaleNetworkInterfaces)
+ if conf.AdminBool("UseUserspaceImplementation") {
+ time.AfterFunc(time.Second*10, cleanupStaleWintunInterfaces)
+ }
time.AfterFunc(time.Second*15, func() {
if !conf.AdminBool("UseUserspaceImplementation") {
tun.WintunPool.DeleteDriver()
diff --git a/tunnel/service.go b/tunnel/service.go
index 9d5631ed..2872fd71 100644
--- a/tunnel/service.go
+++ b/tunnel/service.go
@@ -101,7 +101,7 @@ func (service *tunnelService) Execute(args []string, r <-chan svc.ChangeRequest,
dev.Close()
}
if adapter != nil {
- adapter.Delete()
+ adapter.Close()
}
if logErr == nil && (dev != nil || adapter != nil) && config != nil {
_ = runScriptCommand(config.Interface.PostDown, config.Name)
@@ -167,24 +167,13 @@ func (service *tunnelService) Execute(args []string, r <-chan svc.ChangeRequest,
log.Println("Creating network adapter")
if UseFixedGUIDInsteadOfDeterministic || !conf.AdminBool("UseUserspaceImplementation") {
- // Does an adapter with this name already exist?
- adapter, err = driver.DefaultPool.OpenAdapter(config.Name)
- if err == nil {
- // If so, we delete it, in case it has weird residual configuration.
- _, err = adapter.Delete()
- if err != nil {
- err = fmt.Errorf("Error deleting already existing adapter: %w", err)
- serviceError = services.ErrorCreateNetworkAdapter
- return
- }
- }
for i := 0; i < 5; i++ {
if i > 0 {
time.Sleep(time.Second)
log.Printf("Retrying adapter creation after failure because system just booted (T+%v): %v", windows.DurationSinceBoot(), err)
}
var rebootRequired bool
- adapter, rebootRequired, err = driver.DefaultPool.CreateAdapter(config.Name, deterministicGUID(config))
+ adapter, err = driver.CreateAdapter(config.Name, "WireGuard", deterministicGUID(config))
if err == nil || windows.DurationSinceBoot() > time.Minute*10 {
if rebootRequired {
log.Println("Windows indicated a reboot is required.")