chore: simplify provider GetConnection

This commit is contained in:
Quentin McGaw
2022-04-19 14:28:57 +00:00
parent 306d8494d6
commit 0c0f1663b1
36 changed files with 243 additions and 707 deletions

View File

@@ -77,6 +77,12 @@ func (o OpenVPNSelection) validate(vpnProvider string) (err error) {
case providers.Perfectprivacy: case providers.Perfectprivacy:
allowedTCP = []uint16{44, 443, 4433} allowedTCP = []uint16{44, 443, 4433}
allowedUDP = []uint16{44, 443, 4433} allowedUDP = []uint16{44, 443, 4433}
case providers.PrivateInternetAccess:
allowedTCP = []uint16{80, 110, 443}
allowedUDP = []uint16{53, 1194, 1197, 1198, 8080, 9201}
case providers.Protonvpn:
allowedTCP = []uint16{443, 5995, 8443}
allowedUDP = []uint16{80, 443, 1194, 4569, 5060}
case providers.Wevpn: case providers.Wevpn:
allowedTCP = []uint16{53, 1195, 1199, 2018} allowedTCP = []uint16{53, 1195, 1199, 2018}
allowedUDP = []uint16{80, 1194, 1198} allowedUDP = []uint16{80, 1194, 1198}

View File

@@ -9,7 +9,6 @@ import (
"github.com/qdm12/gluetun/internal/constants/vpn" "github.com/qdm12/gluetun/internal/constants/vpn"
"github.com/qdm12/gluetun/internal/models" "github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/openvpn/extract" "github.com/qdm12/gluetun/internal/openvpn/extract"
"github.com/qdm12/gluetun/internal/provider/utils"
) )
var ( var (
@@ -37,23 +36,21 @@ func getOpenVPNConnection(extractor extract.Interface,
return connection, fmt.Errorf("cannot extract connection: %w", err) return connection, fmt.Errorf("cannot extract connection: %w", err)
} }
connection.Port = getPort(connection.Port, selection) customPort := *selection.OpenVPN.CustomPort
if customPort > 0 {
connection.Port = customPort
}
return connection, nil return connection, nil
} }
func getWireguardConnection(selection settings.ServerSelection) ( func getWireguardConnection(selection settings.ServerSelection) (
connection models.Connection) { connection models.Connection) {
port := getPort(*selection.Wireguard.EndpointPort, selection)
return models.Connection{ return models.Connection{
Type: vpn.Wireguard, Type: vpn.Wireguard,
IP: selection.Wireguard.EndpointIP, IP: selection.Wireguard.EndpointIP,
Port: port, Port: *selection.Wireguard.EndpointPort,
Protocol: constants.UDP, Protocol: constants.UDP,
PubKey: selection.Wireguard.PublicKey, PubKey: selection.Wireguard.PublicKey,
} }
} }
// Port found is overridden by custom port set with `VPN_ENDPOINT_PORT`.
func getPort(foundPort uint16, selection settings.ServerSelection) (port uint16) {
return utils.GetPort(selection, foundPort, foundPort, foundPort)
}

View File

@@ -2,36 +2,12 @@ package cyberghost
import ( import (
"github.com/qdm12/gluetun/internal/configuration/settings" "github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models" "github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/provider/utils" "github.com/qdm12/gluetun/internal/provider/utils"
) )
func (c *Cyberghost) GetConnection(selection settings.ServerSelection) ( func (c *Cyberghost) GetConnection(selection settings.ServerSelection) (
connection models.Connection, err error) { connection models.Connection, err error) {
const port = 443 defaults := utils.NewConnectionDefaults(443, 443, 0) //nolint:gomnd
protocol := constants.UDP return utils.GetConnection(c.servers, selection, defaults, c.randSource)
if *selection.OpenVPN.TCP {
protocol = constants.TCP
}
servers, err := utils.FilterServers(c.servers, selection)
if err != nil {
return connection, err
}
var connections []models.Connection
for _, server := range servers {
for _, IP := range server.IPs {
connection := models.Connection{
Type: selection.VPN,
IP: IP,
Port: port,
Protocol: protocol,
}
connections = append(connections, connection)
}
}
return utils.PickConnection(connections, selection, c.randSource)
} }

View File

