Code maintenance: rework ovpn host extraction

This commit is contained in:
Quentin McGaw
2020-12-31 20:35:49 +00:00
parent 8c769812ae
commit a56471fe73
4 changed files with 65 additions and 64 deletions

View File

@@ -1,26 +1,50 @@
package updater package updater
import ( import (
"errors"
"fmt"
"net"
"strings" "strings"
) )
func extractRemoteLinesFromOpenvpn(content []byte) (remoteLines []string) { var (
lines := strings.Split(string(content), "\n") errRemoteHostNotFound = errors.New("remote host not found")
for _, line := range lines { )
if strings.HasPrefix(line, "remote ") {
remoteLines = append(remoteLines, line) func extractHostFromOVPN(b []byte) (host, warning string, err error) {
const (
rejectIP = true
rejectDomain = false
)
hosts := extractRemoteHostsFromOpenvpn(b, rejectIP, rejectDomain)
if len(hosts) == 0 {
return "", "", errRemoteHostNotFound
} else if len(hosts) > 1 {
warning = fmt.Sprintf(
"only using the first host %q and discarding %d other hosts",
hosts[0], len(hosts)-1)
} }
} return hosts[0], warning, nil
return remoteLines
} }
func extractHostnamesFromRemoteLines(remoteLines []string) (hostnames []string) { func extractRemoteHostsFromOpenvpn(content []byte,
for _, remoteLine := range remoteLines { rejectIP, rejectDomain bool) (hosts []string) {
fields := strings.Fields(remoteLine) lines := strings.Split(string(content), "\n")
if len(fields[1]) == 0 { for _, line := range lines {
if !strings.HasPrefix(line, "remote ") {
continue continue
} }
hostnames = append(hostnames, fields[1]) fields := strings.Fields(line)
if len(fields) == 1 || len(fields[1]) == 0 {
continue
} }
return hostnames host := fields[1]
parsedIP := net.ParseIP(host)
if (rejectIP && parsedIP != nil) ||
(rejectDomain && parsedIP == nil) {
continue
}
hosts = append(hosts, host)
}
return hosts
} }

View File

