aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/service/ipc_server.go
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2019-03-02 05:54:25 +0100
committerJason A. Donenfeld <Jason@zx2c4.com>2019-03-02 07:07:05 +0100
commit9e43735dfe6a390d2779e3ba226ec3d0bb51a645 (patch)
tree3e15404826ea98d13b938417cc7fcd145b9d7f42 /service/ipc_server.go
parentsyntax: flat border (diff)
downloadwireguard-windows-9e43735dfe6a390d2779e3ba226ec3d0bb51a645.tar.xz
wireguard-windows-9e43735dfe6a390d2779e3ba226ec3d0bb51a645.zip
ipc: work out service state transitions
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to '')
-rw-r--r--service/ipc_server.go72
1 files changed, 58 insertions, 14 deletions
diff --git a/service/ipc_server.go b/service/ipc_server.go
index 3e4c7fd3..c79748db 100644
--- a/service/ipc_server.go
+++ b/service/ipc_server.go
@@ -8,12 +8,13 @@ package service
import (
"bytes"
"encoding/gob"
- "errors"
+ "golang.org/x/sys/windows/svc"
"golang.zx2c4.com/wireguard/windows/conf"
"net/rpc"
"os"
"sync"
"sync/atomic"
+ "syscall"
"time"
)
@@ -41,7 +42,7 @@ func (s *ManagerService) RuntimeConfig(tunnelName string, config *conf.Config) e
return nil
}
-func (s *ManagerService) Start(tunnelName string, state *TunnelState) error {
+func (s *ManagerService) Start(tunnelName string, unused *uintptr) error {
c, err := conf.LoadFromName(tunnelName)
if err != nil {
return err
@@ -51,30 +52,73 @@ func (s *ManagerService) Start(tunnelName string, state *TunnelState) error {
return err
}
return InstallTunnel(path)
- //TODO: write out *state
}
-func (s *ManagerService) Stop(tunnelName string, state *TunnelState) error {
- return UninstallTunnel(tunnelName)
- //TODO: This function should do nothing if the tunnel is already stopped
- //TODO: write out *state
+func (s *ManagerService) Stop(tunnelName string, unused *uintptr) error {
+ err := UninstallTunnel(tunnelName)
+ if err == syscall.Errno(ERROR_SERVICE_DOES_NOT_EXIST) {
+ _, notExistsError := conf.LoadFromName(tunnelName)
+ if notExistsError == nil {
+ return nil
+ }
+ }
+ return err
}
-func (s *ManagerService) Delete(tunnelName string, state *TunnelState) error {
- err := s.Stop(tunnelName, state)
+func (s *ManagerService) WaitForStop(tunnelName string, unused *uintptr) error {
+ serviceName := "WireGuard Tunnel: " + tunnelName
+ m, err := serviceManager()
if err != nil {
return err
}
- //TODO: wait for stopped somehow
- if *state != TunnelStopped {
- return errors.New("Unable to stop tunnel before deleting")
+ for {
+ service, err := m.OpenService(serviceName)
+ if err == nil || err == syscall.Errno(ERROR_SERVICE_MARKED_FOR_DELETE) {
+ service.Close()
+ time.Sleep(time.Second / 3)
+ } else {
+ return nil
+ }
+ }
+}
+
+func (s *ManagerService) Delete(tunnelName string, unused *uintptr) error {
+ err := s.Stop(tunnelName, nil)
+ if err != nil {
+ return err
}
return conf.DeleteName(tunnelName)
}
func (s *ManagerService) State(tunnelName string, state *TunnelState) error {
- //TODO
-
+ serviceName := "WireGuard Tunnel: " + tunnelName
+ m, err := serviceManager()
+ if err != nil {
+ return err
+ }
+ service, err := m.OpenService(serviceName)
+ if err != nil {
+ *state = TunnelStopped
+ return nil
+ }
+ defer service.Close()
+ status, err := service.Query()
+ if err != nil {
+ *state = TunnelUnknown
+ return err
+ }
+ switch status.State {
+ case svc.Stopped:
+ *state = TunnelStopped
+ case svc.StopPending:
+ *state = TunnelStopping
+ case svc.Running:
+ *state = TunnelStarted
+ case svc.StartPending:
+ *state = TunnelStarting
+ default:
+ *state = TunnelUnknown
+ }
return nil
}