Maintenance: deduplicate PIA servers by protocols

This commit is contained in:
Quentin McGaw
2021-02-16 13:06:58 +00:00
parent b9b2f691a5
commit c5af536299
6 changed files with 605 additions and 646 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -22,8 +22,8 @@ func GetAllServers() (allServers models.AllServers) {
Servers: NordvpnServers(),
},
Pia: models.PiaServers{
Version: 3,
Timestamp: 1613479739,
Version: 4,
Timestamp: 1613480675,
Servers: PIAServers(),
},
Purevpn: models.PurevpnServers{

View File

@@ -52,7 +52,7 @@ func Test_versions(t *testing.T) {
"Private Internet Access": {
model: models.PIAServer{},
version: allServers.Pia.Version,
digest: "b90147aa",
digest: "3e6066ec",
},
"Privado": {
model: models.PrivadoServer{},
@@ -133,7 +133,7 @@ func Test_timestamps(t *testing.T) {
"Private Internet Access": {
servers: allServers.Pia.Servers,
timestamp: allServers.Pia.Timestamp,
digest: "921daf32",
digest: "e0f95a01",
},
"Purevpn": {
servers: allServers.Purevpn.Servers,

View File

@@ -10,14 +10,15 @@ import (
type PIAServer struct {
Region string `json:"region"`
ServerName string `json:"server_name"`
Protocol string `json:"protocol"`
TCP bool `json:"tcp"`
UDP bool `json:"udp"`
PortForward bool `json:"port_forward"`
IP net.IP `json:"ip"`
}
func (p *PIAServer) String() string {
return fmt.Sprintf("{Region: %q, ServerName: %q, Protocol: %q, PortForward: %t, IP: %s}",
p.Region, p.ServerName, p.Protocol, p.PortForward, goStringifyIP(p.IP))
return fmt.Sprintf("{Region: %q, ServerName: %q, TCP: %t, UDP: %t, PortForward: %t, IP: %s}",
p.Region, p.ServerName, p.TCP, p.UDP, p.PortForward, goStringifyIP(p.IP))
}
type MullvadServer struct {

View File

@@ -341,8 +341,9 @@ func filterPIAServers(servers []models.PIAServer, regions []string, protocol str
filtered []models.PIAServer) {
for _, server := range servers {
switch {
case filterByPossibilities(server.Region, regions):
case server.Protocol != protocol:
case filterByPossibilities(server.Region, regions),
protocol == constants.TCP && !server.TCP,
protocol == constants.UDP && !server.UDP:
default:
filtered = append(filtered, server)
}

View File

@@ -10,7 +10,6 @@ import (
"sort"
"strings"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/gluetun/internal/models"
)
@@ -48,34 +47,62 @@ func (u *updater) updatePIA(ctx context.Context) (err error) {
return err
}
servers := make([]models.PIAServer, 0, len(data.Regions))
// Deduplicate servers with the same IP address
type NetProtocols struct {
tcp, udp bool
}
ipToProtocols := make(map[string]NetProtocols)
for _, region := range data.Regions {
for _, udpServer := range region.Servers.UDP {
protocols := ipToProtocols[udpServer.IP.String()]
protocols.udp = true
ipToProtocols[udpServer.IP.String()] = protocols
}
for _, tcpServer := range region.Servers.TCP {
protocols := ipToProtocols[tcpServer.IP.String()]
protocols.tcp = true
ipToProtocols[tcpServer.IP.String()] = protocols
}
}
servers := make([]models.PIAServer, 0, len(ipToProtocols)) // set the capacity, not the length of the slice
for _, region := range data.Regions {
for _, udpServer := range region.Servers.UDP {
protocols, ok := ipToProtocols[udpServer.IP.String()]
if !ok { // already added that IP for a server
continue
}
server := models.PIAServer{
Region: region.Name,
ServerName: udpServer.CN,
Protocol: constants.UDP,
TCP: protocols.tcp,
UDP: protocols.udp,
PortForward: region.PortForward,
IP: udpServer.IP,
}
delete(ipToProtocols, udpServer.IP.String())
servers = append(servers, server)
}
for _, tcpServer := range region.Servers.TCP {
protocols, ok := ipToProtocols[tcpServer.IP.String()]
if !ok { // already added that IP for a server
continue
}
server := models.PIAServer{
Region: region.Name,
ServerName: tcpServer.CN,
Protocol: constants.TCP,
TCP: protocols.tcp,
UDP: protocols.udp,
PortForward: region.PortForward,
IP: tcpServer.IP,
}
delete(ipToProtocols, tcpServer.IP.String())
servers = append(servers, server)
}
}
sort.Slice(servers, func(i, j int) bool {
if servers[i].Region == servers[j].Region {
if servers[i].ServerName == servers[j].ServerName {
return servers[i].Protocol < servers[j].Protocol
}
return servers[i].ServerName < servers[j].ServerName
}
return servers[i].Region < servers[j].Region