diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-04-29 13:30:28 +0200 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-04-29 13:44:04 +0200 |
commit | fe1f44fc37c6442617d02010077292d9537e5b3b (patch) | |
tree | 86c554d239919013446eb101309f6488535766a3 /service/ipc_server.go | |
parent | updater: use /qb instead of /quiet (diff) | |
download | wireguard-windows-fe1f44fc37c6442617d02010077292d9537e5b3b.tar.xz wireguard-windows-fe1f44fc37c6442617d02010077292d9537e5b3b.zip |
service: improve state transitions
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to '')
-rw-r--r-- | service/ipc_server.go | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/service/ipc_server.go b/service/ipc_server.go index 6d576846..4dd36b2d 100644 --- a/service/ipc_server.go +++ b/service/ipc_server.go @@ -8,10 +8,12 @@ package service import ( "bytes" "encoding/gob" + "fmt" "github.com/Microsoft/go-winio" "golang.org/x/sys/windows/svc" "golang.zx2c4.com/wireguard/windows/conf" "io/ioutil" + "log" "net/rpc" "os" "sync" @@ -74,13 +76,32 @@ func (s *ManagerService) Start(tunnelName string, unused *uintptr) error { // For now, enforce only one tunnel at a time. Later we'll remove this silly restriction. trackedTunnelsLock.Lock() tt := make([]string, 0, len(trackedTunnels)) - for t := range trackedTunnels { + var inTransition string + for t, state := range trackedTunnels { tt = append(tt, t) + if len(t) > 0 && (state == TunnelStarting || state == TunnelUnknown) { + inTransition = t + break + } } trackedTunnelsLock.Unlock() - for _, t := range tt { - s.Stop(t, unused) + if len(inTransition) != 0 { + return fmt.Errorf("Please allow the tunnel \"%s\" to finish activating", inTransition) } + go func() { + for _, t := range tt { + s.Stop(t, unused) + } + for _, t := range tt { + var state TunnelState + var unused uintptr + if s.State(t, &state) == nil && (state == TunnelStarted || state == TunnelStarting) { + log.Printf("[%s] Trying again to stop zombie tunnel", t) + s.Stop(t, &unused) + time.Sleep(time.Millisecond * 100) + } + } + }() // After that process is started -- it's somewhat asynchronous -- we install the new one. c, err := conf.LoadFromName(tunnelName) |