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
|
// Package proxy is a wrapper around proxyguard that integrates it with eduvpn-common settings
// - leaves out some options not applicable to the common integration, e.g. fwmark
// - integrates with eduvpn-common's logger
// - integrates eduvpn-common's user agent
package proxy
import (
"context"
"codeberg.org/eduVPN/proxyguard"
"codeberg.org/eduVPN/eduvpn-common/i18nerr"
httpw "codeberg.org/eduVPN/eduvpn-common/internal/http"
"codeberg.org/eduVPN/eduvpn-common/internal/log"
)
// Logger is defined here such that we can update the proxyguard logger
type Logger struct{}
// Logf logs a message with parameters
func (l *Logger) Logf(msg string, params ...interface{}) {
log.Logger.Infof("[Proxyguard] "+msg, params...)
}
// Log logs a message
func (l *Logger) Log(msg string) {
log.Logger.Infof("[Proxyguard] %s", msg)
}
// Proxy is the ProxyGuard client with a channel used for restarting
type Proxy struct {
proxyguard.Client
resChan chan struct{}
}
// NewProxyguard sets up proxyguard for proxied WireGuard connections
func NewProxyguard(ctx context.Context, lp int, tcpsp int, peer string, setupSocket func(fd int)) (*Proxy, error) {
proxyguard.UpdateLogger(&Logger{})
proxy := Proxy{
Client: proxyguard.Client{
Peer: peer,
ListenPort: lp,
TCPSourcePort: tcpsp,
SetupSocket: setupSocket,
UserAgent: httpw.UserAgent,
},
resChan: make(chan struct{}),
}
_, err := proxy.Setup(ctx)
if err != nil {
return nil, i18nerr.WrapInternal(err, "The ProxyGuard DNS could not be resolved")
}
return &proxy, nil
}
// Tunnel tunnels the ProxyGuard connection. `wglisten` is the WireGuard listen port
func (p *Proxy) Tunnel(ctx context.Context, wglisten int) error {
log.Logger.Infof("callying tunnel")
errChan := make(chan error, 1)
gctx, cancel := context.WithCancel(ctx)
go func() {
err := p.Client.Tunnel(gctx, wglisten)
if err != nil {
err = i18nerr.WrapInternal(err, "The VPN proxy exited")
}
errChan <- err
}()
select {
case err := <-errChan:
cancel()
return err
case <-p.resChan:
cancel()
<-errChan
return p.Tunnel(ctx, wglisten)
}
}
// Restart restarts the existing ProxyGuard process, for e.g. roaming
func (p *Proxy) Restart() {
p.resChan <- struct{}{}
}
|