wintun: work around GetInterface staleness bug
This commit is contained in:
parent
46dbf54040
commit
2e988467c2
|
@ -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{
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in a new issue