diff options
Diffstat (limited to 'proxy')
| -rw-r--r-- | proxy/proxy.go | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/proxy/proxy.go b/proxy/proxy.go new file mode 100644 index 0000000..af0cd89 --- /dev/null +++ b/proxy/proxy.go @@ -0,0 +1,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" + "fmt" + "log/slog" + + "codeberg.org/eduVPN/proxyguard" + + "codeberg.org/eduVPN/eduvpn-common/i18n/err" + httpw "codeberg.org/eduVPN/eduvpn-common/internal/http" +) + +// 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 ...any) { + slog.Info("Proxyguard log", "msg", fmt.Sprintf(msg, params...)) +} + +// Log logs a message +func (l *Logger) Log(msg string) { + slog.Info("Proxyguard log", "msg", 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 { + 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{}{} +} |