@@ -8,37 +8,6 @@ import (
func (p *Provider) GetConnection(selection settings.ServerSelection) ( func (p *Provider) GetConnection(selection settings.ServerSelection) (
connection models.Connection, err error) { connection models.Connection, err error) {
port := getPort(selection) defaults := utils.NewConnectionDefaults(0, 1195, 0) //nolint:gomnd
protocol := utils.GetProtocol(selection) return utils.GetConnection(p.servers, selection, defaults, p.randSource)
servers, err := utils.FilterServers(p.servers, selection)
if err != nil {
return connection, err
}
var connections []models.Connection
for _, server := range servers {
for _, IP := range server.IPs {
connection := models.Connection{
Type: selection.VPN,
IP: IP,
Port: port,
Protocol: protocol,
Hostname: server.Hostname,
}
connections = append(connections, connection)
}
}
return utils.PickConnection(connections, selection, p.randSource)
}
func getPort(selection settings.ServerSelection) (port uint16) {
const (
defaultOpenVPNTCP = 0
defaultOpenVPNUDP = 1195
defaultWireguard = 0
)
return utils.GetPort(selection, defaultOpenVPNTCP,
defaultOpenVPNUDP, defaultWireguard)
} }

View File

@@ -27,7 +27,7 @@ func Test_Provider_GetConnection(t *testing.T) {
"no server available": { "no server available": {
selection: settings.ServerSelection{}.WithDefaults(providers.Expressvpn), selection: settings.ServerSelection{}.WithDefaults(providers.Expressvpn),
errWrapped: utils.ErrNoServerFound, errWrapped: utils.ErrNoServerFound,
errMessage: "no server found: for VPN openvpn; protocol udp", errMessage: "cannot filter servers: no server found: for VPN openvpn; protocol udp",
}, },
"no filter": { "no filter": {
servers: []models.Server{ servers: []models.Server{

View File

@@ -2,36 +2,12 @@ package fastestvpn
import ( import (
"github.com/qdm12/gluetun/internal/configuration/settings" "github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models" "github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/provider/utils" "github.com/qdm12/gluetun/internal/provider/utils"
) )
func (f *Fastestvpn) GetConnection(selection settings.ServerSelection) ( func (f *Fastestvpn) GetConnection(selection settings.ServerSelection) (
connection models.Connection, err error) { connection models.Connection, err error) {
const port = 4443 defaults := utils.NewConnectionDefaults(4443, 4443, 0) //nolint:gomnd
protocol := constants.UDP return utils.GetConnection(f.servers, selection, defaults, f.randSource)
if *selection.OpenVPN.TCP {
protocol = constants.TCP
}
servers, err := utils.FilterServers(f.servers, selection)
if err != nil {
return connection, err
}
var connections []models.Connection
for _, server := range servers {
for _, IP := range server.IPs {
connection := models.Connection{
Type: selection.VPN,
IP: IP,
Port: port,
Protocol: protocol,
}
connections = append(connections, connection)
}
}
return utils.PickConnection(connections, selection, f.randSource)
} }

View File

@@ -2,41 +2,12 @@ package hidemyass
import ( import (
"github.com/qdm12/gluetun/internal/configuration/settings" "github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models" "github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/provider/utils" "github.com/qdm12/gluetun/internal/provider/utils"
) )
func (h *HideMyAss) GetConnection(selection settings.ServerSelection) ( func (h *HideMyAss) GetConnection(selection settings.ServerSelection) (
connection models.Connection, err error) { connection models.Connection, err error) {
var port uint16 = 553 defaults := utils.NewConnectionDefaults(8080, 553, 0) //nolint:gomnd
protocol := constants.UDP return utils.GetConnection(h.servers, selection, defaults, h.randSource)
if *selection.OpenVPN.TCP {
protocol = constants.TCP
port = 8080
}
if *selection.OpenVPN.CustomPort > 0 {
port = *selection.OpenVPN.CustomPort
}
servers, err := utils.FilterServers(h.servers, selection)
if err != nil {
return connection, err
}
var connections []models.Connection
for _, server := range servers {
for _, IP := range server.IPs {
connection := models.Connection{
Type: selection.VPN,
IP: IP,
Port: port,
Protocol: protocol,
}
connections = append(connections, connection)
}
}
return utils.PickConnection(connections, selection, h.randSource)
} }

View File

@@ -2,34 +2,12 @@ package ipvanish
import ( import (
"github.com/qdm12/gluetun/internal/configuration/settings" "github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models" "github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/provider/utils" "github.com/qdm12/gluetun/internal/provider/utils"
) )
func (i *Ipvanish) GetConnection(selection settings.ServerSelection) ( func (i *Ipvanish) GetConnection(selection settings.ServerSelection) (
connection models.Connection, err error) { connection models.Connection, err error) {
const port = 443 defaults := utils.NewConnectionDefaults(0, 443, 0) //nolint:gomnd
const protocol = constants.UDP return utils.GetConnection(i.servers, selection, defaults, i.randSource)
servers, err := utils.FilterServers(i.servers, selection)
if err != nil {
return connection, err
}
var connections []models.Connection
for _, server := range servers {
for _, IP := range server.IPs {
connection := models.Connection{
Type: selection.VPN,
IP: IP,
Port: port,
Protocol: protocol,
Hostname: server.Hostname,
}
connections = append(connections, connection)
}
}
return utils.PickConnection(connections, selection, i.randSource)
} }

View File

@@ -8,38 +8,6 @@ import (
func (i *Ivpn) GetConnection(selection settings.ServerSelection) ( func (i *Ivpn) GetConnection(selection settings.ServerSelection) (
connection models.Connection, err error) { connection models.Connection, err error) {
port := getPort(selection) defaults := utils.NewConnectionDefaults(443, 1194, 58237) //nolint:gomnd
protocol := utils.GetProtocol(selection) return utils.GetConnection(i.servers, selection, defaults, i.randSource)
servers, err := utils.FilterServers(i.servers, selection)
if err != nil {
return connection, err
}
var connections []models.Connection
for _, server := range servers {
for _, IP := range server.IPs {
connection := models.Connection{
Type: selection.VPN,
IP: IP,
Port: port,
Protocol: protocol,
Hostname: server.Hostname,
PubKey: server.WgPubKey, // Wireguard only
}
connections = append(connections, connection)
}
}
return utils.PickConnection(connections, selection, i.randSource)
}
func getPort(selection settings.ServerSelection) (port uint16) {
const (
defaultOpenVPNTCP = 443
defaultOpenVPNUDP = 1194
defaultWireguard = 58237
)
return utils.GetPort(selection, defaultOpenVPNTCP,
defaultOpenVPNUDP, defaultWireguard)
} }

View File

@@ -27,7 +27,7 @@ func Test_Ivpn_GetConnection(t *testing.T) {
"no server available": { "no server available": {
selection: settings.ServerSelection{}.WithDefaults(providers.Ivpn), selection: settings.ServerSelection{}.WithDefaults(providers.Ivpn),
errWrapped: utils.ErrNoServerFound, errWrapped: utils.ErrNoServerFound,
errMessage: "no server found: for VPN openvpn; protocol udp", errMessage: "cannot filter servers: no server found: for VPN openvpn; protocol udp",
}, },
"no filter": { "no filter": {
servers: []models.Server{ servers: []models.Server{

View File

@@ -8,41 +8,6 @@ import (
func (m *Mullvad) GetConnection(selection settings.ServerSelection) ( func (m *Mullvad) GetConnection(selection settings.ServerSelection) (
connection models.Connection, err error) { connection models.Connection, err error) {
port := getPort(selection) defaults := utils.NewConnectionDefaults(443, 1194, 51820) //nolint:gomnd
protocol := utils.GetProtocol(selection) return utils.GetConnection(m.servers, selection, defaults, m.randSource)
servers, err := utils.FilterServers(m.servers, selection)
if err != nil {
return connection, err
}
connections := make([]models.Connection, 0, len(servers))
for _, server := range servers {
for _, IP := range server.IPs {
if IP.To4() == nil {
// do not use IPv6 connections for now
continue
}
connection := models.Connection{
Type: selection.VPN,
IP: IP,
Port: port,
Protocol: protocol,
PubKey: server.WgPubKey, // Wireguard only
}
connections = append(connections, connection)
}
}
return utils.PickConnection(connections, selection, m.randSource)
}
func getPort(selection settings.ServerSelection) (port uint16) {
const (
defaultOpenVPNTCP = 443
defaultOpenVPNUDP = 1194
defaultWireguard = 51820
)
return utils.GetPort(selection, defaultOpenVPNTCP,
defaultOpenVPNUDP, defaultWireguard)
} }

View File

@@ -27,7 +27,7 @@ func Test_Mullvad_GetConnection(t *testing.T) {
"no server available": { "no server available": {
selection: settings.ServerSelection{}.WithDefaults(providers.Mullvad), selection: settings.ServerSelection{}.WithDefaults(providers.Mullvad),
errWrapped: utils.ErrNoServerFound, errWrapped: utils.ErrNoServerFound,
errMessage: "no server found: for VPN openvpn; protocol udp", errMessage: "cannot filter servers: no server found: for VPN openvpn; protocol udp",
}, },
"no filter": { "no filter": {
servers: []models.Server{ servers: []models.Server{
@@ -72,6 +72,7 @@ func Test_Mullvad_GetConnection(t *testing.T) {
Type: vpn.OpenVPN, Type: vpn.OpenVPN,
IP: net.IPv4(2, 2, 2, 2), IP: net.IPv4(2, 2, 2, 2),
Port: 1194, Port: 1194,
Hostname: "b",
Protocol: constants.UDP, Protocol: constants.UDP,
}, },
}, },

View File

@@ -2,37 +2,12 @@ package nordvpn
import ( import (
"github.com/qdm12/gluetun/internal/configuration/settings" "github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models" "github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/provider/utils" "github.com/qdm12/gluetun/internal/provider/utils"
) )
func (n *Nordvpn) GetConnection(selection settings.ServerSelection) ( func (n *Nordvpn) GetConnection(selection settings.ServerSelection) (
connection models.Connection, err error) { connection models.Connection, err error) {
var port uint16 = 1194 defaults := utils.NewConnectionDefaults(443, 1194, 0) //nolint:gomnd
protocol := constants.UDP return utils.GetConnection(n.servers, selection, defaults, n.randSource)
if *selection.OpenVPN.TCP {
port = 443
protocol = constants.TCP
}
servers, err := utils.FilterServers(n.servers, selection)
if err != nil {
return connection, err
}
connections := make([]models.Connection, 0, len(servers))
for _, server := range servers {
for _, ip := range server.IPs {
connection := models.Connection{
Type: selection.VPN,
IP: ip,
Port: port,
Protocol: protocol,
}
connections = append(connections, connection)
}
}
return utils.PickConnection(connections, selection, n.randSource)
} }

View File

@@ -8,30 +8,6 @@ import (
func (p *Perfectprivacy) GetConnection(selection settings.ServerSelection) ( func (p *Perfectprivacy) GetConnection(selection settings.ServerSelection) (
connection models.Connection, err error) { connection models.Connection, err error) {
const defaultPort uint16 = 443 defaults := utils.NewConnectionDefaults(443, 443, 0) //nolint:gomnd
port := defaultPort return utils.GetConnection(p.servers, selection, defaults, p.randSource)
if *selection.OpenVPN.CustomPort > 0 {
port = *selection.OpenVPN.CustomPort
}
protocol := utils.GetProtocol(selection)
servers, err := utils.FilterServers(p.servers, selection)
if err != nil {
return connection, err
}
var connections []models.Connection
for _, server := range servers {
for _, IP := range server.IPs {
connection := models.Connection{
Type: selection.VPN,
IP: IP,
Port: port,
Protocol: protocol,
}
connections = append(connections, connection)
}
}
return utils.PickConnection(connections, selection, p.randSource)
} }

View File

@@ -2,34 +2,12 @@ package privado
import ( import (
"github.com/qdm12/gluetun/internal/configuration/settings" "github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models" "github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/provider/utils" "github.com/qdm12/gluetun/internal/provider/utils"
) )
func (p *Privado) GetConnection(selection settings.ServerSelection) ( func (p *Privado) GetConnection(selection settings.ServerSelection) (
connection models.Connection, err error) { connection models.Connection, err error) {
const port = 1194 defaults := utils.NewConnectionDefaults(0, 1194, 0) //nolint:gomnd
const protocol = constants.UDP return utils.GetConnection(p.servers, selection, defaults, p.randSource)
servers, err := utils.FilterServers(p.servers, selection)
if err != nil {
return connection, err
}
connections := make([]models.Connection, 0, len(servers))
for _, server := range servers {
for _, ip := range server.IPs {
connection := models.Connection{
Type: selection.VPN,
IP: ip,
Port: port,
Protocol: protocol,
Hostname: server.Hostname,
}
connections = append(connections, connection)
}
}
return utils.PickConnection(connections, selection, p.randSource)
} }

View File

@@ -9,34 +9,16 @@ import (
func (p *PIA) GetConnection(selection settings.ServerSelection) ( func (p *PIA) GetConnection(selection settings.ServerSelection) (
connection models.Connection, err error) { connection models.Connection, err error) {
protocol := constants.UDP // Set port defaults depending on encryption preset.
if *selection.OpenVPN.TCP { var defaults utils.ConnectionDefaults
protocol = constants.TCP switch *selection.OpenVPN.PIAEncPreset {
case constants.PIAEncryptionPresetNone, constants.PIAEncryptionPresetNormal:
defaults.OpenVPNTCPPort = 502
defaults.OpenVPNUDPPort = 1198
case constants.PIAEncryptionPresetStrong:
defaults.OpenVPNTCPPort = 501
defaults.OpenVPNUDPPort = 1197
} }
port, err := getPort(selection.OpenVPN) return utils.GetConnection(p.servers, selection, defaults, p.randSource)
if err != nil {
return connection, err
}
servers, err := utils.FilterServers(p.servers, selection)
if err != nil {
return connection, err
}
var connections []models.Connection
for _, server := range servers {
for _, IP := range server.IPs {
connection := models.Connection{
Type: selection.VPN,
IP: IP,
Port: port,
Protocol: protocol,
Hostname: server.ServerName, // used for port forwarding TLS
}
connections = append(connections, connection)
}
}
return utils.PickConnection(connections, selection, p.randSource)
} }

View File

@@ -1,62 +0,0 @@
package privateinternetaccess
import (
"errors"
"fmt"
"github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
)
func getPort(openvpnSelection settings.OpenVPNSelection) (
port uint16, err error) {
customPort := *openvpnSelection.CustomPort
tcp := *openvpnSelection.TCP
if customPort == 0 {
return getDefaultPort(tcp, *openvpnSelection.PIAEncPreset), nil
}
if err := checkPort(customPort, tcp); err != nil {
return 0, err
}
return customPort, nil
}
func getDefaultPort(tcp bool, encryptionPreset string) (port uint16) {
if tcp {
switch encryptionPreset {
case constants.PIAEncryptionPresetNone, constants.PIAEncryptionPresetNormal:
port = 502
case constants.PIAEncryptionPresetStrong:
port = 501
}
} else {
switch encryptionPreset {
case constants.PIAEncryptionPresetNone, constants.PIAEncryptionPresetNormal:
port = 1198
case constants.PIAEncryptionPresetStrong:
port = 1197
}
}
return port
}
var ErrInvalidPort = errors.New("invalid port number")
func checkPort(port uint16, tcp bool) (err error) {
if tcp {
switch port {
case 80, 110, 443: //nolint:gomnd
return nil
default:
return fmt.Errorf("%w: %d for protocol TCP", ErrInvalidPort, port)
}
}
switch port {
case 53, 1194, 1197, 1198, 8080, 9201: //nolint:gomnd
return nil
default:
return fmt.Errorf("%w: %d for protocol UDP", ErrInvalidPort, port)
}
}

View File

@@ -2,40 +2,12 @@ package privatevpn
import ( import (
"github.com/qdm12/gluetun/internal/configuration/settings" "github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models" "github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/provider/utils" "github.com/qdm12/gluetun/internal/provider/utils"
) )
func (p *Privatevpn) GetConnection(selection settings.ServerSelection) ( func (p *Privatevpn) GetConnection(selection settings.ServerSelection) (
connection models.Connection, err error) { connection models.Connection, err error) {
protocol := constants.UDP defaults := utils.NewConnectionDefaults(443, 1194, 0) //nolint:gomnd
var port uint16 = 1194 return utils.GetConnection(p.servers, selection, defaults, p.randSource)
if *selection.OpenVPN.TCP {
protocol = constants.TCP
port = 443
}
if *selection.OpenVPN.CustomPort > 0 {
port = *selection.OpenVPN.CustomPort
}
servers, err := utils.FilterServers(p.servers, selection)
if err != nil {
return connection, err
}
var connections []models.Connection
for _, server := range servers {
for _, ip := range server.IPs {
connection := models.Connection{
Type: selection.VPN,
IP: ip,
Port: port,
Protocol: protocol,
}
connections = append(connections, connection)
}
}
return utils.PickConnection(connections, selection, p.randSource)
} }

View File

@@ -2,40 +2,12 @@ package protonvpn
import ( import (
"github.com/qdm12/gluetun/internal/configuration/settings" "github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models" "github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/provider/utils" "github.com/qdm12/gluetun/internal/provider/utils"
) )
func (p *Protonvpn) GetConnection(selection settings.ServerSelection) ( func (p *Protonvpn) GetConnection(selection settings.ServerSelection) (
connection models.Connection, err error) { connection models.Connection, err error) {
protocol := constants.UDP defaults := utils.NewConnectionDefaults(443, 1194, 0) //nolint:gomnd
if *selection.OpenVPN.TCP { return utils.GetConnection(p.servers, selection, defaults, p.randSource)
protocol = constants.TCP
}
port, err := getPort(*selection.OpenVPN.TCP, *selection.OpenVPN.CustomPort)
if err != nil {
return connection, err
}
servers, err := utils.FilterServers(p.servers, selection)
if err != nil {
return connection, err
}
connections := make([]models.Connection, 0, len(servers))
for _, server := range servers {
for _, ip := range server.IPs {
connection := models.Connection{
Type: selection.VPN,
IP: ip,
Port: port,
Protocol: protocol,
}
connections = append(connections, connection)
}
}
return utils.PickConnection(connections, selection, p.randSource)
} }

View File

@@ -1,41 +0,0 @@
package protonvpn
import (
"errors"
"fmt"
)
func getPort(tcp bool, customPort uint16) (port uint16, err error) {
if customPort == 0 {
const defaultTCPPort, defaultUDPPort = 443, 1194
if tcp {
return defaultTCPPort, nil
}
return defaultUDPPort, nil
}
if err := checkPort(customPort, tcp); err != nil {
return 0, err
}
return customPort, nil
}
var ErrInvalidPort = errors.New("invalid port number")
func checkPort(port uint16, tcp bool) (err error) {
if tcp {
switch port {
case 443, 5995, 8443: //nolint:gomnd
return nil
default:
return fmt.Errorf("%w: %d for protocol TCP", ErrInvalidPort, port)
}
}
switch port {
case 80, 443, 1194, 4569, 5060: //nolint:gomnd
return nil
default:
return fmt.Errorf("%w: %d for protocol UDP", ErrInvalidPort, port)
}
}

View File

@@ -2,37 +2,12 @@ package purevpn
import ( import (
"github.com/qdm12/gluetun/internal/configuration/settings" "github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models" "github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/provider/utils" "github.com/qdm12/gluetun/internal/provider/utils"
) )
func (p *Purevpn) GetConnection(selection settings.ServerSelection) ( func (p *Purevpn) GetConnection(selection settings.ServerSelection) (
connection models.Connection, err error) { connection models.Connection, err error) {
protocol := constants.UDP defaults := utils.NewConnectionDefaults(80, 53, 0) //nolint:gomnd
var port uint16 = 53 return utils.GetConnection(p.servers, selection, defaults, p.randSource)
if *selection.OpenVPN.TCP {
protocol = constants.TCP
port = 80
}
servers, err := utils.FilterServers(p.servers, selection)
if err != nil {
return connection, err
}
var connections []models.Connection
for _, server := range servers {
for _, IP := range server.IPs {
connection := models.Connection{
Type: selection.VPN,
IP: IP,
Port: port,
Protocol: protocol,
}
connections = append(connections, connection)
}
}
return utils.PickConnection(connections, selection, p.randSource)
} }

View File

@@ -2,37 +2,12 @@ package surfshark
import ( import (
"github.com/qdm12/gluetun/internal/configuration/settings" "github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models" "github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/provider/utils" "github.com/qdm12/gluetun/internal/provider/utils"
) )
func (s *Surfshark) GetConnection(selection settings.ServerSelection) ( func (s *Surfshark) GetConnection(selection settings.ServerSelection) (
connection models.Connection, err error) { connection models.Connection, err error) {
protocol := constants.UDP defaults := utils.NewConnectionDefaults(1443, 1194, 0) //nolint:gomnd
var port uint16 = 1194 return utils.GetConnection(s.servers, selection, defaults, s.randSource)
if *selection.OpenVPN.TCP {
protocol = constants.TCP
port = 1443
}
servers, err := utils.FilterServers(s.servers, selection)
if err != nil {
return connection, err
}
var connections []models.Connection
for _, server := range servers {
for _, IP := range server.IPs {
connection := models.Connection{
Type: selection.VPN,
IP: IP,
Port: port,
Protocol: protocol,
}
connections = append(connections, connection)
}
}
return utils.PickConnection(connections, selection, s.randSource)
} }

View File

@@ -2,40 +2,12 @@ package torguard
import ( import (
"github.com/qdm12/gluetun/internal/configuration/settings" "github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models" "github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/provider/utils" "github.com/qdm12/gluetun/internal/provider/utils"
) )
func (t *Torguard) GetConnection(selection settings.ServerSelection) ( func (p *Torguard) GetConnection(selection settings.ServerSelection) (
connection models.Connection, err error) { connection models.Connection, err error) {
protocol := constants.UDP defaults := utils.NewConnectionDefaults(1912, 1912, 0) //nolint:gomnd
if *selection.OpenVPN.TCP { return utils.GetConnection(p.servers, selection, defaults, p.randSource)
protocol = constants.TCP
}
var port uint16 = 1912
if *selection.OpenVPN.CustomPort > 0 {
port = *selection.OpenVPN.CustomPort
}
servers, err := utils.FilterServers(t.servers, selection)
if err != nil {
return connection, err
}
var connections []models.Connection
for _, server := range servers {
for _, IP := range server.IPs {
connection := models.Connection{
Type: selection.VPN,
IP: IP,
Port: port,
Protocol: protocol,
}
connections = append(connections, connection)
}
}
return utils.PickConnection(connections, selection, t.randSource)
} }

View File

@@ -0,0 +1,60 @@
package utils
import (
"fmt"
"math/rand"
"github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/models"
)
type ConnectionDefaults struct {
OpenVPNTCPPort uint16
OpenVPNUDPPort uint16
WireguardPort uint16
}
func NewConnectionDefaults(openvpnTCPPort, openvpnUDPPort,
wireguardPort uint16) ConnectionDefaults {
return ConnectionDefaults{
OpenVPNTCPPort: openvpnTCPPort,
OpenVPNUDPPort: openvpnUDPPort,
WireguardPort: wireguardPort,
}
}
func GetConnection(servers []models.Server,
selection settings.ServerSelection,
defaults ConnectionDefaults,
randSource rand.Source) (
connection models.Connection, err error) {
servers, err = FilterServers(servers, selection)
if err != nil {
return connection, fmt.Errorf("cannot filter servers: %w", err)
}
protocol := getProtocol(selection)
port := GetPort(selection, defaults.OpenVPNTCPPort,
defaults.OpenVPNUDPPort, defaults.WireguardPort)
connections := make([]models.Connection, 0, len(servers))
for _, server := range servers {
for _, ip := range server.IPs {
if ip.To4() == nil {
// do not use IPv6 connections for now
continue
}
connection := models.Connection{
Type: selection.VPN,
IP: ip,
Port: port,
Protocol: protocol,
Hostname: server.Hostname,
PubKey: server.WgPubKey, // Wireguard
}
connections = append(connections, connection)
}
}
return PickConnection(connections, selection, randSource)
}

View File

@@ -0,0 +1,9 @@
package utils
import "testing"
func Test_GetConnection(t *testing.T) {
t.Parallel()
// testCases := map[string]struct{}{}
}

View File

@@ -34,7 +34,7 @@ func filterServer(server models.Server,
return true return true
} }
if FilterByProtocol(selection, server.TCP, server.UDP) { if filterByProtocol(selection, server.TCP, server.UDP) {
return true return true
} }

View File

@@ -1,7 +1,11 @@
package utils package utils
import ( import (
"errors"
"fmt"
"github.com/qdm12/gluetun/internal/configuration/settings" "github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/constants/vpn" "github.com/qdm12/gluetun/internal/constants/vpn"
) )
@@ -13,6 +17,7 @@ func GetPort(selection settings.ServerSelection,
if customPort > 0 { if customPort > 0 {
return customPort return customPort
} }
checkDefined("Wireguard", defaultWireguard)
return defaultWireguard return defaultWireguard
default: // OpenVPN default: // OpenVPN
customPort := *selection.OpenVPN.CustomPort customPort := *selection.OpenVPN.CustomPort
@@ -20,8 +25,40 @@ func GetPort(selection settings.ServerSelection,
return customPort return customPort
} }
if *selection.OpenVPN.TCP { if *selection.OpenVPN.TCP {
checkDefined("OpenVPN TCP", defaultOpenVPNTCP)
return defaultOpenVPNTCP return defaultOpenVPNTCP
} }
checkDefined("OpenVPN UDP", defaultOpenVPNUDP)
return defaultOpenVPNUDP return defaultOpenVPNUDP
} }
} }
func checkDefined(portName string, port uint16) {
if port > 0 {
return
}
message := fmt.Sprintf("no default %s port is defined!", portName)
panic(message)
}
var ErrInvalidPort = errors.New("invalid port number")
// CheckPortAllowed for custom port used for OpenVPN.
func CheckPortAllowed(port uint16, tcp bool,
allowedTCP, allowedUDP []uint16) (err error) {
allowedPorts := allowedUDP
protocol := constants.UDP
if tcp {
allowedPorts = allowedTCP
protocol = constants.TCP
}
for _, allowedPort := range allowedPorts {
if port == allowedPort {
return nil
}
}
return fmt.Errorf("%w: %d for protocol %s",
ErrInvalidPort, port, protocol)
}

View File

@@ -22,10 +22,17 @@ func Test_GetPort(t *testing.T) {
testCases := map[string]struct { testCases := map[string]struct {
selection settings.ServerSelection selection settings.ServerSelection
defaultOpenVPNTCP uint16
defaultOpenVPNUDP uint16
defaultWireguard uint16
port uint16 port uint16
panics string
}{ }{
"default": { "default": {
selection: settings.ServerSelection{}.WithDefaults(""), selection: settings.ServerSelection{}.WithDefaults(""),
defaultOpenVPNTCP: defaultOpenVPNTCP,
defaultOpenVPNUDP: defaultOpenVPNUDP,
defaultWireguard: defaultWireguard,
port: defaultOpenVPNUDP, port: defaultOpenVPNUDP,
}, },
"OpenVPN UDP": { "OpenVPN UDP": {
@@ -36,8 +43,21 @@ func Test_GetPort(t *testing.T) {
TCP: boolPtr(false), TCP: boolPtr(false),
}, },
}, },
defaultOpenVPNTCP: defaultOpenVPNTCP,
defaultOpenVPNUDP: defaultOpenVPNUDP,
defaultWireguard: defaultWireguard,
port: defaultOpenVPNUDP, port: defaultOpenVPNUDP,
}, },
"OpenVPN UDP no default port defined": {
selection: settings.ServerSelection{
VPN: vpn.OpenVPN,
OpenVPN: settings.OpenVPNSelection{
CustomPort: uint16Ptr(0),
TCP: boolPtr(false),
},
},
panics: "no default OpenVPN UDP port is defined!",
},
"OpenVPN TCP": { "OpenVPN TCP": {
selection: settings.ServerSelection{ selection: settings.ServerSelection{
VPN: vpn.OpenVPN, VPN: vpn.OpenVPN,
@@ -46,8 +66,19 @@ func Test_GetPort(t *testing.T) {
TCP: boolPtr(true), TCP: boolPtr(true),
}, },
}, },
defaultOpenVPNTCP: defaultOpenVPNTCP,
port: defaultOpenVPNTCP, port: defaultOpenVPNTCP,
}, },
"OpenVPN TCP no default port defined": {
selection: settings.ServerSelection{
VPN: vpn.OpenVPN,
OpenVPN: settings.OpenVPNSelection{
CustomPort: uint16Ptr(0),
TCP: boolPtr(true),
},
},
panics: "no default OpenVPN TCP port is defined!",
},
"OpenVPN custom port": { "OpenVPN custom port": {
selection: settings.ServerSelection{ selection: settings.ServerSelection{
VPN: vpn.OpenVPN, VPN: vpn.OpenVPN,
@@ -61,6 +92,7 @@ func Test_GetPort(t *testing.T) {
selection: settings.ServerSelection{ selection: settings.ServerSelection{
VPN: vpn.Wireguard, VPN: vpn.Wireguard,
}.WithDefaults(""), }.WithDefaults(""),
defaultWireguard: defaultWireguard,
port: defaultWireguard, port: defaultWireguard,
}, },
"Wireguard custom port": { "Wireguard custom port": {
@@ -70,8 +102,15 @@ func Test_GetPort(t *testing.T) {
EndpointPort: uint16Ptr(1234), EndpointPort: uint16Ptr(1234),
}, },
}, },
defaultWireguard: defaultWireguard,
port: 1234, port: 1234,
}, },
"Wireguard no default port defined": {
selection: settings.ServerSelection{
VPN: vpn.Wireguard,
}.WithDefaults(""),
panics: "no default Wireguard port is defined!",
},
} }
for name, testCase := range testCases { for name, testCase := range testCases {
@@ -79,8 +118,20 @@ func Test_GetPort(t *testing.T) {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
t.Parallel() t.Parallel()
if testCase.panics != "" {
assert.PanicsWithValue(t, testCase.panics, func() {
_ = GetPort(testCase.selection,
testCase.defaultOpenVPNTCP,
testCase.defaultOpenVPNUDP,
testCase.defaultWireguard)
})
return
}
port := GetPort(testCase.selection, port := GetPort(testCase.selection,
defaultOpenVPNTCP, defaultOpenVPNUDP, defaultWireguard) testCase.defaultOpenVPNTCP,
testCase.defaultOpenVPNUDP,
testCase.defaultWireguard)
assert.Equal(t, testCase.port, port) assert.Equal(t, testCase.port, port)
}) })

View File

@@ -6,14 +6,14 @@ import (
"github.com/qdm12/gluetun/internal/constants/vpn" "github.com/qdm12/gluetun/internal/constants/vpn"
) )
func GetProtocol(selection settings.ServerSelection) (protocol string) { func getProtocol(selection settings.ServerSelection) (protocol string) {
if selection.VPN == vpn.OpenVPN && *selection.OpenVPN.TCP { if selection.VPN == vpn.OpenVPN && *selection.OpenVPN.TCP {
return constants.TCP return constants.TCP
} }
return constants.UDP return constants.UDP
} }
func FilterByProtocol(selection settings.ServerSelection, func filterByProtocol(selection settings.ServerSelection,
serverTCP, serverUDP bool) (filtered bool) { serverTCP, serverUDP bool) (filtered bool) {
switch selection.VPN { switch selection.VPN {
case vpn.Wireguard: case vpn.Wireguard:

View File

@@ -9,7 +9,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func Test_GetProtocol(t *testing.T) { func Test_getProtocol(t *testing.T) {
t.Parallel() t.Parallel()
testCases := map[string]struct { testCases := map[string]struct {
@@ -50,14 +50,14 @@ func Test_GetProtocol(t *testing.T) {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
t.Parallel() t.Parallel()
protocol := GetProtocol(testCase.selection) protocol := getProtocol(testCase.selection)
assert.Equal(t, testCase.protocol, protocol) assert.Equal(t, testCase.protocol, protocol)
}) })
} }
} }
func Test_FilterByProtocol(t *testing.T) { func Test_filterByProtocol(t *testing.T) {
t.Parallel() t.Parallel()
testCases := map[string]struct { testCases := map[string]struct {
@@ -127,7 +127,7 @@ func Test_FilterByProtocol(t *testing.T) {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
t.Parallel() t.Parallel()
filtered := FilterByProtocol(testCase.selection, filtered := filterByProtocol(testCase.selection,
testCase.serverTCP, testCase.serverUDP) testCase.serverTCP, testCase.serverUDP)
assert.Equal(t, testCase.filtered, filtered) assert.Equal(t, testCase.filtered, filtered)

View File

@@ -2,33 +2,12 @@ package vpnunlimited
import ( import (
"github.com/qdm12/gluetun/internal/configuration/settings" "github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models" "github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/provider/utils" "github.com/qdm12/gluetun/internal/provider/utils"
) )
func (p *Provider) GetConnection(selection settings.ServerSelection) ( func (p *Provider) GetConnection(selection settings.ServerSelection) (
connection models.Connection, err error) { connection models.Connection, err error) {
const port = 1194 defaults := utils.NewConnectionDefaults(0, 1194, 0) //nolint:gomnd
const protocol = constants.UDP return utils.GetConnection(p.servers, selection, defaults, p.randSource)
servers, err := utils.FilterServers(p.servers, selection)
if err != nil {
return connection, err
}
var connections []models.Connection
for _, server := range servers {
for _, IP := range server.IPs {
connection := models.Connection{
Type: selection.VPN,
IP: IP,
Port: port,
Protocol: protocol,
}
connections = append(connections, connection)
}
}
return utils.PickConnection(connections, selection, p.randSource)
} }

View File

@@ -2,33 +2,12 @@ package vyprvpn
import ( import (
"github.com/qdm12/gluetun/internal/configuration/settings" "github.com/qdm12/gluetun/internal/configuration/settings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models" "github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/provider/utils" "github.com/qdm12/gluetun/internal/provider/utils"
) )
func (v *Vyprvpn) GetConnection(selection settings.ServerSelection) ( func (v *Vyprvpn) GetConnection(selection settings.ServerSelection) (
connection models.Connection, err error) { connection models.Connection, err error) {
const port = 443 defaults := utils.NewConnectionDefaults(0, 443, 0) //nolint:gomnd
const protocol = constants.UDP return utils.GetConnection(v.servers, selection, defaults, v.randSource)
servers, err := utils.FilterServers(v.servers, selection)
if err != nil {
return connection, err
}
var connections []models.Connection
for _, server := range servers {
for _, IP := range server.IPs {
connection := models.Connection{
Type: selection.VPN,
IP: IP,
Port: port,
Protocol: protocol,
}
connections = append(connections, connection)
}
}
return utils.PickConnection(connections, selection, v.randSource)
} }

View File

@@ -8,36 +8,6 @@ import (
func (w *Wevpn) GetConnection(selection settings.ServerSelection) ( func (w *Wevpn) GetConnection(selection settings.ServerSelection) (
connection models.Connection, err error) { connection models.Connection, err error) {
port := getPort(selection) defaults := utils.NewConnectionDefaults(1195, 1194, 0) //nolint:gomnd
protocol := utils.GetProtocol(selection) return utils.GetConnection(w.servers, selection, defaults, w.randSource)
servers, err := utils.FilterServers(w.servers, selection)
if err != nil {
return connection, err
}
var connections []models.Connection
for _, server := range servers {
for _, IP := range server.IPs {
connection := models.Connection{
Type: selection.VPN,
IP: IP,
Port: port,
Protocol: protocol,
}
connections = append(connections, connection)
}
}
return utils.PickConnection(connections, selection, w.randSource)
}
func getPort(selection settings.ServerSelection) (port uint16) {
const (
defaultOpenVPNTCP = 1195
defaultOpenVPNUDP = 1194
defaultWireguard = 0 // Wireguard not supported
)
return utils.GetPort(selection, defaultOpenVPNTCP,
defaultOpenVPNUDP, defaultWireguard)
} }

View File

@@ -29,7 +29,7 @@ func Test_Wevpn_GetConnection(t *testing.T) {
VPN: vpn.OpenVPN, VPN: vpn.OpenVPN,
}.WithDefaults(providers.Wevpn), }.WithDefaults(providers.Wevpn),
errWrapped: utils.ErrNoServerFound, errWrapped: utils.ErrNoServerFound,
errMessage: "no server found: for VPN openvpn; protocol udp", errMessage: "cannot filter servers: no server found: for VPN openvpn; protocol udp",
}, },
"no filter": { "no filter": {
servers: []models.Server{ servers: []models.Server{
@@ -74,6 +74,7 @@ func Test_Wevpn_GetConnection(t *testing.T) {
Type: vpn.OpenVPN, Type: vpn.OpenVPN,
IP: net.IPv4(2, 2, 2, 2), IP: net.IPv4(2, 2, 2, 2),
Port: 1194, Port: 1194,
Hostname: "b",
Protocol: constants.UDP, Protocol: constants.UDP,
}, },
}, },

View File

@@ -6,40 +6,8 @@ import (
"github.com/qdm12/gluetun/internal/provider/utils" "github.com/qdm12/gluetun/internal/provider/utils"
) )
func (w *Windscribe) GetConnection(selection settings.ServerSelection) ( func (p *Windscribe) GetConnection(selection settings.ServerSelection) (
connection models.Connection, err error) { connection models.Connection, err error) {
port := getPort(selection) defaults := utils.NewConnectionDefaults(443, 1194, 1194) //nolint:gomnd
protocol := utils.GetProtocol(selection) return utils.GetConnection(p.servers, selection, defaults, p.randSource)
servers, err := utils.FilterServers(w.servers, selection)
if err != nil {
return connection, err
}
var connections []models.Connection
for _, server := range servers {
for _, IP := range server.IPs {
connection := models.Connection{
Type: selection.VPN,
IP: IP,
Port: port,
Protocol: protocol,
Hostname: server.OvpnX509,
PubKey: server.WgPubKey,
}
connections = append(connections, connection)
}
}
return utils.PickConnection(connections, selection, w.randSource)
}
func getPort(selection settings.ServerSelection) (port uint16) {
const (
defaultOpenVPNTCP = 443
defaultOpenVPNUDP = 1194
defaultWireguard = 1194
)
return utils.GetPort(selection, defaultOpenVPNTCP,
defaultOpenVPNUDP, defaultWireguard)
} }

View File

@@ -27,7 +27,7 @@ func Test_Windscribe_GetConnection(t *testing.T) {
"no server available": { "no server available": {
selection: settings.ServerSelection{}.WithDefaults(providers.Windscribe), selection: settings.ServerSelection{}.WithDefaults(providers.Windscribe),
errWrapped: utils.ErrNoServerFound, errWrapped: utils.ErrNoServerFound,
errMessage: "no server found: for VPN openvpn; protocol udp", errMessage: "cannot filter servers: no server found: for VPN openvpn; protocol udp",
}, },
"no filter": { "no filter": {
servers: []models.Server{ servers: []models.Server{
@@ -72,6 +72,7 @@ func Test_Windscribe_GetConnection(t *testing.T) {
Type: vpn.OpenVPN, Type: vpn.OpenVPN,
IP: net.IPv4(2, 2, 2, 2), IP: net.IPv4(2, 2, 2, 2),
Port: 1194, Port: 1194,
Hostname: "b",
Protocol: constants.UDP, Protocol: constants.UDP,
}, },
}, },