aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/manager/ipc_uapi.go
blob: b339e3ac5f05860b427afdb319c1c4af0306ea3a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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()
}