diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2021-10-20 00:11:37 -0600 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2021-10-21 12:46:29 -0600 |
commit | d7e576e72824e8042128b7cb994f55a7cf9e4e6d (patch) | |
tree | 7e1cbf7e386cd25b3a61c8e10ab53a83bb86d76e | |
parent | docs: fix typo in netquirk (diff) | |
download | wireguard-windows-d7e576e72824e8042128b7cb994f55a7cf9e4e6d.tar.xz wireguard-windows-d7e576e72824e8042128b7cb994f55a7cf9e4e6d.zip |
tunnel: add retry loop to certain interface config failures
I wish there was another way here, but we have too little control over
Windows' boot sequence.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-rw-r--r-- | conf/dnsresolver_windows.go | 2 | ||||
-rw-r--r-- | tunnel/addressconfig.go | 41 | ||||
-rw-r--r-- | tunnel/service.go | 2 |
3 files changed, 33 insertions, 12 deletions
diff --git a/conf/dnsresolver_windows.go b/conf/dnsresolver_windows.go index 47b9b6ae..85923950 100644 --- a/conf/dnsresolver_windows.go +++ b/conf/dnsresolver_windows.go @@ -20,7 +20,7 @@ import ( func resolveHostname(name string) (resolvedIPString string, err error) { maxTries := 10 - systemJustBooted := windows.DurationSinceBoot() <= time.Minute*4 + systemJustBooted := windows.DurationSinceBoot() <= time.Minute*10 if systemJustBooted { maxTries *= 4 } diff --git a/tunnel/addressconfig.go b/tunnel/addressconfig.go index bf3352b3..7e59c9d1 100644 --- a/tunnel/addressconfig.go +++ b/tunnel/addressconfig.go @@ -11,6 +11,7 @@ import ( "log" "net" "sort" + "time" "golang.org/x/sys/windows" "golang.zx2c4.com/wireguard/windows/conf" @@ -57,6 +58,17 @@ func cleanupAddressesOnDisconnectedInterfaces(family winipcfg.AddressFamily, add } func configureInterface(family winipcfg.AddressFamily, conf *conf.Config, luid winipcfg.LUID) error { + systemJustBooted := windows.DurationSinceBoot() <= time.Minute*10 + tryTimes := 0 +startOver: + var err error + if tryTimes > 0 { + log.Printf("Retrying interface configuration after failure because system just booted (T+%v): %v", windows.DurationSinceBoot(), err) + time.Sleep(time.Second) + systemJustBooted = systemJustBooted && tryTimes < 15 + } + tryTimes++ + estimatedRouteCount := 0 for _, peer := range conf.Peers { estimatedRouteCount += len(peer.AllowedIPs) @@ -127,22 +139,27 @@ func configureInterface(family winipcfg.AddressFamily, conf *conf.Config, luid w } if !conf.Interface.TableOff { - err := luid.SetRoutesForFamily(family, deduplicatedRoutes) - if err != nil { - return fmt.Errorf("unable to set routes %+v: %w", deduplicatedRoutes, err) + err = luid.SetRoutesForFamily(family, deduplicatedRoutes) + if err == windows.ERROR_NOT_FOUND && systemJustBooted { + goto startOver + } else if err != nil { + return fmt.Errorf("unable to set routes: %w", err) } } - err := luid.SetIPAddressesForFamily(family, addresses) + err = luid.SetIPAddressesForFamily(family, addresses) if err == windows.ERROR_OBJECT_ALREADY_EXISTS { cleanupAddressesOnDisconnectedInterfaces(family, addresses) err = luid.SetIPAddressesForFamily(family, addresses) } - if err != nil { - return fmt.Errorf("unable to set ips %+v: %w", addresses, err) + if err == windows.ERROR_NOT_FOUND && systemJustBooted { + goto startOver + } else if err != nil { + return fmt.Errorf("unable to set ips: %w", err) } - ipif, err := luid.IPInterface(family) + var ipif *winipcfg.MibIPInterfaceRow + ipif, err = luid.IPInterface(family) if err != nil { return err } @@ -158,13 +175,17 @@ func configureInterface(family winipcfg.AddressFamily, conf *conf.Config, luid w ipif.Metric = 0 } err = ipif.Set() - if err != nil { + if err == windows.ERROR_NOT_FOUND && systemJustBooted { + goto startOver + } else if err != nil { return fmt.Errorf("unable to set metric and MTU: %w", err) } err = luid.SetDNS(family, conf.Interface.DNS, conf.Interface.DNSSearch) - if err != nil { - return fmt.Errorf("unable to set DNS %v %v: %w", conf.Interface.DNS, conf.Interface.DNSSearch, err) + if err == windows.ERROR_NOT_FOUND && systemJustBooted { + goto startOver + } else if err != nil { + return fmt.Errorf("unable to set DNS: %w", err) } return nil } diff --git a/tunnel/service.go b/tunnel/service.go index 013548df..5680d0fc 100644 --- a/tunnel/service.go +++ b/tunnel/service.go @@ -147,7 +147,7 @@ func (service *tunnelService) Execute(args []string, r <-chan svc.ChangeRequest, } log.Println("Creating network adapter") - for i := 0; i < 5; i++ { + for i := 0; i < 15; i++ { if i > 0 { time.Sleep(time.Second) log.Printf("Retrying adapter creation after failure because system just booted (T+%v): %v", windows.DurationSinceBoot(), err) |