wintun: work around GetInterface staleness bug

This commit is contained in:
Jason A. Donenfeld 2019-05-03 00:11:59 +02:00
parent 46dbf54040
commit 2e988467c2
2 changed files with 31 additions and 19 deletions

View file

@ -7,6 +7,7 @@ package tun
import ( import (
"errors" "errors"
"fmt"
"os" "os"
"sync" "sync"
"time" "time"
@ -59,32 +60,43 @@ func packetAlign(size uint32) uint32 {
// adapter with the same name exist, it is reused. // adapter with the same name exist, it is reused.
// //
func CreateTUN(ifname string) (TUNDevice, error) { func CreateTUN(ifname string) (TUNDevice, error) {
var err error
var wt *wintun.Wintun
for i := 0; i < 3; i++ {
// Does an interface with this name already exist? // Does an interface with this name already exist?
wt, err := wintun.GetInterface(ifname, 0) wt, err = wintun.GetInterface(ifname, 0)
if wt == nil { if wt == nil {
// Interface does not exist or an error occured. Create one. // Interface does not exist or an error occured. Create one.
wt, _, err = wintun.CreateInterface("WireGuard Tunnel Adapter", 0) wt, _, err = wintun.CreateInterface("WireGuard Tunnel Adapter", 0)
if err != nil { if err != nil {
return nil, errors.New("Creating Wintun adapter failed: " + err.Error()) err = fmt.Errorf("wintun.CreateInterface: %v", err)
continue
} }
} else if err != nil { } else if err != nil {
// Foreign interface with the same name found. // Foreign interface with the same name found.
// We could create a Wintun interface under a temporary name. But, should our // We could create a Wintun interface under a temporary name. But, should our
// proces die without deleting this interface first, the interface would remain // process die without deleting this interface first, the interface would remain
// orphaned. // orphaned.
return nil, err err = fmt.Errorf("wintun.GetInterface: %v", err)
continue
} }
err = wt.SetInterfaceName(ifname) err = wt.SetInterfaceName(ifname) //TODO: This is the function that most often fails
if err != nil { if err != nil {
wt.DeleteInterface(0) wt.DeleteInterface(0)
wt = nil
err = fmt.Errorf("wintun.SetInterfaceName: %v", err)
continue
}
}
if err != nil {
return nil, err return nil, err
} }
err = wt.FlushInterface() err = wt.FlushInterface()
if err != nil { if err != nil {
wt.DeleteInterface(0) wt.DeleteInterface(0)
return nil, errors.New("Flushing interface failed: " + err.Error()) return nil, fmt.Errorf("wintun.FlushInterface: %v", err)
} }
return &NativeTun{ return &NativeTun{

View file

@ -11,8 +11,8 @@ import (
) )
const ( const (
numRetries = 100 numRetries = 50
retryTimeout = 150 * time.Millisecond retryTimeout = 100 * time.Millisecond
) )
func registryOpenKeyRetry(k registry.Key, path string, access uint32) (key registry.Key, err error) { func registryOpenKeyRetry(k registry.Key, path string, access uint32) (key registry.Key, err error) {