From 2faf2dcf908f96fccbfacc8e74b68c2cc4a929c7 Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Fri, 22 Mar 2019 15:57:23 +0100 Subject: [PATCH] tun: windows: Make adapter rename asynchronous Signed-off-by: Simon Rozman --- tun/tun_windows.go | 17 +++++++---- tun/wintun/wintun_windows.go | 56 +----------------------------------- 2 files changed, 13 insertions(+), 60 deletions(-) diff --git a/tun/tun_windows.go b/tun/tun_windows.go index 4223190..2d8364d 100644 --- a/tun/tun_windows.go +++ b/tun/tun_windows.go @@ -75,11 +75,18 @@ func CreateTUN(ifname string) (TUNDevice, error) { return nil, err } - err = wt.SetInterfaceName(ifname) - if err != nil { - wt.DeleteInterface(0) - return nil, errors.New("Setting interface name failed: " + err.Error()) - } + go func() { + retries := retryTimeout * retryRate + for { + err := wt.SetInterfaceName(ifname) + if err != nil && retries > 0 { + time.Sleep(time.Second / retryRate) + retries-- + continue + } + return + } + }() err = wt.FlushInterface() if err != nil { diff --git a/tun/wintun/wintun_windows.go b/tun/wintun/wintun_windows.go index 7170686..f2f3684 100644 --- a/tun/wintun/wintun_windows.go +++ b/tun/wintun/wintun_windows.go @@ -297,62 +297,8 @@ func CreateInterface(description string, hwndParent uintptr) (*Wintun, bool, err // Get network interface. DIF_INSTALLDEVICE returns almost immediately, while the device // installation continues in the background. It might take a while, before all registry // keys and values are populated. - getInterface := func() (*Wintun, error) { - // Open HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\\ registry key. - keyDev, err := devInfoList.OpenDevRegKey(deviceData, setupapi.DICS_FLAG_GLOBAL, 0, setupapi.DIREG_DRV, registry.READ) - if err != nil { - return nil, errors.New("Device-specific registry key open failed: " + err.Error()) - } - defer keyDev.Close() - - // Read the NetCfgInstanceId value. - value, err := getRegStringValue(keyDev, "NetCfgInstanceId") - if err != nil { - if errWin, ok := err.(syscall.Errno); ok && errWin == windows.ERROR_FILE_NOT_FOUND { - return nil, err - } - - return nil, errors.New("RegQueryStringValue(\"NetCfgInstanceId\") failed: " + err.Error()) - } - - // Convert to windows.GUID. - ifid, err := guid.FromString(value) - if err != nil { - return nil, fmt.Errorf("NetCfgInstanceId registry value is not a GUID (expected: \"{...}\", provided: %q)", value) - } - - wintun := &Wintun{CfgInstanceID: *ifid} - keyNetName := wintun.GetNetRegKeyName() - keyNet, err := registry.OpenKey(registry.LOCAL_MACHINE, keyNetName, registry.QUERY_VALUE) - if err != nil { - if errWin, ok := err.(syscall.Errno); ok && errWin == windows.ERROR_FILE_NOT_FOUND { - return nil, err - } - - return nil, errors.New(fmt.Sprintf("RegOpenKeyEx(%q) failed: ", keyNetName) + err.Error()) - } - defer keyNet.Close() - - // Query the interface name. - _, valueType, err := keyNet.GetValue("Name", nil) - if err != nil { - if errWin, ok := err.(syscall.Errno); ok && errWin == windows.ERROR_FILE_NOT_FOUND { - return nil, err - } - - return nil, errors.New("RegQueryValueEx(\"Name\") failed: " + err.Error()) - } - switch valueType { - case registry.SZ, registry.EXPAND_SZ: - default: - return nil, fmt.Errorf("Interface name registry value is not REG_SZ or REG_EXPAND_SZ (expected: %v or %v, provided: %v)", registry.SZ, registry.EXPAND_SZ, valueType) - } - - // TUN interface is ready. (As much as we need it.) - return wintun, nil - } for numAttempts := 0; numAttempts < 30; numAttempts++ { - wintun, err = getInterface() + wintun, err = MakeWintun(devInfoList, deviceData) if err != nil { if errWin, ok := err.(syscall.Errno); ok && errWin == windows.ERROR_FILE_NOT_FOUND { // Wait and retry. TODO: Wait for a cancellable event instead.