mirror of
https://github.com/qdm12/gluetun.git
synced 2026-07-31 17:33:22 +02:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 88ffd887b4 | |||
| df3c9fa668 | |||
| 257787ce15 |
@@ -85,13 +85,13 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- uses: actions/setup-go@v7
|
||||
- uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version-file: ./devrun/go.mod
|
||||
- run: go test ./...
|
||||
working-directory: ./devrun
|
||||
|
||||
- uses: actions/setup-go@v7
|
||||
- uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version-file: ./ci/go.mod
|
||||
- run: go test ./...
|
||||
@@ -114,7 +114,7 @@ jobs:
|
||||
- run: docker build -t qmcgaw/gluetun .
|
||||
|
||||
- name: Setup Go for CI utility
|
||||
uses: actions/setup-go@v7
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version-file: ci/go.mod
|
||||
|
||||
@@ -162,7 +162,7 @@ jobs:
|
||||
security-events: write
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-go@v7
|
||||
- uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
- uses: github/codeql-action/init@v4
|
||||
@@ -241,3 +241,5 @@ jobs:
|
||||
VERSION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
push: true
|
||||
provenance: mode=max
|
||||
sbom: true
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"net"
|
||||
"net/netip"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/healthcheck/dns"
|
||||
@@ -24,7 +23,6 @@ type Checker struct {
|
||||
icmpTargetIPs []netip.Addr
|
||||
smallCheckType string
|
||||
startupOnFail bool
|
||||
configMutex sync.Mutex
|
||||
|
||||
icmpNotPermitted *bool
|
||||
|
||||
@@ -55,8 +53,6 @@ func NewChecker(logger Logger) *Checker {
|
||||
func (c *Checker) SetConfig(tlsDialAddrs []string, icmpTargets []netip.Addr,
|
||||
smallCheckType string, startupOnFail bool,
|
||||
) {
|
||||
c.configMutex.Lock()
|
||||
defer c.configMutex.Unlock()
|
||||
c.tlsDialAddrs = tlsDialAddrs
|
||||
c.icmpTargetIPs = icmpTargets
|
||||
c.smallCheckType = smallCheckType
|
||||
@@ -166,10 +162,8 @@ func (c *Checker) Stop() error {
|
||||
}
|
||||
|
||||
func (c *Checker) smallPeriodicCheck(ctx context.Context) error {
|
||||
c.configMutex.Lock()
|
||||
icmpTargetIPs := make([]netip.Addr, len(c.icmpTargetIPs))
|
||||
copy(icmpTargetIPs, c.icmpTargetIPs)
|
||||
c.configMutex.Unlock()
|
||||
tryTimeouts := []time.Duration{
|
||||
5 * time.Second,
|
||||
5 * time.Second,
|
||||
|
||||
@@ -99,6 +99,7 @@ func (l *Loop) run(runCtx context.Context, runDone chan<- struct{},
|
||||
case partialUpdate := <-updateTrigger:
|
||||
updatedSettings, err := l.settings.updateWith(partialUpdate, *l.settings.VPNIsUp)
|
||||
if err != nil {
|
||||
l.logger.Debug(fmt.Sprintf("port forward loop: run: updateWith error %v", err))
|
||||
updateResult <- err
|
||||
continue
|
||||
}
|
||||
@@ -136,6 +137,7 @@ func (l *Loop) run(runCtx context.Context, runDone chan<- struct{},
|
||||
if err != nil {
|
||||
err = fmt.Errorf("starting port forwarding service: %w", err)
|
||||
}
|
||||
l.logger.Debug(fmt.Sprintf("port forward loop: Start: error is %v", err))
|
||||
updateResult <- err
|
||||
} else if err != nil {
|
||||
// Log the error and schedule a retry
|
||||
@@ -150,6 +152,7 @@ func (l *Loop) UpdateWith(partialUpdate Settings) (err error) {
|
||||
case l.updateTrigger <- partialUpdate:
|
||||
select {
|
||||
case err = <-l.updatedResult:
|
||||
l.logger.Debug(fmt.Sprintf("port forward loop: UpdateWith: received error %v", err))
|
||||
return err
|
||||
case <-l.runCtx.Done():
|
||||
return l.runCtx.Err()
|
||||
|
||||
@@ -123,7 +123,9 @@ func (s *Service) onNewPorts(ctx context.Context, internalToExternalPorts map[ui
|
||||
}
|
||||
}
|
||||
|
||||
s.logger.Debug(fmt.Sprintf("writePortForwardedFile with externalPorts: %v", externalPorts))
|
||||
err = s.writePortForwardedFile(externalPorts)
|
||||
s.logger.Debug(fmt.Sprintf("writing port file: error is %v", err))
|
||||
if err != nil {
|
||||
_ = s.cleanup()
|
||||
return fmt.Errorf("writing port file: %w", err)
|
||||
|
||||
@@ -58,6 +58,7 @@ func (s *Service) cleanup() (err error) {
|
||||
|
||||
s.ports = nil
|
||||
|
||||
s.logger.Debug("writePortForwardedFile in cleanup")
|
||||
err = s.writePortForwardedFile(nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("clearing port file: %w", err)
|
||||
|
||||
@@ -133,6 +133,20 @@ func (p *Provider) KeepPortForward(ctx context.Context,
|
||||
case <-timer.C:
|
||||
}
|
||||
|
||||
_, externalIPv4Address, err := client.ExternalAddress(ctx, objects.Gateway)
|
||||
if err != nil {
|
||||
switch {
|
||||
case strings.HasSuffix(err.Error(), "connection refused"):
|
||||
err = fmt.Errorf("%w - make sure you have +pmp at the end of your OpenVPN username "+
|
||||
"or that your Wireguard key is set to work with PMP", err)
|
||||
case strings.Contains(err.Error(), "i/o timeout"):
|
||||
err = fmt.Errorf("%w - make sure FIREWALL_OUTBOUND_SUBNETS does not conflict with "+
|
||||
"the VPN gateway ip address %s", err, objects.Gateway)
|
||||
}
|
||||
logger.Error(fmt.Sprintf("getting external IPv4 address: %v", err))
|
||||
}
|
||||
logger.Debug("gateway external IPv4 address is " + externalIPv4Address.String())
|
||||
|
||||
objects.Logger.Debug("refreshing forwarded ports since 45 seconds have elapsed")
|
||||
const lifetime = 60 * time.Second
|
||||
for internalPort, externalPort := range p.internalToExternalPorts {
|
||||
|
||||
@@ -45,6 +45,7 @@ type Loop struct {
|
||||
start <-chan struct{}
|
||||
running chan<- models.LoopStatus
|
||||
userTrigger bool
|
||||
healthDone <-chan struct{}
|
||||
// Internal constant values
|
||||
backoffTime time.Duration
|
||||
}
|
||||
@@ -70,6 +71,11 @@ func NewLoop(vpnSettings settings.VPN, ipv6SupportLevel netlink.IPv6SupportLevel
|
||||
statusManager := loopstate.New(constants.Stopped, start, running, stop, stopped)
|
||||
state := state.New(statusManager, vpnSettings)
|
||||
|
||||
// Initialize healthDone channel to a closed channel so that the first time
|
||||
// we call <-l.healthDone it does not block
|
||||
healthDone := make(chan struct{})
|
||||
close(healthDone)
|
||||
|
||||
return &Loop{
|
||||
statusManager: statusManager,
|
||||
state: state,
|
||||
@@ -98,6 +104,7 @@ func NewLoop(vpnSettings settings.VPN, ipv6SupportLevel netlink.IPv6SupportLevel
|
||||
stop: stop,
|
||||
stopped: stopped,
|
||||
userTrigger: true,
|
||||
healthDone: healthDone,
|
||||
backoffTime: defaultBackoffTime,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,9 @@ func (l *Loop) startPortForwarding(data tunnelUpData) (err error) {
|
||||
Password: data.password,
|
||||
},
|
||||
}
|
||||
return l.portForward.UpdateWith(partialUpdate)
|
||||
err = l.portForward.UpdateWith(partialUpdate)
|
||||
l.logger.Debug(fmt.Sprintf("vpn loop: start port forwarding: error is %v", err))
|
||||
return err
|
||||
}
|
||||
|
||||
func (l *Loop) stopPortForwarding() (err error) {
|
||||
|
||||
@@ -81,6 +81,7 @@ func (l *Loop) onTunnelUp(ctx, loopCtx context.Context, data tunnelUpData) {
|
||||
|
||||
_, _ = l.dnsLooper.ApplyStatus(ctx, constants.Running)
|
||||
|
||||
<-l.healthDone // make sure the health checker is stopped before restarting it
|
||||
icmpTargetIPs := l.healthSettings.ICMPTargetIPs
|
||||
if len(icmpTargetIPs) == 1 && icmpTargetIPs[0].IsUnspecified() {
|
||||
icmpTargetIPs = []netip.Addr{data.serverIP}
|
||||
@@ -104,7 +105,12 @@ func (l *Loop) onTunnelUp(ctx, loopCtx context.Context, data tunnelUpData) {
|
||||
// Start collecting health errors asynchronously, since
|
||||
// we should not wait for the code below to complete
|
||||
// to start monitoring health and auto-healing.
|
||||
go l.collectHealthErrors(ctx, loopCtx, healthErrCh)
|
||||
// We keep track of when this goroutine is done with the healthDone
|
||||
// channel to avoid a race condition where the health checker is stopped
|
||||
// after being reconfigured and restarted, instead of before.
|
||||
healthDone := make(chan struct{})
|
||||
l.healthDone = healthDone
|
||||
go l.collectHealthErrors(ctx, loopCtx, healthDone, healthErrCh)
|
||||
|
||||
err = l.publicip.RunOnce(ctx)
|
||||
if err != nil {
|
||||
@@ -140,7 +146,10 @@ func (l *Loop) onTunnelUp(ctx, loopCtx context.Context, data tunnelUpData) {
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Loop) collectHealthErrors(ctx, loopCtx context.Context, healthErrCh <-chan error) {
|
||||
func (l *Loop) collectHealthErrors(ctx, loopCtx context.Context,
|
||||
done chan<- struct{}, healthErrCh <-chan error,
|
||||
) {
|
||||
defer close(done)
|
||||
var previousHealthErr error
|
||||
for {
|
||||
select {
|
||||
|
||||
Reference in New Issue
Block a user