Feat: Perfect privacy support (#606)

This commit is contained in:
Quentin McGaw
2021-10-05 10:44:15 -07:00
committed by GitHub
parent e7c952cbf7
commit e0e3ca3832
38 changed files with 1142 additions and 188 deletions

View File

@@ -88,6 +88,11 @@ func Test_versions(t *testing.T) {
version: allServers.Nordvpn.Version,
digest: "a8043704",
},
"Perfect privacy": {
model: models.PerfectprivacyServer{},
version: allServers.Perfectprivacy.Version,
digest: "233f0dd4",
},
"Privado": {
model: models.PrivadoServer{},
version: allServers.Privado.Version,

View File

@@ -28,26 +28,27 @@ func (s *Storage) logTimeDiff(provider string, persistedUnix, hardcodedUnix int6
func (s *Storage) mergeServers(hardcoded, persisted models.AllServers) models.AllServers {
return models.AllServers{
Version: hardcoded.Version,
Cyberghost: s.mergeCyberghost(hardcoded.Cyberghost, persisted.Cyberghost),
Expressvpn: s.mergeExpressvpn(hardcoded.Expressvpn, persisted.Expressvpn),
Fastestvpn: s.mergeFastestvpn(hardcoded.Fastestvpn, persisted.Fastestvpn),
HideMyAss: s.mergeHideMyAss(hardcoded.HideMyAss, persisted.HideMyAss),
Ipvanish: s.mergeIpvanish(hardcoded.Ipvanish, persisted.Ipvanish),
Ivpn: s.mergeIvpn(hardcoded.Ivpn, persisted.Ivpn),
Mullvad: s.mergeMullvad(hardcoded.Mullvad, persisted.Mullvad),
Nordvpn: s.mergeNordVPN(hardcoded.Nordvpn, persisted.Nordvpn),
Privado: s.mergePrivado(hardcoded.Privado, persisted.Privado),
Pia: s.mergePIA(hardcoded.Pia, persisted.Pia),
Privatevpn: s.mergePrivatevpn(hardcoded.Privatevpn, persisted.Privatevpn),
Protonvpn: s.mergeProtonvpn(hardcoded.Protonvpn, persisted.Protonvpn),
Purevpn: s.mergePureVPN(hardcoded.Purevpn, persisted.Purevpn),
Surfshark: s.mergeSurfshark(hardcoded.Surfshark, persisted.Surfshark),
Torguard: s.mergeTorguard(hardcoded.Torguard, persisted.Torguard),
VPNUnlimited: s.mergeVPNUnlimited(hardcoded.VPNUnlimited, persisted.VPNUnlimited),
Vyprvpn: s.mergeVyprvpn(hardcoded.Vyprvpn, persisted.Vyprvpn),
Wevpn: s.mergeWevpn(hardcoded.Wevpn, persisted.Wevpn),
Windscribe: s.mergeWindscribe(hardcoded.Windscribe, persisted.Windscribe),
Version: hardcoded.Version,
Cyberghost: s.mergeCyberghost(hardcoded.Cyberghost, persisted.Cyberghost),
Expressvpn: s.mergeExpressvpn(hardcoded.Expressvpn, persisted.Expressvpn),
Fastestvpn: s.mergeFastestvpn(hardcoded.Fastestvpn, persisted.Fastestvpn),
HideMyAss: s.mergeHideMyAss(hardcoded.HideMyAss, persisted.HideMyAss),
Ipvanish: s.mergeIpvanish(hardcoded.Ipvanish, persisted.Ipvanish),
Ivpn: s.mergeIvpn(hardcoded.Ivpn, persisted.Ivpn),
Mullvad: s.mergeMullvad(hardcoded.Mullvad, persisted.Mullvad),
Nordvpn: s.mergeNordVPN(hardcoded.Nordvpn, persisted.Nordvpn),
Perfectprivacy: s.mergePerfectprivacy(hardcoded.Perfectprivacy, persisted.Perfectprivacy),
Privado: s.mergePrivado(hardcoded.Privado, persisted.Privado),
Pia: s.mergePIA(hardcoded.Pia, persisted.Pia),
Privatevpn: s.mergePrivatevpn(hardcoded.Privatevpn, persisted.Privatevpn),
Protonvpn: s.mergeProtonvpn(hardcoded.Protonvpn, persisted.Protonvpn),
Purevpn: s.mergePureVPN(hardcoded.Purevpn, persisted.Purevpn),
Surfshark: s.mergeSurfshark(hardcoded.Surfshark, persisted.Surfshark),
Torguard: s.mergeTorguard(hardcoded.Torguard, persisted.Torguard),
VPNUnlimited: s.mergeVPNUnlimited(hardcoded.VPNUnlimited, persisted.VPNUnlimited),
Vyprvpn: s.mergeVyprvpn(hardcoded.Vyprvpn, persisted.Vyprvpn),
Wevpn: s.mergeWevpn(hardcoded.Wevpn, persisted.Wevpn),
Windscribe: s.mergeWindscribe(hardcoded.Windscribe, persisted.Windscribe),
}
}
@@ -123,6 +124,15 @@ func (s *Storage) mergeNordVPN(hardcoded, persisted models.NordvpnServers) model
return persisted
}
func (s *Storage) mergePerfectprivacy(hardcoded, persisted models.PerfectprivacyServers) models.PerfectprivacyServers {
if persisted.Timestamp <= hardcoded.Timestamp {
return hardcoded
}
s.logTimeDiff("Perfect Privacy", persisted.Timestamp, hardcoded.Timestamp)
return persisted
}
func (s *Storage) mergePrivado(hardcoded, persisted models.PrivadoServers) models.PrivadoServers {
if persisted.Timestamp <= hardcoded.Timestamp {
return hardcoded

View File

@@ -126,6 +126,15 @@ func (s *Storage) extractServersFromBytes(b []byte, hardcoded models.AllServers)
}
}
if hardcoded.Perfectprivacy.Version != versions.Perfectprivacy.Version {
s.logVersionDiff("Perfect Privacy", hardcoded.Perfectprivacy.Version, versions.Perfectprivacy.Version)
} else {
err = json.Unmarshal(rawMessages.Perfectprivacy, &servers.Perfectprivacy)
if err != nil {
return servers, fmt.Errorf("%w: %s: %s", errDecodeProvider, "Perfect Privacy", err)
}
}
if hardcoded.Privado.Version != versions.Privado.Version {
s.logVersionDiff("Privado", hardcoded.Privado.Version, versions.Privado.Version)
} else {
@@ -231,26 +240,27 @@ func (s *Storage) extractServersFromBytes(b []byte, hardcoded models.AllServers)
// allVersions is a subset of models.AllServers structure used to track
// versions to avoid unmarshaling errors.
type allVersions struct {
Version uint16 `json:"version"` // used for migration of the top level scheme
Cyberghost serverVersion `json:"cyberghost"`
Expressvpn serverVersion `json:"expressvpn"`
Fastestvpn serverVersion `json:"fastestvpn"`
HideMyAss serverVersion `json:"hidemyass"`
Ipvanish serverVersion `json:"ipvanish"`
Ivpn serverVersion `json:"ivpn"`
Mullvad serverVersion `json:"mullvad"`
Nordvpn serverVersion `json:"nordvpn"`
Privado serverVersion `json:"privado"`
Pia serverVersion `json:"pia"`
Privatevpn serverVersion `json:"privatevpn"`
Protonvpn serverVersion `json:"protonvpn"`
Purevpn serverVersion `json:"purevpn"`
Surfshark serverVersion `json:"surfshark"`
Torguard serverVersion `json:"torguard"`
VPNUnlimited serverVersion `json:"vpnunlimited"`
Vyprvpn serverVersion `json:"vyprvpn"`
Wevpn serverVersion `json:"wevpn"`
Windscribe serverVersion `json:"windscribe"`
Version uint16 `json:"version"` // used for migration of the top level scheme
Cyberghost serverVersion `json:"cyberghost"`
Expressvpn serverVersion `json:"expressvpn"`
Fastestvpn serverVersion `json:"fastestvpn"`
HideMyAss serverVersion `json:"hidemyass"`
Ipvanish serverVersion `json:"ipvanish"`
Ivpn serverVersion `json:"ivpn"`
Mullvad serverVersion `json:"mullvad"`
Nordvpn serverVersion `json:"nordvpn"`
Perfectprivacy serverVersion `json:"perfectprivacy"`
Privado serverVersion `json:"privado"`
Pia serverVersion `json:"pia"`
Privatevpn serverVersion `json:"privatevpn"`
Protonvpn serverVersion `json:"protonvpn"`
Purevpn serverVersion `json:"purevpn"`
Surfshark serverVersion `json:"surfshark"`
Torguard serverVersion `json:"torguard"`
VPNUnlimited serverVersion `json:"vpnunlimited"`
Vyprvpn serverVersion `json:"vyprvpn"`
Wevpn serverVersion `json:"wevpn"`
Windscribe serverVersion `json:"windscribe"`
}
type serverVersion struct {
@@ -259,24 +269,25 @@ type serverVersion struct {
// allJSONRawMessages is to delay decoding of each provider servers.
type allJSONRawMessages struct {
Version uint16 `json:"version"` // used for migration of the top level scheme
Cyberghost json.RawMessage `json:"cyberghost"`
Expressvpn json.RawMessage `json:"expressvpn"`
Fastestvpn json.RawMessage `json:"fastestvpn"`
HideMyAss json.RawMessage `json:"hidemyass"`
Ipvanish json.RawMessage `json:"ipvanish"`
Ivpn json.RawMessage `json:"ivpn"`
Mullvad json.RawMessage `json:"mullvad"`
Nordvpn json.RawMessage `json:"nordvpn"`
Privado json.RawMessage `json:"privado"`
Pia json.RawMessage `json:"pia"`
Privatevpn json.RawMessage `json:"privatevpn"`
Protonvpn json.RawMessage `json:"protonvpn"`
Purevpn json.RawMessage `json:"purevpn"`
Surfshark json.RawMessage `json:"surfshark"`
Torguard json.RawMessage `json:"torguard"`
VPNUnlimited json.RawMessage `json:"vpnunlimited"`
Vyprvpn json.RawMessage `json:"vyprvpn"`
Wevpn json.RawMessage `json:"wevpn"`
Windscribe json.RawMessage `json:"windscribe"`
Version uint16 `json:"version"` // used for migration of the top level scheme
Cyberghost json.RawMessage `json:"cyberghost"`
Expressvpn json.RawMessage `json:"expressvpn"`
Fastestvpn json.RawMessage `json:"fastestvpn"`
HideMyAss json.RawMessage `json:"hidemyass"`
Ipvanish json.RawMessage `json:"ipvanish"`
Ivpn json.RawMessage `json:"ivpn"`
Mullvad json.RawMessage `json:"mullvad"`
Nordvpn json.RawMessage `json:"nordvpn"`
Perfectprivacy json.RawMessage `json:"perfectprivacy"`
Privado json.RawMessage `json:"privado"`
Pia json.RawMessage `json:"pia"`
Privatevpn json.RawMessage `json:"privatevpn"`
Protonvpn json.RawMessage `json:"protonvpn"`
Purevpn json.RawMessage `json:"purevpn"`
Surfshark json.RawMessage `json:"surfshark"`
Torguard json.RawMessage `json:"torguard"`
VPNUnlimited json.RawMessage `json:"vpnunlimited"`
Vyprvpn json.RawMessage `json:"vyprvpn"`
Wevpn json.RawMessage `json:"wevpn"`
Windscribe json.RawMessage `json:"windscribe"`
}

View File

@@ -30,25 +30,26 @@ func Test_extractServersFromBytes(t *testing.T) {
"different versions": {
b: []byte(`{}`),
hardcoded: models.AllServers{
Cyberghost: models.CyberghostServers{Version: 1},
Expressvpn: models.ExpressvpnServers{Version: 1},
Fastestvpn: models.FastestvpnServers{Version: 1},
HideMyAss: models.HideMyAssServers{Version: 1},
Ipvanish: models.IpvanishServers{Version: 1},
Ivpn: models.IvpnServers{Version: 1},
Mullvad: models.MullvadServers{Version: 1},
Nordvpn: models.NordvpnServers{Version: 1},
Privado: models.PrivadoServers{Version: 1},
Pia: models.PiaServers{Version: 1},
Privatevpn: models.PrivatevpnServers{Version: 1},
Protonvpn: models.ProtonvpnServers{Version: 1},
Purevpn: models.PurevpnServers{Version: 1},
Surfshark: models.SurfsharkServers{Version: 1},
Torguard: models.TorguardServers{Version: 1},
VPNUnlimited: models.VPNUnlimitedServers{Version: 1},
Vyprvpn: models.VyprvpnServers{Version: 1},
Wevpn: models.WevpnServers{Version: 1},
Windscribe: models.WindscribeServers{Version: 1},
Cyberghost: models.CyberghostServers{Version: 1},
Expressvpn: models.ExpressvpnServers{Version: 1},
Fastestvpn: models.FastestvpnServers{Version: 1},
HideMyAss: models.HideMyAssServers{Version: 1},
Ipvanish: models.IpvanishServers{Version: 1},
Ivpn: models.IvpnServers{Version: 1},
Mullvad: models.MullvadServers{Version: 1},
Nordvpn: models.NordvpnServers{Version: 1},
Perfectprivacy: models.PerfectprivacyServers{Version: 1},
Privado: models.PrivadoServers{Version: 1},
Pia: models.PiaServers{Version: 1},
Privatevpn: models.PrivatevpnServers{Version: 1},
Protonvpn: models.ProtonvpnServers{Version: 1},
Purevpn: models.PurevpnServers{Version: 1},
Surfshark: models.SurfsharkServers{Version: 1},
Torguard: models.TorguardServers{Version: 1},
VPNUnlimited: models.VPNUnlimitedServers{Version: 1},
Vyprvpn: models.VyprvpnServers{Version: 1},
Wevpn: models.WevpnServers{Version: 1},
Windscribe: models.WindscribeServers{Version: 1},
},
logged: []string{
"Cyberghost servers from file discarded because they have version 0 and hardcoded servers have version 1",
@@ -59,6 +60,7 @@ func Test_extractServersFromBytes(t *testing.T) {
"Ivpn servers from file discarded because they have version 0 and hardcoded servers have version 1",
"Mullvad servers from file discarded because they have version 0 and hardcoded servers have version 1",
"Nordvpn servers from file discarded because they have version 0 and hardcoded servers have version 1",
"Perfect Privacy servers from file discarded because they have version 0 and hardcoded servers have version 1",
"Privado servers from file discarded because they have version 0 and hardcoded servers have version 1",
"Pia servers from file discarded because they have version 0 and hardcoded servers have version 1",
"Privatevpn servers from file discarded because they have version 0 and hardcoded servers have version 1",
@@ -82,6 +84,7 @@ func Test_extractServersFromBytes(t *testing.T) {
"ivpn": {"version": 1, "timestamp": 1},
"mullvad": {"version": 1, "timestamp": 1},
"nordvpn": {"version": 1, "timestamp": 1},
"perfectprivacy": {"version": 1, "timestamp": 1},
"privado": {"version": 1, "timestamp": 1},
"pia": {"version": 1, "timestamp": 1},
"privatevpn": {"version": 1, "timestamp": 1},
@@ -95,46 +98,48 @@ func Test_extractServersFromBytes(t *testing.T) {
"windscribe": {"version": 1, "timestamp": 1}
}`),
hardcoded: models.AllServers{
Cyberghost: models.CyberghostServers{Version: 1},
Expressvpn: models.ExpressvpnServers{Version: 1},
Fastestvpn: models.FastestvpnServers{Version: 1},
HideMyAss: models.HideMyAssServers{Version: 1},
Ipvanish: models.IpvanishServers{Version: 1},
Ivpn: models.IvpnServers{Version: 1},
Mullvad: models.MullvadServers{Version: 1},
Nordvpn: models.NordvpnServers{Version: 1},
Privado: models.PrivadoServers{Version: 1},
Pia: models.PiaServers{Version: 1},
Privatevpn: models.PrivatevpnServers{Version: 1},
Protonvpn: models.ProtonvpnServers{Version: 1},
Purevpn: models.PurevpnServers{Version: 1},
Surfshark: models.SurfsharkServers{Version: 1},
Torguard: models.TorguardServers{Version: 1},
VPNUnlimited: models.VPNUnlimitedServers{Version: 1},
Vyprvpn: models.VyprvpnServers{Version: 1},
Wevpn: models.WevpnServers{Version: 1},
Windscribe: models.WindscribeServers{Version: 1},
Cyberghost: models.CyberghostServers{Version: 1},
Expressvpn: models.ExpressvpnServers{Version: 1},
Fastestvpn: models.FastestvpnServers{Version: 1},
HideMyAss: models.HideMyAssServers{Version: 1},
Ipvanish: models.IpvanishServers{Version: 1},
Ivpn: models.IvpnServers{Version: 1},
Mullvad: models.MullvadServers{Version: 1},
Nordvpn: models.NordvpnServers{Version: 1},
Perfectprivacy: models.PerfectprivacyServers{Version: 1},
Privado: models.PrivadoServers{Version: 1},
Pia: models.PiaServers{Version: 1},
Privatevpn: models.PrivatevpnServers{Version: 1},
Protonvpn: models.ProtonvpnServers{Version: 1},
Purevpn: models.PurevpnServers{Version: 1},
Surfshark: models.SurfsharkServers{Version: 1},
Torguard: models.TorguardServers{Version: 1},
VPNUnlimited: models.VPNUnlimitedServers{Version: 1},
Vyprvpn: models.VyprvpnServers{Version: 1},
Wevpn: models.WevpnServers{Version: 1},
Windscribe: models.WindscribeServers{Version: 1},
},
persisted: models.AllServers{
Cyberghost: models.CyberghostServers{Version: 1, Timestamp: 1},
Expressvpn: models.ExpressvpnServers{Version: 1, Timestamp: 1},
Fastestvpn: models.FastestvpnServers{Version: 1, Timestamp: 1},
HideMyAss: models.HideMyAssServers{Version: 1, Timestamp: 1},
Ipvanish: models.IpvanishServers{Version: 1, Timestamp: 1},
Ivpn: models.IvpnServers{Version: 1, Timestamp: 1},
Mullvad: models.MullvadServers{Version: 1, Timestamp: 1},
Nordvpn: models.NordvpnServers{Version: 1, Timestamp: 1},
Privado: models.PrivadoServers{Version: 1, Timestamp: 1},
Pia: models.PiaServers{Version: 1, Timestamp: 1},
Privatevpn: models.PrivatevpnServers{Version: 1, Timestamp: 1},
Protonvpn: models.ProtonvpnServers{Version: 1, Timestamp: 1},
Purevpn: models.PurevpnServers{Version: 1, Timestamp: 1},
Surfshark: models.SurfsharkServers{Version: 1, Timestamp: 1},
Torguard: models.TorguardServers{Version: 1, Timestamp: 1},
VPNUnlimited: models.VPNUnlimitedServers{Version: 1, Timestamp: 1},
Vyprvpn: models.VyprvpnServers{Version: 1, Timestamp: 1},
Wevpn: models.WevpnServers{Version: 1, Timestamp: 1},
Windscribe: models.WindscribeServers{Version: 1, Timestamp: 1},
Cyberghost: models.CyberghostServers{Version: 1, Timestamp: 1},
Expressvpn: models.ExpressvpnServers{Version: 1, Timestamp: 1},
Fastestvpn: models.FastestvpnServers{Version: 1, Timestamp: 1},
HideMyAss: models.HideMyAssServers{Version: 1, Timestamp: 1},
Ipvanish: models.IpvanishServers{Version: 1, Timestamp: 1},
Ivpn: models.IvpnServers{Version: 1, Timestamp: 1},
Mullvad: models.MullvadServers{Version: 1, Timestamp: 1},
Nordvpn: models.NordvpnServers{Version: 1, Timestamp: 1},
Perfectprivacy: models.PerfectprivacyServers{Version: 1, Timestamp: 1},
Privado: models.PrivadoServers{Version: 1, Timestamp: 1},
Pia: models.PiaServers{Version: 1, Timestamp: 1},
Privatevpn: models.PrivatevpnServers{Version: 1, Timestamp: 1},
Protonvpn: models.ProtonvpnServers{Version: 1, Timestamp: 1},
Purevpn: models.PurevpnServers{Version: 1, Timestamp: 1},
Surfshark: models.SurfsharkServers{Version: 1, Timestamp: 1},
Torguard: models.TorguardServers{Version: 1, Timestamp: 1},
VPNUnlimited: models.VPNUnlimitedServers{Version: 1, Timestamp: 1},
Vyprvpn: models.VyprvpnServers{Version: 1, Timestamp: 1},
Wevpn: models.WevpnServers{Version: 1, Timestamp: 1},
Windscribe: models.WindscribeServers{Version: 1, Timestamp: 1},
},
},
}

View File

@@ -39835,6 +39835,421 @@
}
]
},
"perfectprivacy": {
"version": 1,
"timestamp": 1633357036,
"servers": [
{
"city": "Amsterdam",
"ips": [
"95.211.95.244",
"95.211.95.244",
"95.211.95.244",
"37.48.94.1",
"85.17.64.131",
"95.211.95.232",
"85.17.28.145"
],
"tcp": true,
"udp": true
},
{
"city": "Basel",
"ips": [
"82.199.134.162",
"82.199.134.162",
"82.199.134.162",
"80.255.7.66"
],
"tcp": true,
"udp": true
},
{
"city": "Belgrade",
"ips": [
"152.89.160.98",
"152.89.160.98",
"152.89.160.98"
],
"tcp": true,
"udp": true
},
{
"city": "Berlin",
"ips": [
"80.255.7.98",
"80.255.7.98",
"80.255.7.98"
],
"tcp": true,
"udp": true
},
{
"city": "Bucharest",
"ips": [
"185.57.82.25",
"185.57.82.25",
"185.57.82.25"
],
"tcp": true,
"udp": true
},
{
"city": "Calais",
"ips": [
"149.202.77.77",
"149.202.77.77",
"149.202.77.77"
],
"tcp": true,
"udp": true
},
{
"city": "Chicago",
"ips": [
"104.237.193.26",
"104.237.193.26",
"104.237.193.26"
],
"tcp": true,
"udp": true
},
{
"city": "Copenhagen",
"ips": [
"185.152.32.66",
"185.152.32.66",
"185.152.32.66"
],
"tcp": true,
"udp": true
},
{
"city": "Dallas",
"ips": [
"138.128.136.164",
"138.128.136.164",
"138.128.136.164"
],
"tcp": true,
"udp": true
},
{
"city": "Erfurt",
"ips": [
"217.114.218.18",
"217.114.218.18",
"217.114.218.18"
],
"tcp": true,
"udp": true
},
{
"city": "Frankfurt",
"ips": [
"178.162.194.30",
"178.162.194.30",
"178.162.194.30",
"37.58.58.239"
],
"tcp": true,
"udp": true
},
{
"city": "Hamburg",
"ips": [
"80.255.7.114",
"80.255.7.114",
"80.255.7.114"
],
"tcp": true,
"udp": true
},
{
"city": "Hongkong",
"ips": [
"209.58.188.129",
"209.58.188.129",
"209.58.188.129"
],
"tcp": true,
"udp": true
},
{
"city": "Istanbul",
"ips": [
"185.65.205.18",
"185.65.205.18",
"185.65.205.18"
],
"tcp": true,
"udp": true
},
{
"city": "Jerusalem",
"ips": [
"82.81.85.231",
"82.81.85.231",
"82.81.85.231"
],
"tcp": true,
"udp": true
},
{
"city": "London",
"ips": [
"82.199.130.34",
"82.199.130.34",
"82.199.130.34",
"5.187.21.98"
],
"tcp": true,
"udp": true
},
{
"city": "LosAngeles",
"ips": [
"162.245.206.242",
"162.245.206.242",
"162.245.206.242"
],
"tcp": true,
"udp": true
},
{
"city": "Madrid",
"ips": [
"185.183.106.146",
"185.183.106.146",
"185.183.106.146"
],
"tcp": true,
"udp": true
},
{
"city": "Malmoe",
"ips": [
"194.68.170.51",
"194.68.170.51",
"194.68.170.51"
],
"tcp": true,
"udp": true
},
{
"city": "Manchester",
"ips": [
"217.138.196.98",
"217.138.196.98",
"217.138.196.98"
],
"tcp": true,
"udp": true
},
{
"city": "Miami",
"ips": [
"38.132.118.66",
"38.132.118.66",
"38.132.118.66"
],
"tcp": true,
"udp": true
},
{
"city": "Milan",
"ips": [
"192.145.127.210",
"192.145.127.210",
"192.145.127.210"
],
"tcp": true,
"udp": true
},
{
"city": "Montreal",
"ips": [
"167.114.209.103",
"167.114.209.103",
"167.114.209.103"
],
"tcp": true,
"udp": true
},
{
"city": "Moscow",
"ips": [
"192.162.100.241",
"192.162.100.241",
"192.162.100.241",
"192.162.100.240"
],
"tcp": true,
"udp": true
},
{
"city": "NewYork",
"ips": [
"96.9.246.194",
"96.9.246.194",
"96.9.246.194"
],
"tcp": true,
"udp": true
},
{
"city": "Nuremberg",
"ips": [
"81.95.5.34",
"81.95.5.34",
"81.95.5.34",
"80.255.10.194"
],
"tcp": true,
"udp": true
},
{
"city": "Oslo",
"ips": [
"91.205.187.186",
"91.205.187.186",
"91.205.187.186"
],
"tcp": true,
"udp": true
},
{
"city": "Paris",
"ips": [
"5.135.143.84",
"5.135.143.84",
"5.135.143.84"
],
"tcp": true,
"udp": true
},
{
"city": "Prague",
"ips": [
"195.138.249.2",
"195.138.249.2",
"195.138.249.2"
],
"tcp": true,
"udp": true
},
{
"city": "Reykjavik",
"ips": [
"82.221.105.61",
"82.221.105.61",
"82.221.105.61"
],
"tcp": true,
"udp": true
},
{
"city": "Riga",
"ips": [
"46.183.221.194",
"46.183.221.194",
"46.183.221.194"
],
"tcp": true,
"udp": true
},
{
"city": "Rotterdam",
"ips": [
"31.204.152.102",
"31.204.152.102",
"31.204.152.102",
"31.204.152.189",
"31.204.150.106",
"31.204.150.138",
"31.204.153.106"
],
"tcp": true,
"udp": true
},
{
"city": "Singapore",
"ips": [
"103.254.153.202",
"103.254.153.202",
"103.254.153.202",
"209.58.162.197"
],
"tcp": true,
"udp": true
},
{
"city": "Steinsel",
"ips": [
"94.242.243.162",
"94.242.243.162",
"94.242.243.162",
"94.242.243.66"
],
"tcp": true,
"udp": true
},
{
"city": "Stockholm",
"ips": [
"185.41.240.18",
"185.41.240.18",
"185.41.240.18",
"185.217.1.2"
],
"tcp": true,
"udp": true
},
{
"city": "Strasbourg",
"ips": [
"37.187.163.66",
"37.187.163.66",
"37.187.163.66"
],
"tcp": true,
"udp": true
},
{
"city": "Sydney",
"ips": [
"66.203.112.50",
"66.203.112.50",
"66.203.112.50",
"66.203.112.47"
],
"tcp": true,
"udp": true
},
{
"city": "Tokyo",
"ips": [
"31.204.145.166",
"31.204.145.166",
"31.204.145.166"
],
"tcp": true,
"udp": true
},
{
"city": "Zurich",
"ips": [
"37.120.213.210",
"37.120.213.210",
"37.120.213.210",
"37.120.213.194",
"152.89.162.226"
],
"tcp": true,
"udp": true
}
]
},
"nordvpn": {
"version": 3,
"timestamp": 1627008323,
@@ -111526,4 +111941,4 @@
}
]
}
}
}

View File

@@ -22,6 +22,7 @@ func countServers(allServers models.AllServers) int {
len(allServers.Ivpn.Servers) +
len(allServers.Mullvad.Servers) +
len(allServers.Nordvpn.Servers) +
len(allServers.Perfectprivacy.Servers) +
len(allServers.Privado.Servers) +
len(allServers.Pia.Servers) +
len(allServers.Privatevpn.Servers) +