summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2019-05-03 00:11:59 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2019-05-03 00:42:36 +0200
commit2e988467c2c9b7a94369f605bad6b08c70a9df7e (patch)
treed0406814fb8499554917a6df7e7470e940bb9d4a
parent46dbf5404013e83867356ea8a590a45a569acbf4 (diff)
wintun: work around GetInterface staleness bug
-rw-r--r--tun/tun_windows.go44
-rw-r--r--tun/wintun/registryhacks_windows.go4
2 files changed, 30 insertions, 18 deletions
diff --git a/tun/tun_windows.go b/tun/tun_windows.go
index 2fa6901..b319c27 100644
--- a/tun/tun_windows.go
+++ b/tun/tun_windows.go
@@ -7,6 +7,7 @@ package tun
import (
"errors"
+ "fmt"
"os"
"sync"
"time"
@@ -59,32 +60,43 @@ func packetAlign(size uint32) uint32 {
// adapter with the same name exist, it is reused.
//
func CreateTUN(ifname string) (TUNDevice, error) {
- // Does an interface with this name already exist?
- wt, err := wintun.GetInterface(ifname, 0)
- if wt == nil {
- // Interface does not exist or an error occured. Create one.
- wt, _, err = wintun.CreateInterface("WireGuard Tunnel Adapter", 0)
+ var err error
+ var wt *wintun.Wintun
+ for i := 0; i < 3; i++ {
+ // Does an interface with this name already exist?
+ wt, err = wintun.GetInterface(ifname, 0)
+ if wt == nil {
+ // Interface does not exist or an error occured. Create one.
+ wt, _, err = wintun.CreateInterface("WireGuard Tunnel Adapter", 0)
+ if err != nil {
+ err = fmt.Errorf("wintun.CreateInterface: %v", err)
+ continue
+ }
+ } else if err != nil {
+ // Foreign interface with the same name found.
+ // We could create a Wintun interface under a temporary name. But, should our
+ // process die without deleting this interface first, the interface would remain
+ // orphaned.
+ err = fmt.Errorf("wintun.GetInterface: %v", err)
+ continue
+ }
+
+ err = wt.SetInterfaceName(ifname) //TODO: This is the function that most often fails
if err != nil {
- return nil, errors.New("Creating Wintun adapter failed: " + err.Error())
+ wt.DeleteInterface(0)
+ wt = nil
+ err = fmt.Errorf("wintun.SetInterfaceName: %v", err)
+ continue
}
- } else if err != nil {
- // Foreign interface with the same name found.
- // We could create a Wintun interface under a temporary name. But, should our
- // proces die without deleting this interface first, the interface would remain
- // orphaned.
- return nil, err
}
-
- err = wt.SetInterfaceName(ifname)
if err != nil {
- wt.DeleteInterface(0)
return nil, err
}
err = wt.FlushInterface()
if err != nil {
wt.DeleteInterface(0)
- return nil, errors.New("Flushing interface failed: " + err.Error())
+ return nil, fmt.Errorf("wintun.FlushInterface: %v", err)
}
return &NativeTun{
diff --git a/tun/wintun/registryhacks_windows.go b/tun/wintun/registryhacks_windows.go
index 94cc2f3..bf72f92 100644
--- a/tun/wintun/registryhacks_windows.go
+++ b/tun/wintun/registryhacks_windows.go
@@ -11,8 +11,8 @@ import (
)
const (
- numRetries = 100
- retryTimeout = 150 * time.Millisecond
+ numRetries = 50
+ retryTimeout = 100 * time.Millisecond
)
func registryOpenKeyRetry(k registry.Key, path string, access uint32) (key registry.Key, err error) {