Merge branch 'master' into pmtu

This commit is contained in:
Quentin McGaw
2025-10-17 00:17:45 +00:00
28 changed files with 1505 additions and 665 deletions

View File

@@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"net/netip"
"time"
"github.com/qdm12/dns/v2/pkg/check"
@@ -14,13 +15,13 @@ import (
)
type tunnelUpData struct {
// vpnIntf is the name of the VPN network interface
// which is used both for port forwarding and MTU discovery
vpnIntf string
// Healthcheck
serverIP netip.Addr
// vpnType is used for path MTU discovery to find the protocol overhead.
// It can be "wireguard" or "openvpn".
vpnType string
// Port forwarding fields:
// Port forwarding
vpnIntf string
serverName string // used for PIA
canPortForward bool // used for PIA
username string // used for PIA
@@ -28,7 +29,7 @@ type tunnelUpData struct {
portForwarder PortForwarder
}
func (l *Loop) onTunnelUp(ctx context.Context, data tunnelUpData) {
func (l *Loop) onTunnelUp(ctx, loopCtx context.Context, data tunnelUpData) {
l.client.CloseIdleConnections()
mtuLogger := l.logger.New(log.SetComponent("MTU discovery"))
@@ -45,6 +46,24 @@ func (l *Loop) onTunnelUp(ctx context.Context, data tunnelUpData) {
}
}
icmpTarget := l.healthSettings.ICMPTargetIP
if icmpTarget.IsUnspecified() {
icmpTarget = data.serverIP
}
l.healthChecker.SetConfig(l.healthSettings.TargetAddress, icmpTarget)
healthErrCh, err := l.healthChecker.Start(ctx)
l.healthServer.SetError(err)
if err != nil {
// Note this restart call must be done in a separate goroutine
// from the VPN loop goroutine.
l.restartVPN(loopCtx, err)
return
}
defer func() {
_ = l.healthChecker.Stop()
}()
if *l.dnsLooper.GetSettings().DoT.Enabled {
_, _ = l.dnsLooper.ApplyStatus(ctx, constants.Running)
} else {
@@ -73,6 +92,23 @@ func (l *Loop) onTunnelUp(ctx context.Context, data tunnelUpData) {
if err != nil {
l.logger.Error(err.Error())
}
select {
case <-ctx.Done():
case healthErr := <-healthErrCh:
l.healthServer.SetError(healthErr)
// Note this restart call must be done in a separate goroutine
// from the VPN loop goroutine.
l.restartVPN(loopCtx, healthErr)
}
}
func (l *Loop) restartVPN(ctx context.Context, healthErr error) {
l.logger.Warnf("restarting VPN because it failed to pass the healthcheck: %s", healthErr)
l.logger.Info("👉 See https://github.com/qdm12/gluetun-wiki/blob/main/faq/healthcheck.md")
l.logger.Info("DO NOT OPEN AN ISSUE UNLESS YOU HAVE READ AND TRIED EVERY POSSIBLE SOLUTION")
_, _ = l.ApplyStatus(ctx, constants.Stopped)
_, _ = l.ApplyStatus(ctx, constants.Running)
}
var errVPNTypeUnknown = errors.New("unknown VPN type")