@@ -3,7 +3,6 @@ package updater
import ( import (
"context" "context"
"fmt" "fmt"
"net"
"sort" "sort"
"github.com/qdm12/gluetun/internal/models" "github.com/qdm12/gluetun/internal/models"
@@ -39,22 +38,12 @@ func findPrivadoServersFromZip(ctx context.Context, client network.Client, looku
if err := ctx.Err(); err != nil { if err := ctx.Err(); err != nil {
return nil, warnings, err return nil, warnings, err
} }
remoteLines := extractRemoteLinesFromOpenvpn(content) hostname, warning, err := extractHostFromOVPN(content)
if len(remoteLines) == 0 { if len(warning) > 0 {
return nil, warnings, fmt.Errorf("cannot find any remote lines in %s", fileName)
}
hostnames := extractHostnamesFromRemoteLines(remoteLines)
if len(hostnames) == 0 {
return nil, warnings, fmt.Errorf("cannot find any hosts in %s", fileName)
} else if len(hostnames) > 1 {
warning := fmt.Sprintf("more than one host in %q, only taking first one %q into account", fileName, hostnames[0])
warnings = append(warnings, warning) warnings = append(warnings, warning)
} }
hostname := hostnames[0] if err != nil {
if net.ParseIP(hostname) != nil { return nil, warnings, fmt.Errorf("%w in %q", err, fileName)
warning := fmt.Sprintf("ignoring IP address host %q in %s", hostname, fileName)
warnings = append(warnings, warning)
continue
} }
const repetition = 1 const repetition = 1
IPs, err := resolveRepeat(ctx, lookupIP, hostname, repetition) IPs, err := resolveRepeat(ctx, lookupIP, hostname, repetition)

View File

@@ -4,7 +4,6 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"net"
"net/http" "net/http"
"sort" "sort"
"strings" "strings"
@@ -84,22 +83,12 @@ func findSurfsharkServersFromZip(ctx context.Context, client network.Client, loo
if strings.HasSuffix(fileName, "_tcp.ovpn") { if strings.HasSuffix(fileName, "_tcp.ovpn") {
continue // only parse UDP files continue // only parse UDP files
} }
remoteLines := extractRemoteLinesFromOpenvpn(content) host, warning, err := extractHostFromOVPN(content)
if len(remoteLines) == 0 { if len(warning) > 0 {
return nil, warnings, fmt.Errorf("cannot find any remote lines in %s", fileName)
}
hosts := extractHostnamesFromRemoteLines(remoteLines)
if len(hosts) == 0 {
return nil, warnings, fmt.Errorf("cannot find any hosts in %s", fileName)
} else if len(hosts) > 1 {
warning := fmt.Sprintf("more than one host in %q, only taking first one %q into account", fileName, hosts[0])
warnings = append(warnings, warning) warnings = append(warnings, warning)
} }
host := hosts[0] if err != nil {
if net.ParseIP(host) != nil { return nil, warnings, fmt.Errorf("%w in %s", err, fileName)
warning := fmt.Sprintf("ignoring IP address host %q in %q", host, fileName)
warnings = append(warnings, warning)
continue
} }
const repetition = 5 const repetition = 5
IPs, err := resolveRepeat(ctx, lookupIP, host, repetition) IPs, err := resolveRepeat(ctx, lookupIP, host, repetition)
@@ -115,7 +104,7 @@ func findSurfsharkServersFromZip(ctx context.Context, client network.Client, loo
if ok { if ok {
delete(mapping, subdomain) delete(mapping, subdomain)
} else { } else {
region = strings.TrimSuffix(hosts[0], ".prod.surfshark.com") region = strings.TrimSuffix(host, ".prod.surfshark.com")
warning := fmt.Sprintf("subdomain %q not found in Surfshark mapping", subdomain) warning := fmt.Sprintf("subdomain %q not found in Surfshark mapping", subdomain)
warnings = append(warnings, warning) warnings = append(warnings, warning)
} }

View File

@@ -3,7 +3,6 @@ package updater
import ( import (
"context" "context"
"fmt" "fmt"
"net"
"sort" "sort"
"strings" "strings"
@@ -12,7 +11,12 @@ import (
) )
func (u *updater) updateVyprvpn(ctx context.Context) (err error) { func (u *updater) updateVyprvpn(ctx context.Context) (err error) {
servers, err := findVyprvpnServers(ctx, u.client, u.lookupIP) servers, warnings, err := findVyprvpnServers(ctx, u.client, u.lookupIP)
if u.options.CLI {
for _, warning := range warnings {
u.logger.Warn("Privado: %s", warning)
}
}
if err != nil { if err != nil {
return fmt.Errorf("cannot update Vyprvpn servers: %w", err) return fmt.Errorf("cannot update Vyprvpn servers: %w", err)
} }
@@ -25,32 +29,27 @@ func (u *updater) updateVyprvpn(ctx context.Context) (err error) {
} }
func findVyprvpnServers(ctx context.Context, client network.Client, lookupIP lookupIPFunc) ( func findVyprvpnServers(ctx context.Context, client network.Client, lookupIP lookupIPFunc) (
servers []models.VyprvpnServer, err error) { servers []models.VyprvpnServer, warnings []string, err error) {
const zipURL = "https://support.vyprvpn.com/hc/article_attachments/360052617332/Vypr_OpenVPN_20200320.zip" const zipURL = "https://support.vyprvpn.com/hc/article_attachments/360052617332/Vypr_OpenVPN_20200320.zip"
contents, err := fetchAndExtractFiles(ctx, client, zipURL) contents, err := fetchAndExtractFiles(ctx, client, zipURL)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
for fileName, content := range contents { for fileName, content := range contents {
if err := ctx.Err(); err != nil { if err := ctx.Err(); err != nil {
return nil, err return nil, warnings, err
} }
remoteLines := extractRemoteLinesFromOpenvpn(content) host, warning, err := extractHostFromOVPN(content)
if len(remoteLines) == 0 { if len(warning) > 0 {
return nil, fmt.Errorf("cannot find any remote lines in %s", fileName) warnings = append(warnings, warning)
} }
hosts := extractHostnamesFromRemoteLines(remoteLines)
if len(hosts) == 0 {
return nil, fmt.Errorf("cannot find any hosts in %s", fileName)
}
var IPs []net.IP
for _, host := range hosts {
const repetitions = 1
newIPs, err := resolveRepeat(ctx, lookupIP, host, repetitions)
if err != nil { if err != nil {
return nil, err return nil, warnings, fmt.Errorf("%w in %s", err, fileName)
} }
IPs = append(IPs, newIPs...) const repetitions = 1
IPs, err := resolveRepeat(ctx, lookupIP, host, repetitions)
if err != nil {
return nil, warnings, err
} }
region := strings.TrimSuffix(fileName, ".ovpn") region := strings.TrimSuffix(fileName, ".ovpn")
region = strings.ReplaceAll(region, " - ", " ") region = strings.ReplaceAll(region, " - ", " ")
@@ -63,7 +62,7 @@ func findVyprvpnServers(ctx context.Context, client network.Client, lookupIP loo
sort.Slice(servers, func(i, j int) bool { sort.Slice(servers, func(i, j int) bool {
return servers[i].Region < servers[j].Region return servers[i].Region < servers[j].Region
}) })
return servers, nil return servers, warnings, nil
} }
func stringifyVyprvpnServers(servers []models.VyprvpnServer) (s string) { func stringifyVyprvpnServers(servers []models.VyprvpnServer) (s string) {