diff options
Diffstat (limited to '')
-rw-r--r-- | conf/parser.go | 15 | ||||
-rw-r--r-- | embeddable-dll-service/csharp/DemoUI/MainWindow.cs | 30 | ||||
-rw-r--r-- | go.mod | 2 | ||||
-rw-r--r-- | go.sum | 4 | ||||
-rw-r--r-- | manager/ipc_server.go | 35 | ||||
-rw-r--r-- | manager/ipc_uapi.go | 71 | ||||
-rw-r--r-- | manager/tunneltracker.go | 1 |
7 files changed, 117 insertions, 41 deletions
diff --git a/conf/parser.go b/conf/parser.go index d26bdea4..dd0ee317 100644 --- a/conf/parser.go +++ b/conf/parser.go @@ -6,8 +6,10 @@ package conf import ( + "bufio" "encoding/base64" "encoding/hex" + "io" "net" "strconv" "strings" @@ -367,8 +369,7 @@ func FromWgQuickWithUnknownEncoding(s string, name string) (*Config, error) { return nil, firstErr } -func FromUAPI(s string, existingConfig *Config) (*Config, error) { - lines := strings.Split(s, "\n") +func FromUAPI(reader io.Reader, existingConfig *Config) (*Config, error) { parserState := inInterfaceSection conf := Config{ Name: existingConfig.Name, @@ -380,9 +381,15 @@ func FromUAPI(s string, existingConfig *Config) (*Config, error) { }, } var peer *Peer - for _, line := range lines { + lineReader := bufio.NewReader(reader) + for { + line, err := lineReader.ReadString('\n') + if err != nil { + return nil, err + } + line = line[:len(line)-1] if len(line) == 0 { - continue + break } equals := strings.IndexByte(line, '=') if equals < 0 { diff --git a/embeddable-dll-service/csharp/DemoUI/MainWindow.cs b/embeddable-dll-service/csharp/DemoUI/MainWindow.cs index 13499fcb..50a42c42 100644 --- a/embeddable-dll-service/csharp/DemoUI/MainWindow.cs +++ b/embeddable-dll-service/csharp/DemoUI/MainWindow.cs @@ -58,24 +58,25 @@ namespace DemoUI private void tailTransfer() { + StreamReader reader = null; NamedPipeClientStream stream = null; + while (threadsRunning) + { + try + { + stream = Tunnel.Service.GetPipe(configFile); + stream.Connect(); + reader = new StreamReader(stream); + break; + } + catch { } + Thread.Sleep(1000); + } + try { while (threadsRunning) { - while (threadsRunning) - { - try - { - stream = Tunnel.Service.GetPipe(configFile); - stream.Connect(); - break; - } - catch { } - Thread.Sleep(1000); - } - - var reader = new StreamReader(stream); stream.Write(Encoding.UTF8.GetBytes("get=1\n\n")); ulong rx = 0, tx = 0; while (threadsRunning) @@ -92,14 +93,13 @@ namespace DemoUI tx += ulong.Parse(line.Substring(9)); } Invoke(new Action<ulong, ulong>(updateTransferTitle), new object[] { rx, tx }); - stream.Close(); Thread.Sleep(1000); } } catch { } finally { - if (stream != null && stream.IsConnected) + if (stream.IsConnected) stream.Close(); } } @@ -9,7 +9,7 @@ require ( golang.org/x/net v0.0.0-20210119194325-5f4716e94777 golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c golang.org/x/text v0.3.5 - golang.zx2c4.com/wireguard v0.0.20201119-0.20210120232502-fcc8ad05df75 + golang.zx2c4.com/wireguard v0.0.20201119-0.20210125194828-18e47795e598 ) replace ( @@ -19,8 +19,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.zx2c4.com/wireguard v0.0.20201119-0.20210120232502-fcc8ad05df75 h1:Q8bLImgHajG+re7SSJQstC0ySZtGYx2KH6wVg8BG5YU= -golang.zx2c4.com/wireguard v0.0.20201119-0.20210120232502-fcc8ad05df75/go.mod h1:r0ExowOoGFfDoLDxx+M9SYbNVsoZ0xviLL+K4f2mt+A= +golang.zx2c4.com/wireguard v0.0.20201119-0.20210125194828-18e47795e598 h1:adinkobWM0mDfoPbr3b13Lwy0+G6pr4dlXmYaY5lbm8= +golang.zx2c4.com/wireguard v0.0.20201119-0.20210125194828-18e47795e598/go.mod h1:r0ExowOoGFfDoLDxx+M9SYbNVsoZ0xviLL+K4f2mt+A= golang.zx2c4.com/wireguard/windows v0.0.0-20201107183008-659a4e955570 h1:sbXpfRwl+7YQY72KBuzyacG7ucr6w4OueJiEb7+pvSk= golang.zx2c4.com/wireguard/windows v0.0.0-20201107183008-659a4e955570/go.mod h1:KxxjdtRkfNoYDCUP5ryK7XJJNTnpC8atvtmTheChOtk= golang.zx2c4.com/wireguard/windows v0.0.0-20210121140954-e7fc19d483bd h1:kAUzMAITME2MCtrXBaUa9P4tndiXGWO674k9gn6ZR28= diff --git a/manager/ipc_server.go b/manager/ipc_server.go index 19298016..ccdfe85e 100644 --- a/manager/ipc_server.go +++ b/manager/ipc_server.go @@ -10,7 +10,6 @@ import ( "encoding/gob" "fmt" "io" - "io/ioutil" "log" "os" "sync" @@ -20,8 +19,6 @@ import ( "golang.org/x/sys/windows" "golang.org/x/sys/windows/svc" - "golang.zx2c4.com/wireguard/ipc/winpipe" - "golang.zx2c4.com/wireguard/windows/conf" "golang.zx2c4.com/wireguard/windows/services" "golang.zx2c4.com/wireguard/windows/updater" @@ -54,30 +51,30 @@ func (s *ManagerService) RuntimeConfig(tunnelName string) (*conf.Config, error) if err != nil { return nil, err } - pipePath, err := services.PipePathOfTunnel(storedConfig.Name) - if err != nil { - return nil, err - } - localSystem, err := windows.CreateWellKnownSid(windows.WinLocalSystemSid) + pipe, err := connectTunnelServicePipe(tunnelName) if err != nil { return nil, err } - pipe, err := winpipe.DialPipe(pipePath, nil, localSystem) - if err != nil { - return nil, err - } - defer pipe.Close() - pipe.SetWriteDeadline(time.Now().Add(time.Second * 2)) + pipe.SetDeadline(time.Now().Add(time.Second * 2)) _, err = pipe.Write([]byte("get=1\n\n")) - if err != nil { - return nil, err + if err == windows.ERROR_NO_DATA { + log.Println("IPC pipe closed unexpectedly, so reopening") + pipe.Unlock() + disconnectTunnelServicePipe(tunnelName) + pipe, err = connectTunnelServicePipe(tunnelName) + if err != nil { + return nil, err + } + pipe.SetDeadline(time.Now().Add(time.Second * 2)) + _, err = pipe.Write([]byte("get=1\n\n")) } - pipe.SetReadDeadline(time.Now().Add(time.Second * 2)) - resp, err := ioutil.ReadAll(pipe) if err != nil { + pipe.Unlock() + disconnectTunnelServicePipe(tunnelName) return nil, err } - conf, err := conf.FromUAPI(string(resp), storedConfig) + conf, err := conf.FromUAPI(pipe, storedConfig) + pipe.Unlock() if err != nil { return nil, err } diff --git a/manager/ipc_uapi.go b/manager/ipc_uapi.go new file mode 100644 index 00000000..b339e3ac --- /dev/null +++ b/manager/ipc_uapi.go @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: MIT + * + * Copyright (C) 2019-2021 WireGuard LLC. All Rights Reserved. + */ + +package manager + +import ( + "net" + "sync" + + "golang.org/x/sys/windows" + "golang.zx2c4.com/wireguard/ipc/winpipe" + + "golang.zx2c4.com/wireguard/windows/services" +) + +type connectedTunnel struct { + net.Conn + sync.Mutex +} + +var connectedTunnelServicePipes = make(map[string]*connectedTunnel) +var connectedTunnelServicePipesLock sync.RWMutex + +func connectTunnelServicePipe(tunnelName string) (*connectedTunnel, error) { + connectedTunnelServicePipesLock.RLock() + pipe, ok := connectedTunnelServicePipes[tunnelName] + if ok { + pipe.Lock() + connectedTunnelServicePipesLock.RUnlock() + return pipe, nil + } + connectedTunnelServicePipesLock.RUnlock() + connectedTunnelServicePipesLock.Lock() + defer connectedTunnelServicePipesLock.Unlock() + pipe, ok = connectedTunnelServicePipes[tunnelName] + if ok { + pipe.Lock() + return pipe, nil + } + pipePath, err := services.PipePathOfTunnel(tunnelName) + if err != nil { + return nil, err + } + localSystem, err := windows.CreateWellKnownSid(windows.WinLocalSystemSid) + if err != nil { + return nil, err + } + pipe = &connectedTunnel{} + pipe.Conn, err = winpipe.DialPipe(pipePath, nil, localSystem) + if err != nil { + return nil, err + } + connectedTunnelServicePipes[tunnelName] = pipe + pipe.Lock() + return pipe, nil +} + +func disconnectTunnelServicePipe(tunnelName string) { + connectedTunnelServicePipesLock.Lock() + defer connectedTunnelServicePipesLock.Unlock() + pipe, ok := connectedTunnelServicePipes[tunnelName] + if !ok { + return + } + pipe.Lock() + pipe.Close() + delete(connectedTunnelServicePipes, tunnelName) + pipe.Unlock() +} diff --git a/manager/tunneltracker.go b/manager/tunneltracker.go index cfd28693..4625a8e8 100644 --- a/manager/tunneltracker.go +++ b/manager/tunneltracker.go @@ -273,4 +273,5 @@ func trackTunnelService(tunnelName string, service *mgr.Service) { IPCServerNotifyTunnelChange(tunnelName, TunnelStopped, fmt.Errorf("Unable to continue monitoring service, so stopping: %w", err)) service.Control(svc.Stop) } + disconnectTunnelServicePipe(tunnelName) } |