summaryrefslogtreecommitdiffhomepage
path: root/tun
diff options
context:
space:
mode:
Diffstat (limited to 'tun')
-rw-r--r--tun/tun_windows.go17
-rw-r--r--tun/wintun/wintun_windows.go56
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\<class>\<id> 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.