mirror of
https://github.com/qdm12/gluetun.git
synced 2026-05-07 04:20:12 +02:00
be92aa2ac4
- Existing option `WIREGUARD_MTU` , if set, disables PMTUD and is used - New option `PMTUD_ICMP_ADDRESSES=1.1.1.1,8.8.8.8` and `PMTUD_TCP_ADDRESSES=1.1.1.1:443,8.8.8.8:443` - ICMP PMTUD now targets external-by-default IP addresses - New TCP PMTUD (binary search only) as a second MTU confirmation and fallback mechanism. - Force set TCP MSS to MTU - IP header - TCP base header - "magic 20 bytes" 🎆 - Fix #3108
120 lines
3.1 KiB
Go
120 lines
3.1 KiB
Go
package vpn
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/qdm12/gluetun/internal/constants"
|
|
"github.com/qdm12/gluetun/internal/constants/vpn"
|
|
"github.com/qdm12/gluetun/internal/models"
|
|
"github.com/qdm12/log"
|
|
)
|
|
|
|
func (l *Loop) Run(ctx context.Context, done chan<- struct{}) {
|
|
defer close(done)
|
|
|
|
select {
|
|
case <-l.start:
|
|
case <-ctx.Done():
|
|
return
|
|
}
|
|
|
|
for ctx.Err() == nil {
|
|
settings := l.state.GetSettings()
|
|
|
|
providerConf := l.providers.Get(settings.Provider.Name)
|
|
|
|
portForwarder := getPortForwarder(providerConf, l.providers,
|
|
*settings.Provider.PortForwarding.Provider)
|
|
|
|
var vpnRunner interface {
|
|
Run(ctx context.Context, waitError chan<- error, tunnelReady chan<- struct{})
|
|
}
|
|
var vpnInterface string
|
|
var connection models.Connection
|
|
var err error
|
|
subLogger := l.logger.New(log.SetComponent(settings.Type))
|
|
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)
|
|
} else { // Wireguard
|
|
vpnInterface = settings.Wireguard.Interface
|
|
vpnRunner, connection, err = setupWireguard(ctx, l.netLinker, l.fw,
|
|
providerConf, settings, l.ipv6Supported, subLogger)
|
|
}
|
|
if err != nil {
|
|
l.crashed(ctx, err)
|
|
continue
|
|
}
|
|
tunnelUpData := tunnelUpData{
|
|
pmtud: tunnelUpPMTUDData{
|
|
enabled: settings.Type != vpn.Wireguard || *settings.Wireguard.MTU == 0,
|
|
vpnType: settings.Type,
|
|
network: connection.Protocol,
|
|
icmpAddrs: settings.PMTUD.ICMPAddresses,
|
|
tcpAddrs: settings.PMTUD.TCPAddresses,
|
|
},
|
|
serverIP: connection.IP,
|
|
serverName: connection.ServerName,
|
|
canPortForward: connection.PortForward,
|
|
portForwarder: portForwarder,
|
|
vpnIntf: vpnInterface,
|
|
username: settings.Provider.PortForwarding.Username,
|
|
password: settings.Provider.PortForwarding.Password,
|
|
}
|
|
|
|
vpnCtx, vpnCancel := context.WithCancel(context.Background())
|
|
waitError := make(chan error)
|
|
tunnelReady := make(chan struct{})
|
|
|
|
go vpnRunner.Run(vpnCtx, waitError, tunnelReady)
|
|
|
|
if err := l.waitForError(ctx, waitError); err != nil {
|
|
vpnCancel()
|
|
l.crashed(ctx, err)
|
|
continue
|
|
}
|
|
|
|
l.backoffTime = defaultBackoffTime
|
|
l.signalOrSetStatus(constants.Running)
|
|
|
|
stayHere := true
|
|
for stayHere {
|
|
select {
|
|
case <-tunnelReady:
|
|
go l.onTunnelUp(vpnCtx, ctx, tunnelUpData)
|
|
case <-ctx.Done():
|
|
l.cleanup()
|
|
vpnCancel()
|
|
<-waitError
|
|
close(waitError)
|
|
return
|
|
case <-l.stop:
|
|
l.userTrigger = true
|
|
l.logger.Info("stopping")
|
|
l.cleanup()
|
|
vpnCancel()
|
|
<-waitError
|
|
// do not close waitError or the waitError
|
|
// select case will trigger
|
|
l.stopped <- struct{}{}
|
|
case <-l.start:
|
|
l.userTrigger = true
|
|
l.logger.Info("starting")
|
|
stayHere = false
|
|
case err := <-waitError: // unexpected error
|
|
l.statusManager.Lock() // prevent SetStatus from running in parallel
|
|
|
|
l.cleanup()
|
|
vpnCancel()
|
|
l.statusManager.SetStatus(constants.Crashed)
|
|
l.logAndWait(ctx, err)
|
|
stayHere = false
|
|
|
|
l.statusManager.Unlock()
|
|
}
|
|
}
|
|
vpnCancel()
|
|
}
|
|
}
|