Files
gluetun/internal/configuration/sources/env/serverselection.go
Quentin McGaw a951110461 feat(vpn): VPN_ENDPOINT_IP
- Deprecate `OPENVPN_TARGET_IP`
- Deprecate `WIREGUARD_ENDPOINT_IP`
2022-01-28 00:09:58 +00:00

141 lines
3.2 KiB
Go

package env
import (
"errors"
"fmt"
"net"
"os"
"strconv"
"strings"
"github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
)
var (
ErrServerNumberNotValid = errors.New("server number is not valid")
)
func (r *Reader) readServerSelection(vpnProvider, vpnType string) (
ss settings.ServerSelection, err error) {
ss.VPN = vpnType
ss.TargetIP, err = r.readOpenVPNTargetIP()
if err != nil {
return ss, err
}
countriesCSV := os.Getenv("COUNTRY")
if vpnProvider == constants.Cyberghost && countriesCSV == "" {
// Retro-compatibility
r.onRetroActive("REGION", "COUNTRY")
countriesCSV = os.Getenv("REGION")
}
if countriesCSV != "" {
ss.Countries = lowerAndSplit(countriesCSV)
}
ss.Regions = envToCSV("REGION")
ss.Cities = envToCSV("CITY")
ss.ISPs = envToCSV("ISP")
ss.Hostnames = envToCSV("SERVER_HOSTNAME")
ss.Names = envToCSV("SERVER_NAME")
if csv := os.Getenv("SERVER_NUMBER"); csv != "" {
numbersStrings := strings.Split(csv, ",")
numbers := make([]uint16, len(numbersStrings))
for i, numberString := range numbersStrings {
number, err := strconv.Atoi(numberString)
if err != nil {
return ss, fmt.Errorf("%w: %s",
ErrServerNumberNotValid, numberString)
} else if number < 0 || number > 65535 {
return ss, fmt.Errorf("%w: %d must be between 0 and 65535",
ErrServerNumberNotValid, number)
}
numbers[i] = uint16(number)
}
ss.Numbers = numbers
}
// Mullvad only
ss.OwnedOnly, err = r.readOwnedOnly()
if err != nil {
return ss, err
}
// VPNUnlimited and ProtonVPN only
ss.FreeOnly, err = envToBoolPtr("FREE_ONLY")
if err != nil {
return ss, fmt.Errorf("environment variable FREE_ONLY: %w", err)
}
// VPNUnlimited only
ss.MultiHopOnly, err = envToBoolPtr("MULTIHOP_ONLY")
if err != nil {
return ss, fmt.Errorf("environment variable MULTIHOP_ONLY: %w", err)
}
// VPNUnlimited only
ss.MultiHopOnly, err = envToBoolPtr("STREAM_ONLY")
if err != nil {
return ss, fmt.Errorf("environment variable STREAM_ONLY: %w", err)
}
ss.OpenVPN, err = r.readOpenVPNSelection()
if err != nil {
return ss, err
}
ss.Wireguard, err = r.readWireguardSelection()
if err != nil {
return ss, err
}
return ss, nil
}
var (
ErrInvalidIP = errors.New("invalid IP address")
)
func (r *Reader) readOpenVPNTargetIP() (ip net.IP, err error) {
envKey := "OPENVPN_TARGET_IP"
s := os.Getenv(envKey) // Retro-compatibility
if s == "" {
envKey = "VPN_ENDPOINT_IP"
s = os.Getenv(envKey)
if s == "" {
return nil, nil
}
} else {
r.onRetroActive("OPENVPN_TARGET_IP", "VPN_ENDPOINT_IP")
}
ip = net.ParseIP(s)
if ip == nil {
return nil, fmt.Errorf("environment variable %s: %w: %s",
envKey, ErrInvalidIP, s)
}
return ip, nil
}
func (r *Reader) readOwnedOnly() (ownedOnly *bool, err error) {
// Retro-compatibility
ownedOnly, err = envToBoolPtr("OWNED")
if err != nil {
r.onRetroActive("OWNED", "OWNED_ONLY")
return nil, fmt.Errorf("environment variable OWNED: %w", err)
} else if ownedOnly != nil {
r.onRetroActive("OWNED", "OWNED_ONLY")
return ownedOnly, nil
}
ownedOnly, err = envToBoolPtr("OWNED_ONLY")
if err != nil {
return nil, fmt.Errorf("environment variable OWNED_ONLY: %w", err)
}
return ownedOnly, nil
}