aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/service/ipc_server.go
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2019-04-29 13:30:28 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2019-04-29 13:44:04 +0200
commitfe1f44fc37c6442617d02010077292d9537e5b3b (patch)
tree86c554d239919013446eb101309f6488535766a3 /service/ipc_server.go
parentupdater: use /qb instead of /quiet (diff)
downloadwireguard-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.go27
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)