From d98afce793edd8eb841610ac45f73d3ae5f3568f Mon Sep 17 00:00:00 2001 From: Quentin McGaw Date: Sun, 8 Mar 2026 23:06:32 +0000 Subject: [PATCH] hotfix(vpn): inject cmder object for up/down commands and fix cleanup panic --- internal/vpn/interfaces.go | 8 +++----- internal/vpn/loop.go | 11 +++++------ internal/vpn/openvpn.go | 2 +- internal/vpn/run.go | 2 +- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/internal/vpn/interfaces.go b/internal/vpn/interfaces.go index bfc52eb5..199ffd51 100644 --- a/internal/vpn/interfaces.go +++ b/internal/vpn/interfaces.go @@ -100,10 +100,12 @@ type PublicIPLoop interface { ClearData() (err error) } -type CmdStarter interface { +type Cmder interface { Start(cmd *exec.Cmd) ( stdoutLines, stderrLines <-chan string, waitError <-chan error, startErr error) + RunAndLog(ctx context.Context, command string, + logger command.Logger) (err error) } type HealthChecker interface { @@ -121,7 +123,3 @@ type Service interface { Start() (runError <-chan error, err error) Stop() error } - -type Cmder interface { - RunAndLog(ctx context.Context, command string, logger command.Logger) (err error) -} diff --git a/internal/vpn/loop.go b/internal/vpn/loop.go index 3ff7cde0..75335a13 100644 --- a/internal/vpn/loop.go +++ b/internal/vpn/loop.go @@ -17,7 +17,6 @@ type Loop struct { state *state.State providers Providers storage Storage - cmder Cmder healthSettings settings.Health healthChecker HealthChecker healthServer HealthServer @@ -36,9 +35,9 @@ type Loop struct { dnsLooper DNSLoop boringPoll Service // Other objects - starter CmdStarter // for OpenVPN - logger log.LoggerInterface - client *http.Client + cmder Cmder // for OpenVPN and up/down commands + logger log.LoggerInterface + client *http.Client // Internal channels and values stop <-chan struct{} stopped chan<- struct{} @@ -57,7 +56,7 @@ func NewLoop(vpnSettings settings.VPN, ipv6Supported bool, vpnInputPorts []uint1 providers Providers, storage Storage, boringPoll Service, healthSettings settings.Health, healthChecker HealthChecker, healthServer HealthServer, openvpnConf OpenVPN, netLinker NetLinker, fw Firewall, routing Routing, - portForward PortForward, starter CmdStarter, + portForward PortForward, cmder Cmder, publicip PublicIPLoop, dnsLooper DNSLoop, logger log.LoggerInterface, client *http.Client, buildInfo models.BuildInformation, versionInfo bool, @@ -90,7 +89,7 @@ func NewLoop(vpnSettings settings.VPN, ipv6Supported bool, vpnInputPorts []uint1 portForward: portForward, publicip: publicip, dnsLooper: dnsLooper, - starter: starter, + cmder: cmder, logger: logger, client: client, start: start, diff --git a/internal/vpn/openvpn.go b/internal/vpn/openvpn.go index c6e8bc9e..a8d85919 100644 --- a/internal/vpn/openvpn.go +++ b/internal/vpn/openvpn.go @@ -14,7 +14,7 @@ import ( // It returns a serverName for port forwarding (PIA) and an error if it fails. func setupOpenVPN(ctx context.Context, fw Firewall, openvpnConf OpenVPN, providerConf provider.Provider, - settings settings.VPN, ipv6Supported bool, starter CmdStarter, + settings settings.VPN, ipv6Supported bool, starter Cmder, logger openvpn.Logger) (runner *openvpn.Runner, connection models.Connection, err error, ) { connection, err = providerConf.GetConnection(settings.Provider.ServerSelection, ipv6Supported) diff --git a/internal/vpn/run.go b/internal/vpn/run.go index 5b23a22a..2fe33c03 100644 --- a/internal/vpn/run.go +++ b/internal/vpn/run.go @@ -36,7 +36,7 @@ func (l *Loop) Run(ctx context.Context, done chan<- struct{}) { if settings.Type == vpn.OpenVPN { vpnInterface = settings.OpenVPN.Interface vpnRunner, connection, err = setupOpenVPN(ctx, l.fw, - l.openvpnConf, providerConf, settings, l.ipv6Supported, l.starter, subLogger) + l.openvpnConf, providerConf, settings, l.ipv6Supported, l.cmder, subLogger) } else { // Wireguard vpnInterface = settings.Wireguard.Interface vpnRunner, connection, err = setupWireguard(ctx, l.netLinker, l.fw,