2022-01-06 06:40:23 -05:00
|
|
|
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
|
|
|
|
|
|
2022-01-28 00:09:58 +00:00
|
|
|
ss.TargetIP, err = r.readOpenVPNTargetIP()
|
2022-01-06 06:40:23 -05:00
|
|
|
if err != nil {
|
|
|
|
|
return ss, err
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-05 23:15:20 +00:00
|
|
|
_, countriesCSV := r.getEnvWithRetro("SERVER_COUNTRIES", "COUNTRY")
|
|
|
|
|
ss.Countries = lowerAndSplit(countriesCSV)
|
2022-02-05 23:04:28 +00:00
|
|
|
if vpnProvider == constants.Cyberghost && len(ss.Countries) == 0 {
|
|
|
|
|
// Retro-compatibility for Cyberghost using the REGION variable
|
|
|
|
|
ss.Countries = envToCSV("REGION")
|
|
|
|
|
if len(ss.Countries) > 0 {
|
2022-02-05 23:15:20 +00:00
|
|
|
r.onRetroActive("REGION", "SERVER_COUNTRIES")
|
2022-01-29 14:21:41 +00:00
|
|
|
}
|
2022-01-06 06:40:23 -05:00
|
|
|
}
|
|
|
|
|
|
2022-02-05 23:18:58 +00:00
|
|
|
_, regionsCSV := r.getEnvWithRetro("SERVER_REGIONS", "REGION")
|
|
|
|
|
ss.Regions = lowerAndSplit(regionsCSV)
|
2022-02-05 23:16:47 +00:00
|
|
|
|
|
|
|
|
_, citiesCSV := r.getEnvWithRetro("SERVER_CITIES", "CITY")
|
|
|
|
|
ss.Cities = lowerAndSplit(citiesCSV)
|
|
|
|
|
|
2022-01-06 06:40:23 -05:00
|
|
|
ss.ISPs = envToCSV("ISP")
|
2022-02-05 23:20:17 +00:00
|
|
|
|
|
|
|
|
_, hostnamesCSV := r.getEnvWithRetro("SERVER_HOSTNAMES", "SERVER_HOSTNAME")
|
|
|
|
|
ss.Hostnames = lowerAndSplit(hostnamesCSV)
|
|
|
|
|
|
2022-02-05 23:22:25 +00:00
|
|
|
_, namesCSV := r.getEnvWithRetro("SERVER_NAMES", "SERVER_NAME")
|
|
|
|
|
ss.Names = lowerAndSplit(namesCSV)
|
2022-01-06 06:40:23 -05:00
|
|
|
|
|
|
|
|
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)
|
2022-01-06 17:42:10 +00:00
|
|
|
} else if number < 0 || number > 65535 {
|
|
|
|
|
return ss, fmt.Errorf("%w: %d must be between 0 and 65535",
|
2022-01-06 06:40:23 -05:00
|
|
|
ErrServerNumberNotValid, number)
|
|
|
|
|
}
|
|
|
|
|
numbers[i] = uint16(number)
|
|
|
|
|
}
|
|
|
|
|
ss.Numbers = numbers
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Mullvad only
|
2022-01-27 14:12:25 +00:00
|
|
|
ss.OwnedOnly, err = r.readOwnedOnly()
|
2022-01-06 06:40:23 -05:00
|
|
|
if err != nil {
|
2022-01-27 14:12:25 +00:00
|
|
|
return ss, err
|
2022-01-06 06:40:23 -05:00
|
|
|
}
|
|
|
|
|
|
2022-01-07 22:41:57 +00:00
|
|
|
// VPNUnlimited and ProtonVPN only
|
2022-01-06 06:40:23 -05:00
|
|
|
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")
|
|
|
|
|
)
|
|
|
|
|
|
2022-01-28 00:09:58 +00:00
|
|
|
func (r *Reader) readOpenVPNTargetIP() (ip net.IP, err error) {
|
2022-01-29 14:55:56 +00:00
|
|
|
envKey, s := r.getEnvWithRetro("VPN_ENDPOINT_IP", "OPENVPN_TARGET_IP")
|
2022-01-06 06:40:23 -05:00
|
|
|
ip = net.ParseIP(s)
|
|
|
|
|
if ip == nil {
|
2022-01-28 00:09:58 +00:00
|
|
|
return nil, fmt.Errorf("environment variable %s: %w: %s",
|
|
|
|
|
envKey, ErrInvalidIP, s)
|
2022-01-06 06:40:23 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ip, nil
|
|
|
|
|
}
|
2022-01-27 14:12:25 +00:00
|
|
|
|
|
|
|
|
func (r *Reader) readOwnedOnly() (ownedOnly *bool, err error) {
|
2022-01-29 14:55:56 +00:00
|
|
|
envKey, _ := r.getEnvWithRetro("OWNED_ONLY", "OWNED")
|
|
|
|
|
ownedOnly, err = envToBoolPtr(envKey)
|
2022-01-27 14:12:25 +00:00
|
|
|
if err != nil {
|
2022-01-29 14:55:56 +00:00
|
|
|
return nil, fmt.Errorf("environment variable %s: %w", envKey, err)
|
2022-01-27 14:12:25 +00:00
|
|
|
}
|
|
|
|
|
return ownedOnly, nil
|
|
|
|
|
}
|