mirror of
https://github.com/qdm12/gluetun.git
synced 2026-05-07 04:20:12 +02:00
11883aa830
- add option `IPV6_CHECK_ADDRESSESES=[2001:4860:4860::8888]:53,[2606:4700:4700::1111]:53` - gluetun needs access to the addresses above through the host firewall, to test ipv6 support before setting up the vpn
128 lines
3.4 KiB
Go
128 lines
3.4 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))
|
|
switch settings.Type {
|
|
case vpn.AmneziaWg:
|
|
vpnInterface = settings.AmneziaWg.Wireguard.Interface
|
|
vpnRunner, connection, err = setupAmneziaWg(ctx, l.netLinker, l.fw,
|
|
providerConf, settings, l.ipv6SupportLevel, subLogger)
|
|
case vpn.OpenVPN:
|
|
vpnInterface = settings.OpenVPN.Interface
|
|
vpnRunner, connection, err = setupOpenVPN(ctx, l.fw,
|
|
l.openvpnConf, providerConf, settings, l.ipv6SupportLevel, l.cmder, subLogger)
|
|
case vpn.Wireguard:
|
|
vpnInterface = settings.Wireguard.Interface
|
|
vpnRunner, connection, err = setupWireguard(ctx, l.netLinker, l.fw,
|
|
providerConf, settings, l.ipv6SupportLevel, subLogger)
|
|
default:
|
|
panic("vpn type not implemented: " + settings.Type)
|
|
}
|
|
if err != nil {
|
|
l.crashed(ctx, err)
|
|
continue
|
|
}
|
|
tunnelUpData := tunnelUpData{
|
|
upCommand: *settings.UpCommand,
|
|
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()
|
|
}
|
|
}
|