From 2e988467c2c9b7a94369f605bad6b08c70a9df7e Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Fri, 3 May 2019 00:11:59 +0200 Subject: wintun: work around GetInterface staleness bug --- tun/tun_windows.go | 44 +++++++++++++++++++++++-------------- tun/wintun/registryhacks_windows.go | 4 ++-- 2 files changed, 30 insertions(+), 18 deletions(-) (limited to 'tun') 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) { -- cgit v1.2.3-59-g8ed1b