wintun: add more retry loops
This commit is contained in:
parent
2e0ed4614a
commit
92f8474832
@ -75,18 +75,11 @@ func CreateTUN(ifname string) (TUNDevice, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
err = wt.SetInterfaceName(ifname)
|
||||||
retries := retryTimeout * retryRate
|
if err != nil {
|
||||||
for {
|
wt.DeleteInterface(0)
|
||||||
err := wt.SetInterfaceName(ifname)
|
return nil, err
|
||||||
if err != nil && retries > 0 {
|
}
|
||||||
time.Sleep(time.Second / retryRate)
|
|
||||||
retries--
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
err = wt.FlushInterface()
|
err = wt.FlushInterface()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
42
tun/wintun/registryhacks_windows.go
Normal file
42
tun/wintun/registryhacks_windows.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 WireGuard LLC. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package wintun
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/sys/windows/registry"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
numRetries = 25
|
||||||
|
retryTimeout = 100 * time.Millisecond
|
||||||
|
)
|
||||||
|
|
||||||
|
func registryOpenKeyRetry(k registry.Key, path string, access uint32) (key registry.Key, err error) {
|
||||||
|
for i := 0; i < numRetries; i++ {
|
||||||
|
key, err = registry.OpenKey(k, path, access)
|
||||||
|
if err == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if i != numRetries - 1 {
|
||||||
|
time.Sleep(retryTimeout)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func keyGetStringValueRetry(k registry.Key, name string) (val string, valtype uint32, err error) {
|
||||||
|
for i := 0; i < numRetries; i++ {
|
||||||
|
val, valtype, err = k.GetStringValue(name)
|
||||||
|
if err == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if i != numRetries - 1 {
|
||||||
|
time.Sleep(retryTimeout)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
@ -48,22 +48,14 @@ func MakeWintun(deviceInfoSet setupapi.DevInfo, deviceInfoData *setupapi.DevInfo
|
|||||||
var valueStr string
|
var valueStr string
|
||||||
var valueType uint32
|
var valueType uint32
|
||||||
|
|
||||||
//TODO: Figure out a way to not need to loop like this.
|
// Read the NetCfgInstanceId value.
|
||||||
for i := 0; i < 30; i++ {
|
valueStr, valueType, err = keyGetStringValueRetry(key, "NetCfgInstanceId")
|
||||||
// Read the NetCfgInstanceId value.
|
|
||||||
valueStr, valueType, err = key.GetStringValue("NetCfgInstanceId")
|
|
||||||
if err != nil {
|
|
||||||
time.Sleep(time.Millisecond * 100)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if valueType != registry.SZ {
|
|
||||||
return nil, fmt.Errorf("NetCfgInstanceId registry value is not REG_SZ (expected: %v, provided: %v)", registry.SZ, valueType)
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.New("RegQueryStringValue(\"NetCfgInstanceId\") failed: " + err.Error())
|
return nil, errors.New("RegQueryStringValue(\"NetCfgInstanceId\") failed: " + err.Error())
|
||||||
}
|
}
|
||||||
|
if valueType != registry.SZ {
|
||||||
|
return nil, fmt.Errorf("NetCfgInstanceId registry value is not REG_SZ (expected: %v, provided: %v)", registry.SZ, valueType)
|
||||||
|
}
|
||||||
|
|
||||||
// Convert to windows.GUID.
|
// Convert to windows.GUID.
|
||||||
ifid, err := guid.FromString(valueStr)
|
ifid, err := guid.FromString(valueStr)
|
||||||
@ -117,7 +109,6 @@ func GetInterface(ifname string, hwndParent uintptr) (*Wintun, error) {
|
|||||||
// "foobar" would cause conflict with "FooBar".
|
// "foobar" would cause conflict with "FooBar".
|
||||||
ifname = strings.ToLower(ifname)
|
ifname = strings.ToLower(ifname)
|
||||||
|
|
||||||
// Iterate.
|
|
||||||
for index := 0; ; index++ {
|
for index := 0; ; index++ {
|
||||||
// Get the device from the list. Should anything be wrong with this device, continue with next.
|
// Get the device from the list. Should anything be wrong with this device, continue with next.
|
||||||
deviceData, err := devInfoList.EnumDeviceInfo(index)
|
deviceData, err := devInfoList.EnumDeviceInfo(index)
|
||||||
@ -174,7 +165,7 @@ func GetInterface(ifname string, hwndParent uintptr) (*Wintun, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This interface is not using Wintun driver.
|
// This interface is not using Wintun driver.
|
||||||
return wintun, errors.New("Foreign network interface with the same name exists")
|
return nil, errors.New("Foreign network interface with the same name exists")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -444,7 +435,7 @@ func checkReboot(deviceInfoSet setupapi.DevInfo, deviceInfoData *setupapi.DevInf
|
|||||||
// GetInterfaceName returns network interface name.
|
// GetInterfaceName returns network interface name.
|
||||||
//
|
//
|
||||||
func (wintun *Wintun) GetInterfaceName() (string, error) {
|
func (wintun *Wintun) GetInterfaceName() (string, error) {
|
||||||
key, err := registry.OpenKey(registry.LOCAL_MACHINE, wintun.GetNetRegKeyName(), registry.QUERY_VALUE)
|
key, err := registryOpenKeyRetry(registry.LOCAL_MACHINE, wintun.GetNetRegKeyName(), registry.QUERY_VALUE)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.New("Network-specific registry key open failed: " + err.Error())
|
return "", errors.New("Network-specific registry key open failed: " + err.Error())
|
||||||
}
|
}
|
||||||
@ -458,7 +449,7 @@ func (wintun *Wintun) GetInterfaceName() (string, error) {
|
|||||||
// SetInterfaceName sets network interface name.
|
// SetInterfaceName sets network interface name.
|
||||||
//
|
//
|
||||||
func (wintun *Wintun) SetInterfaceName(ifname string) error {
|
func (wintun *Wintun) SetInterfaceName(ifname string) error {
|
||||||
key, err := registry.OpenKey(registry.LOCAL_MACHINE, wintun.GetNetRegKeyName(), registry.SET_VALUE)
|
key, err := registryOpenKeyRetry(registry.LOCAL_MACHINE, wintun.GetNetRegKeyName(), registry.SET_VALUE)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("Network-specific registry key open failed: " + err.Error())
|
return errors.New("Network-specific registry key open failed: " + err.Error())
|
||||||
}
|
}
|
||||||
@ -483,7 +474,7 @@ func (wintun *Wintun) GetNetRegKeyName() string {
|
|||||||
//
|
//
|
||||||
func getRegStringValue(key registry.Key, name string) (string, error) {
|
func getRegStringValue(key registry.Key, name string) (string, error) {
|
||||||
// Read string value.
|
// Read string value.
|
||||||
value, valueType, err := key.GetStringValue(name)
|
value, valueType, err := keyGetStringValueRetry(key, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user