feat(protonvpn): feature filters (#2182)

- `SECURE_CORE_ONLY`
- `TOR_ONLY`
- `P2P_ONLY`
This commit is contained in:
Koen van Zuijlen
2024-07-29 08:57:31 +02:00
committed by GitHub
parent 2bf2525bc5
commit cb99f90bb5
11 changed files with 7007 additions and 2933 deletions

View File

@@ -23,6 +23,7 @@ type logicalServer struct {
Region *string `json:"Region"`
City *string `json:"City"`
Servers []physicalServer `json:"Servers"`
Features uint16 `json:"Features"`
}
type physicalServer struct {

View File

@@ -9,8 +9,15 @@ import (
type ipToServer map[string]models.Server
type features struct {
secureCore bool
tor bool
p2p bool
stream bool
}
func (its ipToServer) add(country, region, city, name, hostname string,
free bool, entryIP netip.Addr) {
free bool, entryIP netip.Addr, features features) {
key := entryIP.String()
server, ok := its[key]
@@ -25,6 +32,10 @@ func (its ipToServer) add(country, region, city, name, hostname string,
server.ServerName = name
server.Hostname = hostname
server.Free = free
server.SecureCore = features.secureCore
server.Tor = features.tor
server.P2P = features.p2p
server.Stream = features.stream
server.UDP = true
server.TCP = true
server.IPs = []netip.Addr{entryIP}

View File

@@ -37,6 +37,18 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
// TODO v4 remove `name` field because of
// https://github.com/qdm12/gluetun/issues/1018#issuecomment-1151750179
name := logicalServer.Name
//nolint:lll
// See https://github.com/ProtonVPN/protonvpn-nm-lib/blob/31d5f99fbc89274e4e977a11e7432c0eab5a3ef8/protonvpn_nm_lib/enums.py#L44-L49
featuresBits := logicalServer.Features
features := features{
secureCore: featuresBits&1 != 0,
tor: featuresBits&2 != 0,
p2p: featuresBits&4 != 0,
stream: featuresBits&8 != 0,
// ipv6: featuresBits&16 != 0, - unused.
}
for _, physicalServer := range logicalServer.Servers {
if physicalServer.Status == 0 { // disabled so skip server
u.warner.Warn("ignoring server " + physicalServer.Domain + " with status 0")
@@ -60,7 +72,7 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
u.warner.Warn(warning)
}
ipToServer.add(country, region, city, name, hostname, free, entryIP)
ipToServer.add(country, region, city, name, hostname, free, entryIP, features)
}
}

View File

@@ -57,6 +57,18 @@ func filterServer(server models.Server,
return true
}
if *selection.SecureCoreOnly && !server.SecureCore {
return true
}
if *selection.TorOnly && !server.Tor {
return true
}
if *selection.P2POnly && !server.P2P {
return true
}
if filterByPossibilities(server.Country, selection.Countries) {
return true
}

View File

@@ -115,6 +115,45 @@ func Test_FilterServers(t *testing.T) {
{Stream: true, VPN: vpn.OpenVPN, UDP: true},
},
},
"filter by secure core only": {
selection: settings.ServerSelection{
SecureCoreOnly: boolPtr(true),
}.WithDefaults(providers.Protonvpn),
servers: []models.Server{
{SecureCore: false, VPN: vpn.OpenVPN, UDP: true},
{SecureCore: true, VPN: vpn.OpenVPN, UDP: true},
{SecureCore: false, VPN: vpn.OpenVPN, UDP: true},
},
filtered: []models.Server{
{SecureCore: true, VPN: vpn.OpenVPN, UDP: true},
},
},
"filter by tor only": {
selection: settings.ServerSelection{
TorOnly: boolPtr(true),
}.WithDefaults(providers.Protonvpn),
servers: []models.Server{
{Tor: false, VPN: vpn.OpenVPN, UDP: true},
{Tor: true, VPN: vpn.OpenVPN, UDP: true},
{Tor: false, VPN: vpn.OpenVPN, UDP: true},
},
filtered: []models.Server{
{Tor: true, VPN: vpn.OpenVPN, UDP: true},
},
},
"filter by P2P only": {
selection: settings.ServerSelection{
P2POnly: boolPtr(true),
}.WithDefaults(providers.Protonvpn),
servers: []models.Server{
{P2P: false, VPN: vpn.OpenVPN, UDP: true},
{P2P: true, VPN: vpn.OpenVPN, UDP: true},
{P2P: false, VPN: vpn.OpenVPN, UDP: true},
},
filtered: []models.Server{
{P2P: true, VPN: vpn.OpenVPN, UDP: true},
},
},
"filter by owned": {
selection: settings.ServerSelection{
OwnedOnly: boolPtr(true),