From 2c40b69ae2bda312e2c2afb596a30c440405c90a Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Thu, 28 Feb 2019 03:58:43 +0100 Subject: ipc: implement event system with pipes Also use Go 1.12's Sysconn --- service/ipc_client.go | 67 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 60 insertions(+), 7 deletions(-) (limited to 'service/ipc_client.go') diff --git a/service/ipc_client.go b/service/ipc_client.go index 25575014..c3d08897 100644 --- a/service/ipc_client.go +++ b/service/ipc_client.go @@ -6,7 +6,7 @@ package service import ( - "golang.org/x/sys/windows" + "encoding/gob" "golang.zx2c4.com/wireguard/windows/conf" "net/rpc" "os" @@ -27,10 +27,54 @@ const ( TunnelDeleting ) +type NotificationType int + +const ( + TunnelChangeNotificationType NotificationType = iota + TunnelsChangeNotificationType +) + var rpcClient *rpc.Client -func InitializeIPCClient(reader *os.File, writer *os.File) { +type tunnelChangeCallback struct { + cb func(tunnel string) +} + +var tunnelChangeCallbacks = make(map[*tunnelChangeCallback]bool) + +type tunnelsChangeCallback struct { + cb func() +} + +var tunnelsChangeCallbacks = make(map[*tunnelsChangeCallback]bool) + +func InitializeIPCClient(reader *os.File, writer *os.File, events *os.File) { rpcClient = rpc.NewClient(&pipeRWC{reader, writer}) + go func() { + decoder := gob.NewDecoder(events) + for { + var notificationType NotificationType + err := decoder.Decode(¬ificationType) + if err != nil { + return + } + switch notificationType { + case TunnelChangeNotificationType: + var tunnel string + err := decoder.Decode(&tunnel) + if err != nil || len(tunnel) == 0 { + continue + } + for cb := range tunnelChangeCallbacks { + cb.cb(tunnel) + } + case TunnelsChangeNotificationType: + for cb := range tunnelsChangeCallbacks { + cb.cb() + } + } + } + }() } func (t *Tunnel) StoredConfig() (c conf.Config, err error) { @@ -78,10 +122,19 @@ func IPCClientQuit(stopTunnelsOnQuit bool) (bool, error) { return alreadyQuit, rpcClient.Call("ManagerService.Quit", stopTunnelsOnQuit, &alreadyQuit) } -func IPCClientRegisterAsNotificationThread() error { - return rpcClient.Call("ManagerService.RegisterAsNotificationThread", windows.GetCurrentThreadId(), nil) +func IPCClientRegisterTunnelChange(cb func(tunnel string)) *tunnelChangeCallback { + s := &tunnelChangeCallback{cb} + tunnelChangeCallbacks[s] = true + return s } - -func IPCClientUnregisterAsNotificationThread() error { - return rpcClient.Call("ManagerService.UnregisterAsNotificationThread", windows.GetCurrentThreadId(), nil) +func IPCClientUnregisterTunnelChange(cb *tunnelChangeCallback) { + delete(tunnelChangeCallbacks, cb) +} +func IPCClientRegisterTunnelsChange(cb func()) *tunnelsChangeCallback { + s := &tunnelsChangeCallback{cb} + tunnelsChangeCallbacks[s] = true + return s +} +func IPCClientUnregisterTunnelsChange(cb *tunnelsChangeCallback) { + delete(tunnelsChangeCallbacks, cb) } -- cgit v1.2.3-59-g8ed1b