Feature: filter by name and hostname for NordVPN

This commit is contained in:
Quentin McGaw
2021-05-08 22:51:59 +00:00
parent 2924d711cb
commit 248cc0d3d3
8 changed files with 5394 additions and 5326 deletions

View File

@@ -97,7 +97,7 @@ ENV VPNSP=pia \
OPENVPN_CLIENTKEY_SECRETFILE=/run/secrets/openvpn_clientkey \ OPENVPN_CLIENTKEY_SECRETFILE=/run/secrets/openvpn_clientkey \
# Nordvpn only: # Nordvpn only:
SERVER_NUMBER= \ SERVER_NUMBER= \
# ProtonVPN only: # NordVPN and ProtonVPN only:
SERVER_NAME= \ SERVER_NAME= \
# Openvpn # Openvpn
OPENVPN_CIPHER= \ OPENVPN_CIPHER= \

View File

@@ -13,6 +13,14 @@ func (settings *Provider) nordvpnLines() (lines []string) {
lines = append(lines, lastIndent+"Regions: "+commaJoin(settings.ServerSelection.Regions)) lines = append(lines, lastIndent+"Regions: "+commaJoin(settings.ServerSelection.Regions))
} }
if len(settings.ServerSelection.Hostnames) > 0 {
lines = append(lines, lastIndent+"Hostnames: "+commaJoin(settings.ServerSelection.Hostnames))
}
if len(settings.ServerSelection.Names) > 0 {
lines = append(lines, lastIndent+"Names: "+commaJoin(settings.ServerSelection.Hostnames))
}
if numbersUint16 := settings.ServerSelection.Numbers; len(numbersUint16) > 0 { if numbersUint16 := settings.ServerSelection.Numbers; len(numbersUint16) > 0 {
numbersString := make([]string, len(numbersUint16)) numbersString := make([]string, len(numbersUint16))
for i, numberUint16 := range numbersUint16 { for i, numberUint16 := range numbersUint16 {
@@ -42,6 +50,16 @@ func (settings *Provider) readNordvpn(r reader) (err error) {
return err return err
} }
settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", constants.NordvpnHostnameChoices())
if err != nil {
return err
}
settings.ServerSelection.Names, err = r.env.CSVInside("SERVER_NAME", constants.NordvpnHostnameChoices())
if err != nil {
return err
}
settings.ServerSelection.Numbers, err = readNordVPNServerNumbers(r.env) settings.ServerSelection.Numbers, err = readNordVPNServerNumbers(r.env)
if err != nil { if err != nil {
return err return err

File diff suppressed because it is too large Load Diff

View File

@@ -27,8 +27,8 @@ func GetAllServers() (allServers models.AllServers) {
Servers: MullvadServers(), Servers: MullvadServers(),
}, },
Nordvpn: models.NordvpnServers{ Nordvpn: models.NordvpnServers{
Version: 1, Version: 2,
Timestamp: 1620435633, Timestamp: 1620514180,
Servers: NordvpnServers(), Servers: NordvpnServers(),
}, },
Privado: models.PrivadoServers{ Privado: models.PrivadoServers{

View File

@@ -57,7 +57,7 @@ func Test_versions(t *testing.T) {
"Nordvpn": { "Nordvpn": {
model: models.NordvpnServer{}, model: models.NordvpnServer{},
version: allServers.Nordvpn.Version, version: allServers.Nordvpn.Version,
digest: "040de8d0", digest: "a3b5d609",
}, },
"Privado": { "Privado": {
model: models.PrivadoServer{}, model: models.PrivadoServer{},
@@ -163,7 +163,7 @@ func Test_timestamps(t *testing.T) {
"Nordvpn": { "Nordvpn": {
servers: allServers.Nordvpn.Servers, servers: allServers.Nordvpn.Servers,
timestamp: allServers.Nordvpn.Timestamp, timestamp: allServers.Nordvpn.Timestamp,
digest: "69cb84b3", digest: "b2619eea",
}, },
"Privado": { "Privado": {
servers: allServers.Privado.Servers, servers: allServers.Privado.Servers,

View File

@@ -63,16 +63,18 @@ func (s *MullvadServer) String() string {
} }
type NordvpnServer struct { //nolint:maligned type NordvpnServer struct { //nolint:maligned
Region string `json:"region"` Region string `json:"region"`
Number uint16 `json:"number"` Hostname string `json:"hostname"`
IP net.IP `json:"ip"` Name string `json:"name"`
TCP bool `json:"tcp"` Number uint16 `json:"number"`
UDP bool `json:"udp"` IP net.IP `json:"ip"`
TCP bool `json:"tcp"`
UDP bool `json:"udp"`
} }
func (s *NordvpnServer) String() string { func (s *NordvpnServer) String() string {
return fmt.Sprintf("{Region: %q, Number: %d, TCP: %t, UDP: %t, IP: %s}", return fmt.Sprintf("{Region: %q, Hostname: %q, Name: %q, Number: %d, TCP: %t, UDP: %t, IP: %s}",
s.Region, s.Number, s.TCP, s.UDP, goStringifyIP(s.IP)) s.Region, s.Hostname, s.Name, s.Number, s.TCP, s.UDP, goStringifyIP(s.IP))
} }
type PrivadoServer struct { type PrivadoServer struct {

View File

@@ -2,6 +2,7 @@ package provider
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"math/rand" "math/rand"
"net" "net"
@@ -28,7 +29,7 @@ func newNordvpn(servers []models.NordvpnServer, timeNow timeNowFunc) *nordvpn {
} }
} }
func (n *nordvpn) filterServers(regions []string, protocol string, numbers []uint16) ( func (n *nordvpn) filterServers(regions, hostnames, names []string, numbers []uint16, protocol string) (
servers []models.NordvpnServer) { servers []models.NordvpnServer) {
numbersStr := make([]string, len(numbers)) numbersStr := make([]string, len(numbers))
for i := range numbers { for i := range numbers {
@@ -41,6 +42,8 @@ func (n *nordvpn) filterServers(regions []string, protocol string, numbers []uin
protocol == constants.TCP && !server.TCP, protocol == constants.TCP && !server.TCP,
protocol == constants.UDP && !server.UDP, protocol == constants.UDP && !server.UDP,
filterByPossibilities(server.Region, regions), filterByPossibilities(server.Region, regions),
filterByPossibilities(server.Hostname, hostnames),
filterByPossibilities(server.Name, names),
filterByPossibilities(numberStr, numbersStr): filterByPossibilities(numberStr, numbersStr):
default: default:
servers = append(servers, server) servers = append(servers, server)
@@ -49,6 +52,34 @@ func (n *nordvpn) filterServers(regions []string, protocol string, numbers []uin
return servers return servers
} }
var errNoServerFound = errors.New("no server found")
func (n *nordvpn) notFoundErr(selection configuration.ServerSelection) error {
message := "for protocol " + selection.Protocol
if len(selection.Regions) > 0 {
message += " + regions " + commaJoin(selection.Regions)
}
if len(selection.Hostnames) > 0 {
message += " + hostnames " + commaJoin(selection.Hostnames)
}
if len(selection.Names) > 0 {
message += " + names " + commaJoin(selection.Names)
}
if len(selection.Numbers) > 0 {
numbers := make([]string, len(selection.Numbers))
for i, n := range selection.Numbers {
numbers[i] = strconv.Itoa(int(n))
}
message += " + numbers " + commaJoin(numbers)
}
return fmt.Errorf("%w: %s", errNoServerFound, message)
}
func (n *nordvpn) GetOpenVPNConnection(selection configuration.ServerSelection) ( func (n *nordvpn) GetOpenVPNConnection(selection configuration.ServerSelection) (
connection models.OpenVPNConnection, err error) { connection models.OpenVPNConnection, err error) {
var port uint16 var port uint16
@@ -65,10 +96,10 @@ func (n *nordvpn) GetOpenVPNConnection(selection configuration.ServerSelection)
return models.OpenVPNConnection{IP: selection.TargetIP, Port: port, Protocol: selection.Protocol}, nil return models.OpenVPNConnection{IP: selection.TargetIP, Port: port, Protocol: selection.Protocol}, nil
} }
servers := n.filterServers(selection.Regions, selection.Protocol, selection.Numbers) servers := n.filterServers(selection.Regions, selection.Hostnames,
selection.Names, selection.Numbers, selection.Protocol)
if len(servers) == 0 { if len(servers) == 0 {
return connection, fmt.Errorf("no server found for region %s, protocol %s and numbers %v", return connection, n.notFoundErr(selection)
commaJoin(selection.Regions), selection.Protocol, selection.Numbers)
} }
connections := make([]models.OpenVPNConnection, len(servers)) connections := make([]models.OpenVPNConnection, len(servers))

View File

@@ -44,11 +44,13 @@ func GetServers(ctx context.Context, client *http.Client, minServers int) (
} }
server := models.NordvpnServer{ server := models.NordvpnServer{
Region: jsonServer.Country, Region: jsonServer.Country,
Number: number, Hostname: jsonServer.Domain,
IP: ip, Name: jsonServer.Name,
TCP: jsonServer.Features.TCP, Number: number,
UDP: jsonServer.Features.UDP, IP: ip,
TCP: jsonServer.Features.TCP,
UDP: jsonServer.Features.UDP,
} }
servers = append(servers, server) servers = append(servers, server)
} }