]> git.ipfire.org Git - thirdparty/wireguard-go.git/commitdiff
wintun: don't retry when not creating
authorJason A. Donenfeld <Jason@zx2c4.com>
Thu, 2 May 2019 21:53:15 +0000 (23:53 +0200)
committerJason A. Donenfeld <Jason@zx2c4.com>
Thu, 2 May 2019 21:53:15 +0000 (23:53 +0200)
The only time we're trying to counteract the race condition is when
we're creating a driver. When we're simply looking up all drivers, it
doesn't make sense to retry.

tun/wintun/registryhacks_windows.go
tun/wintun/wintun_windows.go

index bbcc0207526955c5226affffcb99755dd7e3995a..94cc2f324e38d847e4f1c45ad92b6530a1fa9261 100644 (file)
@@ -11,7 +11,7 @@ import (
 )
 
 const (
-       numRetries = 100
+       numRetries   = 100
        retryTimeout = 150 * time.Millisecond
 )
 
@@ -21,7 +21,7 @@ func registryOpenKeyRetry(k registry.Key, path string, access uint32) (key regis
                if err == nil {
                        break
                }
-               if i != numRetries - 1 {
+               if i != numRetries-1 {
                        time.Sleep(retryTimeout)
                }
        }
@@ -34,7 +34,7 @@ func keyGetStringValueRetry(k registry.Key, name string) (val string, valtype ui
                if err == nil {
                        break
                }
-               if i != numRetries - 1 {
+               if i != numRetries-1 {
                        time.Sleep(retryTimeout)
                }
        }
index eae283bc2c252defce126b143a0b1269767fcaf1..e1b46a838aee11ce7bd25577eabde3a003d3f4fe 100644 (file)
@@ -38,7 +38,7 @@ const machineName = ""
 //
 // MakeWintun creates interface handle and populates it from device registry key
 //
-func MakeWintun(deviceInfoSet setupapi.DevInfo, deviceInfoData *setupapi.DevInfoData) (*Wintun, error) {
+func makeWintun(deviceInfoSet setupapi.DevInfo, deviceInfoData *setupapi.DevInfoData, wait bool) (*Wintun, error) {
        // Open HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\<class>\<id> registry key.
        key, err := deviceInfoSet.OpenDevRegKey(deviceInfoData, setupapi.DICS_FLAG_GLOBAL, 0, setupapi.DIREG_DRV, registry.READ)
        if err != nil {
@@ -50,7 +50,11 @@ func MakeWintun(deviceInfoSet setupapi.DevInfo, deviceInfoData *setupapi.DevInfo
        var valueType uint32
 
        // Read the NetCfgInstanceId value.
-       valueStr, valueType, err = keyGetStringValueRetry(key, "NetCfgInstanceId")
+       if wait {
+               valueStr, valueType, err = keyGetStringValueRetry(key, "NetCfgInstanceId")
+       } else {
+               valueStr, valueType, err = key.GetStringValue("NetCfgInstanceId")
+       }
        if err != nil {
                return nil, errors.New("RegQueryStringValue(\"NetCfgInstanceId\") failed: " + err.Error())
        }
@@ -121,13 +125,14 @@ func GetInterface(ifname string, hwndParent uintptr) (*Wintun, error) {
                }
 
                // Get interface ID.
-               wintun, err := MakeWintun(devInfoList, deviceData)
+               wintun, err := makeWintun(devInfoList, deviceData, false)
                if err != nil {
                        continue
                }
 
+               //TODO: is there a better way than comparing ifnames?
                // Get interface name.
-               ifname2, err := wintun.GetInterfaceName()
+               ifname2, err := wintun.getInterfaceNameNoRetry()
                if err != nil {
                        continue
                }
@@ -301,7 +306,7 @@ func CreateInterface(description string, hwndParent uintptr) (*Wintun, bool, err
                // installation continues in the background. It might take a while, before all registry
                // keys and values are populated.
                for numAttempts := 0; numAttempts < 30; numAttempts++ {
-                       wintun, err = MakeWintun(devInfoList, deviceData)
+                       wintun, err = makeWintun(devInfoList, deviceData, true)
                        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.
@@ -371,7 +376,8 @@ func (wintun *Wintun) DeleteInterface(hwndParent uintptr) (bool, bool, error) {
                }
 
                // Get interface ID.
-               wintun2, err := MakeWintun(devInfoList, deviceData)
+               //TODO: Store some ID in the Wintun object such that this call isn't required.
+               wintun2, err := makeWintun(devInfoList, deviceData, false)
                if err != nil {
                        continue
                }
@@ -446,6 +452,17 @@ func (wintun *Wintun) GetInterfaceName() (string, error) {
        return getRegStringValue(key, "Name")
 }
 
+func (wintun *Wintun) getInterfaceNameNoRetry() (string, error) {
+       key, err := registry.OpenKey(registry.LOCAL_MACHINE, wintun.GetNetRegKeyName(), registry.QUERY_VALUE)
+       if err != nil {
+               return "", errors.New("Network-specific registry key open failed: " + err.Error())
+       }
+       defer key.Close()
+
+       // Get the interface name.
+       return getRegStringValue(key, "Name")
+}
+
 //
 // SetInterfaceName sets network interface name.
 //