-
Notifications
You must be signed in to change notification settings - Fork 0
/
connection.go
92 lines (78 loc) · 2.14 KB
/
connection.go
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// Package wg helps with the creation and usage of userland wireguard networks.
package wg
import (
"errors"
"github.com/point-c/wgapi"
"github.com/point-c/wglog"
"golang.zx2c4.com/wireguard/device"
"sync/atomic"
)
// Wireguard handles configuring and closing a wireguard client/server.
type Wireguard struct {
dev *device.Device
close atomic.Pointer[error]
closers []func() error
}
var (
ErrNoDeviceSpecified = errors.New("no device specified")
)
// New allows the creating of a new wireguard interface.
func New(opts ...Option) (_ *Wireguard, err error) {
// apply options
var o options
if err = o.apply(opts); err != nil {
return nil, err
}
// no recover check for panic
failed := true
defer o.cleanUp(&failed, &err)
// require tun to be set
if o.tun == nil {
return nil, ErrNoDeviceSpecified
}
// if bind is not set use default
if o.bind == nil {
o.bind = DefaultBind()
o.closer = append(o.closer, o.bind.Close)
}
// create wireguard device with tun, bind, and loggers
c := &Wireguard{dev: device.NewDevice(o.tun, o.bind, wglog.Multi(o.loggers...))}
defer func() { c.closers = o.closer }()
o.closer = append(o.closer, func() error { c.dev.Close(); return nil })
// update wireguard config
if o.cfg != nil {
if err := c.SetConfig(*o.cfg); err != nil {
return nil, err
}
}
// bring device up
if err := c.dev.Up(); err != nil {
return nil, err
}
o.closer = append(o.closer, c.dev.Down)
// success
failed = false
return c, nil
}
// GetConfig gets the raw config from an IPC get=1 operation.
func (c *Wireguard) GetConfig() (v wgapi.IPC, err error) {
var ipc wgapi.IPCGet
if err = c.dev.IpcGetOperation(&ipc); err == nil {
v, err = ipc.Value()
}
return
}
// SetConfig performs an IPC set=1 operation.
func (c *Wireguard) SetConfig(cfg wgapi.Configurable) error {
return c.dev.IpcSetOperation(cfg.WGConfig())
}
// Close closes the wireguard server/client, rendering it unusable in the future.
func (c *Wireguard) Close() (err error) {
if c.close.CompareAndSwap(nil, &err) {
for i := len(c.closers) - 1; i >= 0; i-- {
err = errors.Join(err, c.closers[i]())
}
c.closers = nil
}
return *c.close.Load()
}