Feat: Perfect privacy support (#606)
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"`
|
||||
}
|
||||
|
||||
@@ -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},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -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 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) +
|
||||
|
||||
Reference in New Issue
Block a user