Compare commits
33 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
06c8792887 | ||
|
|
3ea376a1b2 | ||
|
|
9667d30907 | ||
|
|
3f7ccc6c49 | ||
|
|
dd97ff5895 | ||
|
|
2e4d80d9bc | ||
|
|
1227dc5a2b | ||
|
|
ed828bc733 | ||
|
|
c25a018c05 | ||
|
|
266596af68 | ||
|
|
2c77b73ebc | ||
|
|
d81d4bbda3 | ||
|
|
400affe429 | ||
|
|
d3c63680e8 | ||
|
|
28de8a834c | ||
|
|
208374fc54 | ||
|
|
535a136a27 | ||
|
|
ba4c3e30a4 | ||
|
|
16d8a388cb | ||
|
|
5ea31b0b64 | ||
|
|
582c6d1c43 | ||
|
|
c63ae3f3af | ||
|
|
4c0df96a95 | ||
|
|
05c6b9379a | ||
|
|
fb7fdcd925 | ||
|
|
1774e2ad88 | ||
|
|
a402d9135e | ||
|
|
3d2c56d9ee | ||
|
|
f9308e6fed | ||
|
|
6710468020 | ||
|
|
ad1981fff6 | ||
|
|
01f9e71912 | ||
|
|
d41b75ee35 |
4
.github/ISSUE_TEMPLATE/bug.md
vendored
4
.github/ISSUE_TEMPLATE/bug.md
vendored
@@ -39,3 +39,7 @@ PASTE YOUR LOGS
|
||||
IN THERE
|
||||
|
||||
```
|
||||
|
||||
<!---
|
||||
💡 You can highlight your code with https://docs.github.com/en/github/writing-on-github/working-with-advanced-formatting/creating-and-highlighting-code-blocks#syntax-highlight
|
||||
-->
|
||||
|
||||
10
.github/ISSUE_TEMPLATE/help.md
vendored
10
.github/ISSUE_TEMPLATE/help.md
vendored
@@ -7,6 +7,12 @@ assignees:
|
||||
|
||||
---
|
||||
|
||||
<!---
|
||||
⚠️ If this about a Docker configuration problem or another service:
|
||||
Start a discussion at https://github.com/qdm12/gluetun/discussions/new
|
||||
OR I WILL INSTA-CLOSE YOUR ISSUE.
|
||||
-->
|
||||
|
||||
<!---
|
||||
⚠️ Answer the following or I'll insta-close your issue
|
||||
-->
|
||||
@@ -40,6 +46,10 @@ IN THERE
|
||||
|
||||
**What are you using to run your container?**: Docker Compose
|
||||
|
||||
<!---
|
||||
💡 You can highlight your code with https://docs.github.com/en/github/writing-on-github/working-with-advanced-formatting/creating-and-highlighting-code-blocks#syntax-highlight
|
||||
-->
|
||||
|
||||
Please also share your configuration file:
|
||||
|
||||
```yml
|
||||
|
||||
6
.github/labels.yml
vendored
6
.github/labels.yml
vendored
@@ -21,6 +21,9 @@
|
||||
- name: ":cloud: HideMyAss"
|
||||
color: "cfe8d4"
|
||||
description: ""
|
||||
- name: ":cloud: IPVanish"
|
||||
color: "cfe8d4"
|
||||
description: ""
|
||||
- name: ":cloud: IVPN"
|
||||
color: "cfe8d4"
|
||||
description: ""
|
||||
@@ -53,6 +56,9 @@
|
||||
- name: ":cloud: Torguard"
|
||||
color: "cfe8d4"
|
||||
description: ""
|
||||
- name: ":cloud: VPNUnlimited"
|
||||
color: "cfe8d4"
|
||||
description: ""
|
||||
- name: ":cloud: Vyprvpn"
|
||||
color: "cfe8d4"
|
||||
description: ""
|
||||
|
||||
11
.github/workflows/build.yml
vendored
11
.github/workflows/build.yml
vendored
@@ -34,13 +34,7 @@ jobs:
|
||||
touch coverage.txt
|
||||
docker run --rm \
|
||||
-v "$(pwd)/coverage.txt:/tmp/gobuild/coverage.txt" \
|
||||
test-container \
|
||||
go test \
|
||||
-race \
|
||||
-coverpkg=./... \
|
||||
-coverprofile=coverage.txt \
|
||||
-covermode=atomic \
|
||||
./...
|
||||
test-container
|
||||
|
||||
- name: Code security analysis
|
||||
uses: snyk/actions/golang@master
|
||||
@@ -92,13 +86,14 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Build and push final image
|
||||
uses: docker/build-push-action@v2
|
||||
uses: docker/build-push-action@v2.4.0
|
||||
with:
|
||||
platforms: ${{ steps.vars.outputs.platforms }}
|
||||
build-args: |
|
||||
BUILD_DATE=${{ steps.vars.outputs.build_date }}
|
||||
COMMIT=${{ steps.vars.outputs.commit }}
|
||||
VERSION=${{ steps.vars.outputs.version }}
|
||||
ALLTARGETPLATFORMS=${{ steps.vars.outputs.platforms }}
|
||||
tags: |
|
||||
qmcgaw/gluetun:${{ steps.vars.outputs.version }}
|
||||
qmcgaw/private-internet-access:${{ steps.vars.outputs.version }}
|
||||
|
||||
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
scratch.txt
|
||||
@@ -17,6 +17,15 @@ issues:
|
||||
- path: internal/configuration/
|
||||
linters:
|
||||
- dupl
|
||||
- text: "exported: exported var Err*"
|
||||
linters:
|
||||
- revive
|
||||
- text: "mnd: Magic number: 0644*"
|
||||
linters:
|
||||
- gomnd
|
||||
- text: "mnd: Magic number: 0400*"
|
||||
linters:
|
||||
- gomnd
|
||||
linters:
|
||||
disable-all: true
|
||||
enable:
|
||||
@@ -36,12 +45,12 @@ linters:
|
||||
- gocritic
|
||||
- gocyclo
|
||||
- godot
|
||||
- goerr113
|
||||
- goheader
|
||||
- goimports
|
||||
- gomnd
|
||||
- goprintffuncname
|
||||
- gosec
|
||||
- goerr113
|
||||
- gosimple
|
||||
- govet
|
||||
- importas
|
||||
@@ -55,8 +64,8 @@ linters:
|
||||
- nolintlint
|
||||
- prealloc
|
||||
- predeclared
|
||||
- revive
|
||||
- rowserrcheck
|
||||
- exportloopref
|
||||
- sqlclosecheck
|
||||
- staticcheck
|
||||
- structcheck
|
||||
|
||||
21
Dockerfile
21
Dockerfile
@@ -2,9 +2,14 @@ ARG ALPINE_VERSION=3.13
|
||||
ARG GO_VERSION=1.16
|
||||
ARG BUILDPLATFORM=linux/amd64
|
||||
|
||||
FROM --platform=$BUILDPLATFORM qmcgaw/xcputranslate:v0.6.0 AS xcputranslate
|
||||
|
||||
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS base
|
||||
RUN apk --update add git
|
||||
COPY --from=xcputranslate /xcputranslate /usr/local/bin/xcputranslate
|
||||
RUN apk --update add git g++
|
||||
ENV CGO_ENABLED=0
|
||||
ARG GOLANGCI_LINT_VERSION=v1.41.1
|
||||
RUN go get github.com/golangci/golangci-lint/cmd/golangci-lint@${GOLANGCI_LINT_VERSION}
|
||||
WORKDIR /tmp/gobuild
|
||||
COPY go.mod go.sum ./
|
||||
RUN go mod download
|
||||
@@ -14,14 +19,11 @@ COPY internal/ ./internal/
|
||||
FROM --platform=$BUILDPLATFORM base AS test
|
||||
# Note on the go race detector:
|
||||
# - we set CGO_ENABLED=1 to have it enabled
|
||||
# - we install g++ to support the race detector
|
||||
# - we installed g++ to support the race detector
|
||||
ENV CGO_ENABLED=1
|
||||
RUN apk --update --no-cache add g++
|
||||
ENTRYPOINT go test -race -coverpkg=./... -coverprofile=coverage.txt -covermode=atomic ./...
|
||||
|
||||
FROM --platform=$BUILDPLATFORM base AS lint
|
||||
ARG GOLANGCI_LINT_VERSION=v1.40.1
|
||||
RUN wget -O- -nv https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | \
|
||||
sh -s -- -b /usr/local/bin ${GOLANGCI_LINT_VERSION}
|
||||
COPY .golangci.yml ./
|
||||
RUN golangci-lint run --timeout=10m
|
||||
|
||||
@@ -35,13 +37,14 @@ RUN git init && \
|
||||
git diff --exit-code -- go.mod
|
||||
|
||||
FROM --platform=$BUILDPLATFORM base AS build
|
||||
COPY --from=qmcgaw/xcputranslate:v0.4.0 /xcputranslate /usr/local/bin/xcputranslate
|
||||
ARG TARGETPLATFORM
|
||||
ARG ALLTARGETPLATFORMS=${TARGETPLATFORM}
|
||||
ARG VERSION=unknown
|
||||
ARG BUILD_DATE="an unknown date"
|
||||
ARG COMMIT=unknown
|
||||
RUN GOARCH="$(xcputranslate -field arch -targetplatform ${TARGETPLATFORM})" \
|
||||
GOARM="$(xcputranslate -field arm -targetplatform ${TARGETPLATFORM})" \
|
||||
RUN xcputranslate sleep -targetplatform ${TARGETPLATFORM} -buildtime=10s -order=${ALLTARGETPLATFORMS}
|
||||
RUN GOARCH="$(xcputranslate translate -field arch -targetplatform ${TARGETPLATFORM})" \
|
||||
GOARM="$(xcputranslate translate -field arm -targetplatform ${TARGETPLATFORM})" \
|
||||
go build -trimpath -ldflags="-s -w \
|
||||
-X 'main.version=$VERSION' \
|
||||
-X 'main.buildDate=$BUILD_DATE' \
|
||||
|
||||
24
README.md
24
README.md
@@ -1,8 +1,8 @@
|
||||
# Gluetun VPN client
|
||||
|
||||
*Lightweight swiss-knife-like VPN client to tunnel to Cyberghost, FastestVPN,
|
||||
HideMyAss, IVPN, Mullvad, NordVPN, Privado, Private Internet Access, PrivateVPN,
|
||||
ProtonVPN, PureVPN, Surfshark, TorGuard, VyprVPN and Windscribe VPN servers
|
||||
HideMyAss, IPVanish, IVPN, Mullvad, NordVPN, Privado, Private Internet Access, PrivateVPN,
|
||||
ProtonVPN, PureVPN, Surfshark, TorGuard, VPNUnlimited, VyprVPN and Windscribe VPN servers
|
||||
using Go, OpenVPN, iptables, DNS over TLS, ShadowSocks and an HTTP proxy*
|
||||
|
||||
**ANNOUNCEMENT**:
|
||||
@@ -39,7 +39,7 @@ using Go, OpenVPN, iptables, DNS over TLS, ShadowSocks and an HTTP proxy*
|
||||
## Features
|
||||
|
||||
- Based on Alpine 3.13 for a small Docker image of 54MB
|
||||
- Supports: **Cyberghost**, **FastestVPN**, **HideMyAss**, **IVPN**, **Mullvad**, **NordVPN**, **Privado**, **Private Internet Access**, **PrivateVPN**, **ProtonVPN**, **PureVPN**, **Surfshark**, **TorGuard**, **Vyprvpn**, **Windscribe** servers
|
||||
- Supports: **Cyberghost**, **FastestVPN**, **HideMyAss**, **IPVanish**, **IVPN**, **Mullvad**, **NordVPN**, **Privado**, **Private Internet Access**, **PrivateVPN**, **ProtonVPN**, **PureVPN**, **Surfshark**, **TorGuard**, **VPNUnlimited**, **Vyprvpn**, **Windscribe** servers
|
||||
- Supports Openvpn only for now
|
||||
- DNS over TLS baked in with service provider(s) of your choice
|
||||
- DNS fine blocking of malicious/ads/surveillance hostnames and IP addresses, with live update every 24 hours
|
||||
@@ -58,9 +58,17 @@ using Go, OpenVPN, iptables, DNS over TLS, ShadowSocks and an HTTP proxy*
|
||||
|
||||
## Setup
|
||||
|
||||
1. On some devices you may need to setup your tunnel kernel module on your host with `insmod /lib/modules/tun.ko` or `modprobe tun`
|
||||
- [Synology users Wiki page](https://github.com/qdm12/gluetun/wiki/Synology-setup)
|
||||
1. ⚠️ Raspberry Pi users running 32 bit systems: from image `v3.16.0` you need to do [this](https://github.com/alpinelinux/docker-alpine/issues/135#issuecomment-812287338) on your host to run the container.
|
||||
1. Ensure your `tun` kernel module is setup:
|
||||
|
||||
```sh
|
||||
sudo modprobe tun
|
||||
# or, if you don't have modprobe, with
|
||||
sudo insmod /lib/modules/tun.ko
|
||||
```
|
||||
|
||||
1. Extra steps:
|
||||
- [For Synology users](https://github.com/qdm12/gluetun/wiki/Synology-setup)
|
||||
- [For 32 bit Operating systems (**Rasberry Pis**)](https://github.com/qdm12/gluetun/wiki/32-bit-setup)
|
||||
1. Launch the container with:
|
||||
|
||||
```bash
|
||||
@@ -74,8 +82,6 @@ using Go, OpenVPN, iptables, DNS over TLS, ShadowSocks and an HTTP proxy*
|
||||
or use [docker-compose.yml](https://github.com/qdm12/gluetun/blob/master/docker-compose.yml) with:
|
||||
|
||||
```bash
|
||||
echo "your openvpn username" > openvpn_user
|
||||
echo "your openvpn password" > openvpn_password
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
@@ -85,12 +91,12 @@ using Go, OpenVPN, iptables, DNS over TLS, ShadowSocks and an HTTP proxy*
|
||||
|
||||
The following points are all optional but should give you insights on all the possibilities with this container.
|
||||
|
||||
- Use [Docker secrets](https://github.com/qdm12/gluetun/wiki/Docker-secrets) to read your credentials instead of environment variables
|
||||
- [Test your setup](https://github.com/qdm12/gluetun/wiki/Test-your-setup)
|
||||
- [How to connect other containers and devices to Gluetun](https://github.com/qdm12/gluetun/wiki/Connect-to-gluetun)
|
||||
- [VPN server side port forwarding](https://github.com/qdm12/gluetun/wiki/Port-forwarding)
|
||||
- [HTTP control server](https://github.com/qdm12/gluetun/wiki/HTTP-Control-server) to automate things, restart Openvpn etc.
|
||||
- Update the image with `docker pull qmcgaw/gluetun:latest`. See this [Wiki document](https://github.com/qdm12/gluetun/wiki/Docker-image-tags) for Docker tags available.
|
||||
- Use [Docker secrets](https://github.com/qdm12/gluetun/wiki/Docker-secrets) to read your credentials instead of environment variables
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@ import (
|
||||
"github.com/qdm12/gluetun/internal/routing"
|
||||
"github.com/qdm12/gluetun/internal/server"
|
||||
"github.com/qdm12/gluetun/internal/shadowsocks"
|
||||
"github.com/qdm12/gluetun/internal/shutdown"
|
||||
"github.com/qdm12/gluetun/internal/storage"
|
||||
"github.com/qdm12/gluetun/internal/unix"
|
||||
"github.com/qdm12/gluetun/internal/updater"
|
||||
@@ -38,6 +37,7 @@ import (
|
||||
"github.com/qdm12/golibs/os"
|
||||
"github.com/qdm12/golibs/os/user"
|
||||
"github.com/qdm12/golibs/params"
|
||||
"github.com/qdm12/goshutdown"
|
||||
"github.com/qdm12/updated/pkg/dnscrypto"
|
||||
)
|
||||
|
||||
@@ -275,82 +275,113 @@ func _main(ctx context.Context, buildInfo models.BuildInformation,
|
||||
}
|
||||
} // TODO move inside firewall?
|
||||
|
||||
const (
|
||||
shutdownMaxTimeout = 3 * time.Second
|
||||
shutdownRoutineTimeout = 400 * time.Millisecond
|
||||
shutdownOpenvpnTimeout = time.Second
|
||||
)
|
||||
|
||||
healthy := make(chan bool)
|
||||
controlWave := shutdown.NewWave("control")
|
||||
tickerWave := shutdown.NewWave("tickers")
|
||||
healthWave := shutdown.NewWave("health")
|
||||
dnsWave := shutdown.NewWave("DNS")
|
||||
vpnWave := shutdown.NewWave("VPN")
|
||||
serverWave := shutdown.NewWave("servers")
|
||||
|
||||
// Shutdown settings
|
||||
const defaultShutdownTimeout = 400 * time.Millisecond
|
||||
defaultShutdownOnSuccess := func(goRoutineName string) {
|
||||
logger.Info(goRoutineName + ": terminated ✔️")
|
||||
}
|
||||
defaultShutdownOnFailure := func(goRoutineName string, err error) {
|
||||
logger.Warn(goRoutineName + ": " + err.Error() + " ⚠️")
|
||||
}
|
||||
defaultGoRoutineSettings := goshutdown.GoRoutineSettings{Timeout: defaultShutdownTimeout}
|
||||
defaultGroupSettings := goshutdown.GroupSettings{
|
||||
Timeout: defaultShutdownTimeout,
|
||||
OnFailure: defaultShutdownOnFailure,
|
||||
OnSuccess: defaultShutdownOnSuccess,
|
||||
}
|
||||
|
||||
controlGroupHandler := goshutdown.NewGroupHandler("control", defaultGroupSettings)
|
||||
tickersGroupHandler := goshutdown.NewGroupHandler("tickers", defaultGroupSettings)
|
||||
otherGroupHandler := goshutdown.NewGroupHandler("other", defaultGroupSettings)
|
||||
|
||||
openvpnLooper := openvpn.NewLooper(allSettings.OpenVPN, nonRootUsername, puid, pgid, allServers,
|
||||
ovpnConf, firewallConf, routingConf, logger, httpClient, os.OpenFile, tunnelReadyCh, healthy)
|
||||
openvpnCtx, openvpnDone := vpnWave.Add("openvpn", shutdownOpenvpnTimeout)
|
||||
openvpnHandler, openvpnCtx, openvpnDone := goshutdown.NewGoRoutineHandler(
|
||||
"openvpn", goshutdown.GoRoutineSettings{Timeout: time.Second})
|
||||
// wait for restartOpenvpn
|
||||
go openvpnLooper.Run(openvpnCtx, openvpnDone)
|
||||
|
||||
updaterLooper := updater.NewLooper(allSettings.Updater,
|
||||
allServers, storage, openvpnLooper.SetServers, httpClient,
|
||||
logger.NewChild(logging.Settings{Prefix: "updater: "}))
|
||||
updaterCtx, updaterDone := tickerWave.Add("updater", shutdownRoutineTimeout)
|
||||
updaterHandler, updaterCtx, updaterDone := goshutdown.NewGoRoutineHandler(
|
||||
"updater", defaultGoRoutineSettings)
|
||||
// wait for updaterLooper.Restart() or its ticket launched with RunRestartTicker
|
||||
go updaterLooper.Run(updaterCtx, updaterDone)
|
||||
tickersGroupHandler.Add(updaterHandler)
|
||||
|
||||
unboundLogger := logger.NewChild(logging.Settings{Prefix: "dns over tls: "})
|
||||
unboundLooper := dns.NewLooper(dnsConf, allSettings.DNS, httpClient,
|
||||
unboundLogger, os.OpenFile)
|
||||
dnsCtx, dnsDone := dnsWave.Add("unbound", shutdownRoutineTimeout)
|
||||
dnsHandler, dnsCtx, dnsDone := goshutdown.NewGoRoutineHandler(
|
||||
"unbound", defaultGoRoutineSettings)
|
||||
// wait for unboundLooper.Restart or its ticker launched with RunRestartTicker
|
||||
go unboundLooper.Run(dnsCtx, dnsDone)
|
||||
otherGroupHandler.Add(dnsHandler)
|
||||
|
||||
publicIPLooper := publicip.NewLooper(httpClient,
|
||||
logger.NewChild(logging.Settings{Prefix: "ip getter: "}),
|
||||
allSettings.PublicIP, puid, pgid, os)
|
||||
pubIPCtx, pubIPDone := serverWave.Add("public IP", shutdownRoutineTimeout)
|
||||
pubIPHandler, pubIPCtx, pubIPDone := goshutdown.NewGoRoutineHandler(
|
||||
"public IP", defaultGoRoutineSettings)
|
||||
go publicIPLooper.Run(pubIPCtx, pubIPDone)
|
||||
otherGroupHandler.Add(pubIPHandler)
|
||||
|
||||
pubIPTickerCtx, pubIPTickerDone := tickerWave.Add("public IP", shutdownRoutineTimeout)
|
||||
pubIPTickerHandler, pubIPTickerCtx, pubIPTickerDone := goshutdown.NewGoRoutineHandler(
|
||||
"public IP", defaultGoRoutineSettings)
|
||||
go publicIPLooper.RunRestartTicker(pubIPTickerCtx, pubIPTickerDone)
|
||||
tickersGroupHandler.Add(pubIPTickerHandler)
|
||||
|
||||
httpProxyLooper := httpproxy.NewLooper(
|
||||
logger.NewChild(logging.Settings{Prefix: "http proxy: "}),
|
||||
allSettings.HTTPProxy)
|
||||
httpProxyCtx, httpProxyDone := serverWave.Add("http proxy", shutdownRoutineTimeout)
|
||||
httpProxyHandler, httpProxyCtx, httpProxyDone := goshutdown.NewGoRoutineHandler(
|
||||
"http proxy", defaultGoRoutineSettings)
|
||||
go httpProxyLooper.Run(httpProxyCtx, httpProxyDone)
|
||||
otherGroupHandler.Add(httpProxyHandler)
|
||||
|
||||
shadowsocksLooper := shadowsocks.NewLooper(allSettings.ShadowSocks,
|
||||
logger.NewChild(logging.Settings{Prefix: "shadowsocks: "}))
|
||||
shadowsocksCtx, shadowsocksDone := serverWave.Add("shadowsocks proxy", shutdownRoutineTimeout)
|
||||
shadowsocksHandler, shadowsocksCtx, shadowsocksDone := goshutdown.NewGoRoutineHandler(
|
||||
"shadowsocks proxy", defaultGoRoutineSettings)
|
||||
go shadowsocksLooper.Run(shadowsocksCtx, shadowsocksDone)
|
||||
otherGroupHandler.Add(shadowsocksHandler)
|
||||
|
||||
eventsRoutingCtx, eventsRoutingDone := controlWave.Add("events routing", shutdownRoutineTimeout)
|
||||
eventsRoutingHandler, eventsRoutingCtx, eventsRoutingDone := goshutdown.NewGoRoutineHandler(
|
||||
"events routing", defaultGoRoutineSettings)
|
||||
go routeReadyEvents(eventsRoutingCtx, eventsRoutingDone, buildInfo, tunnelReadyCh,
|
||||
unboundLooper, updaterLooper, publicIPLooper, routingConf, logger, httpClient,
|
||||
allSettings.VersionInformation, allSettings.OpenVPN.Provider.PortForwarding.Enabled, openvpnLooper.PortForward,
|
||||
)
|
||||
controlGroupHandler.Add(eventsRoutingHandler)
|
||||
|
||||
controlServerAddress := ":" + strconv.Itoa(int(allSettings.ControlServer.Port))
|
||||
controlServerLogging := allSettings.ControlServer.Log
|
||||
httpServer := server.New(controlServerAddress, controlServerLogging,
|
||||
logger.NewChild(logging.Settings{Prefix: "http server: "}),
|
||||
buildInfo, openvpnLooper, unboundLooper, updaterLooper, publicIPLooper)
|
||||
httpServerCtx, httpServerDone := controlWave.Add("http server", shutdownRoutineTimeout)
|
||||
httpServerHandler, httpServerCtx, httpServerDone := goshutdown.NewGoRoutineHandler(
|
||||
"http server", defaultGoRoutineSettings)
|
||||
go httpServer.Run(httpServerCtx, httpServerDone)
|
||||
controlGroupHandler.Add(httpServerHandler)
|
||||
|
||||
healthcheckServer := healthcheck.NewServer(constants.HealthcheckAddress,
|
||||
logger.NewChild(logging.Settings{Prefix: "healthcheck: "}))
|
||||
healthServerCtx, healthServerDone := healthWave.Add("HTTP health server", shutdownRoutineTimeout)
|
||||
healthServerHandler, healthServerCtx, healthServerDone := goshutdown.NewGoRoutineHandler(
|
||||
"HTTP health server", defaultGoRoutineSettings)
|
||||
go healthcheckServer.Run(healthServerCtx, healthy, healthServerDone)
|
||||
|
||||
shutdownOrder := shutdown.NewOrder()
|
||||
shutdownOrder.Append(controlWave, tickerWave, healthWave,
|
||||
dnsWave, vpnWave, serverWave,
|
||||
)
|
||||
const orderShutdownTimeout = 3 * time.Second
|
||||
orderSettings := goshutdown.OrderSettings{
|
||||
Timeout: orderShutdownTimeout,
|
||||
OnFailure: defaultShutdownOnFailure,
|
||||
OnSuccess: defaultShutdownOnSuccess,
|
||||
}
|
||||
orderHandler := goshutdown.NewOrder("gluetun", orderSettings)
|
||||
orderHandler.Append(controlGroupHandler, tickersGroupHandler, healthServerHandler,
|
||||
openvpnHandler, otherGroupHandler)
|
||||
|
||||
// Start openvpn for the first time in a blocking call
|
||||
// until openvpn is launched
|
||||
@@ -365,7 +396,7 @@ func _main(ctx context.Context, buildInfo models.BuildInformation,
|
||||
}
|
||||
}
|
||||
|
||||
return shutdownOrder.Shutdown(shutdownMaxTimeout, logger)
|
||||
return orderHandler.Shutdown(context.Background())
|
||||
}
|
||||
|
||||
type printVersionElement struct {
|
||||
|
||||
@@ -14,18 +14,11 @@ services:
|
||||
# command:
|
||||
volumes:
|
||||
- /yourpath:/gluetun
|
||||
secrets:
|
||||
- openvpn_user
|
||||
- openvpn_password
|
||||
environment:
|
||||
# More variables are available, see the readme table
|
||||
- OPENVPN_USER=
|
||||
- OPENVPN_PASSWORD=
|
||||
- VPNSP=private internet access
|
||||
# Timezone for accurate logs times
|
||||
- TZ=
|
||||
restart: always
|
||||
|
||||
secrets:
|
||||
openvpn_user:
|
||||
file: ./openvpn_user
|
||||
openvpn_password:
|
||||
file: ./openvpn_password
|
||||
|
||||
12
go.mod
12
go.mod
@@ -3,13 +3,13 @@ module github.com/qdm12/gluetun
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/fatih/color v1.10.0
|
||||
github.com/golang/mock v1.5.0
|
||||
github.com/kyokomi/emoji v2.2.4+incompatible
|
||||
github.com/qdm12/dns v1.7.0
|
||||
github.com/qdm12/golibs v0.0.0-20210402232648-cfebf1e87d1b
|
||||
github.com/fatih/color v1.12.0
|
||||
github.com/golang/mock v1.6.0
|
||||
github.com/qdm12/dns v1.8.0
|
||||
github.com/qdm12/golibs v0.0.0-20210603202746-e5494e9c2ebb
|
||||
github.com/qdm12/goshutdown v0.1.0
|
||||
github.com/qdm12/ss-server v0.2.0
|
||||
github.com/qdm12/updated v0.0.0-20210102012151-76b7f5994638
|
||||
github.com/qdm12/updated v0.0.0-20210603204757-205acfe6937e
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/vishvananda/netlink v1.1.0
|
||||
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015
|
||||
|
||||
71
go.sum
71
go.sum
@@ -1,4 +1,3 @@
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
|
||||
@@ -12,9 +11,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/dvyukov/go-fuzz v0.0.0-20210103155950-6a8e9d1f2415/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
|
||||
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
|
||||
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
|
||||
github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg=
|
||||
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
||||
github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc=
|
||||
github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||
github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
||||
@@ -31,58 +29,52 @@ github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsd
|
||||
github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
|
||||
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
||||
github.com/go-openapi/validate v0.17.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g=
|
||||
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
|
||||
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gotify/go-api-client/v2 v2.0.4/go.mod h1:VKiah/UK20bXsr0JObE1eBVLW44zbBouzjuri9iwjFU=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kyokomi/emoji v2.2.4+incompatible h1:np0woGKwx9LiHAQmwZx79Oc0rHpNw3o+3evou4BEPv4=
|
||||
github.com/kyokomi/emoji v2.2.4+incompatible/go.mod h1:mZ6aGCD7yk8j6QY6KICwnZ2pxoszVseX1DNoGtU2tBA=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
|
||||
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/miekg/dns v1.1.40 h1:pyyPFfGMnciYUk/mXpKkVmeMQjfXqt3FAJ2hy7tPiLA=
|
||||
github.com/miekg/dns v1.1.40/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mr-tron/base58 v1.1.3 h1:v+sk57XuaCKGXpWtVBX8YJzO7hMGx4Aajh4TQbdEFdc=
|
||||
github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
|
||||
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
|
||||
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
|
||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo=
|
||||
github.com/phayes/permbits v0.0.0-20190612203442-39d7c581d2ee/go.mod h1:3uODdxMgOaPYeWU7RzZLxVtJHZ/x1f/iHkBZuKJDzuY=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/qdm12/dns v1.7.0 h1:R8YGDPREzsXKx0k0TUbzPoI0+1oRzAnn79hzRXPHPcg=
|
||||
github.com/qdm12/dns v1.7.0/go.mod h1:f2zChaUVDmE1MxUx+MKMFmBSh4G6DSU0rFZ+hHExSu0=
|
||||
github.com/qdm12/golibs v0.0.0-20201227203847-2fd99ffdfdba/go.mod h1:pikkTN7g7zRuuAnERwqW1yAFq6pYmxrxpjiwGvb0Ysc=
|
||||
github.com/qdm12/golibs v0.0.0-20210402232648-cfebf1e87d1b h1:tSD0qWqssS8AUFTGmlP1JFfbLViOt7xrjIxGZ1AFacY=
|
||||
github.com/qdm12/golibs v0.0.0-20210402232648-cfebf1e87d1b/go.mod h1:y0qNgur9dTkHK2Bb5tK0UCtYyvEiK08flVIglROmnBg=
|
||||
github.com/qdm12/dns v1.8.0 h1:GZ40kptmfDHOMNxBKWSA4zrbNyGm41BA57zv2MaDtCI=
|
||||
github.com/qdm12/dns v1.8.0/go.mod h1:P2mm63NDYZdx2NAd5CVLM0FBnNdi1ZgVjsRSnX+96vg=
|
||||
github.com/qdm12/golibs v0.0.0-20210603202746-e5494e9c2ebb h1:5WkOssTWl6Tv2H7VFb2jwB08A7BxxNCebkkpvz1PzrY=
|
||||
github.com/qdm12/golibs v0.0.0-20210603202746-e5494e9c2ebb/go.mod h1:15RBzkun0i8XB7ADIoLJWp9ITRgsz3LroEI2FiOXLRg=
|
||||
github.com/qdm12/goshutdown v0.1.0 h1:lmwnygdXtnr2pa6VqfR/bm8077/BnBef1+7CP96B7Sw=
|
||||
github.com/qdm12/goshutdown v0.1.0/go.mod h1:/LP3MWLqI+wGH/ijfaUG+RHzBbKXIiVKnrg5vXOCf6Q=
|
||||
github.com/qdm12/ss-server v0.2.0 h1:+togLzeeLAJ68MD1JqOWvYi9rl9t/fx1Qh7wKzZhY1g=
|
||||
github.com/qdm12/ss-server v0.2.0/go.mod h1:+1bWO1EfWNvsGM5Cuep6vneChK2OHniqtAsED9Fh1y0=
|
||||
github.com/qdm12/updated v0.0.0-20210102012151-76b7f5994638 h1:dM8OO6LO+uou14C5a/LUrot0oyqzPcoiSho6cEmOROc=
|
||||
github.com/qdm12/updated v0.0.0-20210102012151-76b7f5994638/go.mod h1:bbJGxEYCnsA8WU4vBcXYU6mOoHyzdP458FIKP4mfLJM=
|
||||
github.com/qdm12/updated v0.0.0-20210603204757-205acfe6937e h1:4q+uFLawkaQRq3yARYLsjJPZd2wYwxn4g6G/5v0xW1g=
|
||||
github.com/qdm12/updated v0.0.0-20210603204757-205acfe6937e/go.mod h1:UvJRGkZ9XL3/D7e7JiTTVLm1F3Cymd3/gFpD6frEpBo=
|
||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg=
|
||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
@@ -90,7 +82,6 @@ github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoH
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0=
|
||||
@@ -100,10 +91,7 @@ github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17
|
||||
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
|
||||
github.com/yl2chen/cidranger v1.0.2/go.mod h1:9U1yz7WPYDwf0vpNWFaeRh0bjwz5RVgRy/9UEQfHl0g=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
go4.org/intern v0.0.0-20210108033219-3eb7198706b2 h1:VFTf+jjIgsldaz/Mr00VaCSswHJrI2hIjQygE/W4IMg=
|
||||
go4.org/intern v0.0.0-20210108033219-3eb7198706b2/go.mod h1:vLqJ+12kCw61iCWsPto0EOHhBS+o4rO5VIucbc9g2Cc=
|
||||
go4.org/unsafe/assume-no-moving-gc v0.0.0-20201222175341-b30ae309168e/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E=
|
||||
@@ -111,68 +99,58 @@ go4.org/unsafe/assume-no-moving-gc v0.0.0-20201222180813-1025295fd063 h1:1tk03FU
|
||||
go4.org/unsafe/assume-no-moving-gc v0.0.0-20201222180813-1025295fd063/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E=
|
||||
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a h1:kr2P4QFmQr29mSLA43kwrOcgcReGTfbE9N577tCTuBc=
|
||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015 h1:hZR0X1kPW+nwyJ9xRxqZk1vx5RUObAPBdKVvXPDUH/E=
|
||||
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
|
||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98=
|
||||
gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g=
|
||||
gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQbYDu2z8=
|
||||
@@ -181,8 +159,5 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
inet.af/netaddr v0.0.0-20210511181906-37180328850c h1:rzDy/tC8LjEdN94+i0Bu22tTo/qE9cvhKyfD0HMU0NU=
|
||||
inet.af/netaddr v0.0.0-20210511181906-37180328850c/go.mod h1:z0nx+Dh+7N7CC8V5ayHtHGpZpxLQZZxkIaaz6HN65Ls=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
|
||||
@@ -33,6 +33,7 @@ func (c *cli) Update(ctx context.Context, args []string, os os.OS, logger loggin
|
||||
flagSet.BoolVar(&options.Cyberghost, "cyberghost", false, "Update Cyberghost servers")
|
||||
flagSet.BoolVar(&options.Fastestvpn, "fastestvpn", false, "Update FastestVPN servers")
|
||||
flagSet.BoolVar(&options.HideMyAss, "hidemyass", false, "Update HideMyAss servers")
|
||||
flagSet.BoolVar(&options.Ipvanish, "ipvanish", false, "Update IpVanish servers")
|
||||
flagSet.BoolVar(&options.Ivpn, "ivpn", false, "Update IVPN servers")
|
||||
flagSet.BoolVar(&options.Mullvad, "mullvad", false, "Update Mullvad servers")
|
||||
flagSet.BoolVar(&options.Nordvpn, "nordvpn", false, "Update Nordvpn servers")
|
||||
@@ -43,6 +44,7 @@ func (c *cli) Update(ctx context.Context, args []string, os os.OS, logger loggin
|
||||
flagSet.BoolVar(&options.Purevpn, "purevpn", false, "Update Purevpn servers")
|
||||
flagSet.BoolVar(&options.Surfshark, "surfshark", false, "Update Surfshark servers")
|
||||
flagSet.BoolVar(&options.Torguard, "torguard", false, "Update Torguard servers")
|
||||
flagSet.BoolVar(&options.VPNUnlimited, "vpnunlimited", false, "Update VPN Unlimited servers")
|
||||
flagSet.BoolVar(&options.Vyprvpn, "vyprvpn", false, "Update Vyprvpn servers")
|
||||
flagSet.BoolVar(&options.Windscribe, "windscribe", false, "Update Windscribe servers")
|
||||
if err := flagSet.Parse(args); err != nil {
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
package configuration
|
||||
|
||||
import (
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/constants"
|
||||
"github.com/qdm12/golibs/params"
|
||||
)
|
||||
@@ -44,12 +40,12 @@ func (settings *Provider) readCyberghost(r reader) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
settings.ExtraConfigOptions.ClientKey, err = readCyberghostClientKey(r)
|
||||
settings.ExtraConfigOptions.ClientKey, err = readClientKey(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
settings.ExtraConfigOptions.ClientCertificate, err = readCyberghostClientCertificate(r)
|
||||
settings.ExtraConfigOptions.ClientCertificate, err = readClientCertificate(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -72,49 +68,3 @@ func (settings *Provider) readCyberghost(r reader) (err error) {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func readCyberghostClientKey(r reader) (clientKey string, err error) {
|
||||
b, err := r.getFromFileOrSecretFile("OPENVPN_CLIENTKEY", constants.ClientKey)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return extractClientKey(b)
|
||||
}
|
||||
|
||||
var errDecodePEMBlockClientKey = errors.New("cannot decode PEM block from client key")
|
||||
|
||||
func extractClientKey(b []byte) (key string, err error) {
|
||||
pemBlock, _ := pem.Decode(b)
|
||||
if pemBlock == nil {
|
||||
return "", errDecodePEMBlockClientKey
|
||||
}
|
||||
parsedBytes := pem.EncodeToMemory(pemBlock)
|
||||
s := string(parsedBytes)
|
||||
s = strings.ReplaceAll(s, "\n", "")
|
||||
s = strings.TrimPrefix(s, "-----BEGIN PRIVATE KEY-----")
|
||||
s = strings.TrimSuffix(s, "-----END PRIVATE KEY-----")
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func readCyberghostClientCertificate(r reader) (clientCertificate string, err error) {
|
||||
b, err := r.getFromFileOrSecretFile("OPENVPN_CLIENTCRT", constants.ClientCertificate)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return extractClientCertificate(b)
|
||||
}
|
||||
|
||||
var errDecodePEMBlockClientCert = errors.New("cannot decode PEM block from client certificate")
|
||||
|
||||
func extractClientCertificate(b []byte) (certificate string, err error) {
|
||||
pemBlock, _ := pem.Decode(b)
|
||||
if pemBlock == nil {
|
||||
return "", errDecodePEMBlockClientCert
|
||||
}
|
||||
parsedBytes := pem.EncodeToMemory(pemBlock)
|
||||
s := string(parsedBytes)
|
||||
s = strings.ReplaceAll(s, "\n", "")
|
||||
s = strings.TrimPrefix(s, "-----BEGIN CERTIFICATE-----")
|
||||
s = strings.TrimSuffix(s, "-----END CERTIFICATE-----")
|
||||
return s, nil
|
||||
}
|
||||
|
||||
@@ -29,11 +29,7 @@ func (settings *DNS) readBlacklistBuilding(r reader) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := settings.readBlacklistUnblockedHostnames(r); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return settings.readBlacklistUnblockedHostnames(r)
|
||||
}
|
||||
|
||||
var (
|
||||
|
||||
@@ -69,11 +69,7 @@ func (settings *Firewall) read(r reader) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := settings.readOutboundSubnets(r); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return settings.readOutboundSubnets(r)
|
||||
}
|
||||
|
||||
func (settings *Firewall) readVPNInputPorts(env params.Env) (err error) {
|
||||
|
||||
52
internal/configuration/ipvanish.go
Normal file
52
internal/configuration/ipvanish.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package configuration
|
||||
|
||||
import (
|
||||
"github.com/qdm12/gluetun/internal/constants"
|
||||
)
|
||||
|
||||
func (settings *Provider) ipvanishLines() (lines []string) {
|
||||
if len(settings.ServerSelection.Countries) > 0 {
|
||||
lines = append(lines, lastIndent+"Countries: "+commaJoin(settings.ServerSelection.Countries))
|
||||
}
|
||||
|
||||
if len(settings.ServerSelection.Cities) > 0 {
|
||||
lines = append(lines, lastIndent+"Cities: "+commaJoin(settings.ServerSelection.Cities))
|
||||
}
|
||||
|
||||
if len(settings.ServerSelection.Hostnames) > 0 {
|
||||
lines = append(lines, lastIndent+"Hostnames: "+commaJoin(settings.ServerSelection.Hostnames))
|
||||
}
|
||||
|
||||
return lines
|
||||
}
|
||||
|
||||
func (settings *Provider) readIpvanish(r reader) (err error) {
|
||||
settings.Name = constants.Ipvanish
|
||||
|
||||
settings.ServerSelection.TCP, err = readProtocol(r.env)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
settings.ServerSelection.TargetIP, err = readTargetIP(r.env)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
settings.ServerSelection.Countries, err = r.env.CSVInside("COUNTRY", constants.IpvanishCountryChoices())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
settings.ServerSelection.Cities, err = r.env.CSVInside("CITY", constants.IpvanishCityChoices())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", constants.IpvanishHostnameChoices())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
192
internal/configuration/ipvanish_test.go
Normal file
192
internal/configuration/ipvanish_test.go
Normal file
@@ -0,0 +1,192 @@
|
||||
package configuration
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/qdm12/gluetun/internal/constants"
|
||||
"github.com/qdm12/golibs/params/mock_params"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test_Provider_ipvanishLines(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := map[string]struct {
|
||||
settings Provider
|
||||
lines []string
|
||||
}{
|
||||
"empty settings": {},
|
||||
"full settings": {
|
||||
settings: Provider{
|
||||
ServerSelection: ServerSelection{
|
||||
Countries: []string{"A", "B"},
|
||||
Cities: []string{"C", "D"},
|
||||
Hostnames: []string{"E", "F"},
|
||||
},
|
||||
},
|
||||
lines: []string{
|
||||
"|--Countries: A, B",
|
||||
"|--Cities: C, D",
|
||||
"|--Hostnames: E, F",
|
||||
},
|
||||
},
|
||||
}
|
||||
for name, testCase := range testCases {
|
||||
testCase := testCase
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
lines := testCase.settings.ipvanishLines()
|
||||
|
||||
assert.Equal(t, testCase.lines, lines)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Provider_readIpvanish(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var errDummy = errors.New("dummy test error")
|
||||
|
||||
type singleStringCall struct {
|
||||
call bool
|
||||
value string
|
||||
err error
|
||||
}
|
||||
|
||||
type sliceStringCall struct {
|
||||
call bool
|
||||
values []string
|
||||
err error
|
||||
}
|
||||
|
||||
testCases := map[string]struct {
|
||||
protocol singleStringCall
|
||||
targetIP singleStringCall
|
||||
countries sliceStringCall
|
||||
cities sliceStringCall
|
||||
hostnames sliceStringCall
|
||||
settings Provider
|
||||
err error
|
||||
}{
|
||||
"protocol error": {
|
||||
protocol: singleStringCall{call: true, err: errDummy},
|
||||
settings: Provider{
|
||||
Name: constants.Ipvanish,
|
||||
},
|
||||
err: errDummy,
|
||||
},
|
||||
"target IP error": {
|
||||
protocol: singleStringCall{call: true},
|
||||
targetIP: singleStringCall{call: true, value: "something", err: errDummy},
|
||||
settings: Provider{
|
||||
Name: constants.Ipvanish,
|
||||
},
|
||||
err: errDummy,
|
||||
},
|
||||
"countries error": {
|
||||
protocol: singleStringCall{call: true},
|
||||
targetIP: singleStringCall{call: true},
|
||||
countries: sliceStringCall{call: true, err: errDummy},
|
||||
settings: Provider{
|
||||
Name: constants.Ipvanish,
|
||||
},
|
||||
err: errDummy,
|
||||
},
|
||||
"cities error": {
|
||||
protocol: singleStringCall{call: true},
|
||||
targetIP: singleStringCall{call: true},
|
||||
countries: sliceStringCall{call: true},
|
||||
cities: sliceStringCall{call: true, err: errDummy},
|
||||
settings: Provider{
|
||||
Name: constants.Ipvanish,
|
||||
},
|
||||
err: errDummy,
|
||||
},
|
||||
"hostnames error": {
|
||||
protocol: singleStringCall{call: true},
|
||||
targetIP: singleStringCall{call: true},
|
||||
countries: sliceStringCall{call: true},
|
||||
cities: sliceStringCall{call: true},
|
||||
hostnames: sliceStringCall{call: true, err: errDummy},
|
||||
settings: Provider{
|
||||
Name: constants.Ipvanish,
|
||||
},
|
||||
err: errDummy,
|
||||
},
|
||||
"default settings": {
|
||||
protocol: singleStringCall{call: true},
|
||||
targetIP: singleStringCall{call: true},
|
||||
countries: sliceStringCall{call: true},
|
||||
cities: sliceStringCall{call: true},
|
||||
hostnames: sliceStringCall{call: true},
|
||||
settings: Provider{
|
||||
Name: constants.Ipvanish,
|
||||
},
|
||||
},
|
||||
"set settings": {
|
||||
protocol: singleStringCall{call: true, value: constants.TCP},
|
||||
targetIP: singleStringCall{call: true, value: "1.2.3.4"},
|
||||
countries: sliceStringCall{call: true, values: []string{"A", "B"}},
|
||||
cities: sliceStringCall{call: true, values: []string{"C", "D"}},
|
||||
hostnames: sliceStringCall{call: true, values: []string{"E", "F"}},
|
||||
settings: Provider{
|
||||
Name: constants.Ipvanish,
|
||||
ServerSelection: ServerSelection{
|
||||
TCP: true,
|
||||
TargetIP: net.IPv4(1, 2, 3, 4),
|
||||
Countries: []string{"A", "B"},
|
||||
Cities: []string{"C", "D"},
|
||||
Hostnames: []string{"E", "F"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for name, testCase := range testCases {
|
||||
testCase := testCase
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctrl := gomock.NewController(t)
|
||||
|
||||
env := mock_params.NewMockEnv(ctrl)
|
||||
if testCase.protocol.call {
|
||||
env.EXPECT().Inside("PROTOCOL", []string{constants.TCP, constants.UDP}, gomock.Any()).
|
||||
Return(testCase.protocol.value, testCase.protocol.err)
|
||||
}
|
||||
if testCase.targetIP.call {
|
||||
env.EXPECT().Get("OPENVPN_TARGET_IP").
|
||||
Return(testCase.targetIP.value, testCase.targetIP.err)
|
||||
}
|
||||
if testCase.countries.call {
|
||||
env.EXPECT().CSVInside("COUNTRY", constants.IpvanishCountryChoices()).
|
||||
Return(testCase.countries.values, testCase.countries.err)
|
||||
}
|
||||
if testCase.cities.call {
|
||||
env.EXPECT().CSVInside("CITY", constants.IpvanishCityChoices()).
|
||||
Return(testCase.cities.values, testCase.cities.err)
|
||||
}
|
||||
if testCase.hostnames.call {
|
||||
env.EXPECT().CSVInside("SERVER_HOSTNAME", constants.IpvanishHostnameChoices()).
|
||||
Return(testCase.hostnames.values, testCase.hostnames.err)
|
||||
}
|
||||
|
||||
r := reader{env: env}
|
||||
|
||||
var settings Provider
|
||||
err := settings.readIpvanish(r)
|
||||
|
||||
if testCase.err != nil {
|
||||
require.Error(t, err)
|
||||
assert.Equal(t, testCase.err.Error(), err.Error())
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
assert.Equal(t, testCase.settings, settings)
|
||||
})
|
||||
}
|
||||
}
|
||||
55
internal/configuration/keys.go
Normal file
55
internal/configuration/keys.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package configuration
|
||||
|
||||
import (
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/constants"
|
||||
)
|
||||
|
||||
func readClientKey(r reader) (clientKey string, err error) {
|
||||
b, err := r.getFromFileOrSecretFile("OPENVPN_CLIENTKEY", constants.ClientKey)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return extractClientKey(b)
|
||||
}
|
||||
|
||||
var errDecodePEMBlockClientKey = errors.New("cannot decode PEM block from client key")
|
||||
|
||||
func extractClientKey(b []byte) (key string, err error) {
|
||||
pemBlock, _ := pem.Decode(b)
|
||||
if pemBlock == nil {
|
||||
return "", errDecodePEMBlockClientKey
|
||||
}
|
||||
parsedBytes := pem.EncodeToMemory(pemBlock)
|
||||
s := string(parsedBytes)
|
||||
s = strings.ReplaceAll(s, "\n", "")
|
||||
s = strings.TrimPrefix(s, "-----BEGIN PRIVATE KEY-----")
|
||||
s = strings.TrimSuffix(s, "-----END PRIVATE KEY-----")
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func readClientCertificate(r reader) (clientCertificate string, err error) {
|
||||
b, err := r.getFromFileOrSecretFile("OPENVPN_CLIENTCRT", constants.ClientCertificate)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return extractClientCertificate(b)
|
||||
}
|
||||
|
||||
var errDecodePEMBlockClientCert = errors.New("cannot decode PEM block from client certificate")
|
||||
|
||||
func extractClientCertificate(b []byte) (certificate string, err error) {
|
||||
pemBlock, _ := pem.Decode(b)
|
||||
if pemBlock == nil {
|
||||
return "", errDecodePEMBlockClientCert
|
||||
}
|
||||
parsedBytes := pem.EncodeToMemory(pemBlock)
|
||||
s := string(parsedBytes)
|
||||
s = strings.ReplaceAll(s, "\n", "")
|
||||
s = strings.TrimPrefix(s, "-----BEGIN CERTIFICATE-----")
|
||||
s = strings.TrimSuffix(s, "-----END CERTIFICATE-----")
|
||||
return s, nil
|
||||
}
|
||||
@@ -69,7 +69,8 @@ func (settings *Provider) readNordvpn(r reader) (err error) {
|
||||
}
|
||||
|
||||
func readNordVPNServerNumbers(env params.Env) (numbers []uint16, err error) {
|
||||
possibilities := make([]string, 65537)
|
||||
const possiblePortsCount = 65537
|
||||
possibilities := make([]string, possiblePortsCount)
|
||||
for i := range possibilities {
|
||||
possibilities[i] = fmt.Sprintf("%d", i)
|
||||
}
|
||||
|
||||
@@ -50,9 +50,13 @@ func (settings *OpenVPN) lines() (lines []string) {
|
||||
lines = append(lines, indent+lastIndent+"Custom configuration: "+settings.Config)
|
||||
}
|
||||
|
||||
lines = append(lines, indent+lastIndent+"Provider:")
|
||||
for _, line := range settings.Provider.lines() {
|
||||
lines = append(lines, indent+indent+line)
|
||||
if settings.Provider.Name == "" {
|
||||
lines = append(lines, indent+lastIndent+"Provider: custom configuration")
|
||||
} else {
|
||||
lines = append(lines, indent+lastIndent+"Provider:")
|
||||
for _, line := range settings.Provider.lines() {
|
||||
lines = append(lines, indent+indent+line)
|
||||
}
|
||||
}
|
||||
|
||||
return lines
|
||||
@@ -64,9 +68,9 @@ var (
|
||||
|
||||
func (settings *OpenVPN) read(r reader) (err error) {
|
||||
vpnsp, err := r.env.Inside("VPNSP", []string{
|
||||
"cyberghost", "fastestvpn", "hidemyass", "ivpn", "mullvad", "nordvpn",
|
||||
"cyberghost", "fastestvpn", "hidemyass", "ipvanish", "ivpn", "mullvad", "nordvpn",
|
||||
"privado", "pia", "private internet access", "privatevpn", "protonvpn",
|
||||
"purevpn", "surfshark", "torguard", "vyprvpn", "windscribe"},
|
||||
"purevpn", "surfshark", "torguard", constants.VPNUnlimited, "vyprvpn", "windscribe"},
|
||||
params.Default("private internet access"))
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -81,8 +85,13 @@ func (settings *OpenVPN) read(r reader) (err error) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
customConfig := settings.Config != ""
|
||||
|
||||
credentialsRequired := len(settings.Config) == 0
|
||||
if customConfig {
|
||||
settings.Provider.Name = ""
|
||||
}
|
||||
|
||||
credentialsRequired := !customConfig && settings.Provider.Name != constants.VPNUnlimited
|
||||
|
||||
settings.User, err = r.getFromEnvOrSecretFile("OPENVPN_USER", credentialsRequired, []string{"USER"})
|
||||
if err != nil {
|
||||
@@ -106,7 +115,7 @@ func (settings *OpenVPN) read(r reader) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
settings.Verbosity, err = r.env.IntRange("OPENVPN_VERBOSITY", 0, 6, params.Default("1"))
|
||||
settings.Verbosity, err = r.env.IntRange("OPENVPN_VERBOSITY", 0, 6, params.Default("1")) //nolint:gomnd
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -126,20 +135,28 @@ func (settings *OpenVPN) read(r reader) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
mssFix, err := r.env.IntRange("OPENVPN_MSSFIX", 0, 10000, params.Default("0"))
|
||||
const maxMSSFix = 10000
|
||||
mssFix, err := r.env.IntRange("OPENVPN_MSSFIX", 0, maxMSSFix, params.Default("0"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
settings.MSSFix = uint16(mssFix)
|
||||
return settings.readProvider(r)
|
||||
}
|
||||
|
||||
func (settings *OpenVPN) readProvider(r reader) error {
|
||||
var readProvider func(r reader) error
|
||||
switch settings.Provider.Name {
|
||||
case "": // custom config
|
||||
readProvider = func(r reader) error { return nil }
|
||||
case constants.Cyberghost:
|
||||
readProvider = settings.Provider.readCyberghost
|
||||
case constants.Fastestvpn:
|
||||
readProvider = settings.Provider.readFastestvpn
|
||||
case constants.HideMyAss:
|
||||
readProvider = settings.Provider.readHideMyAss
|
||||
case constants.Ipvanish:
|
||||
readProvider = settings.Provider.readIpvanish
|
||||
case constants.Ivpn:
|
||||
readProvider = settings.Provider.readIvpn
|
||||
case constants.Mullvad:
|
||||
@@ -160,6 +177,8 @@ func (settings *OpenVPN) read(r reader) (err error) {
|
||||
readProvider = settings.Provider.readSurfshark
|
||||
case constants.Torguard:
|
||||
readProvider = settings.Provider.readTorguard
|
||||
case constants.VPNUnlimited:
|
||||
readProvider = settings.Provider.readVPNUnlimited
|
||||
case constants.Vyprvpn:
|
||||
readProvider = settings.Provider.readVyprvpn
|
||||
case constants.Windscribe:
|
||||
@@ -167,6 +186,5 @@ func (settings *OpenVPN) read(r reader) (err error) {
|
||||
default:
|
||||
return fmt.Errorf("%w: %s", ErrInvalidVPNProvider, settings.Provider.Name)
|
||||
}
|
||||
|
||||
return readProvider(r)
|
||||
}
|
||||
|
||||
@@ -41,7 +41,8 @@ func Test_OpenVPN_JSON(t *testing.T) {
|
||||
"custom_port": 0,
|
||||
"numbers": null,
|
||||
"encryption_preset": "",
|
||||
"free_only": false
|
||||
"free_only": false,
|
||||
"stream_only": false
|
||||
},
|
||||
"extra_config": {
|
||||
"encryption_preset": "",
|
||||
|
||||
@@ -36,6 +36,8 @@ func (settings *Provider) lines() (lines []string) {
|
||||
providerLines = settings.fastestvpnLines()
|
||||
case "hidemyass":
|
||||
providerLines = settings.hideMyAssLines()
|
||||
case "ipvanish":
|
||||
providerLines = settings.ipvanishLines()
|
||||
case "ivpn":
|
||||
providerLines = settings.ivpnLines()
|
||||
case "mullvad":
|
||||
@@ -56,6 +58,8 @@ func (settings *Provider) lines() (lines []string) {
|
||||
providerLines = settings.surfsharkLines()
|
||||
case "torguard":
|
||||
providerLines = settings.torguardLines()
|
||||
case strings.ToLower(constants.VPNUnlimited):
|
||||
providerLines = settings.vpnUnlimitedLines()
|
||||
case "vyprvpn":
|
||||
providerLines = settings.vyprvpnLines()
|
||||
case "windscribe":
|
||||
|
||||
@@ -73,6 +73,23 @@ func Test_Provider_lines(t *testing.T) {
|
||||
" |--Hostnames: e, f",
|
||||
},
|
||||
},
|
||||
"ipvanish": {
|
||||
settings: Provider{
|
||||
Name: constants.Ipvanish,
|
||||
ServerSelection: ServerSelection{
|
||||
Countries: []string{"a", "b"},
|
||||
Cities: []string{"c", "d"},
|
||||
Hostnames: []string{"e", "f"},
|
||||
},
|
||||
},
|
||||
lines: []string{
|
||||
"|--Ipvanish settings:",
|
||||
" |--Network protocol: udp",
|
||||
" |--Countries: a, b",
|
||||
" |--Cities: c, d",
|
||||
" |--Hostnames: e, f",
|
||||
},
|
||||
},
|
||||
"ivpn": {
|
||||
settings: Provider{
|
||||
Name: constants.Ivpn,
|
||||
@@ -249,6 +266,31 @@ func Test_Provider_lines(t *testing.T) {
|
||||
" |--Hostnames: e",
|
||||
},
|
||||
},
|
||||
constants.VPNUnlimited: {
|
||||
settings: Provider{
|
||||
Name: constants.VPNUnlimited,
|
||||
ServerSelection: ServerSelection{
|
||||
Countries: []string{"a", "b"},
|
||||
Cities: []string{"c", "d"},
|
||||
Hostnames: []string{"e", "f"},
|
||||
FreeOnly: true,
|
||||
StreamOnly: true,
|
||||
},
|
||||
ExtraConfigOptions: ExtraConfigOptions{
|
||||
ClientKey: "a",
|
||||
},
|
||||
},
|
||||
lines: []string{
|
||||
"|--Vpn Unlimited settings:",
|
||||
" |--Network protocol: udp",
|
||||
" |--Countries: a, b",
|
||||
" |--Cities: c, d",
|
||||
" |--Hostnames: e, f",
|
||||
" |--Free servers only",
|
||||
" |--Stream servers only",
|
||||
" |--Client key is set",
|
||||
},
|
||||
},
|
||||
"vyprvpn": {
|
||||
settings: Provider{
|
||||
Name: constants.Vyprvpn,
|
||||
|
||||
@@ -15,10 +15,13 @@ type ServerSelection struct { //nolint:maligned
|
||||
// Cyberghost
|
||||
Group string `json:"group"`
|
||||
|
||||
Countries []string `json:"countries"` // Fastestvpn, HideMyAss, IVPN, Mullvad, PrivateVPN, Protonvpn, PureVPN
|
||||
Cities []string `json:"cities"` // HideMyAss, IVPN, Mullvad, PrivateVPN, Protonvpn, PureVPN, Windscribe
|
||||
Hostnames []string `json:"hostnames"` // Fastestvpn, HideMyAss, IVPN, PrivateVPN, Windscribe, Privado, Protonvpn
|
||||
Names []string `json:"names"` // Protonvpn
|
||||
// Fastestvpn, HideMyAss, IPVanish, IVPN, Mullvad, PrivateVPN, Protonvpn, PureVPN, VPNUnlimited
|
||||
Countries []string `json:"countries"`
|
||||
// HideMyAss, IPVanish, IVPN, Mullvad, PrivateVPN, Protonvpn, PureVPN, VPNUnlimited, Windscribe
|
||||
Cities []string `json:"cities"`
|
||||
// Fastestvpn, HideMyAss, IPVanish, IVPN, PrivateVPN, Windscribe, Privado, Protonvpn, VPNUnlimited
|
||||
Hostnames []string `json:"hostnames"`
|
||||
Names []string `json:"names"` // Protonvpn
|
||||
|
||||
// Mullvad
|
||||
ISPs []string `json:"isps"`
|
||||
@@ -35,11 +38,14 @@ type ServerSelection struct { //nolint:maligned
|
||||
|
||||
// ProtonVPN
|
||||
FreeOnly bool `json:"free_only"`
|
||||
|
||||
// VPNUnlimited
|
||||
StreamOnly bool `json:"stream_only"`
|
||||
}
|
||||
|
||||
type ExtraConfigOptions struct {
|
||||
ClientCertificate string `json:"-"` // Cyberghost
|
||||
ClientKey string `json:"-"` // Cyberghost
|
||||
ClientKey string `json:"-"` // Cyberghost, VPNUnlimited
|
||||
EncryptionPreset string `json:"encryption_preset"` // PIA
|
||||
OpenVPNIPv6 bool `json:"openvpn_ipv6"` // Mullvad
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package configuration
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/qdm12/golibs/logging"
|
||||
@@ -43,6 +45,18 @@ func (settings *Settings) lines() (lines []string) {
|
||||
return lines
|
||||
}
|
||||
|
||||
var (
|
||||
ErrOpenvpn = errors.New("cannot read Openvpn settings")
|
||||
ErrSystem = errors.New("cannot read System settings")
|
||||
ErrDNS = errors.New("cannot read DNS settings")
|
||||
ErrFirewall = errors.New("cannot read firewall settings")
|
||||
ErrHTTPProxy = errors.New("cannot read HTTP proxy settings")
|
||||
ErrShadowsocks = errors.New("cannot read Shadowsocks settings")
|
||||
ErrControlServer = errors.New("cannot read control server settings")
|
||||
ErrUpdater = errors.New("cannot read Updater settings")
|
||||
ErrPublicIP = errors.New("cannot read Public IP getter settings")
|
||||
)
|
||||
|
||||
// Read obtains all configuration options for the program and returns an error as soon
|
||||
// as an error is encountered reading them.
|
||||
func (settings *Settings) Read(env params.Env, os os.OS, logger logging.Logger) (err error) {
|
||||
@@ -54,35 +68,35 @@ func (settings *Settings) Read(env params.Env, os os.OS, logger logging.Logger)
|
||||
}
|
||||
|
||||
if err := settings.OpenVPN.read(r); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("%w: %s", ErrOpenvpn, err)
|
||||
}
|
||||
|
||||
if err := settings.System.read(r); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("%w: %s", ErrSystem, err)
|
||||
}
|
||||
|
||||
if err := settings.DNS.read(r); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("%w: %s", ErrDNS, err)
|
||||
}
|
||||
|
||||
if err := settings.Firewall.read(r); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("%w: %s", ErrFirewall, err)
|
||||
}
|
||||
|
||||
if err := settings.HTTPProxy.read(r); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("%w: %s", ErrHTTPProxy, err)
|
||||
}
|
||||
|
||||
if err := settings.ShadowSocks.read(r); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("%w: %s", ErrShadowsocks, err)
|
||||
}
|
||||
|
||||
if err := settings.ControlServer.read(r); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("%w: %s", ErrControlServer, err)
|
||||
}
|
||||
|
||||
if err := settings.Updater.read(r); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("%w: %s", ErrUpdater, err)
|
||||
}
|
||||
|
||||
if ip := settings.DNS.PlaintextAddress; ip != nil {
|
||||
@@ -90,7 +104,7 @@ func (settings *Settings) Read(env params.Env, os os.OS, logger logging.Logger)
|
||||
}
|
||||
|
||||
if err := settings.PublicIP.read(r); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("%w: %s", ErrPublicIP, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -32,13 +32,14 @@ func (settings *System) lines() (lines []string) {
|
||||
}
|
||||
|
||||
func (settings *System) read(r reader) (err error) {
|
||||
settings.PUID, err = r.env.IntRange("PUID", 0, 65535, params.Default("1000"),
|
||||
const maxID = 65535
|
||||
settings.PUID, err = r.env.IntRange("PUID", 0, maxID, params.Default("1000"),
|
||||
params.RetroKeys([]string{"UID"}, r.onRetroActive))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
settings.PGID, err = r.env.IntRange("PGID", 0, 65535, params.Default("1000"),
|
||||
settings.PGID, err = r.env.IntRange("PGID", 0, maxID, params.Default("1000"),
|
||||
params.RetroKeys([]string{"GID"}, r.onRetroActive))
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -43,7 +43,7 @@ func (settings *Provider) readTorguard(r reader) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", constants.TorguardHostnamesChoices())
|
||||
settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", constants.TorguardHostnameChoices())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -29,19 +29,19 @@ func (settings *DNS) readUnbound(r reader) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
verbosityLevel, err := r.env.IntRange("DOT_VERBOSITY", 0, 5, params.Default("1"))
|
||||
verbosityLevel, err := r.env.IntRange("DOT_VERBOSITY", 0, 5, params.Default("1")) //nolint:gomnd
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
settings.Unbound.VerbosityLevel = uint8(verbosityLevel)
|
||||
|
||||
verbosityDetailsLevel, err := r.env.IntRange("DOT_VERBOSITY_DETAILS", 0, 4, params.Default("0"))
|
||||
verbosityDetailsLevel, err := r.env.IntRange("DOT_VERBOSITY_DETAILS", 0, 4, params.Default("0")) //nolint:gomnd
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
settings.Unbound.VerbosityDetailsLevel = uint8(verbosityDetailsLevel)
|
||||
|
||||
validationLogLevel, err := r.env.IntRange("DOT_VALIDATION_LOGLEVEL", 0, 2, params.Default("0"))
|
||||
validationLogLevel, err := r.env.IntRange("DOT_VALIDATION_LOGLEVEL", 0, 2, params.Default("0")) //nolint:gomnd
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -8,23 +8,25 @@ import (
|
||||
)
|
||||
|
||||
type Updater struct {
|
||||
Period time.Duration `json:"period"`
|
||||
DNSAddress string `json:"dns_address"`
|
||||
Cyberghost bool `json:"cyberghost"`
|
||||
Fastestvpn bool `json:"fastestvpn"`
|
||||
HideMyAss bool `json:"hidemyass"`
|
||||
Ivpn bool `json:"ivpn"`
|
||||
Mullvad bool `json:"mullvad"`
|
||||
Nordvpn bool `json:"nordvpn"`
|
||||
PIA bool `json:"pia"`
|
||||
Privado bool `json:"privado"`
|
||||
Privatevpn bool `json:"privatevpn"`
|
||||
Protonvpn bool `json:"protonvpn"`
|
||||
Purevpn bool `json:"purevpn"`
|
||||
Surfshark bool `json:"surfshark"`
|
||||
Torguard bool `json:"torguard"`
|
||||
Vyprvpn bool `json:"vyprvpn"`
|
||||
Windscribe bool `json:"windscribe"`
|
||||
Period time.Duration `json:"period"`
|
||||
DNSAddress string `json:"dns_address"`
|
||||
Cyberghost bool `json:"cyberghost"`
|
||||
Fastestvpn bool `json:"fastestvpn"`
|
||||
HideMyAss bool `json:"hidemyass"`
|
||||
Ipvanish bool `json:"ipvanish"`
|
||||
Ivpn bool `json:"ivpn"`
|
||||
Mullvad bool `json:"mullvad"`
|
||||
Nordvpn bool `json:"nordvpn"`
|
||||
PIA bool `json:"pia"`
|
||||
Privado bool `json:"privado"`
|
||||
Privatevpn bool `json:"privatevpn"`
|
||||
Protonvpn bool `json:"protonvpn"`
|
||||
Purevpn bool `json:"purevpn"`
|
||||
Surfshark bool `json:"surfshark"`
|
||||
Torguard bool `json:"torguard"`
|
||||
VPNUnlimited bool `json:"vpnunlimited"`
|
||||
Vyprvpn bool `json:"vyprvpn"`
|
||||
Windscribe bool `json:"windscribe"`
|
||||
// The two below should be used in CLI mode only
|
||||
Stdout bool `json:"-"` // in order to update constants file (maintainer side)
|
||||
CLI bool `json:"-"`
|
||||
@@ -49,6 +51,7 @@ func (settings *Updater) lines() (lines []string) {
|
||||
func (settings *Updater) read(r reader) (err error) {
|
||||
settings.Cyberghost = true
|
||||
settings.HideMyAss = true
|
||||
settings.Ipvanish = true
|
||||
settings.Ivpn = true
|
||||
settings.Mullvad = true
|
||||
settings.Nordvpn = true
|
||||
@@ -60,6 +63,7 @@ func (settings *Updater) read(r reader) (err error) {
|
||||
settings.Purevpn = true
|
||||
settings.Surfshark = true
|
||||
settings.Torguard = true
|
||||
settings.VPNUnlimited = true
|
||||
settings.Vyprvpn = true
|
||||
settings.Windscribe = true
|
||||
settings.Stdout = false
|
||||
|
||||
85
internal/configuration/vpnunlimited.go
Normal file
85
internal/configuration/vpnunlimited.go
Normal file
@@ -0,0 +1,85 @@
|
||||
package configuration
|
||||
|
||||
import (
|
||||
"github.com/qdm12/gluetun/internal/constants"
|
||||
"github.com/qdm12/golibs/params"
|
||||
)
|
||||
|
||||
func (settings *Provider) vpnUnlimitedLines() (lines []string) {
|
||||
if len(settings.ServerSelection.Countries) > 0 {
|
||||
lines = append(lines, lastIndent+"Countries: "+commaJoin(settings.ServerSelection.Countries))
|
||||
}
|
||||
|
||||
if len(settings.ServerSelection.Cities) > 0 {
|
||||
lines = append(lines, lastIndent+"Cities: "+commaJoin(settings.ServerSelection.Cities))
|
||||
}
|
||||
|
||||
if len(settings.ServerSelection.Hostnames) > 0 {
|
||||
lines = append(lines, lastIndent+"Hostnames: "+commaJoin(settings.ServerSelection.Hostnames))
|
||||
}
|
||||
|
||||
if settings.ServerSelection.FreeOnly {
|
||||
lines = append(lines, lastIndent+"Free servers only")
|
||||
}
|
||||
|
||||
if settings.ServerSelection.StreamOnly {
|
||||
lines = append(lines, lastIndent+"Stream servers only")
|
||||
}
|
||||
|
||||
if settings.ExtraConfigOptions.ClientKey != "" {
|
||||
lines = append(lines, lastIndent+"Client key is set")
|
||||
}
|
||||
|
||||
return lines
|
||||
}
|
||||
|
||||
func (settings *Provider) readVPNUnlimited(r reader) (err error) {
|
||||
settings.Name = constants.VPNUnlimited
|
||||
|
||||
settings.ServerSelection.TCP, err = readProtocol(r.env)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
settings.ServerSelection.TargetIP, err = readTargetIP(r.env)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
settings.ExtraConfigOptions.ClientKey, err = readClientKey(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
settings.ExtraConfigOptions.ClientCertificate, err = readClientCertificate(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
settings.ServerSelection.Countries, err = r.env.CSVInside("COUNTRY", constants.VPNUnlimitedCountryChoices())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
settings.ServerSelection.Cities, err = r.env.CSVInside("CITY", constants.VPNUnlimitedCityChoices())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
settings.ServerSelection.Hostnames, err = r.env.CSVInside("SERVER_HOSTNAME", constants.VPNUnlimitedHostnameChoices())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
settings.ServerSelection.FreeOnly, err = r.env.YesNo("FREE_ONLY", params.Default("no"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
settings.ServerSelection.StreamOnly, err = r.env.YesNo("STREAM_ONLY", params.Default("no"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
42
internal/configuration/vpnunlimited_test.go
Normal file
42
internal/configuration/vpnunlimited_test.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package configuration
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_Provider_vpnUnlimitedLines(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := map[string]struct {
|
||||
settings Provider
|
||||
lines []string
|
||||
}{
|
||||
"empty settings": {},
|
||||
"full settings": {
|
||||
settings: Provider{
|
||||
ServerSelection: ServerSelection{
|
||||
Countries: []string{"A", "B"},
|
||||
Cities: []string{"C", "D"},
|
||||
Hostnames: []string{"E", "F"},
|
||||
},
|
||||
},
|
||||
lines: []string{
|
||||
"|--Countries: A, B",
|
||||
"|--Cities: C, D",
|
||||
"|--Hostnames: E, F",
|
||||
},
|
||||
},
|
||||
}
|
||||
for name, testCase := range testCases {
|
||||
testCase := testCase
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
lines := testCase.settings.vpnUnlimitedLines()
|
||||
|
||||
assert.Equal(t, testCase.lines, lines)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package constants
|
||||
|
||||
const (
|
||||
// HealthcheckAddress is the default listening address for the healthcheck server.
|
||||
HealthcheckAddress = "127.0.0.1:9999"
|
||||
)
|
||||
|
||||
@@ -2,254 +2,255 @@ package constants
|
||||
|
||||
func CountryCodes() map[string]string {
|
||||
return map[string]string{
|
||||
"af": "Afghanistan",
|
||||
"ax": "Aland Islands",
|
||||
"al": "Albania",
|
||||
"dz": "Algeria",
|
||||
"as": "American Samoa",
|
||||
"ad": "Andorra",
|
||||
"ao": "Angola",
|
||||
"ai": "Anguilla",
|
||||
"aq": "Antarctica",
|
||||
"ag": "Antigua and Barbuda",
|
||||
"ar": "Argentina",
|
||||
"am": "Armenia",
|
||||
"aw": "Aruba",
|
||||
"au": "Australia",
|
||||
"at": "Austria",
|
||||
"az": "Azerbaijan",
|
||||
"bs": "Bahamas",
|
||||
"bh": "Bahrain",
|
||||
"bd": "Bangladesh",
|
||||
"bb": "Barbados",
|
||||
"by": "Belarus",
|
||||
"be": "Belgium",
|
||||
"bz": "Belize",
|
||||
"bj": "Benin",
|
||||
"bm": "Bermuda",
|
||||
"bt": "Bhutan",
|
||||
"bo": "Bolivia",
|
||||
"bq": "Bonaire",
|
||||
"ba": "Bosnia and Herzegovina",
|
||||
"bw": "Botswana",
|
||||
"bv": "Bouvet Island",
|
||||
"br": "Brazil",
|
||||
"io": "British Indian Ocean Territory",
|
||||
"vg": "British Virgin Islands",
|
||||
"bn": "Brunei Darussalam",
|
||||
"bg": "Bulgaria",
|
||||
"bf": "Burkina Faso",
|
||||
"bi": "Burundi",
|
||||
"kh": "Cambodia",
|
||||
"cm": "Cameroon",
|
||||
"ca": "Canada",
|
||||
"cv": "Cape Verde",
|
||||
"ky": "Cayman Islands",
|
||||
"cf": "Central African Republic",
|
||||
"td": "Chad",
|
||||
"cl": "Chile",
|
||||
"cn": "China",
|
||||
"cx": "Christmas Island",
|
||||
"cc": "Cocos Islands",
|
||||
"co": "Colombia",
|
||||
"km": "Comoros",
|
||||
"cg": "Congo",
|
||||
"ck": "Cook Islands",
|
||||
"cr": "Costa Rica",
|
||||
"ci": "Cote d'Ivoire",
|
||||
"hr": "Croatia",
|
||||
"cu": "Cuba",
|
||||
"cw": "Curacao",
|
||||
"cy": "Cyprus",
|
||||
"cz": "Czech Republic",
|
||||
"cd": "Democratic Republic of the Congo",
|
||||
"dk": "Denmark",
|
||||
"dj": "Djibouti",
|
||||
"dm": "Dominica",
|
||||
"do": "Dominican Republic",
|
||||
"ec": "Ecuador",
|
||||
"eg": "Egypt",
|
||||
"sv": "El Salvador",
|
||||
"gq": "Equatorial Guinea",
|
||||
"er": "Eritrea",
|
||||
"ee": "Estonia",
|
||||
"et": "Ethiopia",
|
||||
"fk": "Falkland Islands",
|
||||
"fo": "Faroe Islands",
|
||||
"fj": "Fiji",
|
||||
"fi": "Finland",
|
||||
"fr": "France",
|
||||
"gf": "French Guiana",
|
||||
"pf": "French Polynesia",
|
||||
"tf": "French Southern Territories",
|
||||
"ga": "Gabon",
|
||||
"gm": "Gambia",
|
||||
"ge": "Georgia",
|
||||
"de": "Germany",
|
||||
"gh": "Ghana",
|
||||
"gi": "Gibraltar",
|
||||
"gr": "Greece",
|
||||
"gl": "Greenland",
|
||||
"gd": "Grenada",
|
||||
"gp": "Guadeloupe",
|
||||
"gu": "Guam",
|
||||
"gt": "Guatemala",
|
||||
"gg": "Guernsey",
|
||||
"gw": "Guinea-Bissau",
|
||||
"gn": "Guinea",
|
||||
"gy": "Guyana",
|
||||
"ht": "Haiti",
|
||||
"hm": "Heard Island and McDonald Islands",
|
||||
"hn": "Honduras",
|
||||
"hk": "Hong Kong",
|
||||
"hu": "Hungary",
|
||||
"is": "Iceland",
|
||||
"in": "India",
|
||||
"id": "Indonesia",
|
||||
"ir": "Iran",
|
||||
"iq": "Iraq",
|
||||
"ie": "Ireland",
|
||||
"im": "Isle of Man",
|
||||
"il": "Israel",
|
||||
"it": "Italy",
|
||||
"jm": "Jamaica",
|
||||
"jp": "Japan",
|
||||
"je": "Jersey",
|
||||
"jo": "Jordan",
|
||||
"kz": "Kazakhstan",
|
||||
"ke": "Kenya",
|
||||
"ki": "Kiribati",
|
||||
"kr": "Korea",
|
||||
"kw": "Kuwait",
|
||||
"kg": "Kyrgyzstan",
|
||||
"la": "Lao People's Democratic Republic",
|
||||
"lv": "Latvia",
|
||||
"lb": "Lebanon",
|
||||
"ls": "Lesotho",
|
||||
"lr": "Liberia",
|
||||
"ly": "Libya",
|
||||
"li": "Liechtenstein",
|
||||
"lt": "Lithuania",
|
||||
"lu": "Luxembourg",
|
||||
"mo": "Macao",
|
||||
"mk": "Macedonia",
|
||||
"mg": "Madagascar",
|
||||
"mw": "Malawi",
|
||||
"my": "Malaysia",
|
||||
"mv": "Maldives",
|
||||
"ml": "Mali",
|
||||
"mt": "Malta",
|
||||
"mh": "Marshall Islands",
|
||||
"mq": "Martinique",
|
||||
"mr": "Mauritania",
|
||||
"mu": "Mauritius",
|
||||
"yt": "Mayotte",
|
||||
"mx": "Mexico",
|
||||
"fm": "Micronesia",
|
||||
"md": "Moldova",
|
||||
"mc": "Monaco",
|
||||
"mn": "Mongolia",
|
||||
"me": "Montenegro",
|
||||
"ms": "Montserrat",
|
||||
"ma": "Morocco",
|
||||
"mz": "Mozambique",
|
||||
"mm": "Myanmar",
|
||||
"na": "Namibia",
|
||||
"nr": "Nauru",
|
||||
"np": "Nepal",
|
||||
"nl": "Netherlands",
|
||||
"nc": "New Caledonia",
|
||||
"nz": "New Zealand",
|
||||
"ni": "Nicaragua",
|
||||
"ne": "Niger",
|
||||
"ng": "Nigeria",
|
||||
"nu": "Niue",
|
||||
"nf": "Norfolk Island",
|
||||
"mp": "Northern Mariana Islands",
|
||||
"no": "Norway",
|
||||
"om": "Oman",
|
||||
"pk": "Pakistan",
|
||||
"pw": "Palau",
|
||||
"ps": "Palestine, State of",
|
||||
"pa": "Panama",
|
||||
"pg": "Papua New Guinea",
|
||||
"py": "Paraguay",
|
||||
"pe": "Peru",
|
||||
"ph": "Philippines",
|
||||
"pn": "Pitcairn",
|
||||
"pl": "Poland",
|
||||
"pt": "Portugal",
|
||||
"pr": "Puerto Rico",
|
||||
"qa": "Qatar",
|
||||
"re": "Reunion",
|
||||
"ro": "Romania",
|
||||
"ru": "Russian Federation",
|
||||
"rw": "Rwanda",
|
||||
"bl": "Saint Barthelemy",
|
||||
"sh": "Saint Helena",
|
||||
"kn": "Saint Kitts and Nevis",
|
||||
"lc": "Saint Lucia",
|
||||
"mf": "Saint Martin",
|
||||
"pm": "Saint Pierre and Miquelon",
|
||||
"vc": "Saint Vincent and the Grenadines",
|
||||
"ws": "Samoa",
|
||||
"sm": "San Marino",
|
||||
"st": "Sao Tome and Principe",
|
||||
"sa": "Saudi Arabia",
|
||||
"sn": "Senegal",
|
||||
"rs": "Serbia",
|
||||
"sc": "Seychelles",
|
||||
"sl": "Sierra Leone",
|
||||
"sg": "Singapore",
|
||||
"sx": "Sint Maarten",
|
||||
"sk": "Slovakia",
|
||||
"si": "Slovenia",
|
||||
"sb": "Solomon Islands",
|
||||
"so": "Somalia",
|
||||
"za": "South Africa",
|
||||
"gs": "South Georgia and the South Sandwich Islands",
|
||||
"ss": "South Sudan",
|
||||
"es": "Spain",
|
||||
"lk": "Sri Lanka",
|
||||
"sd": "Sudan",
|
||||
"sr": "Suriname",
|
||||
"sj": "Svalbard and Jan Mayen",
|
||||
"sz": "Swaziland",
|
||||
"se": "Sweden",
|
||||
"ch": "Switzerland",
|
||||
"sy": "Syrian Arab Republic",
|
||||
"tw": "Taiwan",
|
||||
"tj": "Tajikistan",
|
||||
"tz": "Tanzania",
|
||||
"th": "Thailand",
|
||||
"tl": "Timor-Leste",
|
||||
"tg": "Togo",
|
||||
"tk": "Tokelau",
|
||||
"to": "Tonga",
|
||||
"tt": "Trinidad and Tobago",
|
||||
"tn": "Tunisia",
|
||||
"tr": "Turkey",
|
||||
"tm": "Turkmenistan",
|
||||
"tc": "Turks and Caicos Islands",
|
||||
"tv": "Tuvalu",
|
||||
"ug": "Uganda",
|
||||
"ua": "Ukraine",
|
||||
"ae": "United Arab Emirates",
|
||||
"gb": "United Kingdom",
|
||||
"uk": "United Kingdom",
|
||||
"um": "United States Minor Outlying Islands",
|
||||
"us": "United States",
|
||||
"uy": "Uruguay",
|
||||
"vi": "US Virgin Islands",
|
||||
"uz": "Uzbekistan",
|
||||
"vu": "Vanuatu",
|
||||
"va": "Vatican City State",
|
||||
"ve": "Venezuela",
|
||||
"vn": "Vietnam",
|
||||
"wf": "Wallis and Futuna",
|
||||
"eh": "Western Sahara",
|
||||
"ye": "Yemen",
|
||||
"zm": "Zambia",
|
||||
"zw": "Zimbabwe",
|
||||
"af": "Afghanistan",
|
||||
"ax": "Aland Islands",
|
||||
"al": "Albania",
|
||||
"dz": "Algeria",
|
||||
"as": "American Samoa",
|
||||
"ad": "Andorra",
|
||||
"ao": "Angola",
|
||||
"ai": "Anguilla",
|
||||
"aq": "Antarctica",
|
||||
"ag": "Antigua and Barbuda",
|
||||
"ar": "Argentina",
|
||||
"am": "Armenia",
|
||||
"aw": "Aruba",
|
||||
"au": "Australia",
|
||||
"at": "Austria",
|
||||
"az": "Azerbaijan",
|
||||
"bs": "Bahamas",
|
||||
"bh": "Bahrain",
|
||||
"bd": "Bangladesh",
|
||||
"bb": "Barbados",
|
||||
"by": "Belarus",
|
||||
"be": "Belgium",
|
||||
"bz": "Belize",
|
||||
"bj": "Benin",
|
||||
"bm": "Bermuda",
|
||||
"bt": "Bhutan",
|
||||
"bo": "Bolivia",
|
||||
"bq": "Bonaire",
|
||||
"ba": "Bosnia and Herzegovina",
|
||||
"bw": "Botswana",
|
||||
"bv": "Bouvet Island",
|
||||
"br": "Brazil",
|
||||
"io": "British Indian Ocean Territory",
|
||||
"vg": "British Virgin Islands",
|
||||
"bn": "Brunei Darussalam",
|
||||
"bg": "Bulgaria",
|
||||
"bf": "Burkina Faso",
|
||||
"bi": "Burundi",
|
||||
"kh": "Cambodia",
|
||||
"cm": "Cameroon",
|
||||
"ca": "Canada",
|
||||
"cv": "Cape Verde",
|
||||
"ky": "Cayman Islands",
|
||||
"cf": "Central African Republic",
|
||||
"td": "Chad",
|
||||
"cl": "Chile",
|
||||
"cn": "China",
|
||||
"cx": "Christmas Island",
|
||||
"cc": "Cocos Islands",
|
||||
"co": "Colombia",
|
||||
"km": "Comoros",
|
||||
"cg": "Congo",
|
||||
"ck": "Cook Islands",
|
||||
"cr": "Costa Rica",
|
||||
"ci": "Cote d'Ivoire",
|
||||
"hr": "Croatia",
|
||||
"cu": "Cuba",
|
||||
"cw": "Curacao",
|
||||
"cy": "Cyprus",
|
||||
"cz": "Czech Republic",
|
||||
"cd": "Democratic Republic of the Congo",
|
||||
"dk": "Denmark",
|
||||
"dj": "Djibouti",
|
||||
"dm": "Dominica",
|
||||
"do": "Dominican Republic",
|
||||
"ec": "Ecuador",
|
||||
"eg": "Egypt",
|
||||
"sv": "El Salvador",
|
||||
"gq": "Equatorial Guinea",
|
||||
"er": "Eritrea",
|
||||
"ee": "Estonia",
|
||||
"et": "Ethiopia",
|
||||
"fk": "Falkland Islands",
|
||||
"fo": "Faroe Islands",
|
||||
"fj": "Fiji",
|
||||
"fi": "Finland",
|
||||
"fr": "France",
|
||||
"gf": "French Guiana",
|
||||
"pf": "French Polynesia",
|
||||
"tf": "French Southern Territories",
|
||||
"ga": "Gabon",
|
||||
"gm": "Gambia",
|
||||
"ge": "Georgia",
|
||||
"de": "Germany",
|
||||
"gh": "Ghana",
|
||||
"gi": "Gibraltar",
|
||||
"gr": "Greece",
|
||||
"gl": "Greenland",
|
||||
"gd": "Grenada",
|
||||
"gp": "Guadeloupe",
|
||||
"gu": "Guam",
|
||||
"gt": "Guatemala",
|
||||
"gg": "Guernsey",
|
||||
"gw": "Guinea-Bissau",
|
||||
"gn": "Guinea",
|
||||
"gy": "Guyana",
|
||||
"ht": "Haiti",
|
||||
"hm": "Heard Island and McDonald Islands",
|
||||
"hn": "Honduras",
|
||||
"hk": "Hong Kong",
|
||||
"hu": "Hungary",
|
||||
"is": "Iceland",
|
||||
"in": "India",
|
||||
"id": "Indonesia",
|
||||
"ir": "Iran",
|
||||
"iq": "Iraq",
|
||||
"ie": "Ireland",
|
||||
"im": "Isle of Man",
|
||||
"il": "Israel",
|
||||
"it": "Italy",
|
||||
"jm": "Jamaica",
|
||||
"jp": "Japan",
|
||||
"je": "Jersey",
|
||||
"jo": "Jordan",
|
||||
"kz": "Kazakhstan",
|
||||
"ke": "Kenya",
|
||||
"ki": "Kiribati",
|
||||
"kr": "Korea",
|
||||
"kw": "Kuwait",
|
||||
"kg": "Kyrgyzstan",
|
||||
"la": "Lao People's Democratic Republic",
|
||||
"lv": "Latvia",
|
||||
"lb": "Lebanon",
|
||||
"ls": "Lesotho",
|
||||
"lr": "Liberia",
|
||||
"ly": "Libya",
|
||||
"li": "Liechtenstein",
|
||||
"lt": "Lithuania",
|
||||
"lu": "Luxembourg",
|
||||
"mo": "Macao",
|
||||
"mk": "Macedonia",
|
||||
"mg": "Madagascar",
|
||||
"mw": "Malawi",
|
||||
"my": "Malaysia",
|
||||
"mys": "Kuala Lumpur",
|
||||
"mv": "Maldives",
|
||||
"ml": "Mali",
|
||||
"mt": "Malta",
|
||||
"mh": "Marshall Islands",
|
||||
"mq": "Martinique",
|
||||
"mr": "Mauritania",
|
||||
"mu": "Mauritius",
|
||||
"yt": "Mayotte",
|
||||
"mx": "Mexico",
|
||||
"fm": "Micronesia",
|
||||
"md": "Moldova",
|
||||
"mc": "Monaco",
|
||||
"mn": "Mongolia",
|
||||
"me": "Montenegro",
|
||||
"ms": "Montserrat",
|
||||
"ma": "Morocco",
|
||||
"mz": "Mozambique",
|
||||
"mm": "Myanmar",
|
||||
"na": "Namibia",
|
||||
"nr": "Nauru",
|
||||
"np": "Nepal",
|
||||
"nl": "Netherlands",
|
||||
"nc": "New Caledonia",
|
||||
"nz": "New Zealand",
|
||||
"ni": "Nicaragua",
|
||||
"ne": "Niger",
|
||||
"ng": "Nigeria",
|
||||
"nu": "Niue",
|
||||
"nf": "Norfolk Island",
|
||||
"mp": "Northern Mariana Islands",
|
||||
"no": "Norway",
|
||||
"om": "Oman",
|
||||
"pk": "Pakistan",
|
||||
"pw": "Palau",
|
||||
"ps": "Palestine, State of",
|
||||
"pa": "Panama",
|
||||
"pg": "Papua New Guinea",
|
||||
"py": "Paraguay",
|
||||
"pe": "Peru",
|
||||
"ph": "Philippines",
|
||||
"pn": "Pitcairn",
|
||||
"pl": "Poland",
|
||||
"pt": "Portugal",
|
||||
"pr": "Puerto Rico",
|
||||
"qa": "Qatar",
|
||||
"re": "Reunion",
|
||||
"ro": "Romania",
|
||||
"ru": "Russian Federation",
|
||||
"rw": "Rwanda",
|
||||
"bl": "Saint Barthelemy",
|
||||
"sh": "Saint Helena",
|
||||
"kn": "Saint Kitts and Nevis",
|
||||
"lc": "Saint Lucia",
|
||||
"mf": "Saint Martin",
|
||||
"pm": "Saint Pierre and Miquelon",
|
||||
"vc": "Saint Vincent and the Grenadines",
|
||||
"ws": "Samoa",
|
||||
"sm": "San Marino",
|
||||
"st": "Sao Tome and Principe",
|
||||
"sa": "Saudi Arabia",
|
||||
"sn": "Senegal",
|
||||
"rs": "Serbia",
|
||||
"sc": "Seychelles",
|
||||
"sl": "Sierra Leone",
|
||||
"sg": "Singapore",
|
||||
"sx": "Sint Maarten",
|
||||
"sk": "Slovakia",
|
||||
"si": "Slovenia",
|
||||
"sb": "Solomon Islands",
|
||||
"so": "Somalia",
|
||||
"za": "South Africa",
|
||||
"gs": "South Georgia and the South Sandwich Islands",
|
||||
"ss": "South Sudan",
|
||||
"es": "Spain",
|
||||
"lk": "Sri Lanka",
|
||||
"sd": "Sudan",
|
||||
"sr": "Suriname",
|
||||
"sj": "Svalbard and Jan Mayen",
|
||||
"sz": "Swaziland",
|
||||
"se": "Sweden",
|
||||
"ch": "Switzerland",
|
||||
"sy": "Syrian Arab Republic",
|
||||
"tw": "Taiwan",
|
||||
"tj": "Tajikistan",
|
||||
"tz": "Tanzania",
|
||||
"th": "Thailand",
|
||||
"tl": "Timor-Leste",
|
||||
"tg": "Togo",
|
||||
"tk": "Tokelau",
|
||||
"to": "Tonga",
|
||||
"tt": "Trinidad and Tobago",
|
||||
"tn": "Tunisia",
|
||||
"tr": "Turkey",
|
||||
"tm": "Turkmenistan",
|
||||
"tc": "Turks and Caicos Islands",
|
||||
"tv": "Tuvalu",
|
||||
"ug": "Uganda",
|
||||
"ua": "Ukraine",
|
||||
"ae": "United Arab Emirates",
|
||||
"gb": "United Kingdom",
|
||||
"uk": "United Kingdom",
|
||||
"um": "United States Minor Outlying Islands",
|
||||
"us": "United States",
|
||||
"uy": "Uruguay",
|
||||
"vi": "US Virgin Islands",
|
||||
"uz": "Uzbekistan",
|
||||
"vu": "Vanuatu",
|
||||
"va": "Vatican City State",
|
||||
"ve": "Venezuela",
|
||||
"vn": "Vietnam",
|
||||
"wf": "Wallis and Futuna",
|
||||
"eh": "Western Sahara",
|
||||
"ye": "Yemen",
|
||||
"zm": "Zambia",
|
||||
"zw": "Zimbabwe",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,134 +43,184 @@ func CyberghostHostnameChoices() (choices []string) {
|
||||
// of the Cyberghost server.
|
||||
func CyberghostServers() []models.CyberghostServer {
|
||||
return []models.CyberghostServer{
|
||||
{Region: "Albania", Group: "Premium UDP Europe", Hostname: "87-1-al.cg-dialup.net", IPs: []net.IP{{31, 171, 155, 3}, {31, 171, 155, 4}, {31, 171, 155, 5}, {31, 171, 155, 6}, {31, 171, 155, 7}, {31, 171, 155, 8}, {31, 171, 155, 10}, {31, 171, 155, 11}, {31, 171, 155, 13}, {31, 171, 155, 14}}},
|
||||
{Region: "Algeria", Group: "Premium TCP Europe", Hostname: "97-1-dz.cg-dialup.net", IPs: []net.IP{{176, 125, 228, 131}, {176, 125, 228, 132}, {176, 125, 228, 134}, {176, 125, 228, 135}, {176, 125, 228, 136}, {176, 125, 228, 138}, {176, 125, 228, 141}, {176, 125, 228, 142}, {176, 125, 228, 143}, {176, 125, 228, 144}}},
|
||||
{Region: "Argentina", Group: "Premium TCP USA", Hostname: "93-1-ar.cg-dialup.net", IPs: []net.IP{{190, 106, 130, 15}, {190, 106, 130, 18}, {190, 106, 130, 20}, {190, 106, 130, 22}, {190, 106, 130, 23}, {190, 106, 130, 36}, {190, 106, 130, 43}, {190, 106, 130, 44}, {190, 106, 130, 45}, {190, 106, 130, 52}}},
|
||||
{Region: "Argentina", Group: "Premium UDP USA", Hostname: "94-1-ar.cg-dialup.net", IPs: []net.IP{{190, 106, 130, 15}, {190, 106, 130, 19}, {190, 106, 130, 20}, {190, 106, 130, 21}, {190, 106, 130, 34}, {190, 106, 130, 36}, {190, 106, 130, 38}, {190, 106, 130, 42}, {190, 106, 130, 43}, {190, 106, 130, 52}}},
|
||||
{Region: "Armenia", Group: "Premium TCP Europe", Hostname: "97-1-am.cg-dialup.net", IPs: []net.IP{{185, 253, 160, 131}, {185, 253, 160, 132}, {185, 253, 160, 134}, {185, 253, 160, 138}, {185, 253, 160, 139}, {185, 253, 160, 140}, {185, 253, 160, 141}, {185, 253, 160, 142}, {185, 253, 160, 143}, {185, 253, 160, 144}}},
|
||||
{Region: "Armenia", Group: "Premium UDP Europe", Hostname: "87-1-am.cg-dialup.net", IPs: []net.IP{{185, 253, 160, 131}, {185, 253, 160, 132}, {185, 253, 160, 134}, {185, 253, 160, 136}, {185, 253, 160, 137}, {185, 253, 160, 138}, {185, 253, 160, 139}, {185, 253, 160, 140}, {185, 253, 160, 141}, {185, 253, 160, 143}}},
|
||||
{Region: "Australia", Group: "Premium TCP Asia", Hostname: "96-1-au.cg-dialup.net", IPs: []net.IP{{43, 242, 68, 108}, {202, 60, 80, 5}, {202, 60, 80, 41}, {202, 60, 80, 58}, {202, 60, 91, 204}, {202, 60, 91, 213}, {202, 60, 91, 221}, {202, 60, 91, 222}, {202, 60, 91, 225}, {202, 60, 91, 234}}},
|
||||
{Region: "Australia", Group: "Premium UDP Asia", Hostname: "95-1-au.cg-dialup.net", IPs: []net.IP{{43, 242, 68, 77}, {43, 242, 68, 95}, {43, 242, 68, 108}, {202, 60, 80, 20}, {202, 60, 80, 31}, {202, 60, 80, 47}, {202, 60, 91, 199}, {202, 60, 91, 222}, {202, 60, 91, 226}, {202, 60, 91, 253}}},
|
||||
{Region: "Austria", Group: "Premium UDP Europe", Hostname: "87-1-at.cg-dialup.net", IPs: []net.IP{{37, 19, 223, 112}, {37, 19, 223, 119}, {37, 120, 155, 100}, {37, 120, 155, 102}, {37, 120, 155, 104}, {37, 120, 155, 110}, {89, 187, 168, 166}, {89, 187, 168, 174}, {89, 187, 168, 175}, {89, 187, 168, 177}}},
|
||||
{Region: "Bahamas", Group: "Premium TCP USA", Hostname: "93-1-bs.cg-dialup.net", IPs: []net.IP{{95, 181, 238, 132}, {95, 181, 238, 133}, {95, 181, 238, 137}, {95, 181, 238, 139}, {95, 181, 238, 142}, {95, 181, 238, 144}, {95, 181, 238, 145}, {95, 181, 238, 147}, {95, 181, 238, 148}, {95, 181, 238, 153}}},
|
||||
{Region: "Bangladesh", Group: "Premium TCP Asia", Hostname: "96-1-bd.cg-dialup.net", IPs: []net.IP{{84, 252, 93, 131}, {84, 252, 93, 132}, {84, 252, 93, 133}, {84, 252, 93, 135}, {84, 252, 93, 138}, {84, 252, 93, 140}, {84, 252, 93, 142}, {84, 252, 93, 143}, {84, 252, 93, 144}, {84, 252, 93, 145}}},
|
||||
{Region: "Bangladesh", Group: "Premium UDP Asia", Hostname: "95-1-bd.cg-dialup.net", IPs: []net.IP{{84, 252, 93, 131}, {84, 252, 93, 132}, {84, 252, 93, 133}, {84, 252, 93, 134}, {84, 252, 93, 135}, {84, 252, 93, 137}, {84, 252, 93, 139}, {84, 252, 93, 141}, {84, 252, 93, 143}, {84, 252, 93, 145}}},
|
||||
{Region: "Belarus", Group: "Premium UDP Europe", Hostname: "87-1-by.cg-dialup.net", IPs: []net.IP{{45, 132, 194, 7}, {45, 132, 194, 25}, {45, 132, 194, 33}, {45, 132, 194, 36}, {45, 132, 194, 38}, {45, 132, 194, 43}, {45, 132, 194, 44}, {45, 132, 194, 45}, {45, 132, 194, 48}, {45, 132, 194, 49}}},
|
||||
{Region: "Belgium", Group: "Premium TCP Europe", Hostname: "97-1-be.cg-dialup.net", IPs: []net.IP{{5, 253, 205, 26}, {37, 120, 143, 54}, {37, 120, 143, 57}, {185, 210, 217, 52}, {185, 232, 21, 115}, {193, 9, 114, 212}, {193, 9, 114, 227}, {193, 9, 114, 230}, {193, 9, 114, 249}, {194, 110, 115, 233}}},
|
||||
{Region: "Albania", Group: "Premium TCP Europe", Hostname: "97-1-al.cg-dialup.net", IPs: []net.IP{{31, 171, 155, 3}, {31, 171, 155, 4}, {31, 171, 155, 7}, {31, 171, 155, 8}, {31, 171, 155, 9}, {31, 171, 155, 10}, {31, 171, 155, 11}, {31, 171, 155, 12}, {31, 171, 155, 13}, {31, 171, 155, 14}}},
|
||||
{Region: "Albania", Group: "Premium UDP Europe", Hostname: "87-1-al.cg-dialup.net", IPs: []net.IP{{31, 171, 155, 4}, {31, 171, 155, 5}, {31, 171, 155, 6}, {31, 171, 155, 7}, {31, 171, 155, 8}, {31, 171, 155, 9}, {31, 171, 155, 10}, {31, 171, 155, 11}, {31, 171, 155, 13}, {31, 171, 155, 14}}},
|
||||
{Region: "Algeria", Group: "Premium TCP Europe", Hostname: "97-1-dz.cg-dialup.net", IPs: []net.IP{{176, 125, 228, 132}, {176, 125, 228, 134}, {176, 125, 228, 135}, {176, 125, 228, 136}, {176, 125, 228, 137}, {176, 125, 228, 138}, {176, 125, 228, 139}, {176, 125, 228, 140}, {176, 125, 228, 141}, {176, 125, 228, 142}}},
|
||||
{Region: "Algeria", Group: "Premium UDP Europe", Hostname: "87-1-dz.cg-dialup.net", IPs: []net.IP{{176, 125, 228, 131}, {176, 125, 228, 133}, {176, 125, 228, 134}, {176, 125, 228, 136}, {176, 125, 228, 137}, {176, 125, 228, 139}, {176, 125, 228, 140}, {176, 125, 228, 141}, {176, 125, 228, 142}, {176, 125, 228, 143}}},
|
||||
{Region: "Andorra", Group: "Premium TCP Europe", Hostname: "97-1-ad.cg-dialup.net", IPs: []net.IP{{188, 241, 82, 137}, {188, 241, 82, 138}, {188, 241, 82, 140}, {188, 241, 82, 142}, {188, 241, 82, 147}, {188, 241, 82, 155}, {188, 241, 82, 159}, {188, 241, 82, 160}, {188, 241, 82, 161}, {188, 241, 82, 166}}},
|
||||
{Region: "Andorra", Group: "Premium UDP Europe", Hostname: "87-1-ad.cg-dialup.net", IPs: []net.IP{{188, 241, 82, 133}, {188, 241, 82, 134}, {188, 241, 82, 136}, {188, 241, 82, 137}, {188, 241, 82, 146}, {188, 241, 82, 153}, {188, 241, 82, 155}, {188, 241, 82, 160}, {188, 241, 82, 164}, {188, 241, 82, 168}}},
|
||||
{Region: "Argentina", Group: "Premium TCP USA", Hostname: "93-1-ar.cg-dialup.net", IPs: []net.IP{{146, 70, 39, 4}, {146, 70, 39, 9}, {146, 70, 39, 15}, {146, 70, 39, 19}, {146, 70, 39, 135}, {146, 70, 39, 136}, {146, 70, 39, 139}, {146, 70, 39, 142}, {146, 70, 39, 143}, {146, 70, 39, 145}}},
|
||||
{Region: "Argentina", Group: "Premium UDP USA", Hostname: "94-1-ar.cg-dialup.net", IPs: []net.IP{{146, 70, 39, 3}, {146, 70, 39, 5}, {146, 70, 39, 6}, {146, 70, 39, 8}, {146, 70, 39, 11}, {146, 70, 39, 12}, {146, 70, 39, 131}, {146, 70, 39, 134}, {146, 70, 39, 142}, {146, 70, 39, 143}}},
|
||||
{Region: "Armenia", Group: "Premium TCP Europe", Hostname: "97-1-am.cg-dialup.net", IPs: []net.IP{{185, 253, 160, 131}, {185, 253, 160, 134}, {185, 253, 160, 136}, {185, 253, 160, 137}, {185, 253, 160, 138}, {185, 253, 160, 139}, {185, 253, 160, 140}, {185, 253, 160, 141}, {185, 253, 160, 142}, {185, 253, 160, 143}}},
|
||||
{Region: "Armenia", Group: "Premium UDP Europe", Hostname: "87-1-am.cg-dialup.net", IPs: []net.IP{{185, 253, 160, 131}, {185, 253, 160, 132}, {185, 253, 160, 133}, {185, 253, 160, 134}, {185, 253, 160, 135}, {185, 253, 160, 136}, {185, 253, 160, 137}, {185, 253, 160, 141}, {185, 253, 160, 142}, {185, 253, 160, 144}}},
|
||||
{Region: "Australia", Group: "Premium TCP Asia", Hostname: "96-1-au.cg-dialup.net", IPs: []net.IP{{154, 16, 81, 22}, {181, 214, 215, 7}, {181, 214, 215, 15}, {181, 214, 215, 18}, {191, 101, 210, 15}, {191, 101, 210, 50}, {191, 101, 210, 60}, {202, 60, 80, 78}, {202, 60, 80, 82}, {202, 60, 80, 102}}},
|
||||
{Region: "Australia", Group: "Premium UDP Asia", Hostname: "95-1-au.cg-dialup.net", IPs: []net.IP{{181, 214, 215, 4}, {181, 214, 215, 16}, {191, 101, 210, 18}, {191, 101, 210, 21}, {191, 101, 210, 36}, {191, 101, 210, 58}, {191, 101, 210, 60}, {202, 60, 80, 74}, {202, 60, 80, 106}, {202, 60, 80, 124}}},
|
||||
{Region: "Austria", Group: "Premium TCP Europe", Hostname: "97-1-at.cg-dialup.net", IPs: []net.IP{{37, 19, 223, 9}, {37, 19, 223, 16}, {37, 19, 223, 113}, {37, 19, 223, 205}, {37, 19, 223, 211}, {37, 19, 223, 218}, {37, 19, 223, 223}, {37, 19, 223, 245}, {37, 120, 155, 104}, {89, 187, 168, 174}}},
|
||||
{Region: "Austria", Group: "Premium UDP Europe", Hostname: "87-1-at.cg-dialup.net", IPs: []net.IP{{37, 19, 223, 202}, {37, 19, 223, 205}, {37, 19, 223, 229}, {37, 19, 223, 239}, {37, 19, 223, 241}, {37, 19, 223, 243}, {37, 120, 155, 103}, {89, 187, 168, 160}, {89, 187, 168, 174}, {89, 187, 168, 181}}},
|
||||
{Region: "Bahamas", Group: "Premium TCP USA", Hostname: "93-1-bs.cg-dialup.net", IPs: []net.IP{{95, 181, 238, 131}, {95, 181, 238, 136}, {95, 181, 238, 142}, {95, 181, 238, 144}, {95, 181, 238, 146}, {95, 181, 238, 147}, {95, 181, 238, 148}, {95, 181, 238, 152}, {95, 181, 238, 153}, {95, 181, 238, 155}}},
|
||||
{Region: "Bahamas", Group: "Premium UDP USA", Hostname: "94-1-bs.cg-dialup.net", IPs: []net.IP{{95, 181, 238, 131}, {95, 181, 238, 138}, {95, 181, 238, 140}, {95, 181, 238, 141}, {95, 181, 238, 146}, {95, 181, 238, 147}, {95, 181, 238, 148}, {95, 181, 238, 151}, {95, 181, 238, 153}, {95, 181, 238, 155}}},
|
||||
{Region: "Bangladesh", Group: "Premium TCP Asia", Hostname: "96-1-bd.cg-dialup.net", IPs: []net.IP{{84, 252, 93, 132}, {84, 252, 93, 133}, {84, 252, 93, 135}, {84, 252, 93, 138}, {84, 252, 93, 139}, {84, 252, 93, 141}, {84, 252, 93, 142}, {84, 252, 93, 143}, {84, 252, 93, 144}, {84, 252, 93, 145}}},
|
||||
{Region: "Bangladesh", Group: "Premium UDP Asia", Hostname: "95-1-bd.cg-dialup.net", IPs: []net.IP{{84, 252, 93, 131}, {84, 252, 93, 133}, {84, 252, 93, 134}, {84, 252, 93, 135}, {84, 252, 93, 136}, {84, 252, 93, 139}, {84, 252, 93, 140}, {84, 252, 93, 141}, {84, 252, 93, 143}, {84, 252, 93, 145}}},
|
||||
{Region: "Belarus", Group: "Premium TCP Europe", Hostname: "97-1-by.cg-dialup.net", IPs: []net.IP{{45, 132, 194, 5}, {45, 132, 194, 6}, {45, 132, 194, 23}, {45, 132, 194, 24}, {45, 132, 194, 25}, {45, 132, 194, 27}, {45, 132, 194, 30}, {45, 132, 194, 35}, {45, 132, 194, 44}, {45, 132, 194, 49}}},
|
||||
{Region: "Belarus", Group: "Premium UDP Europe", Hostname: "87-1-by.cg-dialup.net", IPs: []net.IP{{45, 132, 194, 6}, {45, 132, 194, 8}, {45, 132, 194, 9}, {45, 132, 194, 11}, {45, 132, 194, 15}, {45, 132, 194, 19}, {45, 132, 194, 20}, {45, 132, 194, 23}, {45, 132, 194, 24}, {45, 132, 194, 26}}},
|
||||
{Region: "Belgium", Group: "Premium TCP Europe", Hostname: "97-1-be.cg-dialup.net", IPs: []net.IP{{37, 120, 143, 165}, {37, 120, 143, 166}, {185, 210, 217, 10}, {185, 210, 217, 248}, {193, 9, 114, 211}, {193, 9, 114, 220}, {194, 110, 115, 195}, {194, 110, 115, 199}, {194, 110, 115, 205}, {194, 110, 115, 238}}},
|
||||
{Region: "Belgium", Group: "Premium UDP Europe", Hostname: "87-1-be.cg-dialup.net", IPs: []net.IP{{37, 120, 143, 163}, {37, 120, 143, 167}, {185, 210, 217, 9}, {185, 210, 217, 13}, {185, 210, 217, 55}, {185, 210, 217, 251}, {185, 232, 21, 120}, {194, 110, 115, 214}, {194, 110, 115, 218}, {194, 110, 115, 236}}},
|
||||
{Region: "Bosnia and Herzegovina", Group: "Premium TCP Europe", Hostname: "97-1-ba.cg-dialup.net", IPs: []net.IP{{185, 99, 3, 57}, {185, 99, 3, 58}, {185, 99, 3, 72}, {185, 99, 3, 73}, {185, 99, 3, 74}, {185, 99, 3, 130}, {185, 99, 3, 131}, {185, 99, 3, 134}, {185, 99, 3, 135}, {185, 99, 3, 136}}},
|
||||
{Region: "Bosnia and Herzegovina", Group: "Premium UDP Europe", Hostname: "87-1-ba.cg-dialup.net", IPs: []net.IP{{185, 99, 3, 57}, {185, 99, 3, 58}, {185, 99, 3, 72}, {185, 99, 3, 73}, {185, 99, 3, 74}, {185, 99, 3, 130}, {185, 99, 3, 131}, {185, 99, 3, 134}, {185, 99, 3, 135}, {185, 99, 3, 136}}},
|
||||
{Region: "Brazil", Group: "Premium UDP USA", Hostname: "94-1-br.cg-dialup.net", IPs: []net.IP{{188, 241, 177, 11}, {188, 241, 177, 13}, {188, 241, 177, 19}, {188, 241, 177, 20}, {188, 241, 177, 21}, {188, 241, 177, 29}, {188, 241, 177, 30}, {188, 241, 177, 46}, {188, 241, 177, 147}, {188, 241, 177, 156}}},
|
||||
{Region: "Bulgaria", Group: "Premium TCP Europe", Hostname: "97-1-bg.cg-dialup.net", IPs: []net.IP{{37, 120, 152, 99}, {37, 120, 152, 100}, {37, 120, 152, 101}, {37, 120, 152, 102}, {37, 120, 152, 104}, {37, 120, 152, 105}, {37, 120, 152, 106}, {37, 120, 152, 108}, {37, 120, 152, 109}, {37, 120, 152, 110}}},
|
||||
{Region: "Bulgaria", Group: "Premium UDP Europe", Hostname: "87-1-bg.cg-dialup.net", IPs: []net.IP{{37, 120, 152, 99}, {37, 120, 152, 100}, {37, 120, 152, 101}, {37, 120, 152, 103}, {37, 120, 152, 104}, {37, 120, 152, 106}, {37, 120, 152, 107}, {37, 120, 152, 108}, {37, 120, 152, 109}, {37, 120, 152, 110}}},
|
||||
{Region: "Cambodia", Group: "Premium TCP Asia", Hostname: "96-1-kh.cg-dialup.net", IPs: []net.IP{{188, 215, 235, 38}, {188, 215, 235, 41}, {188, 215, 235, 42}, {188, 215, 235, 47}, {188, 215, 235, 48}, {188, 215, 235, 51}, {188, 215, 235, 52}, {188, 215, 235, 54}, {188, 215, 235, 56}, {188, 215, 235, 57}}},
|
||||
{Region: "Canada", Group: "Premium TCP USA", Hostname: "93-1-ca.cg-dialup.net", IPs: []net.IP{{104, 200, 151, 17}, {104, 200, 151, 47}, {104, 200, 151, 74}, {104, 200, 151, 89}, {104, 200, 151, 163}, {172, 98, 89, 147}, {172, 98, 89, 148}, {172, 98, 89, 164}, {172, 98, 89, 171}, {172, 98, 89, 182}}},
|
||||
{Region: "Canada", Group: "Premium UDP USA", Hostname: "94-1-ca.cg-dialup.net", IPs: []net.IP{{66, 115, 142, 190}, {104, 200, 151, 86}, {104, 200, 151, 103}, {104, 200, 151, 127}, {104, 200, 151, 128}, {104, 200, 151, 139}, {172, 98, 89, 143}, {172, 98, 89, 150}, {172, 98, 89, 156}, {172, 98, 89, 180}}},
|
||||
{Region: "Chile", Group: "Premium TCP USA", Hostname: "93-1-cl.cg-dialup.net", IPs: []net.IP{{146, 70, 11, 3}, {146, 70, 11, 4}, {146, 70, 11, 5}, {146, 70, 11, 6}, {146, 70, 11, 8}, {146, 70, 11, 9}, {146, 70, 11, 11}, {146, 70, 11, 12}, {146, 70, 11, 13}, {146, 70, 11, 14}}},
|
||||
{Region: "Chile", Group: "Premium UDP USA", Hostname: "94-1-cl.cg-dialup.net", IPs: []net.IP{{146, 70, 11, 3}, {146, 70, 11, 4}, {146, 70, 11, 7}, {146, 70, 11, 8}, {146, 70, 11, 9}, {146, 70, 11, 10}, {146, 70, 11, 11}, {146, 70, 11, 12}, {146, 70, 11, 13}, {146, 70, 11, 14}}},
|
||||
{Region: "China", Group: "Premium TCP Asia", Hostname: "96-1-cn.cg-dialup.net", IPs: []net.IP{{188, 241, 80, 131}, {188, 241, 80, 132}, {188, 241, 80, 133}, {188, 241, 80, 134}, {188, 241, 80, 135}, {188, 241, 80, 136}, {188, 241, 80, 137}, {188, 241, 80, 138}, {188, 241, 80, 140}, {188, 241, 80, 141}}},
|
||||
{Region: "Colombia", Group: "Premium UDP USA", Hostname: "94-1-co.cg-dialup.net", IPs: []net.IP{{146, 70, 9, 3}, {146, 70, 9, 4}, {146, 70, 9, 5}, {146, 70, 9, 6}, {146, 70, 9, 7}, {146, 70, 9, 8}, {146, 70, 9, 9}, {146, 70, 9, 10}, {146, 70, 9, 11}, {146, 70, 9, 14}}},
|
||||
{Region: "Costa Rica", Group: "Premium TCP USA", Hostname: "93-1-cr.cg-dialup.net", IPs: []net.IP{{146, 70, 10, 3}, {146, 70, 10, 4}, {146, 70, 10, 5}, {146, 70, 10, 6}, {146, 70, 10, 7}, {146, 70, 10, 8}, {146, 70, 10, 9}, {146, 70, 10, 11}, {146, 70, 10, 12}, {146, 70, 10, 14}}},
|
||||
{Region: "Costa Rica", Group: "Premium UDP USA", Hostname: "94-1-cr.cg-dialup.net", IPs: []net.IP{{146, 70, 10, 3}, {146, 70, 10, 4}, {146, 70, 10, 5}, {146, 70, 10, 7}, {146, 70, 10, 8}, {146, 70, 10, 9}, {146, 70, 10, 11}, {146, 70, 10, 12}, {146, 70, 10, 13}, {146, 70, 10, 14}}},
|
||||
{Region: "Croatia", Group: "Premium TCP Europe", Hostname: "97-1-hr.cg-dialup.net", IPs: []net.IP{{146, 70, 8, 3}, {146, 70, 8, 4}, {146, 70, 8, 5}, {146, 70, 8, 7}, {146, 70, 8, 8}, {146, 70, 8, 11}, {146, 70, 8, 12}, {146, 70, 8, 13}, {146, 70, 8, 14}, {146, 70, 8, 16}}},
|
||||
{Region: "Croatia", Group: "Premium UDP Europe", Hostname: "87-1-hr.cg-dialup.net", IPs: []net.IP{{146, 70, 8, 3}, {146, 70, 8, 4}, {146, 70, 8, 5}, {146, 70, 8, 6}, {146, 70, 8, 8}, {146, 70, 8, 10}, {146, 70, 8, 11}, {146, 70, 8, 12}, {146, 70, 8, 15}, {146, 70, 8, 16}}},
|
||||
{Region: "Cyprus", Group: "Premium TCP Europe", Hostname: "97-1-cy.cg-dialup.net", IPs: []net.IP{{185, 253, 162, 131}, {185, 253, 162, 132}, {185, 253, 162, 133}, {185, 253, 162, 134}, {185, 253, 162, 135}, {185, 253, 162, 137}, {185, 253, 162, 141}, {185, 253, 162, 142}, {185, 253, 162, 143}, {185, 253, 162, 144}}},
|
||||
{Region: "Cyprus", Group: "Premium UDP Europe", Hostname: "87-1-cy.cg-dialup.net", IPs: []net.IP{{185, 253, 162, 131}, {185, 253, 162, 132}, {185, 253, 162, 133}, {185, 253, 162, 134}, {185, 253, 162, 135}, {185, 253, 162, 137}, {185, 253, 162, 138}, {185, 253, 162, 139}, {185, 253, 162, 141}, {185, 253, 162, 143}}},
|
||||
{Region: "Czech Republic", Group: "Premium UDP Europe", Hostname: "87-1-cz.cg-dialup.net", IPs: []net.IP{{195, 181, 161, 3}, {195, 181, 161, 4}, {195, 181, 161, 7}, {195, 181, 161, 9}, {195, 181, 161, 11}, {195, 181, 161, 19}, {195, 181, 161, 20}, {195, 181, 161, 21}, {195, 181, 161, 22}, {195, 181, 161, 24}}},
|
||||
{Region: "Denmark", Group: "Premium TCP Europe", Hostname: "97-1-dk.cg-dialup.net", IPs: []net.IP{{37, 120, 145, 89}, {37, 120, 145, 90}, {37, 120, 194, 42}, {37, 120, 194, 45}, {37, 120, 194, 55}, {95, 174, 65, 163}, {95, 174, 65, 166}, {185, 206, 224, 229}, {185, 206, 224, 234}, {185, 206, 224, 254}}},
|
||||
{Region: "Egypt", Group: "Premium TCP Europe", Hostname: "97-1-eg.cg-dialup.net", IPs: []net.IP{{188, 214, 122, 35}, {188, 214, 122, 42}, {188, 214, 122, 48}, {188, 214, 122, 49}, {188, 214, 122, 58}, {188, 214, 122, 61}, {188, 214, 122, 62}, {188, 214, 122, 68}, {188, 214, 122, 73}, {188, 214, 122, 76}}},
|
||||
{Region: "Egypt", Group: "Premium UDP Europe", Hostname: "87-1-eg.cg-dialup.net", IPs: []net.IP{{188, 214, 122, 35}, {188, 214, 122, 36}, {188, 214, 122, 42}, {188, 214, 122, 47}, {188, 214, 122, 51}, {188, 214, 122, 52}, {188, 214, 122, 58}, {188, 214, 122, 62}, {188, 214, 122, 69}, {188, 214, 122, 78}}},
|
||||
{Region: "Estonia", Group: "Premium TCP Europe", Hostname: "97-1-ee.cg-dialup.net", IPs: []net.IP{{95, 153, 32, 83}, {95, 153, 32, 84}, {95, 153, 32, 86}, {95, 153, 32, 87}, {95, 153, 32, 88}, {95, 153, 32, 89}, {95, 153, 32, 90}, {95, 153, 32, 91}, {95, 153, 32, 92}, {95, 153, 32, 94}}},
|
||||
{Region: "Finland", Group: "Premium UDP Europe", Hostname: "87-1-fi.cg-dialup.net", IPs: []net.IP{{188, 126, 89, 102}, {188, 126, 89, 107}, {188, 126, 89, 108}, {188, 126, 89, 109}, {188, 126, 89, 114}, {188, 126, 89, 125}, {188, 126, 89, 136}, {188, 126, 89, 147}, {188, 126, 89, 153}, {188, 126, 89, 156}}},
|
||||
{Region: "France", Group: "Premium TCP Europe", Hostname: "97-1-fr.cg-dialup.net", IPs: []net.IP{{84, 17, 60, 53}, {84, 17, 60, 55}, {84, 17, 60, 83}, {151, 106, 8, 41}, {151, 106, 11, 189}, {191, 101, 31, 156}, {191, 101, 31, 223}, {191, 101, 217, 61}, {191, 101, 217, 94}, {191, 101, 217, 209}}},
|
||||
{Region: "France", Group: "Premium UDP Europe", Hostname: "87-1-fr.cg-dialup.net", IPs: []net.IP{{84, 17, 60, 102}, {92, 204, 174, 92}, {151, 106, 10, 132}, {191, 101, 31, 121}, {191, 101, 31, 167}, {191, 101, 31, 175}, {191, 101, 31, 196}, {191, 101, 217, 86}, {191, 101, 217, 87}, {191, 101, 217, 100}}},
|
||||
{Region: "Georgia", Group: "Premium UDP Europe", Hostname: "87-1-ge.cg-dialup.net", IPs: []net.IP{{95, 181, 236, 132}, {95, 181, 236, 134}, {95, 181, 236, 135}, {95, 181, 236, 136}, {95, 181, 236, 137}, {95, 181, 236, 138}, {95, 181, 236, 140}, {95, 181, 236, 141}, {95, 181, 236, 142}, {95, 181, 236, 143}}},
|
||||
{Region: "Germany", Group: "Premium TCP Europe", Hostname: "97-1-de.cg-dialup.net", IPs: []net.IP{{84, 17, 48, 110}, {84, 17, 48, 133}, {84, 17, 48, 190}, {84, 17, 49, 84}, {84, 17, 49, 143}, {84, 17, 49, 205}, {154, 13, 1, 175}, {154, 28, 188, 51}, {154, 28, 188, 71}, {154, 28, 188, 80}}},
|
||||
{Region: "Germany", Group: "Premium UDP Europe", Hostname: "87-1-de.cg-dialup.net", IPs: []net.IP{{84, 17, 48, 35}, {84, 17, 48, 168}, {84, 17, 49, 2}, {84, 17, 49, 6}, {84, 17, 49, 19}, {84, 17, 49, 186}, {89, 163, 151, 73}, {154, 13, 1, 176}, {154, 28, 188, 79}, {154, 28, 188, 96}}},
|
||||
{Region: "Greece", Group: "Premium TCP Europe", Hostname: "97-1-gr.cg-dialup.net", IPs: []net.IP{{185, 51, 134, 163}, {185, 51, 134, 166}, {185, 51, 134, 171}, {185, 51, 134, 243}, {185, 51, 134, 246}, {185, 51, 134, 247}, {185, 51, 134, 249}, {185, 51, 134, 251}, {185, 51, 134, 252}, {185, 51, 134, 253}}},
|
||||
{Region: "Greece", Group: "Premium UDP Europe", Hostname: "87-1-gr.cg-dialup.net", IPs: []net.IP{{185, 51, 134, 165}, {185, 51, 134, 166}, {185, 51, 134, 168}, {185, 51, 134, 169}, {185, 51, 134, 174}, {185, 51, 134, 246}, {185, 51, 134, 250}, {185, 51, 134, 251}, {185, 51, 134, 252}, {185, 51, 134, 254}}},
|
||||
{Region: "Greenland", Group: "Premium TCP Europe", Hostname: "97-1-gl.cg-dialup.net", IPs: []net.IP{{91, 90, 120, 3}, {91, 90, 120, 4}, {91, 90, 120, 5}, {91, 90, 120, 6}, {91, 90, 120, 8}, {91, 90, 120, 10}, {91, 90, 120, 11}, {91, 90, 120, 12}, {91, 90, 120, 14}, {91, 90, 120, 15}}},
|
||||
{Region: "Greenland", Group: "Premium UDP Europe", Hostname: "87-1-gl.cg-dialup.net", IPs: []net.IP{{91, 90, 120, 3}, {91, 90, 120, 4}, {91, 90, 120, 6}, {91, 90, 120, 7}, {91, 90, 120, 9}, {91, 90, 120, 10}, {91, 90, 120, 12}, {91, 90, 120, 13}, {91, 90, 120, 16}, {91, 90, 120, 17}}},
|
||||
{Region: "Hong Kong", Group: "Premium TCP Asia", Hostname: "96-1-hk.cg-dialup.net", IPs: []net.IP{{84, 17, 56, 132}, {84, 17, 56, 134}, {84, 17, 56, 135}, {84, 17, 56, 139}, {84, 17, 56, 143}, {84, 17, 56, 162}, {84, 17, 56, 164}, {84, 17, 56, 174}, {84, 17, 56, 182}, {84, 17, 56, 183}}},
|
||||
{Region: "Hungary", Group: "Premium TCP Europe", Hostname: "97-1-hu.cg-dialup.net", IPs: []net.IP{{86, 106, 74, 243}, {86, 106, 74, 244}, {86, 106, 74, 246}, {86, 106, 74, 247}, {86, 106, 74, 249}, {185, 189, 114, 115}, {185, 189, 114, 120}, {185, 189, 114, 122}, {185, 189, 114, 123}, {185, 189, 114, 126}}},
|
||||
{Region: "Hungary", Group: "Premium UDP Europe", Hostname: "87-1-hu.cg-dialup.net", IPs: []net.IP{{86, 106, 74, 243}, {86, 106, 74, 244}, {86, 106, 74, 247}, {86, 106, 74, 250}, {86, 106, 74, 251}, {86, 106, 74, 253}, {185, 189, 114, 117}, {185, 189, 114, 120}, {185, 189, 114, 124}, {185, 189, 114, 126}}},
|
||||
{Region: "Iceland", Group: "Premium TCP Europe", Hostname: "97-1-is.cg-dialup.net", IPs: []net.IP{{45, 133, 193, 3}, {45, 133, 193, 5}, {45, 133, 193, 6}, {45, 133, 193, 7}, {45, 133, 193, 9}, {45, 133, 193, 10}, {45, 133, 193, 11}, {45, 133, 193, 12}, {45, 133, 193, 13}, {45, 133, 193, 14}}},
|
||||
{Region: "India", Group: "Premium TCP Europe", Hostname: "97-1-in.cg-dialup.net", IPs: []net.IP{{103, 13, 112, 50}, {103, 13, 112, 52}, {103, 13, 112, 59}, {103, 13, 112, 61}, {103, 13, 112, 67}, {103, 13, 112, 68}, {103, 13, 112, 74}, {103, 13, 112, 78}, {103, 13, 112, 80}, {103, 13, 112, 81}}},
|
||||
{Region: "India", Group: "Premium UDP Europe", Hostname: "87-1-in.cg-dialup.net", IPs: []net.IP{{103, 13, 112, 50}, {103, 13, 112, 51}, {103, 13, 112, 52}, {103, 13, 112, 54}, {103, 13, 112, 59}, {103, 13, 112, 60}, {103, 13, 112, 66}, {103, 13, 112, 67}, {103, 13, 112, 71}, {103, 13, 112, 79}}},
|
||||
{Region: "Indonesia", Group: "Premium TCP Asia", Hostname: "96-1-id.cg-dialup.net", IPs: []net.IP{{146, 70, 14, 3}, {146, 70, 14, 5}, {146, 70, 14, 7}, {146, 70, 14, 9}, {146, 70, 14, 10}, {146, 70, 14, 11}, {146, 70, 14, 12}, {146, 70, 14, 13}, {146, 70, 14, 15}, {146, 70, 14, 16}}},
|
||||
{Region: "Indonesia", Group: "Premium UDP Asia", Hostname: "95-1-id.cg-dialup.net", IPs: []net.IP{{146, 70, 14, 3}, {146, 70, 14, 5}, {146, 70, 14, 7}, {146, 70, 14, 10}, {146, 70, 14, 11}, {146, 70, 14, 12}, {146, 70, 14, 13}, {146, 70, 14, 14}, {146, 70, 14, 15}, {146, 70, 14, 16}}},
|
||||
{Region: "Iran", Group: "Premium TCP Asia", Hostname: "96-1-ir.cg-dialup.net", IPs: []net.IP{{62, 133, 46, 3}, {62, 133, 46, 4}, {62, 133, 46, 5}, {62, 133, 46, 7}, {62, 133, 46, 8}, {62, 133, 46, 9}, {62, 133, 46, 10}, {62, 133, 46, 12}, {62, 133, 46, 14}, {62, 133, 46, 16}}},
|
||||
{Region: "Ireland", Group: "Premium UDP Europe", Hostname: "87-1-ie.cg-dialup.net", IPs: []net.IP{{37, 120, 235, 147}, {37, 120, 235, 158}, {37, 120, 235, 165}, {37, 120, 235, 166}, {84, 247, 48, 5}, {84, 247, 48, 6}, {84, 247, 48, 9}, {84, 247, 48, 23}, {84, 247, 48, 27}, {84, 247, 48, 29}}},
|
||||
{Region: "Isle of Man", Group: "Premium TCP Europe", Hostname: "97-1-im.cg-dialup.net", IPs: []net.IP{{91, 90, 124, 147}, {91, 90, 124, 149}, {91, 90, 124, 150}, {91, 90, 124, 151}, {91, 90, 124, 153}, {91, 90, 124, 154}, {91, 90, 124, 155}, {91, 90, 124, 157}, {91, 90, 124, 158}, {91, 90, 124, 159}}},
|
||||
{Region: "Isle of Man", Group: "Premium UDP Europe", Hostname: "87-1-im.cg-dialup.net", IPs: []net.IP{{91, 90, 124, 147}, {91, 90, 124, 148}, {91, 90, 124, 150}, {91, 90, 124, 151}, {91, 90, 124, 152}, {91, 90, 124, 153}, {91, 90, 124, 154}, {91, 90, 124, 156}, {91, 90, 124, 157}, {91, 90, 124, 158}}},
|
||||
{Region: "Israel", Group: "Premium UDP Europe", Hostname: "87-1-il.cg-dialup.net", IPs: []net.IP{{160, 116, 0, 169}, {160, 116, 0, 170}, {160, 116, 0, 171}, {160, 116, 0, 172}, {185, 77, 248, 114}, {185, 77, 248, 117}, {185, 77, 248, 119}, {185, 77, 248, 121}, {185, 77, 248, 123}, {185, 77, 248, 129}}},
|
||||
{Region: "Italy", Group: "Premium TCP Europe", Hostname: "97-1-it.cg-dialup.net", IPs: []net.IP{{84, 17, 58, 12}, {84, 17, 58, 94}, {84, 17, 58, 96}, {84, 17, 58, 98}, {84, 17, 58, 100}, {84, 17, 58, 105}, {185, 217, 71, 132}, {212, 102, 55, 103}, {212, 102, 55, 109}, {212, 102, 55, 113}}},
|
||||
{Region: "Italy", Group: "Premium UDP Europe", Hostname: "87-1-it.cg-dialup.net", IPs: []net.IP{{84, 17, 58, 10}, {84, 17, 58, 20}, {84, 17, 58, 104}, {84, 17, 58, 105}, {87, 101, 94, 67}, {87, 101, 94, 120}, {87, 101, 94, 123}, {185, 217, 71, 153}, {212, 102, 55, 111}, {212, 102, 55, 122}}},
|
||||
{Region: "Japan", Group: "Premium UDP Asia", Hostname: "95-1-jp.cg-dialup.net", IPs: []net.IP{{156, 146, 35, 10}, {156, 146, 35, 14}, {156, 146, 35, 17}, {156, 146, 35, 18}, {156, 146, 35, 23}, {156, 146, 35, 25}, {156, 146, 35, 30}, {156, 146, 35, 44}, {156, 146, 35, 46}, {156, 146, 35, 48}}},
|
||||
{Region: "Kazakhstan", Group: "Premium TCP Europe", Hostname: "97-1-kz.cg-dialup.net", IPs: []net.IP{{62, 133, 47, 131}, {62, 133, 47, 132}, {62, 133, 47, 134}, {62, 133, 47, 135}, {62, 133, 47, 136}, {62, 133, 47, 137}, {62, 133, 47, 138}, {62, 133, 47, 139}, {62, 133, 47, 140}, {62, 133, 47, 142}}},
|
||||
{Region: "Kazakhstan", Group: "Premium UDP Europe", Hostname: "87-1-kz.cg-dialup.net", IPs: []net.IP{{62, 133, 47, 131}, {62, 133, 47, 132}, {62, 133, 47, 133}, {62, 133, 47, 134}, {62, 133, 47, 135}, {62, 133, 47, 137}, {62, 133, 47, 141}, {62, 133, 47, 142}, {62, 133, 47, 143}, {62, 133, 47, 144}}},
|
||||
{Region: "Brazil", Group: "Premium TCP USA", Hostname: "93-1-br.cg-dialup.net", IPs: []net.IP{{188, 241, 177, 5}, {188, 241, 177, 11}, {188, 241, 177, 38}, {188, 241, 177, 45}, {188, 241, 177, 132}, {188, 241, 177, 135}, {188, 241, 177, 136}, {188, 241, 177, 152}, {188, 241, 177, 153}, {188, 241, 177, 156}}},
|
||||
{Region: "Brazil", Group: "Premium UDP USA", Hostname: "94-1-br.cg-dialup.net", IPs: []net.IP{{188, 241, 177, 8}, {188, 241, 177, 37}, {188, 241, 177, 40}, {188, 241, 177, 42}, {188, 241, 177, 45}, {188, 241, 177, 135}, {188, 241, 177, 139}, {188, 241, 177, 149}, {188, 241, 177, 152}, {188, 241, 177, 154}}},
|
||||
{Region: "Bulgaria", Group: "Premium TCP Europe", Hostname: "97-1-bg.cg-dialup.net", IPs: []net.IP{{37, 120, 152, 99}, {37, 120, 152, 101}, {37, 120, 152, 103}, {37, 120, 152, 104}, {37, 120, 152, 105}, {37, 120, 152, 106}, {37, 120, 152, 107}, {37, 120, 152, 108}, {37, 120, 152, 109}, {37, 120, 152, 110}}},
|
||||
{Region: "Bulgaria", Group: "Premium UDP Europe", Hostname: "87-1-bg.cg-dialup.net", IPs: []net.IP{{37, 120, 152, 99}, {37, 120, 152, 100}, {37, 120, 152, 101}, {37, 120, 152, 102}, {37, 120, 152, 103}, {37, 120, 152, 105}, {37, 120, 152, 106}, {37, 120, 152, 107}, {37, 120, 152, 108}, {37, 120, 152, 109}}},
|
||||
{Region: "Cambodia", Group: "Premium TCP Asia", Hostname: "96-1-kh.cg-dialup.net", IPs: []net.IP{{188, 215, 235, 35}, {188, 215, 235, 36}, {188, 215, 235, 38}, {188, 215, 235, 39}, {188, 215, 235, 45}, {188, 215, 235, 49}, {188, 215, 235, 51}, {188, 215, 235, 53}, {188, 215, 235, 54}, {188, 215, 235, 57}}},
|
||||
{Region: "Cambodia", Group: "Premium UDP Asia", Hostname: "95-1-kh.cg-dialup.net", IPs: []net.IP{{188, 215, 235, 36}, {188, 215, 235, 40}, {188, 215, 235, 42}, {188, 215, 235, 44}, {188, 215, 235, 46}, {188, 215, 235, 47}, {188, 215, 235, 48}, {188, 215, 235, 50}, {188, 215, 235, 55}, {188, 215, 235, 57}}},
|
||||
{Region: "Canada", Group: "Premium TCP USA", Hostname: "93-1-ca.cg-dialup.net", IPs: []net.IP{{66, 115, 142, 136}, {66, 115, 142, 139}, {66, 115, 142, 156}, {66, 115, 142, 162}, {66, 115, 142, 172}, {104, 200, 151, 99}, {104, 200, 151, 111}, {104, 200, 151, 153}, {104, 200, 151, 164}, {172, 98, 89, 137}}},
|
||||
{Region: "Canada", Group: "Premium UDP USA", Hostname: "94-1-ca.cg-dialup.net", IPs: []net.IP{{66, 115, 142, 135}, {66, 115, 142, 154}, {66, 115, 142, 165}, {104, 200, 151, 32}, {104, 200, 151, 57}, {104, 200, 151, 85}, {104, 200, 151, 86}, {104, 200, 151, 147}, {172, 98, 89, 144}, {172, 98, 89, 173}}},
|
||||
{Region: "Chile", Group: "Premium TCP USA", Hostname: "93-1-cl.cg-dialup.net", IPs: []net.IP{{146, 70, 11, 3}, {146, 70, 11, 6}, {146, 70, 11, 7}, {146, 70, 11, 8}, {146, 70, 11, 9}, {146, 70, 11, 10}, {146, 70, 11, 11}, {146, 70, 11, 12}, {146, 70, 11, 13}, {146, 70, 11, 14}}},
|
||||
{Region: "Chile", Group: "Premium UDP USA", Hostname: "94-1-cl.cg-dialup.net", IPs: []net.IP{{146, 70, 11, 3}, {146, 70, 11, 4}, {146, 70, 11, 6}, {146, 70, 11, 7}, {146, 70, 11, 8}, {146, 70, 11, 9}, {146, 70, 11, 10}, {146, 70, 11, 11}, {146, 70, 11, 13}, {146, 70, 11, 14}}},
|
||||
{Region: "China", Group: "Premium TCP Asia", Hostname: "96-1-cn.cg-dialup.net", IPs: []net.IP{{188, 241, 80, 131}, {188, 241, 80, 132}, {188, 241, 80, 133}, {188, 241, 80, 134}, {188, 241, 80, 135}, {188, 241, 80, 137}, {188, 241, 80, 139}, {188, 241, 80, 140}, {188, 241, 80, 141}, {188, 241, 80, 142}}},
|
||||
{Region: "China", Group: "Premium UDP Asia", Hostname: "95-1-cn.cg-dialup.net", IPs: []net.IP{{188, 241, 80, 131}, {188, 241, 80, 132}, {188, 241, 80, 133}, {188, 241, 80, 134}, {188, 241, 80, 135}, {188, 241, 80, 136}, {188, 241, 80, 137}, {188, 241, 80, 138}, {188, 241, 80, 139}, {188, 241, 80, 142}}},
|
||||
{Region: "Colombia", Group: "Premium TCP USA", Hostname: "93-1-co.cg-dialup.net", IPs: []net.IP{{146, 70, 9, 3}, {146, 70, 9, 4}, {146, 70, 9, 5}, {146, 70, 9, 7}, {146, 70, 9, 9}, {146, 70, 9, 10}, {146, 70, 9, 11}, {146, 70, 9, 12}, {146, 70, 9, 13}, {146, 70, 9, 14}}},
|
||||
{Region: "Colombia", Group: "Premium UDP USA", Hostname: "94-1-co.cg-dialup.net", IPs: []net.IP{{146, 70, 9, 3}, {146, 70, 9, 4}, {146, 70, 9, 5}, {146, 70, 9, 6}, {146, 70, 9, 7}, {146, 70, 9, 8}, {146, 70, 9, 9}, {146, 70, 9, 10}, {146, 70, 9, 11}, {146, 70, 9, 12}}},
|
||||
{Region: "Costa Rica", Group: "Premium TCP USA", Hostname: "93-1-cr.cg-dialup.net", IPs: []net.IP{{146, 70, 10, 3}, {146, 70, 10, 4}, {146, 70, 10, 5}, {146, 70, 10, 6}, {146, 70, 10, 7}, {146, 70, 10, 8}, {146, 70, 10, 10}, {146, 70, 10, 11}, {146, 70, 10, 12}, {146, 70, 10, 13}}},
|
||||
{Region: "Costa Rica", Group: "Premium UDP USA", Hostname: "94-1-cr.cg-dialup.net", IPs: []net.IP{{146, 70, 10, 3}, {146, 70, 10, 4}, {146, 70, 10, 5}, {146, 70, 10, 6}, {146, 70, 10, 7}, {146, 70, 10, 8}, {146, 70, 10, 9}, {146, 70, 10, 11}, {146, 70, 10, 12}, {146, 70, 10, 14}}},
|
||||
{Region: "Croatia", Group: "Premium TCP Europe", Hostname: "97-1-hr.cg-dialup.net", IPs: []net.IP{{146, 70, 8, 5}, {146, 70, 8, 8}, {146, 70, 8, 9}, {146, 70, 8, 10}, {146, 70, 8, 11}, {146, 70, 8, 12}, {146, 70, 8, 13}, {146, 70, 8, 14}, {146, 70, 8, 15}, {146, 70, 8, 16}}},
|
||||
{Region: "Croatia", Group: "Premium UDP Europe", Hostname: "87-1-hr.cg-dialup.net", IPs: []net.IP{{146, 70, 8, 3}, {146, 70, 8, 4}, {146, 70, 8, 5}, {146, 70, 8, 6}, {146, 70, 8, 7}, {146, 70, 8, 9}, {146, 70, 8, 11}, {146, 70, 8, 13}, {146, 70, 8, 14}, {146, 70, 8, 16}}},
|
||||
{Region: "Cyprus", Group: "Premium TCP Europe", Hostname: "97-1-cy.cg-dialup.net", IPs: []net.IP{{185, 253, 162, 131}, {185, 253, 162, 133}, {185, 253, 162, 135}, {185, 253, 162, 136}, {185, 253, 162, 137}, {185, 253, 162, 139}, {185, 253, 162, 140}, {185, 253, 162, 142}, {185, 253, 162, 143}, {185, 253, 162, 144}}},
|
||||
{Region: "Cyprus", Group: "Premium UDP Europe", Hostname: "87-1-cy.cg-dialup.net", IPs: []net.IP{{185, 253, 162, 131}, {185, 253, 162, 132}, {185, 253, 162, 134}, {185, 253, 162, 135}, {185, 253, 162, 137}, {185, 253, 162, 138}, {185, 253, 162, 140}, {185, 253, 162, 142}, {185, 253, 162, 143}, {185, 253, 162, 144}}},
|
||||
{Region: "Czech Republic", Group: "Premium TCP Europe", Hostname: "97-1-cz.cg-dialup.net", IPs: []net.IP{{138, 199, 56, 235}, {138, 199, 56, 236}, {138, 199, 56, 237}, {138, 199, 56, 245}, {138, 199, 56, 246}, {138, 199, 56, 249}, {195, 181, 161, 12}, {195, 181, 161, 16}, {195, 181, 161, 20}, {195, 181, 161, 23}}},
|
||||
{Region: "Czech Republic", Group: "Premium UDP Europe", Hostname: "87-1-cz.cg-dialup.net", IPs: []net.IP{{138, 199, 56, 227}, {138, 199, 56, 229}, {138, 199, 56, 231}, {138, 199, 56, 235}, {138, 199, 56, 241}, {138, 199, 56, 247}, {195, 181, 161, 10}, {195, 181, 161, 16}, {195, 181, 161, 18}, {195, 181, 161, 22}}},
|
||||
{Region: "Denmark", Group: "Premium TCP Europe", Hostname: "97-1-dk.cg-dialup.net", IPs: []net.IP{{37, 120, 145, 83}, {37, 120, 145, 88}, {37, 120, 145, 93}, {37, 120, 194, 36}, {37, 120, 194, 56}, {37, 120, 194, 57}, {95, 174, 65, 163}, {95, 174, 65, 174}, {185, 206, 224, 238}, {185, 206, 224, 243}}},
|
||||
{Region: "Denmark", Group: "Premium UDP Europe", Hostname: "87-1-dk.cg-dialup.net", IPs: []net.IP{{37, 120, 194, 39}, {95, 174, 65, 167}, {95, 174, 65, 170}, {185, 206, 224, 227}, {185, 206, 224, 230}, {185, 206, 224, 236}, {185, 206, 224, 238}, {185, 206, 224, 245}, {185, 206, 224, 250}, {185, 206, 224, 254}}},
|
||||
{Region: "Egypt", Group: "Premium TCP Europe", Hostname: "97-1-eg.cg-dialup.net", IPs: []net.IP{{188, 214, 122, 40}, {188, 214, 122, 42}, {188, 214, 122, 43}, {188, 214, 122, 45}, {188, 214, 122, 48}, {188, 214, 122, 50}, {188, 214, 122, 52}, {188, 214, 122, 60}, {188, 214, 122, 70}, {188, 214, 122, 73}}},
|
||||
{Region: "Egypt", Group: "Premium UDP Europe", Hostname: "87-1-eg.cg-dialup.net", IPs: []net.IP{{188, 214, 122, 37}, {188, 214, 122, 38}, {188, 214, 122, 44}, {188, 214, 122, 54}, {188, 214, 122, 57}, {188, 214, 122, 59}, {188, 214, 122, 60}, {188, 214, 122, 61}, {188, 214, 122, 67}, {188, 214, 122, 69}}},
|
||||
{Region: "Estonia", Group: "Premium TCP Europe", Hostname: "97-1-ee.cg-dialup.net", IPs: []net.IP{{95, 153, 32, 83}, {95, 153, 32, 84}, {95, 153, 32, 86}, {95, 153, 32, 88}, {95, 153, 32, 89}, {95, 153, 32, 90}, {95, 153, 32, 91}, {95, 153, 32, 92}, {95, 153, 32, 93}, {95, 153, 32, 94}}},
|
||||
{Region: "Estonia", Group: "Premium UDP Europe", Hostname: "87-1-ee.cg-dialup.net", IPs: []net.IP{{95, 153, 32, 83}, {95, 153, 32, 84}, {95, 153, 32, 85}, {95, 153, 32, 87}, {95, 153, 32, 88}, {95, 153, 32, 89}, {95, 153, 32, 90}, {95, 153, 32, 91}, {95, 153, 32, 92}, {95, 153, 32, 94}}},
|
||||
{Region: "Finland", Group: "Premium TCP Europe", Hostname: "97-1-fi.cg-dialup.net", IPs: []net.IP{{188, 126, 89, 99}, {188, 126, 89, 102}, {188, 126, 89, 105}, {188, 126, 89, 107}, {188, 126, 89, 108}, {188, 126, 89, 110}, {188, 126, 89, 112}, {188, 126, 89, 115}, {188, 126, 89, 116}, {188, 126, 89, 119}}},
|
||||
{Region: "Finland", Group: "Premium UDP Europe", Hostname: "87-1-fi.cg-dialup.net", IPs: []net.IP{{188, 126, 89, 101}, {188, 126, 89, 104}, {188, 126, 89, 109}, {188, 126, 89, 110}, {188, 126, 89, 111}, {188, 126, 89, 113}, {188, 126, 89, 114}, {188, 126, 89, 115}, {188, 126, 89, 122}, {188, 126, 89, 124}}},
|
||||
{Region: "France", Group: "Premium TCP Europe", Hostname: "97-1-fr.cg-dialup.net", IPs: []net.IP{{84, 17, 43, 167}, {84, 17, 60, 147}, {84, 17, 60, 155}, {151, 106, 8, 108}, {191, 101, 31, 202}, {191, 101, 31, 254}, {191, 101, 217, 45}, {191, 101, 217, 159}, {191, 101, 217, 211}, {191, 101, 217, 240}}},
|
||||
{Region: "France", Group: "Premium UDP Europe", Hostname: "87-1-fr.cg-dialup.net", IPs: []net.IP{{84, 17, 60, 59}, {84, 17, 60, 121}, {191, 101, 31, 81}, {191, 101, 31, 84}, {191, 101, 31, 126}, {191, 101, 31, 127}, {191, 101, 217, 140}, {191, 101, 217, 201}, {191, 101, 217, 206}, {191, 101, 217, 211}}},
|
||||
{Region: "Georgia", Group: "Premium TCP Europe", Hostname: "97-1-ge.cg-dialup.net", IPs: []net.IP{{95, 181, 236, 131}, {95, 181, 236, 132}, {95, 181, 236, 133}, {95, 181, 236, 134}, {95, 181, 236, 135}, {95, 181, 236, 136}, {95, 181, 236, 138}, {95, 181, 236, 139}, {95, 181, 236, 142}, {95, 181, 236, 144}}},
|
||||
{Region: "Georgia", Group: "Premium UDP Europe", Hostname: "87-1-ge.cg-dialup.net", IPs: []net.IP{{95, 181, 236, 132}, {95, 181, 236, 133}, {95, 181, 236, 134}, {95, 181, 236, 136}, {95, 181, 236, 137}, {95, 181, 236, 139}, {95, 181, 236, 141}, {95, 181, 236, 142}, {95, 181, 236, 143}, {95, 181, 236, 144}}},
|
||||
{Region: "Germany", Group: "Premium TCP Europe", Hostname: "97-1-de.cg-dialup.net", IPs: []net.IP{{84, 17, 48, 39}, {84, 17, 48, 234}, {84, 17, 49, 106}, {84, 17, 49, 112}, {84, 17, 49, 218}, {154, 28, 188, 35}, {154, 28, 188, 66}, {154, 28, 188, 133}, {154, 28, 188, 144}, {154, 28, 188, 145}}},
|
||||
{Region: "Germany", Group: "Premium UDP Europe", Hostname: "87-1-de.cg-dialup.net", IPs: []net.IP{{84, 17, 48, 41}, {84, 17, 48, 224}, {84, 17, 49, 95}, {84, 17, 49, 236}, {84, 17, 49, 241}, {138, 199, 36, 151}, {154, 13, 1, 177}, {154, 28, 188, 73}, {154, 28, 188, 76}, {154, 28, 188, 93}}},
|
||||
{Region: "Greece", Group: "Premium TCP Europe", Hostname: "97-1-gr.cg-dialup.net", IPs: []net.IP{{185, 51, 134, 163}, {185, 51, 134, 165}, {185, 51, 134, 171}, {185, 51, 134, 172}, {185, 51, 134, 245}, {185, 51, 134, 246}, {185, 51, 134, 247}, {185, 51, 134, 249}, {185, 51, 134, 251}, {185, 51, 134, 254}}},
|
||||
{Region: "Greece", Group: "Premium UDP Europe", Hostname: "87-1-gr.cg-dialup.net", IPs: []net.IP{{185, 51, 134, 163}, {185, 51, 134, 166}, {185, 51, 134, 173}, {185, 51, 134, 174}, {185, 51, 134, 244}, {185, 51, 134, 246}, {185, 51, 134, 247}, {185, 51, 134, 251}, {185, 51, 134, 252}, {185, 51, 134, 253}}},
|
||||
{Region: "Greenland", Group: "Premium TCP Europe", Hostname: "97-1-gl.cg-dialup.net", IPs: []net.IP{{91, 90, 120, 3}, {91, 90, 120, 4}, {91, 90, 120, 5}, {91, 90, 120, 7}, {91, 90, 120, 8}, {91, 90, 120, 10}, {91, 90, 120, 12}, {91, 90, 120, 13}, {91, 90, 120, 14}, {91, 90, 120, 17}}},
|
||||
{Region: "Greenland", Group: "Premium UDP Europe", Hostname: "87-1-gl.cg-dialup.net", IPs: []net.IP{{91, 90, 120, 3}, {91, 90, 120, 4}, {91, 90, 120, 5}, {91, 90, 120, 7}, {91, 90, 120, 9}, {91, 90, 120, 10}, {91, 90, 120, 12}, {91, 90, 120, 14}, {91, 90, 120, 15}, {91, 90, 120, 16}}},
|
||||
{Region: "Hong Kong", Group: "Premium TCP Asia", Hostname: "96-1-hk.cg-dialup.net", IPs: []net.IP{{84, 17, 56, 144}, {84, 17, 56, 148}, {84, 17, 56, 153}, {84, 17, 56, 162}, {84, 17, 56, 163}, {84, 17, 56, 169}, {84, 17, 56, 170}, {84, 17, 56, 179}, {84, 17, 56, 180}, {84, 17, 56, 181}}},
|
||||
{Region: "Hong Kong", Group: "Premium UDP Asia", Hostname: "95-1-hk.cg-dialup.net", IPs: []net.IP{{84, 17, 56, 143}, {84, 17, 56, 147}, {84, 17, 56, 150}, {84, 17, 56, 152}, {84, 17, 56, 161}, {84, 17, 56, 164}, {84, 17, 56, 168}, {84, 17, 56, 179}, {84, 17, 56, 180}, {84, 17, 56, 183}}},
|
||||
{Region: "Hungary", Group: "Premium TCP Europe", Hostname: "97-1-hu.cg-dialup.net", IPs: []net.IP{{86, 106, 74, 247}, {86, 106, 74, 251}, {86, 106, 74, 253}, {185, 189, 114, 117}, {185, 189, 114, 118}, {185, 189, 114, 119}, {185, 189, 114, 121}, {185, 189, 114, 123}, {185, 189, 114, 125}, {185, 189, 114, 126}}},
|
||||
{Region: "Hungary", Group: "Premium UDP Europe", Hostname: "87-1-hu.cg-dialup.net", IPs: []net.IP{{86, 106, 74, 245}, {86, 106, 74, 247}, {86, 106, 74, 248}, {86, 106, 74, 249}, {86, 106, 74, 250}, {86, 106, 74, 252}, {86, 106, 74, 253}, {185, 189, 114, 120}, {185, 189, 114, 121}, {185, 189, 114, 122}}},
|
||||
{Region: "Iceland", Group: "Premium TCP Europe", Hostname: "97-1-is.cg-dialup.net", IPs: []net.IP{{45, 133, 193, 3}, {45, 133, 193, 4}, {45, 133, 193, 6}, {45, 133, 193, 7}, {45, 133, 193, 8}, {45, 133, 193, 10}, {45, 133, 193, 11}, {45, 133, 193, 12}, {45, 133, 193, 13}, {45, 133, 193, 14}}},
|
||||
{Region: "Iceland", Group: "Premium UDP Europe", Hostname: "87-1-is.cg-dialup.net", IPs: []net.IP{{45, 133, 193, 3}, {45, 133, 193, 5}, {45, 133, 193, 6}, {45, 133, 193, 7}, {45, 133, 193, 8}, {45, 133, 193, 9}, {45, 133, 193, 10}, {45, 133, 193, 11}, {45, 133, 193, 13}, {45, 133, 193, 14}}},
|
||||
{Region: "India", Group: "Premium TCP Europe", Hostname: "97-1-in.cg-dialup.net", IPs: []net.IP{{103, 13, 112, 68}, {103, 13, 112, 70}, {103, 13, 112, 72}, {103, 13, 112, 74}, {103, 13, 112, 75}, {103, 13, 113, 74}, {103, 13, 113, 79}, {103, 13, 113, 82}, {103, 13, 113, 83}, {103, 13, 113, 84}}},
|
||||
{Region: "India", Group: "Premium UDP Europe", Hostname: "87-1-in.cg-dialup.net", IPs: []net.IP{{103, 13, 112, 67}, {103, 13, 112, 70}, {103, 13, 112, 71}, {103, 13, 112, 77}, {103, 13, 112, 80}, {103, 13, 113, 72}, {103, 13, 113, 74}, {103, 13, 113, 75}, {103, 13, 113, 77}, {103, 13, 113, 85}}},
|
||||
{Region: "Indonesia", Group: "Premium TCP Asia", Hostname: "96-1-id.cg-dialup.net", IPs: []net.IP{{146, 70, 14, 3}, {146, 70, 14, 4}, {146, 70, 14, 5}, {146, 70, 14, 6}, {146, 70, 14, 7}, {146, 70, 14, 10}, {146, 70, 14, 12}, {146, 70, 14, 13}, {146, 70, 14, 15}, {146, 70, 14, 16}}},
|
||||
{Region: "Indonesia", Group: "Premium UDP Asia", Hostname: "95-1-id.cg-dialup.net", IPs: []net.IP{{146, 70, 14, 3}, {146, 70, 14, 5}, {146, 70, 14, 8}, {146, 70, 14, 9}, {146, 70, 14, 10}, {146, 70, 14, 12}, {146, 70, 14, 13}, {146, 70, 14, 14}, {146, 70, 14, 15}, {146, 70, 14, 16}}},
|
||||
{Region: "Iran", Group: "Premium TCP Asia", Hostname: "96-1-ir.cg-dialup.net", IPs: []net.IP{{62, 133, 46, 3}, {62, 133, 46, 4}, {62, 133, 46, 5}, {62, 133, 46, 6}, {62, 133, 46, 7}, {62, 133, 46, 8}, {62, 133, 46, 9}, {62, 133, 46, 10}, {62, 133, 46, 14}, {62, 133, 46, 15}}},
|
||||
{Region: "Iran", Group: "Premium UDP Asia", Hostname: "95-1-ir.cg-dialup.net", IPs: []net.IP{{62, 133, 46, 3}, {62, 133, 46, 4}, {62, 133, 46, 7}, {62, 133, 46, 8}, {62, 133, 46, 11}, {62, 133, 46, 12}, {62, 133, 46, 13}, {62, 133, 46, 14}, {62, 133, 46, 15}, {62, 133, 46, 16}}},
|
||||
{Region: "Ireland", Group: "Premium TCP Europe", Hostname: "97-1-ie.cg-dialup.net", IPs: []net.IP{{37, 120, 235, 154}, {37, 120, 235, 166}, {37, 120, 235, 174}, {77, 81, 139, 35}, {84, 247, 48, 6}, {84, 247, 48, 19}, {84, 247, 48, 22}, {84, 247, 48, 23}, {84, 247, 48, 25}, {84, 247, 48, 26}}},
|
||||
{Region: "Ireland", Group: "Premium UDP Europe", Hostname: "87-1-ie.cg-dialup.net", IPs: []net.IP{{37, 120, 235, 147}, {37, 120, 235, 148}, {37, 120, 235, 153}, {37, 120, 235, 158}, {37, 120, 235, 169}, {37, 120, 235, 174}, {84, 247, 48, 8}, {84, 247, 48, 11}, {84, 247, 48, 20}, {84, 247, 48, 23}}},
|
||||
{Region: "Isle of Man", Group: "Premium TCP Europe", Hostname: "97-1-im.cg-dialup.net", IPs: []net.IP{{91, 90, 124, 147}, {91, 90, 124, 149}, {91, 90, 124, 150}, {91, 90, 124, 151}, {91, 90, 124, 152}, {91, 90, 124, 153}, {91, 90, 124, 154}, {91, 90, 124, 156}, {91, 90, 124, 157}, {91, 90, 124, 158}}},
|
||||
{Region: "Isle of Man", Group: "Premium UDP Europe", Hostname: "87-1-im.cg-dialup.net", IPs: []net.IP{{91, 90, 124, 147}, {91, 90, 124, 149}, {91, 90, 124, 150}, {91, 90, 124, 151}, {91, 90, 124, 152}, {91, 90, 124, 153}, {91, 90, 124, 154}, {91, 90, 124, 155}, {91, 90, 124, 156}, {91, 90, 124, 157}}},
|
||||
{Region: "Israel", Group: "Premium TCP Europe", Hostname: "97-1-il.cg-dialup.net", IPs: []net.IP{{160, 116, 0, 174}, {185, 77, 248, 103}, {185, 77, 248, 111}, {185, 77, 248, 113}, {185, 77, 248, 114}, {185, 77, 248, 124}, {185, 77, 248, 125}, {185, 77, 248, 127}, {185, 77, 248, 128}, {185, 77, 248, 129}}},
|
||||
{Region: "Israel", Group: "Premium UDP Europe", Hostname: "87-1-il.cg-dialup.net", IPs: []net.IP{{160, 116, 0, 163}, {160, 116, 0, 165}, {160, 116, 0, 172}, {185, 77, 248, 103}, {185, 77, 248, 106}, {185, 77, 248, 114}, {185, 77, 248, 117}, {185, 77, 248, 118}, {185, 77, 248, 126}, {185, 77, 248, 129}}},
|
||||
{Region: "Italy", Group: "Premium TCP Europe", Hostname: "97-1-it.cg-dialup.net", IPs: []net.IP{{84, 17, 58, 21}, {84, 17, 58, 100}, {84, 17, 58, 106}, {84, 17, 58, 111}, {84, 17, 58, 117}, {87, 101, 94, 122}, {212, 102, 55, 100}, {212, 102, 55, 106}, {212, 102, 55, 110}, {212, 102, 55, 122}}},
|
||||
{Region: "Italy", Group: "Premium UDP Europe", Hostname: "87-1-it.cg-dialup.net", IPs: []net.IP{{84, 17, 58, 19}, {84, 17, 58, 95}, {84, 17, 58, 105}, {84, 17, 58, 119}, {84, 17, 58, 120}, {87, 101, 94, 116}, {185, 217, 71, 137}, {185, 217, 71, 138}, {185, 217, 71, 153}, {212, 102, 55, 108}}},
|
||||
{Region: "Japan", Group: "Premium TCP Asia", Hostname: "96-1-jp.cg-dialup.net", IPs: []net.IP{{156, 146, 35, 6}, {156, 146, 35, 10}, {156, 146, 35, 15}, {156, 146, 35, 22}, {156, 146, 35, 37}, {156, 146, 35, 39}, {156, 146, 35, 40}, {156, 146, 35, 41}, {156, 146, 35, 44}, {156, 146, 35, 50}}},
|
||||
{Region: "Japan", Group: "Premium UDP Asia", Hostname: "95-1-jp.cg-dialup.net", IPs: []net.IP{{156, 146, 35, 4}, {156, 146, 35, 14}, {156, 146, 35, 15}, {156, 146, 35, 18}, {156, 146, 35, 25}, {156, 146, 35, 34}, {156, 146, 35, 36}, {156, 146, 35, 46}, {156, 146, 35, 49}, {156, 146, 35, 50}}},
|
||||
{Region: "Kazakhstan", Group: "Premium TCP Europe", Hostname: "97-1-kz.cg-dialup.net", IPs: []net.IP{{62, 133, 47, 131}, {62, 133, 47, 132}, {62, 133, 47, 134}, {62, 133, 47, 136}, {62, 133, 47, 138}, {62, 133, 47, 139}, {62, 133, 47, 140}, {62, 133, 47, 142}, {62, 133, 47, 143}, {62, 133, 47, 144}}},
|
||||
{Region: "Kazakhstan", Group: "Premium UDP Europe", Hostname: "87-1-kz.cg-dialup.net", IPs: []net.IP{{62, 133, 47, 131}, {62, 133, 47, 132}, {62, 133, 47, 133}, {62, 133, 47, 134}, {62, 133, 47, 135}, {62, 133, 47, 138}, {62, 133, 47, 139}, {62, 133, 47, 140}, {62, 133, 47, 142}, {62, 133, 47, 143}}},
|
||||
{Region: "Kenya", Group: "Premium TCP Asia", Hostname: "96-1-ke.cg-dialup.net", IPs: []net.IP{{62, 12, 118, 195}, {62, 12, 118, 196}, {62, 12, 118, 197}, {62, 12, 118, 198}, {62, 12, 118, 199}, {62, 12, 118, 200}, {62, 12, 118, 201}, {62, 12, 118, 202}, {62, 12, 118, 203}, {62, 12, 118, 204}}},
|
||||
{Region: "Kenya", Group: "Premium UDP Asia", Hostname: "95-1-ke.cg-dialup.net", IPs: []net.IP{{62, 12, 118, 195}, {62, 12, 118, 196}, {62, 12, 118, 197}, {62, 12, 118, 198}, {62, 12, 118, 199}, {62, 12, 118, 200}, {62, 12, 118, 201}, {62, 12, 118, 202}, {62, 12, 118, 203}, {62, 12, 118, 204}}},
|
||||
{Region: "Korea", Group: "Premium TCP Asia", Hostname: "96-1-kr.cg-dialup.net", IPs: []net.IP{{79, 110, 55, 131}, {79, 110, 55, 135}, {79, 110, 55, 137}, {79, 110, 55, 142}, {79, 110, 55, 147}, {79, 110, 55, 148}, {79, 110, 55, 149}, {79, 110, 55, 154}, {79, 110, 55, 155}, {79, 110, 55, 158}}},
|
||||
{Region: "Korea", Group: "Premium UDP Asia", Hostname: "95-1-kr.cg-dialup.net", IPs: []net.IP{{79, 110, 55, 131}, {79, 110, 55, 132}, {79, 110, 55, 133}, {79, 110, 55, 141}, {79, 110, 55, 147}, {79, 110, 55, 148}, {79, 110, 55, 150}, {79, 110, 55, 154}, {79, 110, 55, 157}, {79, 110, 55, 158}}},
|
||||
{Region: "Liechtenstein", Group: "Premium TCP Europe", Hostname: "97-1-li.cg-dialup.net", IPs: []net.IP{{91, 90, 122, 133}, {91, 90, 122, 134}, {91, 90, 122, 135}, {91, 90, 122, 137}, {91, 90, 122, 138}, {91, 90, 122, 139}, {91, 90, 122, 140}, {91, 90, 122, 142}, {91, 90, 122, 143}, {91, 90, 122, 144}}},
|
||||
{Region: "Liechtenstein", Group: "Premium UDP Europe", Hostname: "87-1-li.cg-dialup.net", IPs: []net.IP{{91, 90, 122, 131}, {91, 90, 122, 132}, {91, 90, 122, 133}, {91, 90, 122, 134}, {91, 90, 122, 138}, {91, 90, 122, 139}, {91, 90, 122, 140}, {91, 90, 122, 142}, {91, 90, 122, 143}, {91, 90, 122, 145}}},
|
||||
{Region: "Lithuania", Group: "Premium TCP Europe", Hostname: "97-1-lt.cg-dialup.net", IPs: []net.IP{{85, 206, 162, 209}, {85, 206, 162, 215}, {85, 206, 162, 218}, {85, 206, 162, 221}, {85, 206, 162, 222}, {85, 206, 165, 18}, {85, 206, 165, 20}, {85, 206, 165, 23}, {85, 206, 165, 26}, {85, 206, 165, 31}}},
|
||||
{Region: "Lithuania", Group: "Premium UDP Europe", Hostname: "87-1-lt.cg-dialup.net", IPs: []net.IP{{85, 206, 162, 209}, {85, 206, 162, 210}, {85, 206, 162, 211}, {85, 206, 162, 212}, {85, 206, 162, 218}, {85, 206, 162, 221}, {85, 206, 165, 17}, {85, 206, 165, 23}, {85, 206, 165, 24}, {85, 206, 165, 30}}},
|
||||
{Region: "Luxembourg", Group: "Premium TCP Europe", Hostname: "97-1-lu.cg-dialup.net", IPs: []net.IP{{5, 253, 204, 3}, {5, 253, 204, 14}, {5, 253, 204, 22}, {5, 253, 204, 25}, {5, 253, 204, 26}, {5, 253, 204, 28}, {5, 253, 204, 30}, {5, 253, 204, 41}, {5, 253, 204, 43}, {5, 253, 204, 45}}},
|
||||
{Region: "Luxembourg", Group: "Premium UDP Europe", Hostname: "87-1-lu.cg-dialup.net", IPs: []net.IP{{5, 253, 204, 6}, {5, 253, 204, 12}, {5, 253, 204, 13}, {5, 253, 204, 26}, {5, 253, 204, 27}, {5, 253, 204, 36}, {5, 253, 204, 39}, {5, 253, 204, 41}, {5, 253, 204, 43}, {5, 253, 204, 46}}},
|
||||
{Region: "Macao", Group: "Premium TCP Asia", Hostname: "96-1-mo.cg-dialup.net", IPs: []net.IP{{84, 252, 92, 131}, {84, 252, 92, 132}, {84, 252, 92, 134}, {84, 252, 92, 136}, {84, 252, 92, 138}, {84, 252, 92, 140}, {84, 252, 92, 141}, {84, 252, 92, 142}, {84, 252, 92, 143}, {84, 252, 92, 145}}},
|
||||
{Region: "Macao", Group: "Premium UDP Asia", Hostname: "95-1-mo.cg-dialup.net", IPs: []net.IP{{84, 252, 92, 132}, {84, 252, 92, 134}, {84, 252, 92, 135}, {84, 252, 92, 136}, {84, 252, 92, 137}, {84, 252, 92, 138}, {84, 252, 92, 140}, {84, 252, 92, 141}, {84, 252, 92, 143}, {84, 252, 92, 144}}},
|
||||
{Region: "Korea", Group: "Premium TCP Asia", Hostname: "96-1-kr.cg-dialup.net", IPs: []net.IP{{79, 110, 55, 131}, {79, 110, 55, 134}, {79, 110, 55, 141}, {79, 110, 55, 147}, {79, 110, 55, 148}, {79, 110, 55, 151}, {79, 110, 55, 152}, {79, 110, 55, 153}, {79, 110, 55, 155}, {79, 110, 55, 157}}},
|
||||
{Region: "Korea", Group: "Premium UDP Asia", Hostname: "95-1-kr.cg-dialup.net", IPs: []net.IP{{79, 110, 55, 131}, {79, 110, 55, 133}, {79, 110, 55, 134}, {79, 110, 55, 136}, {79, 110, 55, 138}, {79, 110, 55, 140}, {79, 110, 55, 149}, {79, 110, 55, 151}, {79, 110, 55, 152}, {79, 110, 55, 157}}},
|
||||
{Region: "Latvia", Group: "Premium TCP Europe", Hostname: "97-1-lv.cg-dialup.net", IPs: []net.IP{{109, 248, 148, 244}, {109, 248, 148, 245}, {109, 248, 148, 246}, {109, 248, 148, 247}, {109, 248, 148, 249}, {109, 248, 148, 250}, {109, 248, 148, 253}, {109, 248, 149, 22}, {109, 248, 149, 24}, {109, 248, 149, 25}}},
|
||||
{Region: "Latvia", Group: "Premium UDP Europe", Hostname: "87-1-lv.cg-dialup.net", IPs: []net.IP{{109, 248, 148, 248}, {109, 248, 148, 250}, {109, 248, 148, 254}, {109, 248, 149, 19}, {109, 248, 149, 20}, {109, 248, 149, 22}, {109, 248, 149, 24}, {109, 248, 149, 26}, {109, 248, 149, 28}, {109, 248, 149, 30}}},
|
||||
{Region: "Liechtenstein", Group: "Premium UDP Europe", Hostname: "87-1-li.cg-dialup.net", IPs: []net.IP{{91, 90, 122, 131}, {91, 90, 122, 134}, {91, 90, 122, 137}, {91, 90, 122, 138}, {91, 90, 122, 139}, {91, 90, 122, 140}, {91, 90, 122, 141}, {91, 90, 122, 142}, {91, 90, 122, 144}, {91, 90, 122, 145}}},
|
||||
{Region: "Lithuania", Group: "Premium TCP Europe", Hostname: "97-1-lt.cg-dialup.net", IPs: []net.IP{{85, 206, 162, 212}, {85, 206, 162, 215}, {85, 206, 162, 219}, {85, 206, 162, 222}, {85, 206, 165, 17}, {85, 206, 165, 23}, {85, 206, 165, 25}, {85, 206, 165, 26}, {85, 206, 165, 30}, {85, 206, 165, 31}}},
|
||||
{Region: "Lithuania", Group: "Premium UDP Europe", Hostname: "87-1-lt.cg-dialup.net", IPs: []net.IP{{85, 206, 162, 209}, {85, 206, 162, 210}, {85, 206, 162, 211}, {85, 206, 162, 213}, {85, 206, 162, 214}, {85, 206, 162, 217}, {85, 206, 162, 218}, {85, 206, 162, 220}, {85, 206, 165, 26}, {85, 206, 165, 30}}},
|
||||
{Region: "Luxembourg", Group: "Premium UDP Europe", Hostname: "87-1-lu.cg-dialup.net", IPs: []net.IP{{5, 253, 204, 7}, {5, 253, 204, 10}, {5, 253, 204, 12}, {5, 253, 204, 23}, {5, 253, 204, 26}, {5, 253, 204, 30}, {5, 253, 204, 37}, {5, 253, 204, 39}, {5, 253, 204, 44}, {5, 253, 204, 45}}},
|
||||
{Region: "Macao", Group: "Premium TCP Asia", Hostname: "96-1-mo.cg-dialup.net", IPs: []net.IP{{84, 252, 92, 131}, {84, 252, 92, 133}, {84, 252, 92, 135}, {84, 252, 92, 137}, {84, 252, 92, 138}, {84, 252, 92, 139}, {84, 252, 92, 141}, {84, 252, 92, 142}, {84, 252, 92, 144}, {84, 252, 92, 145}}},
|
||||
{Region: "Macao", Group: "Premium UDP Asia", Hostname: "95-1-mo.cg-dialup.net", IPs: []net.IP{{84, 252, 92, 132}, {84, 252, 92, 134}, {84, 252, 92, 135}, {84, 252, 92, 136}, {84, 252, 92, 137}, {84, 252, 92, 139}, {84, 252, 92, 141}, {84, 252, 92, 143}, {84, 252, 92, 144}, {84, 252, 92, 145}}},
|
||||
{Region: "Macedonia", Group: "Premium TCP Europe", Hostname: "97-1-mk.cg-dialup.net", IPs: []net.IP{{185, 225, 28, 3}, {185, 225, 28, 4}, {185, 225, 28, 5}, {185, 225, 28, 6}, {185, 225, 28, 7}, {185, 225, 28, 8}, {185, 225, 28, 9}, {185, 225, 28, 10}, {185, 225, 28, 11}, {185, 225, 28, 12}}},
|
||||
{Region: "Macedonia", Group: "Premium UDP Europe", Hostname: "87-1-mk.cg-dialup.net", IPs: []net.IP{{185, 225, 28, 3}, {185, 225, 28, 4}, {185, 225, 28, 5}, {185, 225, 28, 6}, {185, 225, 28, 7}, {185, 225, 28, 8}, {185, 225, 28, 9}, {185, 225, 28, 10}, {185, 225, 28, 11}, {185, 225, 28, 12}}},
|
||||
{Region: "Malaysia", Group: "Premium TCP Asia", Hostname: "96-1-my.cg-dialup.net", IPs: []net.IP{{146, 70, 15, 3}, {146, 70, 15, 4}, {146, 70, 15, 5}, {146, 70, 15, 6}, {146, 70, 15, 7}, {146, 70, 15, 10}, {146, 70, 15, 11}, {146, 70, 15, 13}, {146, 70, 15, 15}, {146, 70, 15, 16}}},
|
||||
{Region: "Malta", Group: "Premium TCP Europe", Hostname: "97-1-mt.cg-dialup.net", IPs: []net.IP{{176, 125, 230, 131}, {176, 125, 230, 132}, {176, 125, 230, 134}, {176, 125, 230, 136}, {176, 125, 230, 137}, {176, 125, 230, 140}, {176, 125, 230, 141}, {176, 125, 230, 142}, {176, 125, 230, 144}, {176, 125, 230, 145}}},
|
||||
{Region: "Malta", Group: "Premium UDP Europe", Hostname: "87-1-mt.cg-dialup.net", IPs: []net.IP{{176, 125, 230, 131}, {176, 125, 230, 134}, {176, 125, 230, 135}, {176, 125, 230, 138}, {176, 125, 230, 139}, {176, 125, 230, 140}, {176, 125, 230, 142}, {176, 125, 230, 143}, {176, 125, 230, 144}, {176, 125, 230, 145}}},
|
||||
{Region: "Mexico", Group: "Premium TCP USA", Hostname: "93-1-mx.cg-dialup.net", IPs: []net.IP{{77, 81, 142, 130}, {77, 81, 142, 136}, {77, 81, 142, 146}, {77, 81, 142, 148}, {77, 81, 142, 150}, {77, 81, 142, 151}, {77, 81, 142, 152}, {77, 81, 142, 153}, {77, 81, 142, 154}, {77, 81, 142, 155}}},
|
||||
{Region: "Mexico", Group: "Premium UDP USA", Hostname: "94-1-mx.cg-dialup.net", IPs: []net.IP{{77, 81, 142, 130}, {77, 81, 142, 136}, {77, 81, 142, 144}, {77, 81, 142, 146}, {77, 81, 142, 147}, {77, 81, 142, 150}, {77, 81, 142, 151}, {77, 81, 142, 153}, {77, 81, 142, 154}, {77, 81, 142, 155}}},
|
||||
{Region: "Monaco", Group: "Premium TCP Europe", Hostname: "97-1-mc.cg-dialup.net", IPs: []net.IP{{95, 181, 233, 131}, {95, 181, 233, 132}, {95, 181, 233, 133}, {95, 181, 233, 135}, {95, 181, 233, 136}, {95, 181, 233, 137}, {95, 181, 233, 140}, {95, 181, 233, 141}, {95, 181, 233, 143}, {95, 181, 233, 144}}},
|
||||
{Region: "Monaco", Group: "Premium UDP Europe", Hostname: "87-1-mc.cg-dialup.net", IPs: []net.IP{{95, 181, 233, 131}, {95, 181, 233, 132}, {95, 181, 233, 135}, {95, 181, 233, 136}, {95, 181, 233, 138}, {95, 181, 233, 139}, {95, 181, 233, 140}, {95, 181, 233, 142}, {95, 181, 233, 143}, {95, 181, 233, 144}}},
|
||||
{Region: "Mongolia", Group: "Premium TCP Asia", Hostname: "96-1-mn.cg-dialup.net", IPs: []net.IP{{185, 253, 163, 131}, {185, 253, 163, 132}, {185, 253, 163, 133}, {185, 253, 163, 134}, {185, 253, 163, 136}, {185, 253, 163, 138}, {185, 253, 163, 139}, {185, 253, 163, 141}, {185, 253, 163, 142}, {185, 253, 163, 145}}},
|
||||
{Region: "Mongolia", Group: "Premium UDP Asia", Hostname: "95-1-mn.cg-dialup.net", IPs: []net.IP{{185, 253, 163, 131}, {185, 253, 163, 132}, {185, 253, 163, 133}, {185, 253, 163, 134}, {185, 253, 163, 135}, {185, 253, 163, 136}, {185, 253, 163, 142}, {185, 253, 163, 143}, {185, 253, 163, 144}, {185, 253, 163, 145}}},
|
||||
{Region: "Montenegro", Group: "Premium TCP Europe", Hostname: "97-1-me.cg-dialup.net", IPs: []net.IP{{176, 125, 229, 131}, {176, 125, 229, 133}, {176, 125, 229, 134}, {176, 125, 229, 135}, {176, 125, 229, 136}, {176, 125, 229, 138}, {176, 125, 229, 139}, {176, 125, 229, 141}, {176, 125, 229, 144}, {176, 125, 229, 145}}},
|
||||
{Region: "Morocco", Group: "Premium UDP Europe", Hostname: "87-1-ma.cg-dialup.net", IPs: []net.IP{{95, 181, 232, 131}, {95, 181, 232, 132}, {95, 181, 232, 133}, {95, 181, 232, 134}, {95, 181, 232, 135}, {95, 181, 232, 136}, {95, 181, 232, 137}, {95, 181, 232, 139}, {95, 181, 232, 140}, {95, 181, 232, 143}}},
|
||||
{Region: "Netherlands", Group: "Premium TCP Europe", Hostname: "97-1-nl.cg-dialup.net", IPs: []net.IP{{181, 214, 206, 26}, {181, 214, 206, 27}, {191, 96, 168, 57}, {191, 96, 168, 147}, {195, 78, 54, 20}, {195, 78, 54, 26}, {195, 78, 54, 28}, {195, 78, 54, 50}, {195, 78, 54, 109}, {195, 78, 54, 159}}},
|
||||
{Region: "New Zealand", Group: "Premium UDP Asia", Hostname: "95-1-nz.cg-dialup.net", IPs: []net.IP{{114, 141, 194, 2}, {114, 141, 194, 3}, {114, 141, 194, 4}, {114, 141, 194, 5}, {114, 141, 194, 6}, {114, 141, 194, 7}, {114, 141, 194, 9}, {114, 141, 194, 11}, {114, 141, 194, 12}, {114, 141, 194, 13}}},
|
||||
{Region: "Nigeria", Group: "Premium TCP Europe", Hostname: "97-1-ng.cg-dialup.net", IPs: []net.IP{{102, 165, 25, 68}, {102, 165, 25, 69}, {102, 165, 25, 70}, {102, 165, 25, 71}, {102, 165, 25, 72}, {102, 165, 25, 73}, {102, 165, 25, 74}, {102, 165, 25, 75}, {102, 165, 25, 76}, {102, 165, 25, 77}}},
|
||||
{Region: "Nigeria", Group: "Premium UDP Europe", Hostname: "87-1-ng.cg-dialup.net", IPs: []net.IP{{102, 165, 25, 68}, {102, 165, 25, 69}, {102, 165, 25, 70}, {102, 165, 25, 71}, {102, 165, 25, 72}, {102, 165, 25, 73}, {102, 165, 25, 74}, {102, 165, 25, 76}, {102, 165, 25, 77}, {102, 165, 25, 78}}},
|
||||
{Region: "Norway", Group: "Premium TCP Europe", Hostname: "97-1-no.cg-dialup.net", IPs: []net.IP{{45, 12, 223, 139}, {82, 102, 27, 91}, {82, 102, 27, 92}, {185, 206, 225, 229}, {185, 206, 225, 231}, {185, 206, 225, 236}, {185, 253, 97, 235}, {185, 253, 97, 245}, {185, 253, 97, 249}, {185, 253, 97, 251}}},
|
||||
{Region: "Norway", Group: "Premium UDP Europe", Hostname: "87-1-no.cg-dialup.net", IPs: []net.IP{{45, 12, 223, 133}, {45, 12, 223, 137}, {45, 12, 223, 139}, {45, 12, 223, 140}, {185, 206, 225, 27}, {185, 206, 225, 28}, {185, 206, 225, 29}, {185, 206, 225, 230}, {185, 253, 97, 250}, {185, 253, 97, 251}}},
|
||||
{Region: "Philippines", Group: "Premium TCP Asia", Hostname: "96-1-ph.cg-dialup.net", IPs: []net.IP{{188, 214, 125, 36}, {188, 214, 125, 38}, {188, 214, 125, 40}, {188, 214, 125, 41}, {188, 214, 125, 47}, {188, 214, 125, 49}, {188, 214, 125, 51}, {188, 214, 125, 53}, {188, 214, 125, 54}, {188, 214, 125, 61}}},
|
||||
{Region: "Poland", Group: "Premium UDP Europe", Hostname: "87-1-pl.cg-dialup.net", IPs: []net.IP{{37, 120, 156, 4}, {37, 120, 156, 9}, {37, 120, 156, 10}, {37, 120, 156, 20}, {37, 120, 156, 21}, {37, 120, 156, 23}, {37, 120, 156, 26}, {51, 75, 56, 36}, {51, 75, 56, 37}, {51, 75, 56, 43}}},
|
||||
{Region: "Qatar", Group: "Premium TCP Europe", Hostname: "97-1-qa.cg-dialup.net", IPs: []net.IP{{95, 181, 234, 131}, {95, 181, 234, 132}, {95, 181, 234, 134}, {95, 181, 234, 135}, {95, 181, 234, 136}, {95, 181, 234, 137}, {95, 181, 234, 138}, {95, 181, 234, 140}, {95, 181, 234, 142}, {95, 181, 234, 143}}},
|
||||
{Region: "Qatar", Group: "Premium UDP Europe", Hostname: "87-1-qa.cg-dialup.net", IPs: []net.IP{{95, 181, 234, 132}, {95, 181, 234, 134}, {95, 181, 234, 135}, {95, 181, 234, 138}, {95, 181, 234, 139}, {95, 181, 234, 140}, {95, 181, 234, 141}, {95, 181, 234, 142}, {95, 181, 234, 143}, {95, 181, 234, 144}}},
|
||||
{Region: "Russian Federation", Group: "Premium UDP Europe", Hostname: "87-1-ru.cg-dialup.net", IPs: []net.IP{{5, 8, 16, 69}, {5, 8, 16, 87}, {5, 8, 16, 88}, {5, 8, 16, 92}, {5, 8, 16, 109}, {5, 8, 16, 116}, {5, 8, 16, 118}, {5, 8, 16, 134}, {5, 8, 16, 136}, {5, 8, 16, 141}}},
|
||||
{Region: "Saudi Arabia", Group: "Premium TCP Europe", Hostname: "97-1-sa.cg-dialup.net", IPs: []net.IP{{95, 181, 235, 132}, {95, 181, 235, 133}, {95, 181, 235, 134}, {95, 181, 235, 136}, {95, 181, 235, 137}, {95, 181, 235, 138}, {95, 181, 235, 139}, {95, 181, 235, 140}, {95, 181, 235, 141}, {95, 181, 235, 142}}},
|
||||
{Region: "Serbia", Group: "Premium UDP Europe", Hostname: "87-1-rs.cg-dialup.net", IPs: []net.IP{{37, 120, 193, 179}, {37, 120, 193, 183}, {37, 120, 193, 187}, {37, 120, 193, 190}, {141, 98, 103, 37}, {141, 98, 103, 38}, {141, 98, 103, 39}, {141, 98, 103, 40}, {141, 98, 103, 43}, {141, 98, 103, 46}}},
|
||||
{Region: "Malaysia", Group: "Premium TCP Asia", Hostname: "96-1-my.cg-dialup.net", IPs: []net.IP{{146, 70, 15, 4}, {146, 70, 15, 6}, {146, 70, 15, 8}, {146, 70, 15, 9}, {146, 70, 15, 10}, {146, 70, 15, 11}, {146, 70, 15, 12}, {146, 70, 15, 13}, {146, 70, 15, 15}, {146, 70, 15, 16}}},
|
||||
{Region: "Malaysia", Group: "Premium UDP Asia", Hostname: "95-1-my.cg-dialup.net", IPs: []net.IP{{146, 70, 15, 3}, {146, 70, 15, 4}, {146, 70, 15, 5}, {146, 70, 15, 6}, {146, 70, 15, 7}, {146, 70, 15, 8}, {146, 70, 15, 10}, {146, 70, 15, 12}, {146, 70, 15, 15}, {146, 70, 15, 16}}},
|
||||
{Region: "Malta", Group: "Premium TCP Europe", Hostname: "97-1-mt.cg-dialup.net", IPs: []net.IP{{176, 125, 230, 133}, {176, 125, 230, 135}, {176, 125, 230, 136}, {176, 125, 230, 137}, {176, 125, 230, 138}, {176, 125, 230, 140}, {176, 125, 230, 142}, {176, 125, 230, 143}, {176, 125, 230, 144}, {176, 125, 230, 145}}},
|
||||
{Region: "Malta", Group: "Premium UDP Europe", Hostname: "87-1-mt.cg-dialup.net", IPs: []net.IP{{176, 125, 230, 131}, {176, 125, 230, 133}, {176, 125, 230, 134}, {176, 125, 230, 136}, {176, 125, 230, 137}, {176, 125, 230, 138}, {176, 125, 230, 139}, {176, 125, 230, 140}, {176, 125, 230, 144}, {176, 125, 230, 145}}},
|
||||
{Region: "Mexico", Group: "Premium TCP USA", Hostname: "93-1-mx.cg-dialup.net", IPs: []net.IP{{77, 81, 142, 132}, {77, 81, 142, 134}, {77, 81, 142, 136}, {77, 81, 142, 139}, {77, 81, 142, 142}, {77, 81, 142, 154}, {77, 81, 142, 155}, {77, 81, 142, 157}, {77, 81, 142, 158}, {77, 81, 142, 159}}},
|
||||
{Region: "Mexico", Group: "Premium UDP USA", Hostname: "94-1-mx.cg-dialup.net", IPs: []net.IP{{77, 81, 142, 130}, {77, 81, 142, 131}, {77, 81, 142, 132}, {77, 81, 142, 139}, {77, 81, 142, 141}, {77, 81, 142, 142}, {77, 81, 142, 146}, {77, 81, 142, 147}, {77, 81, 142, 154}, {77, 81, 142, 159}}},
|
||||
{Region: "Moldova", Group: "Premium TCP Europe", Hostname: "97-1-md.cg-dialup.net", IPs: []net.IP{{178, 175, 130, 243}, {178, 175, 130, 244}, {178, 175, 130, 245}, {178, 175, 130, 246}, {178, 175, 130, 251}, {178, 175, 130, 254}, {178, 175, 142, 131}, {178, 175, 142, 132}, {178, 175, 142, 133}, {178, 175, 142, 134}}},
|
||||
{Region: "Moldova", Group: "Premium UDP Europe", Hostname: "87-1-md.cg-dialup.net", IPs: []net.IP{{178, 175, 130, 243}, {178, 175, 130, 244}, {178, 175, 130, 246}, {178, 175, 130, 250}, {178, 175, 130, 251}, {178, 175, 130, 253}, {178, 175, 130, 254}, {178, 175, 142, 132}, {178, 175, 142, 133}, {178, 175, 142, 134}}},
|
||||
{Region: "Monaco", Group: "Premium TCP Europe", Hostname: "97-1-mc.cg-dialup.net", IPs: []net.IP{{95, 181, 233, 131}, {95, 181, 233, 132}, {95, 181, 233, 133}, {95, 181, 233, 137}, {95, 181, 233, 138}, {95, 181, 233, 139}, {95, 181, 233, 140}, {95, 181, 233, 141}, {95, 181, 233, 143}, {95, 181, 233, 144}}},
|
||||
{Region: "Monaco", Group: "Premium UDP Europe", Hostname: "87-1-mc.cg-dialup.net", IPs: []net.IP{{95, 181, 233, 132}, {95, 181, 233, 135}, {95, 181, 233, 136}, {95, 181, 233, 137}, {95, 181, 233, 138}, {95, 181, 233, 139}, {95, 181, 233, 141}, {95, 181, 233, 142}, {95, 181, 233, 143}, {95, 181, 233, 144}}},
|
||||
{Region: "Mongolia", Group: "Premium TCP Asia", Hostname: "96-1-mn.cg-dialup.net", IPs: []net.IP{{185, 253, 163, 132}, {185, 253, 163, 133}, {185, 253, 163, 135}, {185, 253, 163, 136}, {185, 253, 163, 139}, {185, 253, 163, 140}, {185, 253, 163, 141}, {185, 253, 163, 142}, {185, 253, 163, 143}, {185, 253, 163, 144}}},
|
||||
{Region: "Mongolia", Group: "Premium UDP Asia", Hostname: "95-1-mn.cg-dialup.net", IPs: []net.IP{{185, 253, 163, 131}, {185, 253, 163, 133}, {185, 253, 163, 134}, {185, 253, 163, 137}, {185, 253, 163, 138}, {185, 253, 163, 139}, {185, 253, 163, 140}, {185, 253, 163, 141}, {185, 253, 163, 142}, {185, 253, 163, 144}}},
|
||||
{Region: "Montenegro", Group: "Premium TCP Europe", Hostname: "97-1-me.cg-dialup.net", IPs: []net.IP{{176, 125, 229, 131}, {176, 125, 229, 135}, {176, 125, 229, 137}, {176, 125, 229, 138}, {176, 125, 229, 140}, {176, 125, 229, 141}, {176, 125, 229, 142}, {176, 125, 229, 143}, {176, 125, 229, 144}, {176, 125, 229, 145}}},
|
||||
{Region: "Montenegro", Group: "Premium UDP Europe", Hostname: "87-1-me.cg-dialup.net", IPs: []net.IP{{176, 125, 229, 131}, {176, 125, 229, 134}, {176, 125, 229, 136}, {176, 125, 229, 137}, {176, 125, 229, 138}, {176, 125, 229, 139}, {176, 125, 229, 140}, {176, 125, 229, 141}, {176, 125, 229, 143}, {176, 125, 229, 144}}},
|
||||
{Region: "Morocco", Group: "Premium TCP Europe", Hostname: "97-1-ma.cg-dialup.net", IPs: []net.IP{{95, 181, 232, 132}, {95, 181, 232, 133}, {95, 181, 232, 134}, {95, 181, 232, 136}, {95, 181, 232, 137}, {95, 181, 232, 138}, {95, 181, 232, 139}, {95, 181, 232, 140}, {95, 181, 232, 141}, {95, 181, 232, 144}}},
|
||||
{Region: "Morocco", Group: "Premium UDP Europe", Hostname: "87-1-ma.cg-dialup.net", IPs: []net.IP{{95, 181, 232, 131}, {95, 181, 232, 132}, {95, 181, 232, 133}, {95, 181, 232, 135}, {95, 181, 232, 137}, {95, 181, 232, 139}, {95, 181, 232, 140}, {95, 181, 232, 141}, {95, 181, 232, 142}, {95, 181, 232, 143}}},
|
||||
{Region: "Netherlands", Group: "Premium TCP Europe", Hostname: "97-1-nl.cg-dialup.net", IPs: []net.IP{{84, 17, 47, 98}, {181, 214, 206, 22}, {181, 214, 206, 27}, {181, 214, 206, 36}, {195, 78, 54, 10}, {195, 78, 54, 20}, {195, 78, 54, 43}, {195, 78, 54, 50}, {195, 78, 54, 119}, {195, 181, 172, 78}}},
|
||||
{Region: "Netherlands", Group: "Premium UDP Europe", Hostname: "87-1-nl.cg-dialup.net", IPs: []net.IP{{84, 17, 47, 110}, {181, 214, 206, 29}, {181, 214, 206, 42}, {195, 78, 54, 8}, {195, 78, 54, 19}, {195, 78, 54, 47}, {195, 78, 54, 110}, {195, 78, 54, 141}, {195, 78, 54, 143}, {195, 78, 54, 157}}},
|
||||
{Region: "New Zealand", Group: "Premium TCP Asia", Hostname: "96-1-nz.cg-dialup.net", IPs: []net.IP{{43, 250, 207, 98}, {43, 250, 207, 99}, {43, 250, 207, 100}, {43, 250, 207, 101}, {43, 250, 207, 102}, {43, 250, 207, 103}, {43, 250, 207, 105}, {43, 250, 207, 106}, {43, 250, 207, 108}, {43, 250, 207, 109}}},
|
||||
{Region: "New Zealand", Group: "Premium UDP Asia", Hostname: "95-1-nz.cg-dialup.net", IPs: []net.IP{{43, 250, 207, 98}, {43, 250, 207, 99}, {43, 250, 207, 102}, {43, 250, 207, 104}, {43, 250, 207, 105}, {43, 250, 207, 106}, {43, 250, 207, 107}, {43, 250, 207, 108}, {43, 250, 207, 109}, {43, 250, 207, 110}}},
|
||||
{Region: "Nigeria", Group: "Premium TCP Europe", Hostname: "97-1-ng.cg-dialup.net", IPs: []net.IP{{102, 165, 25, 68}, {102, 165, 25, 69}, {102, 165, 25, 70}, {102, 165, 25, 71}, {102, 165, 25, 72}, {102, 165, 25, 73}, {102, 165, 25, 75}, {102, 165, 25, 76}, {102, 165, 25, 77}, {102, 165, 25, 78}}},
|
||||
{Region: "Nigeria", Group: "Premium UDP Europe", Hostname: "87-1-ng.cg-dialup.net", IPs: []net.IP{{102, 165, 25, 68}, {102, 165, 25, 69}, {102, 165, 25, 70}, {102, 165, 25, 71}, {102, 165, 25, 72}, {102, 165, 25, 74}, {102, 165, 25, 75}, {102, 165, 25, 76}, {102, 165, 25, 77}, {102, 165, 25, 78}}},
|
||||
{Region: "Norway", Group: "Premium TCP Europe", Hostname: "97-1-no.cg-dialup.net", IPs: []net.IP{{45, 12, 223, 137}, {45, 12, 223, 140}, {185, 206, 225, 29}, {185, 206, 225, 231}, {185, 253, 97, 234}, {185, 253, 97, 236}, {185, 253, 97, 238}, {185, 253, 97, 244}, {185, 253, 97, 250}, {185, 253, 97, 254}}},
|
||||
{Region: "Norway", Group: "Premium UDP Europe", Hostname: "87-1-no.cg-dialup.net", IPs: []net.IP{{45, 12, 223, 133}, {45, 12, 223, 134}, {45, 12, 223, 142}, {185, 206, 225, 227}, {185, 206, 225, 228}, {185, 206, 225, 231}, {185, 206, 225, 235}, {185, 253, 97, 237}, {185, 253, 97, 246}, {185, 253, 97, 254}}},
|
||||
{Region: "Pakistan", Group: "Premium TCP Asia", Hostname: "96-1-pk.cg-dialup.net", IPs: []net.IP{{146, 70, 12, 3}, {146, 70, 12, 4}, {146, 70, 12, 6}, {146, 70, 12, 8}, {146, 70, 12, 9}, {146, 70, 12, 10}, {146, 70, 12, 11}, {146, 70, 12, 12}, {146, 70, 12, 13}, {146, 70, 12, 14}}},
|
||||
{Region: "Pakistan", Group: "Premium UDP Asia", Hostname: "95-1-pk.cg-dialup.net", IPs: []net.IP{{146, 70, 12, 4}, {146, 70, 12, 5}, {146, 70, 12, 6}, {146, 70, 12, 7}, {146, 70, 12, 8}, {146, 70, 12, 10}, {146, 70, 12, 11}, {146, 70, 12, 12}, {146, 70, 12, 13}, {146, 70, 12, 14}}},
|
||||
{Region: "Panama", Group: "Premium TCP Europe", Hostname: "97-1-pa.cg-dialup.net", IPs: []net.IP{{91, 90, 126, 131}, {91, 90, 126, 132}, {91, 90, 126, 133}, {91, 90, 126, 134}, {91, 90, 126, 136}, {91, 90, 126, 138}, {91, 90, 126, 139}, {91, 90, 126, 141}, {91, 90, 126, 142}, {91, 90, 126, 145}}},
|
||||
{Region: "Panama", Group: "Premium UDP Europe", Hostname: "87-1-pa.cg-dialup.net", IPs: []net.IP{{91, 90, 126, 131}, {91, 90, 126, 133}, {91, 90, 126, 134}, {91, 90, 126, 135}, {91, 90, 126, 136}, {91, 90, 126, 138}, {91, 90, 126, 140}, {91, 90, 126, 141}, {91, 90, 126, 142}, {91, 90, 126, 145}}},
|
||||
{Region: "Philippines", Group: "Premium TCP Asia", Hostname: "96-1-ph.cg-dialup.net", IPs: []net.IP{{188, 214, 125, 37}, {188, 214, 125, 38}, {188, 214, 125, 40}, {188, 214, 125, 43}, {188, 214, 125, 44}, {188, 214, 125, 45}, {188, 214, 125, 52}, {188, 214, 125, 55}, {188, 214, 125, 61}, {188, 214, 125, 62}}},
|
||||
{Region: "Philippines", Group: "Premium UDP Asia", Hostname: "95-1-ph.cg-dialup.net", IPs: []net.IP{{188, 214, 125, 37}, {188, 214, 125, 40}, {188, 214, 125, 46}, {188, 214, 125, 49}, {188, 214, 125, 52}, {188, 214, 125, 54}, {188, 214, 125, 57}, {188, 214, 125, 58}, {188, 214, 125, 61}, {188, 214, 125, 62}}},
|
||||
{Region: "Poland", Group: "Premium TCP Europe", Hostname: "97-1-pl.cg-dialup.net", IPs: []net.IP{{138, 199, 59, 132}, {138, 199, 59, 136}, {138, 199, 59, 137}, {138, 199, 59, 143}, {138, 199, 59, 144}, {138, 199, 59, 152}, {138, 199, 59, 153}, {138, 199, 59, 166}, {138, 199, 59, 174}, {138, 199, 59, 175}}},
|
||||
{Region: "Poland", Group: "Premium UDP Europe", Hostname: "87-1-pl.cg-dialup.net", IPs: []net.IP{{138, 199, 59, 130}, {138, 199, 59, 136}, {138, 199, 59, 148}, {138, 199, 59, 149}, {138, 199, 59, 153}, {138, 199, 59, 156}, {138, 199, 59, 157}, {138, 199, 59, 164}, {138, 199, 59, 171}, {138, 199, 59, 173}}},
|
||||
{Region: "Portugal", Group: "Premium TCP Europe", Hostname: "97-1-pt.cg-dialup.net", IPs: []net.IP{{89, 26, 243, 112}, {89, 26, 243, 115}, {89, 26, 243, 195}, {89, 26, 243, 216}, {89, 26, 243, 218}, {89, 26, 243, 220}, {89, 26, 243, 222}, {89, 26, 243, 223}, {89, 26, 243, 225}, {89, 26, 243, 228}}},
|
||||
{Region: "Portugal", Group: "Premium UDP Europe", Hostname: "87-1-pt.cg-dialup.net", IPs: []net.IP{{89, 26, 243, 99}, {89, 26, 243, 113}, {89, 26, 243, 115}, {89, 26, 243, 195}, {89, 26, 243, 199}, {89, 26, 243, 216}, {89, 26, 243, 219}, {89, 26, 243, 225}, {89, 26, 243, 226}, {89, 26, 243, 227}}},
|
||||
{Region: "Qatar", Group: "Premium TCP Europe", Hostname: "97-1-qa.cg-dialup.net", IPs: []net.IP{{95, 181, 234, 133}, {95, 181, 234, 135}, {95, 181, 234, 136}, {95, 181, 234, 137}, {95, 181, 234, 138}, {95, 181, 234, 139}, {95, 181, 234, 140}, {95, 181, 234, 141}, {95, 181, 234, 142}, {95, 181, 234, 143}}},
|
||||
{Region: "Qatar", Group: "Premium UDP Europe", Hostname: "87-1-qa.cg-dialup.net", IPs: []net.IP{{95, 181, 234, 131}, {95, 181, 234, 132}, {95, 181, 234, 133}, {95, 181, 234, 134}, {95, 181, 234, 135}, {95, 181, 234, 137}, {95, 181, 234, 138}, {95, 181, 234, 139}, {95, 181, 234, 142}, {95, 181, 234, 143}}},
|
||||
{Region: "Russian Federation", Group: "Premium TCP Europe", Hostname: "97-1-ru.cg-dialup.net", IPs: []net.IP{{5, 8, 16, 72}, {5, 8, 16, 74}, {5, 8, 16, 84}, {5, 8, 16, 85}, {5, 8, 16, 123}, {5, 8, 16, 124}, {5, 8, 16, 132}, {146, 70, 52, 35}, {146, 70, 52, 44}, {146, 70, 52, 54}}},
|
||||
{Region: "Russian Federation", Group: "Premium UDP Europe", Hostname: "87-1-ru.cg-dialup.net", IPs: []net.IP{{5, 8, 16, 75}, {5, 8, 16, 87}, {5, 8, 16, 99}, {5, 8, 16, 110}, {5, 8, 16, 138}, {146, 70, 52, 29}, {146, 70, 52, 52}, {146, 70, 52, 58}, {146, 70, 52, 59}, {146, 70, 52, 67}}},
|
||||
{Region: "Saudi Arabia", Group: "Premium TCP Europe", Hostname: "97-1-sa.cg-dialup.net", IPs: []net.IP{{95, 181, 235, 131}, {95, 181, 235, 133}, {95, 181, 235, 134}, {95, 181, 235, 135}, {95, 181, 235, 137}, {95, 181, 235, 138}, {95, 181, 235, 139}, {95, 181, 235, 140}, {95, 181, 235, 141}, {95, 181, 235, 142}}},
|
||||
{Region: "Saudi Arabia", Group: "Premium UDP Europe", Hostname: "87-1-sa.cg-dialup.net", IPs: []net.IP{{95, 181, 235, 131}, {95, 181, 235, 132}, {95, 181, 235, 134}, {95, 181, 235, 135}, {95, 181, 235, 136}, {95, 181, 235, 137}, {95, 181, 235, 138}, {95, 181, 235, 139}, {95, 181, 235, 141}, {95, 181, 235, 144}}},
|
||||
{Region: "Serbia", Group: "Premium TCP Europe", Hostname: "97-1-rs.cg-dialup.net", IPs: []net.IP{{37, 120, 193, 179}, {37, 120, 193, 186}, {37, 120, 193, 188}, {37, 120, 193, 190}, {141, 98, 103, 36}, {141, 98, 103, 38}, {141, 98, 103, 39}, {141, 98, 103, 43}, {141, 98, 103, 44}, {141, 98, 103, 46}}},
|
||||
{Region: "Serbia", Group: "Premium UDP Europe", Hostname: "87-1-rs.cg-dialup.net", IPs: []net.IP{{37, 120, 193, 180}, {37, 120, 193, 186}, {37, 120, 193, 187}, {37, 120, 193, 188}, {37, 120, 193, 189}, {37, 120, 193, 190}, {141, 98, 103, 35}, {141, 98, 103, 36}, {141, 98, 103, 39}, {141, 98, 103, 41}}},
|
||||
{Region: "Singapore", Group: "Premium TCP Asia", Hostname: "96-1-sg.cg-dialup.net", IPs: []net.IP{{84, 17, 39, 162}, {84, 17, 39, 165}, {84, 17, 39, 168}, {84, 17, 39, 171}, {84, 17, 39, 175}, {84, 17, 39, 177}, {84, 17, 39, 178}, {84, 17, 39, 181}, {84, 17, 39, 183}, {84, 17, 39, 185}}},
|
||||
{Region: "Singapore", Group: "Premium UDP Asia", Hostname: "95-1-sg.cg-dialup.net", IPs: []net.IP{{84, 17, 39, 162}, {84, 17, 39, 165}, {84, 17, 39, 166}, {84, 17, 39, 167}, {84, 17, 39, 171}, {84, 17, 39, 174}, {84, 17, 39, 175}, {84, 17, 39, 178}, {84, 17, 39, 180}, {84, 17, 39, 185}}},
|
||||
{Region: "Slovakia", Group: "Premium TCP Europe", Hostname: "97-1-sk.cg-dialup.net", IPs: []net.IP{{185, 245, 85, 227}, {185, 245, 85, 228}, {185, 245, 85, 229}, {185, 245, 85, 230}, {185, 245, 85, 231}, {185, 245, 85, 232}, {185, 245, 85, 233}, {185, 245, 85, 234}, {185, 245, 85, 235}, {185, 245, 85, 236}}},
|
||||
{Region: "Slovakia", Group: "Premium UDP Europe", Hostname: "87-1-sk.cg-dialup.net", IPs: []net.IP{{185, 245, 85, 227}, {185, 245, 85, 228}, {185, 245, 85, 229}, {185, 245, 85, 230}, {185, 245, 85, 231}, {185, 245, 85, 232}, {185, 245, 85, 233}, {185, 245, 85, 234}, {185, 245, 85, 235}, {185, 245, 85, 236}}},
|
||||
{Region: "Slovenia", Group: "Premium TCP Europe", Hostname: "97-1-si.cg-dialup.net", IPs: []net.IP{{195, 80, 150, 211}, {195, 80, 150, 212}, {195, 80, 150, 213}, {195, 80, 150, 214}, {195, 80, 150, 215}, {195, 80, 150, 216}, {195, 80, 150, 219}, {195, 80, 150, 220}, {195, 80, 150, 221}, {195, 80, 150, 222}}},
|
||||
{Region: "Slovenia", Group: "Premium UDP Europe", Hostname: "87-1-si.cg-dialup.net", IPs: []net.IP{{195, 80, 150, 211}, {195, 80, 150, 212}, {195, 80, 150, 213}, {195, 80, 150, 215}, {195, 80, 150, 216}, {195, 80, 150, 217}, {195, 80, 150, 218}, {195, 80, 150, 219}, {195, 80, 150, 220}, {195, 80, 150, 221}}},
|
||||
{Region: "South Africa", Group: "Premium TCP Asia", Hostname: "96-1-za.cg-dialup.net", IPs: []net.IP{{154, 127, 50, 215}, {154, 127, 50, 216}, {154, 127, 50, 217}, {154, 127, 50, 220}, {154, 127, 50, 222}, {154, 127, 60, 194}, {154, 127, 60, 196}, {154, 127, 60, 198}, {154, 127, 60, 199}, {154, 127, 60, 202}}},
|
||||
{Region: "Slovenia", Group: "Premium TCP Europe", Hostname: "97-1-si.cg-dialup.net", IPs: []net.IP{{195, 80, 150, 211}, {195, 80, 150, 212}, {195, 80, 150, 214}, {195, 80, 150, 215}, {195, 80, 150, 216}, {195, 80, 150, 217}, {195, 80, 150, 218}, {195, 80, 150, 219}, {195, 80, 150, 221}, {195, 80, 150, 222}}},
|
||||
{Region: "Slovenia", Group: "Premium UDP Europe", Hostname: "87-1-si.cg-dialup.net", IPs: []net.IP{{195, 80, 150, 211}, {195, 80, 150, 212}, {195, 80, 150, 214}, {195, 80, 150, 215}, {195, 80, 150, 216}, {195, 80, 150, 217}, {195, 80, 150, 219}, {195, 80, 150, 220}, {195, 80, 150, 221}, {195, 80, 150, 222}}},
|
||||
{Region: "South Africa", Group: "Premium TCP Asia", Hostname: "96-1-za.cg-dialup.net", IPs: []net.IP{{154, 127, 50, 212}, {154, 127, 50, 215}, {154, 127, 50, 217}, {154, 127, 50, 219}, {154, 127, 50, 220}, {154, 127, 50, 222}, {154, 127, 60, 196}, {154, 127, 60, 198}, {154, 127, 60, 199}, {154, 127, 60, 200}}},
|
||||
{Region: "South Africa", Group: "Premium TCP Europe", Hostname: "97-1-za.cg-dialup.net", IPs: []net.IP{{197, 85, 7, 26}, {197, 85, 7, 27}, {197, 85, 7, 28}, {197, 85, 7, 29}, {197, 85, 7, 30}, {197, 85, 7, 31}, {197, 85, 7, 131}, {197, 85, 7, 132}, {197, 85, 7, 133}, {197, 85, 7, 134}}},
|
||||
{Region: "South Africa", Group: "Premium UDP Asia", Hostname: "95-1-za.cg-dialup.net", IPs: []net.IP{{154, 127, 50, 210}, {154, 127, 50, 214}, {154, 127, 50, 218}, {154, 127, 50, 219}, {154, 127, 50, 220}, {154, 127, 50, 221}, {154, 127, 50, 222}, {154, 127, 60, 195}, {154, 127, 60, 199}, {154, 127, 60, 206}}},
|
||||
{Region: "South Africa", Group: "Premium UDP Europe", Hostname: "87-1-za.cg-dialup.net", IPs: []net.IP{{197, 85, 7, 26}, {197, 85, 7, 27}, {197, 85, 7, 28}, {197, 85, 7, 29}, {197, 85, 7, 30}, {197, 85, 7, 31}, {197, 85, 7, 131}, {197, 85, 7, 132}, {197, 85, 7, 133}, {197, 85, 7, 134}}},
|
||||
{Region: "Spain", Group: "Premium TCP Europe", Hostname: "97-1-es.cg-dialup.net", IPs: []net.IP{{37, 120, 142, 166}, {37, 120, 142, 171}, {82, 102, 26, 197}, {82, 102, 26, 199}, {82, 102, 26, 204}, {84, 17, 62, 135}, {84, 17, 62, 146}, {84, 17, 62, 153}, {185, 93, 3, 106}, {185, 253, 99, 203}}},
|
||||
{Region: "Spain", Group: "Premium UDP Europe", Hostname: "87-1-es.cg-dialup.net", IPs: []net.IP{{37, 120, 142, 45}, {37, 120, 142, 53}, {37, 120, 142, 150}, {37, 120, 142, 151}, {82, 102, 26, 215}, {82, 102, 26, 221}, {84, 17, 62, 131}, {84, 17, 62, 153}, {185, 93, 3, 105}, {185, 93, 3, 112}}},
|
||||
{Region: "Sri Lanka", Group: "Premium TCP Europe", Hostname: "97-1-lk.cg-dialup.net", IPs: []net.IP{{95, 181, 239, 131}, {95, 181, 239, 132}, {95, 181, 239, 134}, {95, 181, 239, 135}, {95, 181, 239, 136}, {95, 181, 239, 137}, {95, 181, 239, 139}, {95, 181, 239, 140}, {95, 181, 239, 142}, {95, 181, 239, 144}}},
|
||||
{Region: "Sri Lanka", Group: "Premium UDP Europe", Hostname: "87-1-lk.cg-dialup.net", IPs: []net.IP{{95, 181, 239, 133}, {95, 181, 239, 134}, {95, 181, 239, 135}, {95, 181, 239, 138}, {95, 181, 239, 139}, {95, 181, 239, 140}, {95, 181, 239, 141}, {95, 181, 239, 142}, {95, 181, 239, 143}, {95, 181, 239, 144}}},
|
||||
{Region: "Sweden", Group: "Premium TCP Europe", Hostname: "97-1-se.cg-dialup.net", IPs: []net.IP{{188, 126, 73, 198}, {188, 126, 79, 5}, {188, 126, 79, 6}, {188, 126, 79, 11}, {188, 126, 79, 15}, {195, 246, 120, 144}, {195, 246, 120, 148}, {195, 246, 120, 156}, {195, 246, 120, 158}, {195, 246, 120, 165}}},
|
||||
{Region: "Sweden", Group: "Premium UDP Europe", Hostname: "87-1-se.cg-dialup.net", IPs: []net.IP{{188, 126, 73, 208}, {188, 126, 73, 219}, {188, 126, 73, 222}, {188, 126, 79, 5}, {188, 126, 79, 9}, {188, 126, 79, 17}, {188, 126, 79, 24}, {188, 126, 79, 25}, {195, 246, 120, 148}, {195, 246, 120, 154}}},
|
||||
{Region: "Switzerland", Group: "Premium TCP Europe", Hostname: "97-1-ch.cg-dialup.net", IPs: []net.IP{{84, 17, 52, 8}, {84, 17, 52, 33}, {84, 17, 52, 35}, {84, 17, 52, 47}, {84, 17, 52, 66}, {84, 17, 52, 72}, {185, 32, 222, 10}, {185, 32, 222, 11}, {185, 32, 222, 13}, {185, 32, 222, 113}}},
|
||||
{Region: "Taiwan", Group: "Premium TCP Asia", Hostname: "96-1-tw.cg-dialup.net", IPs: []net.IP{{45, 133, 181, 99}, {45, 133, 181, 100}, {45, 133, 181, 105}, {45, 133, 181, 106}, {45, 133, 181, 114}, {45, 133, 181, 119}, {45, 133, 181, 120}, {45, 133, 181, 121}, {45, 133, 181, 123}, {45, 133, 181, 126}}},
|
||||
{Region: "Thailand", Group: "Premium TCP Asia", Hostname: "96-1-th.cg-dialup.net", IPs: []net.IP{{146, 70, 13, 5}, {146, 70, 13, 6}, {146, 70, 13, 7}, {146, 70, 13, 8}, {146, 70, 13, 10}, {146, 70, 13, 11}, {146, 70, 13, 12}, {146, 70, 13, 13}, {146, 70, 13, 15}, {146, 70, 13, 16}}},
|
||||
{Region: "Thailand", Group: "Premium UDP Asia", Hostname: "95-1-th.cg-dialup.net", IPs: []net.IP{{146, 70, 13, 3}, {146, 70, 13, 4}, {146, 70, 13, 5}, {146, 70, 13, 6}, {146, 70, 13, 7}, {146, 70, 13, 8}, {146, 70, 13, 11}, {146, 70, 13, 13}, {146, 70, 13, 15}, {146, 70, 13, 16}}},
|
||||
{Region: "Turkey", Group: "Premium TCP Europe", Hostname: "97-1-tr.cg-dialup.net", IPs: []net.IP{{188, 213, 34, 5}, {188, 213, 34, 8}, {188, 213, 34, 10}, {188, 213, 34, 12}, {188, 213, 34, 29}, {188, 213, 34, 35}, {188, 213, 34, 39}, {188, 213, 34, 40}, {188, 213, 34, 41}, {188, 213, 34, 44}}},
|
||||
{Region: "Turkey", Group: "Premium UDP Europe", Hostname: "87-1-tr.cg-dialup.net", IPs: []net.IP{{188, 213, 34, 5}, {188, 213, 34, 13}, {188, 213, 34, 14}, {188, 213, 34, 17}, {188, 213, 34, 19}, {188, 213, 34, 27}, {188, 213, 34, 44}, {188, 213, 34, 101}, {188, 213, 34, 103}, {188, 213, 34, 108}}},
|
||||
{Region: "Ukraine", Group: "Premium TCP Europe", Hostname: "97-1-ua.cg-dialup.net", IPs: []net.IP{{31, 28, 163, 39}, {31, 28, 163, 44}, {31, 28, 163, 50}, {62, 149, 7, 162}, {62, 149, 7, 169}, {62, 149, 29, 37}, {62, 149, 29, 41}, {62, 149, 29, 45}, {62, 149, 29, 50}, {62, 149, 29, 57}}},
|
||||
{Region: "United Arab Emirates", Group: "Premium TCP Europe", Hostname: "97-1-ae.cg-dialup.net", IPs: []net.IP{{217, 138, 193, 179}, {217, 138, 193, 180}, {217, 138, 193, 181}, {217, 138, 193, 182}, {217, 138, 193, 185}, {217, 138, 193, 186}, {217, 138, 193, 187}, {217, 138, 193, 188}, {217, 138, 193, 189}, {217, 138, 193, 190}}},
|
||||
{Region: "United Kingdom", Group: "Premium TCP Europe", Hostname: "97-1-gb.cg-dialup.net", IPs: []net.IP{{45, 133, 172, 115}, {45, 133, 172, 137}, {95, 154, 200, 175}, {181, 215, 176, 248}, {191, 101, 209, 84}, {191, 101, 209, 111}, {191, 101, 209, 119}, {191, 101, 209, 136}, {194, 110, 13, 137}, {194, 110, 13, 149}}},
|
||||
{Region: "United States", Group: "Premium UDP USA", Hostname: "94-1-us.cg-dialup.net", IPs: []net.IP{{89, 187, 182, 22}, {108, 59, 0, 154}, {154, 21, 208, 153}, {154, 21, 208, 175}, {156, 146, 37, 17}, {156, 146, 37, 81}, {156, 146, 49, 145}, {156, 146, 59, 78}, {184, 170, 240, 202}, {199, 115, 119, 247}}},
|
||||
{Region: "Venezuela", Group: "Premium TCP USA", Hostname: "93-1-ve.cg-dialup.net", IPs: []net.IP{{95, 181, 237, 131}, {95, 181, 237, 133}, {95, 181, 237, 134}, {95, 181, 237, 135}, {95, 181, 237, 136}, {95, 181, 237, 138}, {95, 181, 237, 140}, {95, 181, 237, 141}, {95, 181, 237, 143}, {95, 181, 237, 144}}},
|
||||
{Region: "Venezuela", Group: "Premium UDP USA", Hostname: "94-1-ve.cg-dialup.net", IPs: []net.IP{{95, 181, 237, 131}, {95, 181, 237, 133}, {95, 181, 237, 134}, {95, 181, 237, 137}, {95, 181, 237, 138}, {95, 181, 237, 139}, {95, 181, 237, 140}, {95, 181, 237, 141}, {95, 181, 237, 142}, {95, 181, 237, 144}}},
|
||||
{Region: "Vietnam", Group: "Premium TCP Asia", Hostname: "96-1-vn.cg-dialup.net", IPs: []net.IP{{188, 214, 152, 99}, {188, 214, 152, 100}, {188, 214, 152, 101}, {188, 214, 152, 102}, {188, 214, 152, 103}, {188, 214, 152, 104}, {188, 214, 152, 106}, {188, 214, 152, 107}, {188, 214, 152, 108}, {188, 214, 152, 109}}},
|
||||
{Region: "Vietnam", Group: "Premium UDP Asia", Hostname: "95-1-vn.cg-dialup.net", IPs: []net.IP{{188, 214, 152, 99}, {188, 214, 152, 100}, {188, 214, 152, 101}, {188, 214, 152, 102}, {188, 214, 152, 104}, {188, 214, 152, 105}, {188, 214, 152, 106}, {188, 214, 152, 107}, {188, 214, 152, 109}, {188, 214, 152, 110}}},
|
||||
{Region: "Spain", Group: "Premium TCP Europe", Hostname: "97-1-es.cg-dialup.net", IPs: []net.IP{{37, 120, 142, 41}, {37, 120, 142, 52}, {37, 120, 142, 55}, {37, 120, 142, 61}, {37, 120, 142, 173}, {84, 17, 62, 131}, {84, 17, 62, 142}, {84, 17, 62, 144}, {185, 93, 3, 108}, {185, 93, 3, 114}}},
|
||||
{Region: "Sri Lanka", Group: "Premium TCP Europe", Hostname: "97-1-lk.cg-dialup.net", IPs: []net.IP{{95, 181, 239, 131}, {95, 181, 239, 132}, {95, 181, 239, 133}, {95, 181, 239, 134}, {95, 181, 239, 135}, {95, 181, 239, 136}, {95, 181, 239, 137}, {95, 181, 239, 138}, {95, 181, 239, 140}, {95, 181, 239, 144}}},
|
||||
{Region: "Sri Lanka", Group: "Premium UDP Europe", Hostname: "87-1-lk.cg-dialup.net", IPs: []net.IP{{95, 181, 239, 131}, {95, 181, 239, 132}, {95, 181, 239, 133}, {95, 181, 239, 134}, {95, 181, 239, 135}, {95, 181, 239, 136}, {95, 181, 239, 140}, {95, 181, 239, 141}, {95, 181, 239, 142}, {95, 181, 239, 144}}},
|
||||
{Region: "Sweden", Group: "Premium TCP Europe", Hostname: "97-1-se.cg-dialup.net", IPs: []net.IP{{188, 126, 73, 207}, {188, 126, 73, 209}, {188, 126, 73, 214}, {188, 126, 73, 219}, {188, 126, 79, 6}, {188, 126, 79, 11}, {188, 126, 79, 19}, {188, 126, 79, 25}, {195, 246, 120, 148}, {195, 246, 120, 161}}},
|
||||
{Region: "Sweden", Group: "Premium UDP Europe", Hostname: "87-1-se.cg-dialup.net", IPs: []net.IP{{188, 126, 73, 201}, {188, 126, 73, 211}, {188, 126, 73, 213}, {188, 126, 73, 218}, {188, 126, 79, 6}, {188, 126, 79, 8}, {188, 126, 79, 19}, {195, 246, 120, 142}, {195, 246, 120, 144}, {195, 246, 120, 168}}},
|
||||
{Region: "Switzerland", Group: "Premium TCP Europe", Hostname: "97-1-ch.cg-dialup.net", IPs: []net.IP{{84, 17, 52, 4}, {84, 17, 52, 20}, {84, 17, 52, 44}, {84, 17, 52, 65}, {84, 17, 52, 72}, {84, 17, 52, 80}, {84, 17, 52, 83}, {84, 17, 52, 85}, {185, 32, 222, 112}, {185, 189, 150, 73}}},
|
||||
{Region: "Switzerland", Group: "Premium UDP Europe", Hostname: "87-1-ch.cg-dialup.net", IPs: []net.IP{{84, 17, 52, 5}, {84, 17, 52, 14}, {84, 17, 52, 24}, {84, 17, 52, 64}, {84, 17, 52, 73}, {84, 17, 52, 85}, {185, 32, 222, 114}, {185, 189, 150, 52}, {185, 189, 150, 57}, {195, 225, 118, 43}}},
|
||||
{Region: "Taiwan", Group: "Premium TCP Asia", Hostname: "96-1-tw.cg-dialup.net", IPs: []net.IP{{45, 133, 181, 100}, {45, 133, 181, 102}, {45, 133, 181, 103}, {45, 133, 181, 106}, {45, 133, 181, 109}, {45, 133, 181, 113}, {45, 133, 181, 115}, {45, 133, 181, 116}, {45, 133, 181, 123}, {45, 133, 181, 125}}},
|
||||
{Region: "Taiwan", Group: "Premium UDP Asia", Hostname: "95-1-tw.cg-dialup.net", IPs: []net.IP{{45, 133, 181, 99}, {45, 133, 181, 102}, {45, 133, 181, 107}, {45, 133, 181, 108}, {45, 133, 181, 109}, {45, 133, 181, 114}, {45, 133, 181, 116}, {45, 133, 181, 117}, {45, 133, 181, 123}, {45, 133, 181, 124}}},
|
||||
{Region: "Thailand", Group: "Premium TCP Asia", Hostname: "96-1-th.cg-dialup.net", IPs: []net.IP{{146, 70, 13, 3}, {146, 70, 13, 4}, {146, 70, 13, 6}, {146, 70, 13, 7}, {146, 70, 13, 8}, {146, 70, 13, 9}, {146, 70, 13, 11}, {146, 70, 13, 13}, {146, 70, 13, 15}, {146, 70, 13, 16}}},
|
||||
{Region: "Thailand", Group: "Premium UDP Asia", Hostname: "95-1-th.cg-dialup.net", IPs: []net.IP{{146, 70, 13, 3}, {146, 70, 13, 4}, {146, 70, 13, 8}, {146, 70, 13, 9}, {146, 70, 13, 10}, {146, 70, 13, 11}, {146, 70, 13, 12}, {146, 70, 13, 13}, {146, 70, 13, 15}, {146, 70, 13, 16}}},
|
||||
{Region: "Turkey", Group: "Premium TCP Europe", Hostname: "97-1-tr.cg-dialup.net", IPs: []net.IP{{188, 213, 34, 9}, {188, 213, 34, 11}, {188, 213, 34, 15}, {188, 213, 34, 16}, {188, 213, 34, 23}, {188, 213, 34, 25}, {188, 213, 34, 28}, {188, 213, 34, 41}, {188, 213, 34, 108}, {188, 213, 34, 110}}},
|
||||
{Region: "Turkey", Group: "Premium UDP Europe", Hostname: "87-1-tr.cg-dialup.net", IPs: []net.IP{{188, 213, 34, 8}, {188, 213, 34, 11}, {188, 213, 34, 14}, {188, 213, 34, 28}, {188, 213, 34, 35}, {188, 213, 34, 42}, {188, 213, 34, 43}, {188, 213, 34, 100}, {188, 213, 34, 103}, {188, 213, 34, 107}}},
|
||||
{Region: "Ukraine", Group: "Premium TCP Europe", Hostname: "97-1-ua.cg-dialup.net", IPs: []net.IP{{31, 28, 161, 18}, {31, 28, 161, 20}, {31, 28, 161, 27}, {31, 28, 163, 34}, {31, 28, 163, 37}, {31, 28, 163, 44}, {62, 149, 7, 167}, {62, 149, 7, 172}, {62, 149, 29, 45}, {62, 149, 29, 57}}},
|
||||
{Region: "Ukraine", Group: "Premium UDP Europe", Hostname: "87-1-ua.cg-dialup.net", IPs: []net.IP{{31, 28, 161, 27}, {31, 28, 163, 38}, {31, 28, 163, 42}, {31, 28, 163, 54}, {31, 28, 163, 61}, {62, 149, 7, 162}, {62, 149, 7, 163}, {62, 149, 29, 35}, {62, 149, 29, 38}, {62, 149, 29, 41}}},
|
||||
{Region: "United Arab Emirates", Group: "Premium TCP Europe", Hostname: "97-1-ae.cg-dialup.net", IPs: []net.IP{{217, 138, 193, 179}, {217, 138, 193, 180}, {217, 138, 193, 181}, {217, 138, 193, 182}, {217, 138, 193, 183}, {217, 138, 193, 184}, {217, 138, 193, 185}, {217, 138, 193, 186}, {217, 138, 193, 188}, {217, 138, 193, 190}}},
|
||||
{Region: "United Arab Emirates", Group: "Premium UDP Europe", Hostname: "87-1-ae.cg-dialup.net", IPs: []net.IP{{217, 138, 193, 179}, {217, 138, 193, 180}, {217, 138, 193, 181}, {217, 138, 193, 182}, {217, 138, 193, 183}, {217, 138, 193, 186}, {217, 138, 193, 187}, {217, 138, 193, 188}, {217, 138, 193, 189}, {217, 138, 193, 190}}},
|
||||
{Region: "United Kingdom", Group: "Premium TCP Europe", Hostname: "97-1-gb.cg-dialup.net", IPs: []net.IP{{45, 133, 173, 49}, {45, 133, 173, 56}, {45, 133, 173, 82}, {45, 133, 173, 86}, {95, 154, 200, 153}, {95, 154, 200, 156}, {181, 215, 176, 103}, {181, 215, 176, 246}, {181, 215, 176, 251}, {194, 110, 13, 141}}},
|
||||
{Region: "United Kingdom", Group: "Premium UDP Europe", Hostname: "87-1-gb.cg-dialup.net", IPs: []net.IP{{45, 133, 172, 100}, {45, 133, 172, 126}, {45, 133, 173, 84}, {95, 154, 200, 174}, {181, 215, 176, 110}, {181, 215, 176, 151}, {181, 215, 176, 158}, {191, 101, 209, 142}, {194, 110, 13, 107}, {194, 110, 13, 128}}},
|
||||
{Region: "United States", Group: "Premium TCP USA", Hostname: "93-1-us.cg-dialup.net", IPs: []net.IP{{102, 129, 145, 15}, {102, 129, 152, 195}, {102, 129, 152, 248}, {154, 21, 208, 159}, {185, 242, 5, 117}, {185, 242, 5, 123}, {185, 242, 5, 229}, {191, 96, 227, 173}, {191, 96, 227, 196}, {199, 115, 119, 248}}},
|
||||
{Region: "United States", Group: "Premium UDP USA", Hostname: "94-1-us.cg-dialup.net", IPs: []net.IP{{23, 82, 14, 113}, {23, 105, 177, 122}, {45, 89, 173, 222}, {84, 17, 35, 4}, {89, 187, 171, 132}, {156, 146, 37, 45}, {156, 146, 59, 86}, {184, 170, 240, 231}, {191, 96, 150, 248}, {199, 115, 119, 248}}},
|
||||
{Region: "Venezuela", Group: "Premium TCP USA", Hostname: "93-1-ve.cg-dialup.net", IPs: []net.IP{{95, 181, 237, 132}, {95, 181, 237, 133}, {95, 181, 237, 134}, {95, 181, 237, 135}, {95, 181, 237, 136}, {95, 181, 237, 138}, {95, 181, 237, 139}, {95, 181, 237, 140}, {95, 181, 237, 141}, {95, 181, 237, 143}}},
|
||||
{Region: "Venezuela", Group: "Premium UDP USA", Hostname: "94-1-ve.cg-dialup.net", IPs: []net.IP{{95, 181, 237, 131}, {95, 181, 237, 132}, {95, 181, 237, 134}, {95, 181, 237, 135}, {95, 181, 237, 136}, {95, 181, 237, 140}, {95, 181, 237, 141}, {95, 181, 237, 142}, {95, 181, 237, 143}, {95, 181, 237, 144}}},
|
||||
{Region: "Vietnam", Group: "Premium TCP Asia", Hostname: "96-1-vn.cg-dialup.net", IPs: []net.IP{{188, 214, 152, 99}, {188, 214, 152, 101}, {188, 214, 152, 103}, {188, 214, 152, 104}, {188, 214, 152, 105}, {188, 214, 152, 106}, {188, 214, 152, 107}, {188, 214, 152, 108}, {188, 214, 152, 109}, {188, 214, 152, 110}}},
|
||||
{Region: "Vietnam", Group: "Premium UDP Asia", Hostname: "95-1-vn.cg-dialup.net", IPs: []net.IP{{188, 214, 152, 99}, {188, 214, 152, 100}, {188, 214, 152, 101}, {188, 214, 152, 102}, {188, 214, 152, 103}, {188, 214, 152, 104}, {188, 214, 152, 105}, {188, 214, 152, 106}, {188, 214, 152, 107}, {188, 214, 152, 109}}},
|
||||
}
|
||||
}
|
||||
|
||||
1894
internal/constants/ipvanish.go
Normal file
1894
internal/constants/ipvanish.go
Normal file
File diff suppressed because it is too large
Load Diff
@@ -47,6 +47,7 @@ func IvpnServers() []models.IvpnServer {
|
||||
{Country: "Austria", City: "", Hostname: "at.gw.ivpn.net", TCP: false, UDP: true, IPs: []net.IP{{185, 244, 212, 66}}},
|
||||
{Country: "Belgium", City: "", Hostname: "be.gw.ivpn.net", TCP: false, UDP: true, IPs: []net.IP{{194, 187, 251, 10}}},
|
||||
{Country: "Brazil", City: "", Hostname: "br.gw.ivpn.net", TCP: false, UDP: true, IPs: []net.IP{{45, 162, 229, 130}}},
|
||||
{Country: "Bulgaria", City: "", Hostname: "bg.gw.ivpn.net", TCP: false, UDP: true, IPs: []net.IP{{82, 102, 23, 18}}},
|
||||
{Country: "Canada", City: "Montreal", Hostname: "ca-qc.gw.ivpn.net", TCP: false, UDP: true, IPs: []net.IP{{87, 101, 92, 26}}},
|
||||
{Country: "Canada", City: "Toronto", Hostname: "ca.gw.ivpn.net", TCP: false, UDP: true, IPs: []net.IP{{104, 254, 90, 178}}},
|
||||
{Country: "Czech Republic", City: "", Hostname: "cz.gw.ivpn.net", TCP: false, UDP: true, IPs: []net.IP{{195, 181, 160, 167}}},
|
||||
@@ -69,6 +70,7 @@ func IvpnServers() []models.IvpnServer {
|
||||
{Country: "Serbia", City: "", Hostname: "rs.gw.ivpn.net", TCP: false, UDP: true, IPs: []net.IP{{141, 98, 103, 250}}},
|
||||
{Country: "Singapore", City: "", Hostname: "sg.gw.ivpn.net", TCP: false, UDP: true, IPs: []net.IP{{185, 128, 24, 186}}},
|
||||
{Country: "Slovakia", City: "", Hostname: "sk.gw.ivpn.net", TCP: false, UDP: true, IPs: []net.IP{{185, 245, 85, 250}}},
|
||||
{Country: "Spain", City: "", Hostname: "es.gw.ivpn.net", TCP: false, UDP: true, IPs: []net.IP{{185, 93, 3, 193}}},
|
||||
{Country: "Sweden", City: "", Hostname: "se.gw.ivpn.net", TCP: false, UDP: true, IPs: []net.IP{{80, 67, 10, 138}}},
|
||||
{Country: "Switzerland", City: "", Hostname: "ch.gw.ivpn.net", TCP: false, UDP: true, IPs: []net.IP{{185, 212, 170, 138}}},
|
||||
{Country: "USA", City: "Atlanta", Hostname: "us-ga.gw.ivpn.net", TCP: false, UDP: true, IPs: []net.IP{{104, 129, 24, 146}}},
|
||||
|
||||
@@ -21,10 +21,10 @@ const (
|
||||
RootHints string = "/etc/unbound/root.hints"
|
||||
// RootKey is the filepath to the root.key file used by Unbound.
|
||||
RootKey string = "/etc/unbound/root.key"
|
||||
// Client key filepath, used by Cyberghost.
|
||||
// ClientKey is the client key filepath.
|
||||
ClientKey string = "/gluetun/client.key"
|
||||
// Client certificate filepath, used by Cyberghost.
|
||||
// ClientCertificate is the client certificate filepath.
|
||||
ClientCertificate string = "/gluetun/client.crt"
|
||||
// Servers information filepath.
|
||||
// ServersData is the server information filepath.
|
||||
ServersData = "/gluetun/servers.json"
|
||||
)
|
||||
|
||||
@@ -48,6 +48,7 @@ func PrivadoHostnameChoices() (choices []string) {
|
||||
}
|
||||
|
||||
//nolint:lll
|
||||
// PrivadoServers returns a slice of all the Privado servers.
|
||||
func PrivadoServers() []models.PrivadoServer {
|
||||
return []models.PrivadoServer{
|
||||
{Country: "Argentina", Region: "Buenos Aires F.D.", City: "Buenos Aires", Hostname: "eze-001.vpn.privado.io", IP: net.IP{168, 205, 93, 211}},
|
||||
|
||||
@@ -55,43 +55,39 @@ func PurevpnHostnameChoices() (choices []string) {
|
||||
func PurevpnServers() []models.PurevpnServer {
|
||||
return []models.PurevpnServer{
|
||||
{Country: "Australia", Region: "New South Wales", City: "Sydney", Hostname: "au-sd2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{43, 245, 163, 82}, {46, 243, 245, 4}}},
|
||||
{Country: "Australia", Region: "New South Wales", City: "Sydney", Hostname: "au-sd2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{43, 245, 161, 80}, {43, 245, 161, 82}, {43, 245, 161, 84}}},
|
||||
{Country: "Australia", Region: "New South Wales", City: "Sydney", Hostname: "au-sd2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{43, 245, 161, 80}, {43, 245, 161, 81}, {43, 245, 161, 82}, {43, 245, 161, 86}}},
|
||||
{Country: "Australia", Region: "Western Australia", City: "Perth", Hostname: "au2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{43, 250, 205, 50}}},
|
||||
{Country: "Australia", Region: "Western Australia", City: "Perth", Hostname: "au2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{43, 250, 205, 53}, {43, 250, 205, 65}}},
|
||||
{Country: "Australia", Region: "Western Australia", City: "Perth", Hostname: "au2-pe-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{43, 250, 205, 50}}},
|
||||
{Country: "Australia", Region: "Western Australia", City: "Perth", Hostname: "au2-pe-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{43, 250, 205, 52}, {43, 250, 205, 65}}},
|
||||
{Country: "Australia", Region: "Western Australia", City: "Perth", Hostname: "au2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{43, 250, 205, 50}, {43, 250, 205, 61}}},
|
||||
{Country: "Australia", Region: "Western Australia", City: "Perth", Hostname: "au2-pe-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{43, 250, 205, 50}, {43, 250, 205, 51}}},
|
||||
{Country: "Australia", Region: "Western Australia", City: "Perth", Hostname: "au2-pe-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{43, 250, 205, 34}}},
|
||||
{Country: "Austria", Region: "Vienna", City: "Vienna", Hostname: "at2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{217, 64, 127, 251}, {217, 64, 127, 252}}},
|
||||
{Country: "Austria", Region: "Vienna", City: "Vienna", Hostname: "at2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{37, 120, 212, 218}, {37, 120, 212, 220}, {217, 64, 127, 251}}},
|
||||
{Country: "Belgium", Region: "Flanders", City: "Zaventem", Hostname: "vleu-be2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{217, 138, 211, 85}, {217, 138, 211, 86}, {217, 138, 211, 116}, {217, 138, 221, 114}}},
|
||||
{Country: "Belgium", Region: "Flanders", City: "Zaventem", Hostname: "vleu-be2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{217, 138, 211, 87}, {217, 138, 211, 88}, {217, 138, 211, 114}}},
|
||||
{Country: "Austria", Region: "Vienna", City: "Vienna", Hostname: "at2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{37, 120, 212, 219}, {217, 64, 127, 252}}},
|
||||
{Country: "Belgium", Region: "Flanders", City: "Zaventem", Hostname: "vleu-be2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{217, 138, 211, 87}, {217, 138, 211, 116}, {217, 138, 221, 117}}},
|
||||
{Country: "Brazil", Region: "São Paulo", City: "São Paulo", Hostname: "br2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{181, 41, 201, 83}, {181, 41, 201, 84}}},
|
||||
{Country: "Brazil", Region: "São Paulo", City: "São Paulo", Hostname: "br2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{138, 99, 210, 4}, {181, 41, 201, 77}, {181, 41, 201, 83}}},
|
||||
{Country: "Canada", Region: "British Columbia", City: "Vancouver", Hostname: "cav2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{66, 115, 147, 34}, {66, 115, 147, 35}}},
|
||||
{Country: "Canada", Region: "British Columbia", City: "Vancouver", Hostname: "cav2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{66, 115, 147, 38}, {66, 115, 147, 39}, {66, 115, 147, 40}}},
|
||||
{Country: "Canada", Region: "Ontario", City: "Toronto", Hostname: "ca2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{104, 200, 138, 212}, {104, 200, 138, 213}}},
|
||||
{Country: "Canada", Region: "Ontario", City: "Toronto", Hostname: "ca2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{104, 200, 138, 178}, {104, 200, 138, 212}, {104, 200, 138, 218}, {104, 200, 138, 219}}},
|
||||
{Country: "Czech Republic", Region: "Hlavní město Praha", City: "Prague", Hostname: "cz2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{185, 156, 174, 35}, {185, 156, 174, 36}}},
|
||||
{Country: "Czech Republic", Region: "Hlavní město Praha", City: "Prague", Hostname: "cz2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{185, 156, 174, 36}, {217, 138, 199, 252}}},
|
||||
{Country: "France", Region: "Île-de-France", City: "Paris", Hostname: "fr2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{89, 40, 183, 148}}},
|
||||
{Country: "France", Region: "Île-de-France", City: "Paris", Hostname: "fr2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{45, 152, 181, 69}, {45, 152, 181, 70}}},
|
||||
{Country: "Germany", Region: "Hesse", City: "Frankfurt am Main", Hostname: "de2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{5, 254, 88, 171}, {37, 120, 223, 50}}},
|
||||
{Country: "Germany", Region: "Hesse", City: "Frankfurt am Main", Hostname: "de2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{2, 57, 18, 22}, {217, 138, 194, 195}}},
|
||||
{Country: "Hong Kong", Region: "Central and Western", City: "Hong Kong", Hostname: "hk2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{103, 109, 103, 59}}},
|
||||
{Country: "Hong Kong", Region: "Central and Western", City: "Hong Kong", Hostname: "hk2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{103, 109, 103, 60}, {172, 111, 168, 4}}},
|
||||
{Country: "Brazil", Region: "São Paulo", City: "São Paulo", Hostname: "br2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{138, 99, 210, 4}, {181, 41, 201, 75}, {181, 41, 201, 82}, {181, 41, 201, 83}}},
|
||||
{Country: "Bulgaria", Region: "Sofia-Capital", City: "Sofia", Hostname: "vleu-be2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{217, 138, 221, 114}}},
|
||||
{Country: "Canada", Region: "British Columbia", City: "Vancouver", Hostname: "cav2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{66, 115, 147, 34}}},
|
||||
{Country: "Canada", Region: "British Columbia", City: "Vancouver", Hostname: "cav2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{66, 115, 147, 34}, {66, 115, 147, 35}, {66, 115, 147, 37}, {66, 115, 147, 38}, {66, 115, 147, 40}, {66, 115, 147, 43}}},
|
||||
{Country: "Canada", Region: "Ontario", City: "Toronto", Hostname: "ca2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{104, 200, 138, 212}}},
|
||||
{Country: "Canada", Region: "Ontario", City: "Toronto", Hostname: "ca2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{104, 200, 138, 213}, {104, 200, 138, 214}, {104, 200, 138, 216}}},
|
||||
{Country: "Czech Republic", Region: "Hlavní město Praha", City: "Prague", Hostname: "cz2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{185, 156, 174, 36}}},
|
||||
{Country: "Czech Republic", Region: "Hlavní město Praha", City: "Prague", Hostname: "cz2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{185, 156, 174, 38}, {217, 138, 199, 252}}},
|
||||
{Country: "France", Region: "Île-de-France", City: "Paris", Hostname: "fr2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{45, 152, 181, 68}}},
|
||||
{Country: "France", Region: "Île-de-France", City: "Paris", Hostname: "fr2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{45, 152, 181, 67}, {45, 152, 181, 70}}},
|
||||
{Country: "Germany", Region: "Hesse", City: "Frankfurt am Main", Hostname: "de2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{5, 254, 88, 213}}},
|
||||
{Country: "Germany", Region: "Hesse", City: "Frankfurt am Main", Hostname: "de2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{5, 254, 82, 50}, {5, 254, 82, 52}}},
|
||||
{Country: "Hong Kong", Region: "Central and Western", City: "Hong Kong", Hostname: "hk2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{103, 109, 103, 59}, {103, 109, 103, 60}, {119, 81, 228, 109}}},
|
||||
{Country: "Hong Kong", Region: "Central and Western", City: "Hong Kong", Hostname: "hk2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{172, 111, 168, 4}}},
|
||||
{Country: "Hong Kong", Region: "Central and Western", City: "Hong Kong", Hostname: "vlap-ph2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{36, 255, 97, 3}, {129, 227, 119, 84}}},
|
||||
{Country: "Hong Kong", Region: "Central and Western", City: "Hong Kong", Hostname: "vlap-ph2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{128, 1, 209, 21}}},
|
||||
{Country: "India", Region: "Tamil Nadu", City: "Tinnanūr", Hostname: "in2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{104, 250, 160, 132}, {178, 170, 141, 6}}},
|
||||
{Country: "Indonesia", Region: "Aceh", City: "Bireun", Hostname: "in2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{169, 38, 97, 242}, {169, 38, 129, 21}}},
|
||||
{Country: "Hong Kong", Region: "Central and Western", City: "Hong Kong", Hostname: "vlap-ph2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{36, 255, 97, 3}}},
|
||||
{Country: "Italy", Region: "Lombardy", City: "Milan", Hostname: "it2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{172, 111, 173, 3}}},
|
||||
{Country: "Italy", Region: "Lombardy", City: "Milan", Hostname: "it2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{172, 111, 173, 3}}},
|
||||
{Country: "Japan", Region: "Okinawa", City: "Hirara", Hostname: "tw2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{128, 1, 155, 178}}},
|
||||
{Country: "Japan", Region: "Okinawa", City: "Hirara", Hostname: "tw2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{128, 1, 155, 178}}},
|
||||
{Country: "Japan", Region: "Tokyo", City: "Tokyo", Hostname: "jp2-ovpn.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{185, 242, 4, 59}}},
|
||||
{Country: "Korea", Region: "Seoul", City: "Seoul", Hostname: "kr2-ovpn.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{43, 226, 231, 6}}},
|
||||
{Country: "Malaysia", Region: "Kuala Lumpur", City: "Kuala Lumpur", Hostname: "my2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{103, 28, 90, 32}, {103, 55, 10, 133}}},
|
||||
{Country: "Malaysia", Region: "Kuala Lumpur", City: "Kuala Lumpur", Hostname: "my2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{103, 55, 10, 4}, {103, 55, 10, 134}}},
|
||||
{Country: "Netherlands", Region: "North Holland", City: "Amsterdam", Hostname: "nl2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{5, 254, 73, 253}}},
|
||||
{Country: "Netherlands", Region: "North Holland", City: "Amsterdam", Hostname: "nl2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{5, 254, 73, 172}, {5, 254, 73, 203}}},
|
||||
{Country: "Korea", Region: "Gangwon-do", City: "Hongch’ŏn", Hostname: "kr2-ovpn.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{43, 226, 231, 4}, {43, 226, 231, 6}}},
|
||||
{Country: "Malaysia", Region: "Kuala Lumpur", City: "Kuala Lumpur", Hostname: "my2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{103, 55, 10, 134}}},
|
||||
{Country: "Malaysia", Region: "Kuala Lumpur", City: "Kuala Lumpur", Hostname: "my2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{103, 28, 90, 32}}},
|
||||
{Country: "Netherlands", Region: "North Holland", City: "Amsterdam", Hostname: "nl2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{5, 254, 73, 172}, {5, 254, 73, 252}, {92, 119, 179, 195}, {206, 123, 147, 4}}},
|
||||
{Country: "Netherlands", Region: "North Holland", City: "Amsterdam", Hostname: "nl2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{5, 254, 73, 171}, {5, 254, 73, 202}, {92, 119, 179, 195}, {206, 123, 147, 4}}},
|
||||
{Country: "Netherlands", Region: "North Holland", City: "Amsterdam", Hostname: "vlap-th2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{104, 37, 6, 4}}},
|
||||
{Country: "Netherlands", Region: "North Holland", City: "Amsterdam", Hostname: "vlap-th2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{104, 37, 6, 4}}},
|
||||
{Country: "Norway", Region: "Oslo", City: "Oslo", Hostname: "vleu-no2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{82, 102, 22, 212}}},
|
||||
@@ -100,51 +96,55 @@ func PurevpnServers() []models.PurevpnServer {
|
||||
{Country: "Portugal", Region: "Lisbon", City: "Lisbon", Hostname: "Pt2-ovpn.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{5, 154, 174, 3}}},
|
||||
{Country: "Russian Federation", Region: "St.-Petersburg", City: "Saint Petersburg", Hostname: "ru2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{94, 242, 54, 23}, {206, 123, 139, 4}}},
|
||||
{Country: "Russian Federation", Region: "St.-Petersburg", City: "Saint Petersburg", Hostname: "ru2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{94, 242, 54, 23}, {206, 123, 139, 4}}},
|
||||
{Country: "Singapore", Region: "Singapore", City: "Singapore", Hostname: "sg2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{37, 120, 208, 148}, {84, 247, 49, 180}}},
|
||||
{Country: "Singapore", Region: "Singapore", City: "Singapore", Hostname: "sg2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{84, 247, 49, 181}}},
|
||||
{Country: "Singapore", Region: "Singapore", City: "Singapore", Hostname: "sg2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{37, 120, 208, 147}, {37, 120, 208, 148}}},
|
||||
{Country: "Singapore", Region: "Singapore", City: "Singapore", Hostname: "vlap-vn2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{192, 253, 249, 132}}},
|
||||
{Country: "Singapore", Region: "Singapore", City: "Singapore", Hostname: "vlap-vn2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{192, 253, 249, 132}}},
|
||||
{Country: "South Africa", Region: "Gauteng", City: "Johannesburg", Hostname: "za2-ovpn.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{102, 165, 3, 34}}},
|
||||
{Country: "Sweden", Region: "Stockholm", City: "Stockholm", Hostname: "se2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{45, 12, 220, 123}}},
|
||||
{Country: "Sweden", Region: "Stockholm", City: "Stockholm", Hostname: "se2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{86, 106, 103, 181}, {86, 106, 103, 185}}},
|
||||
{Country: "South Africa", Region: "Gauteng", City: "Johannesburg", Hostname: "za2-ovpn.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{102, 165, 3, 33}, {102, 165, 3, 34}}},
|
||||
{Country: "Sweden", Region: "Stockholm", City: "Stockholm", Hostname: "se2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{45, 12, 220, 123}, {86, 106, 103, 178}, {86, 106, 103, 179}}},
|
||||
{Country: "Sweden", Region: "Stockholm", City: "Stockholm", Hostname: "se2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{45, 12, 220, 125}, {86, 106, 103, 183}}},
|
||||
{Country: "Switzerland", Region: "Zurich", City: "Zürich", Hostname: "ch2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{45, 12, 222, 98}, {45, 12, 222, 99}}},
|
||||
{Country: "Switzerland", Region: "Zurich", City: "Zürich", Hostname: "ch2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{45, 12, 222, 100}, {45, 12, 222, 101}, {45, 12, 222, 104}, {45, 12, 222, 107}}},
|
||||
{Country: "Switzerland", Region: "Zurich", City: "Zürich", Hostname: "ch2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{45, 12, 222, 100}, {45, 12, 222, 102}, {45, 12, 222, 106}, {45, 12, 222, 107}}},
|
||||
{Country: "Taiwan", Region: "Taiwan", City: "Taipei", Hostname: "tw2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{128, 1, 155, 178}}},
|
||||
{Country: "Taiwan", Region: "Taiwan", City: "Taipei", Hostname: "tw2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{128, 1, 155, 178}}},
|
||||
{Country: "United Kingdom", Region: "England", City: "London", Hostname: "ukg2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{45, 74, 0, 4}}},
|
||||
{Country: "United Kingdom", Region: "England", City: "London", Hostname: "ukg2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{193, 9, 113, 70}}},
|
||||
{Country: "United Kingdom", Region: "England", City: "London", Hostname: "ukl2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{45, 74, 0, 4}}},
|
||||
{Country: "United Kingdom", Region: "England", City: "London", Hostname: "ukl2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{89, 238, 165, 146}, {193, 9, 113, 70}}},
|
||||
{Country: "United Kingdom", Region: "England", City: "Manchester", Hostname: "ukg2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{89, 238, 165, 148}, {89, 238, 165, 149}}},
|
||||
{Country: "United Kingdom", Region: "England", City: "Manchester", Hostname: "ukl2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{89, 238, 165, 148}, {89, 238, 165, 149}}},
|
||||
{Country: "United Kingdom", Region: "England", City: "Manchester", Hostname: "ukm2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{188, 72, 89, 4}}},
|
||||
{Country: "United Kingdom", Region: "England", City: "Manchester", Hostname: "ukm2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{188, 72, 89, 4}}},
|
||||
{Country: "United States", Region: "California", City: "Los Angeles", Hostname: "usla2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{89, 45, 4, 2}}},
|
||||
{Country: "United States", Region: "California", City: "Los Angeles", Hostname: "vlus-mx2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{104, 243, 243, 131}}},
|
||||
{Country: "United States", Region: "California", City: "Los Angeles", Hostname: "vlus-mx2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{104, 243, 243, 131}}},
|
||||
{Country: "United States", Region: "California", City: "Milpitas", Hostname: "usphx2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{141, 101, 166, 4}, {172, 94, 72, 4}}},
|
||||
{Country: "United States", Region: "California", City: "Milpitas", Hostname: "ussf2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{141, 101, 166, 4}}},
|
||||
{Country: "United States", Region: "California", City: "Milpitas", Hostname: "ussf2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{141, 101, 166, 4}}},
|
||||
{Country: "United States", Region: "Florida", City: "Miami", Hostname: "usfl2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{5, 254, 79, 117}}},
|
||||
{Country: "United States", Region: "California", City: "San Jose", Hostname: "ussf2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{141, 101, 166, 4}}},
|
||||
{Country: "United States", Region: "Florida", City: "Miami", Hostname: "usfl2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{5, 254, 79, 100}, {5, 254, 79, 116}}},
|
||||
{Country: "United States", Region: "Florida", City: "Miami", Hostname: "usfl2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{5, 254, 79, 114}, {5, 254, 79, 115}}},
|
||||
{Country: "United States", Region: "New Jersey", City: "Harrison", Hostname: "vlus-pa2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{172, 111, 149, 4}}},
|
||||
{Country: "United States", Region: "New Jersey", City: "Harrison", Hostname: "vlus-pa2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{172, 111, 149, 4}}},
|
||||
{Country: "United States", Region: "Georgia", City: "Cumming", Hostname: "in2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{169, 38, 69, 12}}},
|
||||
{Country: "United States", Region: "New Jersey", City: "Piscataway", Hostname: "usny2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{209, 127, 184, 71}, {209, 127, 184, 73}, {209, 127, 184, 74}, {209, 127, 184, 76}}},
|
||||
{Country: "United States", Region: "New York", City: "New York City", Hostname: "usnj2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{172, 94, 72, 4}}},
|
||||
{Country: "United States", Region: "New York", City: "New York City", Hostname: "usnj2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{172, 94, 72, 4}}},
|
||||
{Country: "United States", Region: "New York", City: "New York City", Hostname: "usny2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{141, 101, 153, 4}}},
|
||||
{Country: "United States", Region: "New York", City: "New York City", Hostname: "usny2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{172, 94, 72, 4}}},
|
||||
{Country: "United States", Region: "New York", City: "New York City", Hostname: "ussf2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{172, 94, 72, 4}, {172, 94, 86, 4}}},
|
||||
{Country: "United States", Region: "New York", City: "New York City", Hostname: "uswdc2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{172, 94, 72, 4}, {172, 94, 86, 4}}},
|
||||
{Country: "United States", Region: "New York", City: "New York City", Hostname: "vlus-pa2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{172, 111, 149, 4}}},
|
||||
{Country: "United States", Region: "New York", City: "New York City", Hostname: "vlus-pa2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{172, 111, 149, 4}}},
|
||||
{Country: "United States", Region: "Pennsylvania", City: "Pittsburgh", Hostname: "in2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{104, 250, 160, 132}}},
|
||||
{Country: "United States", Region: "Texas", City: "Allen", Hostname: "usga2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{172, 94, 108, 4}}},
|
||||
{Country: "United States", Region: "Texas", City: "Allen", Hostname: "usil2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{172, 94, 108, 4}}},
|
||||
{Country: "United States", Region: "Texas", City: "Dallas", Hostname: "ukm2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{172, 94, 1, 4}, {172, 94, 72, 4}, {172, 94, 123, 4}}},
|
||||
{Country: "United States", Region: "Texas", City: "Dallas", Hostname: "ussa2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{172, 94, 1, 4}, {172, 94, 72, 4}}},
|
||||
{Country: "United States", Region: "Texas", City: "Dallas", Hostname: "ustx2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{104, 217, 255, 178}, {208, 84, 155, 100}}},
|
||||
{Country: "United States", Region: "Texas", City: "Dallas", Hostname: "ustx2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{104, 217, 255, 179}, {104, 217, 255, 184}, {104, 217, 255, 185}}},
|
||||
{Country: "United States", Region: "Utah", City: "Salt Lake City", Hostname: "us2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{45, 74, 52, 4}}},
|
||||
{Country: "United States", Region: "Utah", City: "Salt Lake City", Hostname: "usga2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{45, 74, 52, 4}, {172, 94, 1, 4}}},
|
||||
{Country: "United States", Region: "Utah", City: "Salt Lake City", Hostname: "usil2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{45, 74, 52, 4}, {46, 243, 249, 4}, {172, 94, 72, 4}}},
|
||||
{Country: "United States", Region: "Utah", City: "Salt Lake City", Hostname: "usla2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{45, 74, 52, 4}, {141, 101, 166, 4}, {172, 94, 1, 4}}},
|
||||
{Country: "United States", Region: "Utah", City: "Salt Lake City", Hostname: "usut2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{45, 74, 52, 4}}},
|
||||
{Country: "United States", Region: "Utah", City: "Salt Lake City", Hostname: "uswdc2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{45, 74, 52, 4}, {141, 101, 166, 4}, {172, 94, 72, 4}}},
|
||||
{Country: "United States", Region: "Texas", City: "Dallas", Hostname: "ustx2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{208, 84, 155, 100}, {208, 84, 155, 101}}},
|
||||
{Country: "United States", Region: "Texas", City: "Dallas", Hostname: "ustx2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{104, 217, 255, 185}, {104, 217, 255, 186}}},
|
||||
{Country: "United States", Region: "Virginia", City: "Centreville", Hostname: "usva2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{5, 254, 109, 115}, {37, 221, 173, 212}}},
|
||||
{Country: "United States", Region: "Virginia", City: "Reston", Hostname: "usva2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{5, 254, 77, 26}, {5, 254, 77, 27}}},
|
||||
{Country: "United States", Region: "Virginia", City: "Reston", Hostname: "usva2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{5, 254, 77, 26}, {5, 254, 77, 138}}},
|
||||
{Country: "United States", Region: "Washington", City: "Seattle", Hostname: "ussa2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{172, 94, 86, 4}}},
|
||||
{Country: "United States", Region: "Washington, D.C.", City: "Washington", Hostname: "us2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{46, 243, 249, 4}}},
|
||||
{Country: "United States", Region: "Washington, D.C.", City: "Washington", Hostname: "us2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{141, 101, 169, 4}, {172, 94, 72, 4}, {172, 94, 86, 4}}},
|
||||
{Country: "United States", Region: "Washington, D.C.", City: "Washington", Hostname: "usga2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{141, 101, 169, 4}, {172, 94, 86, 4}}},
|
||||
{Country: "United States", Region: "Washington, D.C.", City: "Washington", Hostname: "usil2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{141, 101, 169, 4}, {172, 94, 72, 4}, {172, 94, 86, 4}}},
|
||||
{Country: "United States", Region: "Washington, D.C.", City: "Washington", Hostname: "usla2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{141, 101, 169, 4}, {172, 94, 72, 4}}},
|
||||
{Country: "United States", Region: "Washington, D.C.", City: "Washington", Hostname: "usphx2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{141, 101, 169, 4}}},
|
||||
{Country: "United States", Region: "Washington, D.C.", City: "Washington", Hostname: "ussa2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{46, 243, 249, 4}}},
|
||||
{Country: "United States", Region: "Washington, D.C.", City: "Washington", Hostname: "usut2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{46, 243, 249, 4}}},
|
||||
{Country: "United States", Region: "Washington, D.C.", City: "Washington", Hostname: "usut2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{141, 101, 169, 4}, {172, 94, 72, 4}, {172, 94, 86, 4}}},
|
||||
{Country: "United States", Region: "Washington, D.C.", City: "Washington", Hostname: "uswdc2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{46, 243, 249, 4}}},
|
||||
{Country: "Vietnam", Region: "Hanoi", City: "Hanoi", Hostname: "vlap-vn2-ovpn-tcp.pointtoserver.com", TCP: true, UDP: false, IPs: []net.IP{{192, 253, 249, 132}}},
|
||||
{Country: "Vietnam", Region: "Hanoi", City: "Hanoi", Hostname: "vlap-vn2-ovpn-udp.pointtoserver.com", TCP: false, UDP: true, IPs: []net.IP{{192, 253, 249, 132}}},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ func GetAllServers() (allServers models.AllServers) {
|
||||
Version: 1, // used for migration of the top level scheme
|
||||
Cyberghost: models.CyberghostServers{
|
||||
Version: 2, // model version
|
||||
Timestamp: 1620491290, // latest takes precedence
|
||||
Timestamp: 1624307338, // latest takes precedence
|
||||
Servers: CyberghostServers(),
|
||||
},
|
||||
Fastestvpn: models.FastestvpnServers{
|
||||
@@ -21,9 +21,14 @@ func GetAllServers() (allServers models.AllServers) {
|
||||
Timestamp: 1620435633,
|
||||
Servers: HideMyAssServers(),
|
||||
},
|
||||
Ipvanish: models.IpvanishServers{
|
||||
Version: 1,
|
||||
Timestamp: 1622430497,
|
||||
Servers: IpvanishServers(),
|
||||
},
|
||||
Ivpn: models.IvpnServers{
|
||||
Version: 1,
|
||||
Timestamp: 1622421364,
|
||||
Timestamp: 1624120443,
|
||||
Servers: IvpnServers(),
|
||||
},
|
||||
Mullvad: models.MullvadServers{
|
||||
@@ -58,7 +63,7 @@ func GetAllServers() (allServers models.AllServers) {
|
||||
},
|
||||
Purevpn: models.PurevpnServers{
|
||||
Version: 2,
|
||||
Timestamp: 1620606921,
|
||||
Timestamp: 1622644308,
|
||||
Servers: PurevpnServers(),
|
||||
},
|
||||
Surfshark: models.SurfsharkServers{
|
||||
@@ -71,6 +76,11 @@ func GetAllServers() (allServers models.AllServers) {
|
||||
Timestamp: 1620611129,
|
||||
Servers: TorguardServers(),
|
||||
},
|
||||
VPNUnlimited: models.VPNUnlimitedServers{
|
||||
Version: 1,
|
||||
Timestamp: 1623950304,
|
||||
Servers: VPNUnlimitedServers(),
|
||||
},
|
||||
Vyprvpn: models.VyprvpnServers{
|
||||
Version: 2,
|
||||
Timestamp: 1620612506,
|
||||
|
||||
@@ -50,6 +50,11 @@ func Test_versions(t *testing.T) {
|
||||
version: allServers.HideMyAss.Version,
|
||||
digest: "a93b4057",
|
||||
},
|
||||
"Ipvanish": {
|
||||
model: models.IpvanishServer{},
|
||||
version: allServers.Ipvanish.Version,
|
||||
digest: "2eb80d28",
|
||||
},
|
||||
"Ivpn": {
|
||||
model: models.IvpnServer{},
|
||||
version: allServers.Ivpn.Version,
|
||||
@@ -100,6 +105,11 @@ func Test_versions(t *testing.T) {
|
||||
version: allServers.Torguard.Version,
|
||||
digest: "6eb9028e",
|
||||
},
|
||||
"VPN Unlimited": {
|
||||
model: models.VPNUnlimitedServer{},
|
||||
version: allServers.VPNUnlimited.Version,
|
||||
digest: "5cb51319",
|
||||
},
|
||||
"Vyprvpn": {
|
||||
model: models.VyprvpnServer{},
|
||||
version: allServers.Vyprvpn.Version,
|
||||
@@ -150,7 +160,7 @@ func Test_timestamps(t *testing.T) {
|
||||
"Cyberghost": {
|
||||
servers: allServers.Cyberghost.Servers,
|
||||
timestamp: allServers.Cyberghost.Timestamp,
|
||||
digest: "1de7ee68",
|
||||
digest: "b3ca3118",
|
||||
},
|
||||
"Fastestvpn": {
|
||||
servers: allServers.Fastestvpn.Version,
|
||||
@@ -162,10 +172,15 @@ func Test_timestamps(t *testing.T) {
|
||||
timestamp: allServers.HideMyAss.Timestamp,
|
||||
digest: "8f872ac4",
|
||||
},
|
||||
"Ipvanish": {
|
||||
servers: allServers.Ipvanish.Servers,
|
||||
timestamp: allServers.Ipvanish.Timestamp,
|
||||
digest: "c62dcf98",
|
||||
},
|
||||
"Ivpn": {
|
||||
servers: allServers.Ivpn.Servers,
|
||||
timestamp: allServers.Ivpn.Timestamp,
|
||||
digest: "158630c0",
|
||||
digest: "42f92754",
|
||||
},
|
||||
"Mullvad": {
|
||||
servers: allServers.Mullvad.Servers,
|
||||
@@ -200,7 +215,7 @@ func Test_timestamps(t *testing.T) {
|
||||
"Purevpn": {
|
||||
servers: allServers.Purevpn.Servers,
|
||||
timestamp: allServers.Purevpn.Timestamp,
|
||||
digest: "e48aa76d",
|
||||
digest: "9263cfdb",
|
||||
},
|
||||
"Surfshark": {
|
||||
servers: allServers.Surfshark.Servers,
|
||||
@@ -212,6 +227,11 @@ func Test_timestamps(t *testing.T) {
|
||||
timestamp: allServers.Torguard.Timestamp,
|
||||
digest: "af54b9e8",
|
||||
},
|
||||
"VPN Unlimited": {
|
||||
servers: allServers.VPNUnlimited.Servers,
|
||||
timestamp: allServers.VPNUnlimited.Timestamp,
|
||||
digest: "f6ddb84c",
|
||||
},
|
||||
"Vyprvpn": {
|
||||
servers: allServers.Vyprvpn.Servers,
|
||||
timestamp: allServers.Vyprvpn.Timestamp,
|
||||
|
||||
@@ -30,7 +30,7 @@ func TorguardCityChoices() (choices []string) {
|
||||
return makeUnique(choices)
|
||||
}
|
||||
|
||||
func TorguardHostnamesChoices() (choices []string) {
|
||||
func TorguardHostnameChoices() (choices []string) {
|
||||
servers := TorguardServers()
|
||||
choices = make([]string, len(servers))
|
||||
for i := range servers {
|
||||
|
||||
@@ -7,11 +7,13 @@ const (
|
||||
Fastestvpn = "fastestvpn"
|
||||
// HideMyAss is a VPN provider.
|
||||
HideMyAss = "hidemyass"
|
||||
// Ipvanish is a VPN provider.
|
||||
Ipvanish = "ipvanish"
|
||||
// Ivpn is a VPN provider.
|
||||
Ivpn = "ivpn"
|
||||
// Mullvad is a VPN provider.
|
||||
Mullvad = "mullvad"
|
||||
// NordVPN is a VPN provider.
|
||||
// Nordvpn is a VPN provider.
|
||||
Nordvpn = "nordvpn"
|
||||
// Privado is a VPN provider.
|
||||
Privado = "privado"
|
||||
@@ -21,12 +23,14 @@ const (
|
||||
Privatevpn = "privatevpn"
|
||||
// Protonvpn is a VPN provider.
|
||||
Protonvpn = "protonvpn"
|
||||
// PureVPN is a VPN provider.
|
||||
// Purevpn is a VPN provider.
|
||||
Purevpn = "purevpn"
|
||||
// Surfshark is a VPN provider.
|
||||
Surfshark = "surfshark"
|
||||
// Torguard is a VPN provider.
|
||||
Torguard = "torguard"
|
||||
// VPNUnlimited is a VPN provider.
|
||||
VPNUnlimited = "vpn unlimited"
|
||||
// Vyprvpn is a VPN provider.
|
||||
Vyprvpn = "vyprvpn"
|
||||
// Windscribe is a VPN provider.
|
||||
|
||||
124
internal/constants/vpnunlimited.go
Normal file
124
internal/constants/vpnunlimited.go
Normal file
@@ -0,0 +1,124 @@
|
||||
package constants
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
)
|
||||
|
||||
//nolint:lll
|
||||
const (
|
||||
VPNUnlimitedCertificateAuthority = "MIIEjjCCA/egAwIBAgIJAKsVbHBdakXuMA0GCSqGSIb3DQEBBQUAMIHgMQswCQYDVQQGEwJVUzELMAkGA1UECBMCTlkxETAPBgNVBAcTCE5ldyBZb3JrMR8wHQYDVQQKExZTaW1wbGV4IFNvbHV0aW9ucyBJbmMuMRYwFAYDVQQLEw1WcG4gVW5saW1pdGVkMSMwIQYDVQQDExpzZXJ2ZXIudnBudW5saW1pdGVkYXBwLmNvbTEjMCEGA1UEKRMac2VydmVyLnZwbnVubGltaXRlZGFwcC5jb20xLjAsBgkqhkiG9w0BCQEWH3N1cHBvcnRAc2ltcGxleHNvbHV0aW9uc2luYy5jb20wHhcNMTMxMjE2MTM1OTQ0WhcNMjMxMjE0MTM1OTQ0WjCB4DELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAk5ZMREwDwYDVQQHEwhOZXcgWW9yazEfMB0GA1UEChMWU2ltcGxleCBTb2x1dGlvbnMgSW5jLjEWMBQGA1UECxMNVnBuIFVubGltaXRlZDEjMCEGA1UEAxMac2VydmVyLnZwbnVubGltaXRlZGFwcC5jb20xIzAhBgNVBCkTGnNlcnZlci52cG51bmxpbWl0ZWRhcHAuY29tMS4wLAYJKoZIhvcNAQkBFh9zdXBwb3J0QHNpbXBsZXhzb2x1dGlvbnNpbmMuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDADUzS8QWGvdhLFKsEzAiq5+b0ukKjBza0k6/dmCeYTvCVqGKg/h1IAtQdVVLAkmEp0zvGH7PuOhXm7zZrCouBr/RiG4tEcoRHwc6AJmowkYERlY7+xGx3OuNrD00QceNTsan0bn78jwt0zhFNmHdoTtFjgK3oqmQYSAtbEVWYgwIDAQABo4IBTDCCAUgwHQYDVR0OBBYEFKClmYP+tMNgWagUJCCHjtaui2k+MIIBFwYDVR0jBIIBDjCCAQqAFKClmYP+tMNgWagUJCCHjtaui2k+oYHmpIHjMIHgMQswCQYDVQQGEwJVUzELMAkGA1UECBMCTlkxETAPBgNVBAcTCE5ldyBZb3JrMR8wHQYDVQQKExZTaW1wbGV4IFNvbHV0aW9ucyBJbmMuMRYwFAYDVQQLEw1WcG4gVW5saW1pdGVkMSMwIQYDVQQDExpzZXJ2ZXIudnBudW5saW1pdGVkYXBwLmNvbTEjMCEGA1UEKRMac2VydmVyLnZwbnVubGltaXRlZGFwcC5jb20xLjAsBgkqhkiG9w0BCQEWH3N1cHBvcnRAc2ltcGxleHNvbHV0aW9uc2luYy5jb22CCQCrFWxwXWpF7jAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBALkWhfw7SSV7it+ZYZmT+cQbExjlYgQ40zae2J2CqIYACRcfsDHvh7Q+fiwSocevv2NE0dWi6WB2H6SiudYjvDvubAX/QbzfBxtbxCCoAIlfPCm8xOnWFN7TUJAzWwHJkKgEnu29GZHu2x8J+7VeDbKH5RTMHHe8FkSxh6Zz/BMN"
|
||||
)
|
||||
|
||||
func VPNUnlimitedCountryChoices() (choices []string) {
|
||||
servers := VPNUnlimitedServers()
|
||||
choices = make([]string, len(servers))
|
||||
for i := range servers {
|
||||
choices[i] = servers[i].Country
|
||||
}
|
||||
return makeUnique(choices)
|
||||
}
|
||||
|
||||
func VPNUnlimitedCityChoices() (choices []string) {
|
||||
servers := VPNUnlimitedServers()
|
||||
choices = make([]string, len(servers))
|
||||
for i := range servers {
|
||||
choices[i] = servers[i].City
|
||||
}
|
||||
return makeUnique(choices)
|
||||
}
|
||||
|
||||
func VPNUnlimitedHostnameChoices() (choices []string) {
|
||||
servers := VPNUnlimitedServers()
|
||||
choices = make([]string, len(servers))
|
||||
for i := range servers {
|
||||
choices[i] = servers[i].Hostname
|
||||
}
|
||||
return makeUnique(choices)
|
||||
}
|
||||
|
||||
//nolint:lll
|
||||
// VPNUnlimitedServers returns a slice of all the server information for VPNUnlimited.
|
||||
func VPNUnlimitedServers() []models.VPNUnlimitedServer {
|
||||
return []models.VPNUnlimitedServer{
|
||||
{Country: "Argentina", City: "", Hostname: "ar.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{131, 255, 4, 187}, {131, 255, 4, 235}}},
|
||||
{Country: "Australia", City: "Sydney", Hostname: "au-syd.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{139, 99, 131, 38}, {139, 99, 130, 220}}},
|
||||
{Country: "Austria", City: "", Hostname: "at.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{50, 7, 115, 19}, {185, 210, 219, 194}, {185, 210, 219, 198}}},
|
||||
{Country: "Belarus", City: "", Hostname: "by.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{185, 66, 68, 23}, {185, 66, 71, 108}, {185, 66, 71, 115}, {185, 66, 68, 84}, {185, 66, 71, 22}, {185, 66, 71, 122}, {185, 66, 71, 8}, {185, 66, 68, 18}}},
|
||||
{Country: "Belgium", City: "", Hostname: "be.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{37, 120, 143, 178}, {82, 102, 19, 110}}},
|
||||
{Country: "Bosnia and Herzegovina", City: "", Hostname: "ba.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{185, 164, 35, 37}}},
|
||||
{Country: "Brazil", City: "", Hostname: "br.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{66, 90, 70, 7}, {177, 67, 82, 222}, {177, 67, 82, 218}, {177, 67, 82, 228}, {177, 67, 82, 221}, {177, 67, 82, 219}, {177, 67, 82, 210}, {177, 67, 82, 223}}},
|
||||
{Country: "Bulgaria", City: "", Hostname: "bg.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{37, 120, 152, 26}}},
|
||||
{Country: "Canada", City: "", Hostname: "ca.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{192, 99, 7, 170}, {192, 99, 6, 164}, {192, 99, 14, 158}, {192, 99, 37, 199}, {192, 99, 6, 166}}},
|
||||
{Country: "Canada", City: "Toronto", Hostname: "ca-tr.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{184, 75, 213, 154}, {162, 253, 131, 106}, {162, 219, 176, 163}, {104, 254, 90, 58}, {104, 254, 92, 42}, {184, 75, 213, 194}, {204, 187, 100, 82}, {104, 254, 90, 34}}},
|
||||
{Country: "Canada", City: "Vancouver", Hostname: "ca-vn.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{162, 221, 202, 138}, {162, 221, 202, 134}, {162, 221, 202, 17}}},
|
||||
{Country: "Costa Rica", City: "", Hostname: "cr.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{138, 59, 19, 8}}},
|
||||
{Country: "Croatia", City: "", Hostname: "hr.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{85, 10, 56, 3}, {85, 10, 56, 100}, {85, 10, 51, 3}, {85, 10, 56, 4}}},
|
||||
{Country: "Cyprus", City: "", Hostname: "cy.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{194, 30, 136, 123}, {194, 30, 136, 102}}},
|
||||
{Country: "Czech Republic", City: "", Hostname: "cz.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{185, 216, 35, 46}}},
|
||||
{Country: "Denmark", City: "", Hostname: "dk.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{37, 120, 194, 174}, {89, 45, 7, 90}}},
|
||||
{Country: "Estonia", City: "", Hostname: "ee.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{185, 155, 96, 132}}},
|
||||
{Country: "Finland", City: "", Hostname: "fi.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{185, 112, 82, 26}, {91, 233, 116, 44}}},
|
||||
{Country: "France", City: "", Hostname: "fr.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{195, 154, 189, 85}, {195, 154, 204, 36}, {195, 154, 211, 84}, {62, 210, 38, 83}, {195, 154, 169, 66}, {195, 154, 166, 20}, {62, 210, 204, 161}, {62, 210, 205, 16}, {62, 210, 139, 124}, {195, 154, 221, 54}, {195, 154, 199, 175}, {195, 154, 189, 212}, {195, 154, 180, 96}, {195, 154, 199, 155}, {195, 154, 209, 149}, {195, 154, 222, 168}}},
|
||||
{Country: "France", City: "Roubaix", Hostname: "fr-rbx.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{151, 80, 27, 199}, {51, 255, 71, 16}, {147, 135, 137, 107}}},
|
||||
{Country: "Germany", City: "", Hostname: "de.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{84, 16, 236, 168}, {178, 162, 205, 77}, {178, 162, 205, 115}, {178, 162, 205, 82}, {84, 16, 238, 220}}},
|
||||
{Country: "Germany", City: "Düsseldorf", Hostname: "de-dus.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{146, 0, 42, 77}, {146, 0, 32, 121}, {85, 14, 243, 42}}},
|
||||
{Country: "Greece", City: "", Hostname: "gr.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{154, 57, 3, 36}}},
|
||||
{Country: "Hungary", City: "", Hostname: "hu.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{91, 219, 238, 174}}},
|
||||
{Country: "Iceland", City: "", Hostname: "is.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{37, 235, 49, 75}, {151, 236, 24, 114}, {37, 235, 49, 42}, {37, 235, 49, 244}, {37, 235, 49, 70}, {37, 235, 49, 15}, {151, 236, 24, 142}}},
|
||||
{Country: "India", City: "", Hostname: "in.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{103, 26, 204, 46}, {103, 26, 204, 84}}},
|
||||
{Country: "India", City: "Karnataka", Hostname: "in-ka.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{139, 59, 67, 224}, {139, 59, 65, 136}, {139, 59, 24, 197}, {139, 59, 24, 198}, {139, 59, 24, 199}, {139, 59, 24, 191}, {139, 59, 16, 78}}},
|
||||
{Country: "Ireland", City: "Dublin", Hostname: "ie-dub.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{188, 241, 178, 118}}},
|
||||
{Country: "Isle of Man", City: "", Hostname: "im.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{192, 71, 211, 15}, {37, 235, 55, 62}, {37, 235, 55, 68}, {37, 235, 55, 14}, {37, 235, 55, 45}}},
|
||||
{Country: "Israel", City: "", Hostname: "il.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{193, 182, 144, 170}, {193, 182, 144, 151}, {193, 182, 144, 23}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "it-mil.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{91, 193, 5, 50}}},
|
||||
{Country: "Japan", City: "", Hostname: "jp.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{172, 104, 67, 80}, {172, 104, 75, 121}, {161, 202, 97, 109}, {172, 104, 71, 35}, {172, 104, 126, 64}, {172, 104, 64, 213}, {85, 208, 110, 122}, {172, 104, 78, 67}, {172, 104, 83, 34}, {172, 104, 99, 172}, {161, 202, 97, 101}, {172, 104, 83, 13}, {172, 104, 87, 163}, {172, 104, 99, 14}}},
|
||||
{Country: "Korea", City: "", Hostname: "kr.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{160, 202, 162, 60}, {160, 202, 163, 122}}},
|
||||
{Country: "Kuala Lumpur", City: "", Hostname: "mys.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{111, 90, 141, 34}, {111, 90, 158, 159}}},
|
||||
{Country: "Latvia", City: "", Hostname: "lv.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{195, 123, 213, 172}, {195, 123, 209, 168}}},
|
||||
{Country: "Libya", City: "", Hostname: "ly.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{41, 208, 71, 39}}},
|
||||
{Country: "Lithuania", City: "", Hostname: "lt.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{185, 64, 105, 93}, {185, 64, 104, 142}, {185, 25, 48, 81}}},
|
||||
{Country: "Luxembourg", City: "", Hostname: "lu.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{94, 242, 246, 45}, {94, 242, 246, 46}, {94, 242, 246, 77}, {94, 242, 246, 38}, {94, 242, 246, 47}}},
|
||||
{Country: "Mexico", City: "", Hostname: "mx.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{169, 57, 35, 104}}},
|
||||
{Country: "Moldova", City: "", Hostname: "md.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{185, 163, 46, 141}}},
|
||||
{Country: "Netherlands", City: "", Hostname: "nl.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{190, 2, 132, 115}, {190, 2, 132, 16}, {190, 2, 132, 52}}},
|
||||
{Country: "New Zealand", City: "", Hostname: "nz.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{103, 75, 119, 109}, {103, 75, 119, 107}, {103, 75, 119, 105}, {103, 75, 119, 102}, {103, 75, 119, 103}, {103, 75, 119, 104}, {103, 75, 119, 106}, {103, 75, 119, 108}, {103, 75, 119, 101}, {103, 75, 119, 11}}},
|
||||
{Country: "Norway", City: "", Hostname: "no.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{185, 90, 61, 21}, {185, 90, 61, 74}}},
|
||||
{Country: "Oman", City: "", Hostname: "om.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{185, 226, 124, 110}}},
|
||||
{Country: "Poland", City: "", Hostname: "pl.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{37, 120, 156, 234}}},
|
||||
{Country: "Portugal", City: "", Hostname: "pt.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{185, 31, 159, 110}}},
|
||||
{Country: "Romania", City: "", Hostname: "ro.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{185, 144, 83, 11}, {93, 115, 92, 207}, {185, 144, 83, 13}, {77, 81, 98, 70}, {93, 115, 92, 208}}},
|
||||
{Country: "Serbia", City: "", Hostname: "rs.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{152, 89, 160, 142}}},
|
||||
{Country: "Singapore", City: "", Hostname: "sg-free.vpnunlimitedapp.com", Free: true, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{178, 128, 48, 177}, {188, 166, 177, 236}, {206, 189, 80, 158}, {178, 128, 117, 139}}},
|
||||
{Country: "Singapore", City: "", Hostname: "sg.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{50, 7, 60, 52}, {117, 20, 41, 9}, {117, 20, 41, 10}, {139, 99, 62, 61}}},
|
||||
{Country: "Slovakia", City: "", Hostname: "sk.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{46, 29, 2, 131}}},
|
||||
{Country: "Slovenia", City: "", Hostname: "si.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{192, 71, 244, 38}, {192, 71, 244, 28}}},
|
||||
{Country: "South Africa", City: "", Hostname: "za.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{129, 232, 130, 187}, {129, 232, 219, 196}, {129, 232, 133, 41}, {129, 232, 129, 157}, {129, 232, 219, 195}, {129, 232, 134, 122}, {129, 232, 130, 186}, {129, 232, 130, 179}}},
|
||||
{Country: "Spain", City: "", Hostname: "es.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{194, 99, 104, 58}, {195, 206, 107, 134}}},
|
||||
{Country: "Sweden", City: "", Hostname: "se.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{91, 132, 138, 174}}},
|
||||
{Country: "Switzerland", City: "", Hostname: "ch.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{152, 89, 162, 90}, {152, 89, 162, 86}}},
|
||||
{Country: "Thailand", City: "", Hostname: "th.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{103, 159, 3, 121}}},
|
||||
{Country: "Turkey", City: "", Hostname: "tr.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{185, 17, 115, 62}, {185, 73, 202, 218}}},
|
||||
{Country: "United Arab Emirates", City: "", Hostname: "ae.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{45, 9, 249, 201}, {45, 9, 249, 209}, {45, 9, 250, 147}, {45, 9, 250, 249}, {45, 9, 250, 138}, {45, 9, 249, 211}, {45, 9, 250, 144}, {45, 9, 249, 216}, {45, 9, 250, 145}, {45, 9, 250, 143}, {45, 9, 250, 134}, {45, 9, 250, 146}, {45, 9, 249, 202}}},
|
||||
{Country: "United Kingdom", City: "", Hostname: "uk.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{176, 227, 198, 122}, {77, 245, 65, 2}, {109, 73, 77, 18}, {5, 152, 213, 186}, {88, 150, 224, 74}, {88, 150, 180, 82}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "uk-cv.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{5, 101, 169, 146}, {5, 101, 143, 66}, {178, 159, 10, 78}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "uk-lon.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{78, 110, 160, 6}, {50, 7, 114, 220}, {5, 101, 136, 154}, {23, 106, 33, 89}}},
|
||||
{Country: "United States", City: "", Hostname: "us-stream.vpnunlimitedapp.com", Free: false, Stream: true, TCP: false, UDP: true, IPs: []net.IP{{167, 99, 96, 113}, {198, 199, 114, 155}, {192, 241, 194, 208}, {165, 227, 49, 171}, {159, 89, 128, 183}, {138, 197, 203, 142}, {64, 227, 111, 143}, {143, 110, 225, 79}, {164, 90, 144, 44}, {198, 199, 103, 243}, {198, 199, 96, 52}, {128, 199, 9, 51}, {143, 110, 156, 9}, {178, 128, 79, 75}, {198, 199, 97, 247}, {198, 199, 105, 87}, {198, 199, 103, 88}, {206, 189, 211, 205}, {206, 189, 165, 44}, {161, 35, 236, 242}}},
|
||||
{Country: "United States", City: "", Hostname: "us.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{199, 115, 117, 81}, {199, 115, 115, 139}, {207, 244, 72, 212}, {199, 115, 115, 160}, {199, 115, 117, 73}}},
|
||||
{Country: "United States", City: "Chicago", Hostname: "us-chi.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{66, 23, 205, 226}, {108, 62, 202, 211}, {173, 234, 41, 130}, {174, 34, 184, 130}}},
|
||||
{Country: "United States", City: "Dallas", Hostname: "us-dal.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{172, 241, 115, 99}, {172, 241, 113, 19}, {172, 241, 112, 92}}},
|
||||
{Country: "United States", City: "Denver", Hostname: "us-den.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{23, 237, 26, 131}, {23, 237, 26, 67}}},
|
||||
{Country: "United States", City: "Houston", Hostname: "us-hou.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{162, 218, 228, 194}, {162, 218, 228, 196}, {66, 187, 75, 122}, {162, 218, 229, 106}}},
|
||||
{Country: "United States", City: "Las Vegas", Hostname: "us-lv.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{185, 242, 5, 18}, {185, 242, 5, 22}}},
|
||||
{Country: "United States", City: "Los Angeles", Hostname: "us-la.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{64, 31, 33, 154}, {192, 184, 48, 10}, {23, 83, 37, 209}, {23, 83, 37, 213}, {45, 136, 131, 40}, {69, 162, 99, 70}}},
|
||||
{Country: "United States", City: "Miami", Hostname: "us-mia.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{186, 233, 185, 29}, {186, 233, 185, 79}, {186, 233, 185, 80}, {186, 233, 184, 187}, {186, 233, 184, 188}, {186, 233, 184, 37}, {186, 233, 184, 31}}},
|
||||
{Country: "United States", City: "New York", Hostname: "us-ny-free.vpnunlimitedapp.com", Free: true, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{64, 94, 215, 66}, {64, 94, 215, 162}, {64, 94, 215, 170}}},
|
||||
{Country: "United States", City: "New York", Hostname: "us-ny.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{64, 42, 178, 202}, {23, 105, 134, 162}, {64, 42, 178, 226}, {23, 237, 58, 112}, {23, 108, 31, 122}}},
|
||||
{Country: "United States", City: "Saint Louis", Hostname: "us-sl.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{69, 64, 58, 110}, {69, 64, 58, 255}, {209, 239, 123, 77}, {209, 239, 123, 107}}},
|
||||
{Country: "United States", City: "Salt Lake City", Hostname: "us-slc.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{209, 95, 53, 223}, {209, 95, 53, 225}}},
|
||||
{Country: "United States", City: "San Francisco", Hostname: "us-sf.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{209, 58, 139, 34}, {209, 58, 135, 72}, {209, 58, 130, 210}, {209, 58, 135, 106}, {209, 58, 135, 108}, {209, 58, 135, 74}, {209, 58, 139, 35}, {209, 58, 137, 94}, {172, 241, 251, 164}, {209, 58, 135, 120}}},
|
||||
{Country: "United States", City: "Seattle", Hostname: "us-sea.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{216, 244, 82, 50}, {23, 81, 209, 137}, {216, 244, 82, 210}}},
|
||||
{Country: "Vietnam", City: "", Hostname: "vn.vpnunlimitedapp.com", Free: false, Stream: false, TCP: false, UDP: true, IPs: []net.IP{{103, 9, 78, 84}, {146, 196, 67, 7}}},
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ func VyprvpnRegionChoices() (choices []string) {
|
||||
}
|
||||
|
||||
//nolint:lll
|
||||
// VyprvpnServers returns a slice of all the VyprVPN servers.
|
||||
func VyprvpnServers() []models.VyprvpnServer {
|
||||
return []models.VyprvpnServer{
|
||||
{Region: "Algeria", Hostname: "dz1.vyprvpn.com", TCP: false, UDP: true, IPs: []net.IP{{209, 99, 75, 20}}},
|
||||
|
||||
@@ -40,6 +40,7 @@ func WindscribeHostnameChoices() (choices []string) {
|
||||
}
|
||||
|
||||
//nolint:lll
|
||||
// WindscribeServers returns a slice of all the Windscribe servers.
|
||||
func WindscribeServers() []models.WindscribeServer {
|
||||
return []models.WindscribeServer{
|
||||
{Region: "Albania", City: "Tirana", Hostname: "al-002.whiskergalaxy.com", IPs: []net.IP{{31, 171, 152, 178}, {31, 171, 152, 179}, {31, 171, 152, 180}}},
|
||||
|
||||
@@ -159,6 +159,11 @@ func (l *looper) Run(ctx context.Context, done chan<- struct{}) {
|
||||
stayHere = false
|
||||
case err := <-waitError: // unexpected error
|
||||
unboundCancel()
|
||||
if ctx.Err() != nil {
|
||||
close(waitError)
|
||||
closeStreams()
|
||||
return
|
||||
}
|
||||
l.state.setStatusWithLock(constants.Crashed)
|
||||
const fallback = true
|
||||
l.useUnencryptedDNS(fallback)
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/kyokomi/emoji"
|
||||
"github.com/qdm12/gluetun/internal/constants"
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
)
|
||||
@@ -36,7 +35,7 @@ func title() []string {
|
||||
"=========== For tunneling to ============",
|
||||
"======== your favorite VPN server =======",
|
||||
"=========================================",
|
||||
"=== Made with " + emoji.Sprint(":heart:") + " by github.com/qdm12 ====",
|
||||
"=== Made with ❤️ by github.com/qdm12 ====",
|
||||
"=========================================",
|
||||
}
|
||||
}
|
||||
@@ -49,14 +48,14 @@ func announcement() []string {
|
||||
if time.Now().After(expirationDate) {
|
||||
return nil
|
||||
}
|
||||
return []string{emoji.Sprint(":mega: ") + constants.Announcement}
|
||||
return []string{"📣" + constants.Announcement}
|
||||
}
|
||||
|
||||
func links() []string {
|
||||
return []string{
|
||||
emoji.Sprint(":wrench: ") + "Need help? " + constants.IssueLink,
|
||||
emoji.Sprint(":computer: ") + "Email? quentin.mcgaw@gmail.com",
|
||||
emoji.Sprint(":coffee: ") + "Slack? Join from the Slack button on Github",
|
||||
emoji.Sprint(":money_with_wings: ") + "Help me? https://github.com/sponsors/qdm12",
|
||||
"🔧 Need help? " + constants.IssueLink,
|
||||
"💻 Email? quentin.mcgaw@gmail.com",
|
||||
"☕ Slack? Join from the Slack button on Github",
|
||||
"💰 Help me? https://github.com/sponsors/qdm12",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,20 @@ func (s *HideMyAssServer) String() string {
|
||||
s.Country, s.Region, s.City, s.Hostname, s.TCP, s.UDP, goStringifyIPs(s.IPs))
|
||||
}
|
||||
|
||||
type IpvanishServer struct {
|
||||
Country string `json:"country"`
|
||||
City string `json:"city"`
|
||||
Hostname string `json:"hostname"`
|
||||
TCP bool `json:"tcp"`
|
||||
UDP bool `json:"udp"`
|
||||
IPs []net.IP `json:"ips"`
|
||||
}
|
||||
|
||||
func (s *IpvanishServer) String() string {
|
||||
return fmt.Sprintf("{Country: %q, City: %q, Hostname: %q, TCP: %t, UDP: %t, IPs: %s}",
|
||||
s.Country, s.City, s.Hostname, s.TCP, s.UDP, goStringifyIPs(s.IPs))
|
||||
}
|
||||
|
||||
type IvpnServer struct {
|
||||
Country string `json:"country"`
|
||||
City string `json:"city"`
|
||||
@@ -188,6 +202,22 @@ func (s *TorguardServer) String() string {
|
||||
s.Country, s.City, s.Hostname, s.TCP, s.UDP, goStringifyIPs(s.IPs))
|
||||
}
|
||||
|
||||
type VPNUnlimitedServer struct {
|
||||
Country string `json:"country"`
|
||||
City string `json:"city"`
|
||||
Hostname string `json:"hostname"`
|
||||
Free bool `json:"free"`
|
||||
Stream bool `json:"stream"`
|
||||
TCP bool `json:"tcp"`
|
||||
UDP bool `json:"udp"`
|
||||
IPs []net.IP `json:"ips"`
|
||||
}
|
||||
|
||||
func (s *VPNUnlimitedServer) String() string {
|
||||
return fmt.Sprintf("{Country: %q, City: %q, Hostname: %q, Free: %t, Stream: %t, TCP: %t, UDP: %t, IPs: %s}",
|
||||
s.Country, s.City, s.Hostname, s.Free, s.Stream, s.TCP, s.UDP, goStringifyIPs(s.IPs))
|
||||
}
|
||||
|
||||
type VyprvpnServer struct {
|
||||
Region string `json:"region"`
|
||||
Hostname string `json:"hostname"`
|
||||
|
||||
@@ -1,28 +1,31 @@
|
||||
package models
|
||||
|
||||
type AllServers struct {
|
||||
Version uint16 `json:"version"`
|
||||
Cyberghost CyberghostServers `json:"cyberghost"`
|
||||
Fastestvpn FastestvpnServers `json:"fastestvpn"`
|
||||
HideMyAss HideMyAssServers `json:"hidemyass"`
|
||||
Ivpn IvpnServers `json:"ivpn"`
|
||||
Mullvad MullvadServers `json:"mullvad"`
|
||||
Nordvpn NordvpnServers `json:"nordvpn"`
|
||||
Privado PrivadoServers `json:"privado"`
|
||||
Pia PiaServers `json:"pia"`
|
||||
Privatevpn PrivatevpnServers `json:"privatevpn"`
|
||||
Protonvpn ProtonvpnServers `json:"protonvpn"`
|
||||
Purevpn PurevpnServers `json:"purevpn"`
|
||||
Surfshark SurfsharkServers `json:"surfshark"`
|
||||
Torguard TorguardServers `json:"torguard"`
|
||||
Vyprvpn VyprvpnServers `json:"vyprvpn"`
|
||||
Windscribe WindscribeServers `json:"windscribe"`
|
||||
Version uint16 `json:"version"`
|
||||
Cyberghost CyberghostServers `json:"cyberghost"`
|
||||
Fastestvpn FastestvpnServers `json:"fastestvpn"`
|
||||
HideMyAss HideMyAssServers `json:"hidemyass"`
|
||||
Ipvanish IpvanishServers `json:"ipvanish"`
|
||||
Ivpn IvpnServers `json:"ivpn"`
|
||||
Mullvad MullvadServers `json:"mullvad"`
|
||||
Nordvpn NordvpnServers `json:"nordvpn"`
|
||||
Privado PrivadoServers `json:"privado"`
|
||||
Pia PiaServers `json:"pia"`
|
||||
Privatevpn PrivatevpnServers `json:"privatevpn"`
|
||||
Protonvpn ProtonvpnServers `json:"protonvpn"`
|
||||
Purevpn PurevpnServers `json:"purevpn"`
|
||||
Surfshark SurfsharkServers `json:"surfshark"`
|
||||
Torguard TorguardServers `json:"torguard"`
|
||||
VPNUnlimited VPNUnlimitedServers `json:"vpnunlimited"`
|
||||
Vyprvpn VyprvpnServers `json:"vyprvpn"`
|
||||
Windscribe WindscribeServers `json:"windscribe"`
|
||||
}
|
||||
|
||||
func (a *AllServers) Count() int {
|
||||
return len(a.Cyberghost.Servers) +
|
||||
len(a.Fastestvpn.Servers) +
|
||||
len(a.HideMyAss.Servers) +
|
||||
len(a.Ipvanish.Servers) +
|
||||
len(a.Ivpn.Servers) +
|
||||
len(a.Mullvad.Servers) +
|
||||
len(a.Nordvpn.Servers) +
|
||||
@@ -33,6 +36,7 @@ func (a *AllServers) Count() int {
|
||||
len(a.Purevpn.Servers) +
|
||||
len(a.Surfshark.Servers) +
|
||||
len(a.Torguard.Servers) +
|
||||
len(a.VPNUnlimited.Servers) +
|
||||
len(a.Vyprvpn.Servers) +
|
||||
len(a.Windscribe.Servers)
|
||||
}
|
||||
@@ -52,6 +56,11 @@ type HideMyAssServers struct {
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
Servers []HideMyAssServer `json:"servers"`
|
||||
}
|
||||
type IpvanishServers struct {
|
||||
Version uint16 `json:"version"`
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
Servers []IpvanishServer `json:"servers"`
|
||||
}
|
||||
type IvpnServers struct {
|
||||
Version uint16 `json:"version"`
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
@@ -102,6 +111,11 @@ type TorguardServers struct {
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
Servers []TorguardServer `json:"servers"`
|
||||
}
|
||||
type VPNUnlimitedServers struct {
|
||||
Version uint16 `json:"version"`
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
Servers []VPNUnlimitedServer `json:"servers"`
|
||||
}
|
||||
type VyprvpnServers struct {
|
||||
Version uint16 `json:"version"`
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/qdm12/gluetun/internal/configuration"
|
||||
"github.com/qdm12/gluetun/internal/constants"
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
"github.com/qdm12/gluetun/internal/provider/utils"
|
||||
"github.com/qdm12/golibs/os"
|
||||
)
|
||||
|
||||
@@ -64,6 +65,7 @@ func modifyCustomConfig(lines []string, username string,
|
||||
strings.HasPrefix(line, "verb "),
|
||||
strings.HasPrefix(line, "auth-user-pass "),
|
||||
len(settings.Cipher) > 0 && strings.HasPrefix(line, "cipher "),
|
||||
len(settings.Cipher) > 0 && strings.HasPrefix(line, "data-ciphers"),
|
||||
len(settings.Auth) > 0 && strings.HasPrefix(line, "auth "),
|
||||
settings.MSSFix > 0 && strings.HasPrefix(line, "mssfix "),
|
||||
!settings.Provider.ExtraConfigOptions.OpenVPNIPv6 && strings.HasPrefix(line, "tun-ipv6"):
|
||||
@@ -78,10 +80,12 @@ func modifyCustomConfig(lines []string, username string,
|
||||
modified = append(modified, "pull-filter ignore \"auth-token\"") // prevent auth failed loop
|
||||
modified = append(modified, "auth-retry nointeract")
|
||||
modified = append(modified, "suppress-timestamps")
|
||||
modified = append(modified, "auth-user-pass "+constants.OpenVPNAuthConf)
|
||||
if settings.User != "" {
|
||||
modified = append(modified, "auth-user-pass "+constants.OpenVPNAuthConf)
|
||||
}
|
||||
modified = append(modified, "verb "+strconv.Itoa(settings.Verbosity))
|
||||
if len(settings.Cipher) > 0 {
|
||||
modified = append(modified, "cipher "+settings.Cipher)
|
||||
modified = append(modified, utils.CipherLines(settings.Cipher, settings.Version)...)
|
||||
}
|
||||
if len(settings.Auth) > 0 {
|
||||
modified = append(modified, "auth "+settings.Auth)
|
||||
@@ -193,10 +197,10 @@ func setConnectionToLines(lines []string, connection models.OpenVPNConnection) (
|
||||
for i, line := range lines {
|
||||
switch {
|
||||
case strings.HasPrefix(line, "proto "):
|
||||
lines[i] = "proto " + connection.Protocol
|
||||
lines[i] = connection.ProtoLine()
|
||||
|
||||
case strings.HasPrefix(line, "remote "):
|
||||
lines[i] = "remote " + connection.RemoteLine()
|
||||
lines[i] = connection.RemoteLine()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -143,10 +143,12 @@ func (l *looper) Run(ctx context.Context, done chan<- struct{}) { //nolint:gocog
|
||||
continue
|
||||
}
|
||||
|
||||
if err := l.conf.WriteAuthFile(settings.User, settings.Password, l.puid, l.pgid); err != nil {
|
||||
l.signalCrashedStatus()
|
||||
l.logAndWait(ctx, err)
|
||||
continue
|
||||
if settings.User != "" {
|
||||
if err := l.conf.WriteAuthFile(settings.User, settings.Password, l.puid, l.pgid); err != nil {
|
||||
l.signalCrashedStatus()
|
||||
l.logAndWait(ctx, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if err := l.fw.SetVPNConnection(ctx, connection); err != nil {
|
||||
@@ -211,6 +213,14 @@ func (l *looper) Run(ctx context.Context, done chan<- struct{}) { //nolint:gocog
|
||||
stayHere = false
|
||||
case err := <-waitError: // unexpected error
|
||||
openvpnCancel()
|
||||
if ctx.Err() != nil {
|
||||
close(waitError)
|
||||
close(stdoutLines)
|
||||
close(stderrLines)
|
||||
<-lineCollectionDone
|
||||
<-portForwardDone
|
||||
return
|
||||
}
|
||||
l.state.setStatusWithLock(constants.Crashed)
|
||||
l.logAndWait(ctx, err)
|
||||
l.crashed = true
|
||||
@@ -317,8 +327,5 @@ func writeOpenvpnConf(lines []string, openFile os.OpenFileFunc) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := file.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return file.Close()
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ func (c *configurator) CheckTUN() error {
|
||||
|
||||
func (c *configurator) CreateTUN() error {
|
||||
c.logger.Info("creating %s", constants.TunnelDevice)
|
||||
if err := c.os.MkdirAll("/dev/net", 0751); err != nil {
|
||||
if err := c.os.MkdirAll("/dev/net", 0751); err != nil { //nolint:gomnd
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ func (c *configurator) CreateTUN() error {
|
||||
return err
|
||||
}
|
||||
|
||||
file, err := c.os.OpenFile(constants.TunnelDevice, os.O_WRONLY, 0666)
|
||||
file, err := c.os.OpenFile(constants.TunnelDevice, os.O_WRONLY, 0666) //nolint:gomnd
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
45
internal/provider/ipvanish/connection.go
Normal file
45
internal/provider/ipvanish/connection.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package ipvanish
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/configuration"
|
||||
"github.com/qdm12/gluetun/internal/constants"
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
"github.com/qdm12/gluetun/internal/provider/utils"
|
||||
)
|
||||
|
||||
var ErrProtocolUnsupported = errors.New("network protocol is not supported")
|
||||
|
||||
func (i *Ipvanish) GetOpenVPNConnection(selection configuration.ServerSelection) (
|
||||
connection models.OpenVPNConnection, err error) {
|
||||
const port = 443
|
||||
const protocol = constants.UDP
|
||||
if selection.TCP {
|
||||
return connection, ErrProtocolUnsupported
|
||||
}
|
||||
|
||||
servers, err := i.filterServers(selection)
|
||||
if err != nil {
|
||||
return connection, err
|
||||
}
|
||||
|
||||
var connections []models.OpenVPNConnection
|
||||
for _, server := range servers {
|
||||
for _, IP := range server.IPs {
|
||||
connection := models.OpenVPNConnection{
|
||||
IP: IP,
|
||||
Port: port,
|
||||
Protocol: protocol,
|
||||
Hostname: server.Hostname,
|
||||
}
|
||||
connections = append(connections, connection)
|
||||
}
|
||||
}
|
||||
|
||||
if selection.TargetIP != nil {
|
||||
return utils.GetTargetIPConnection(connections, selection.TargetIP)
|
||||
}
|
||||
|
||||
return utils.PickRandomConnection(connections, i.randSource), nil
|
||||
}
|
||||
29
internal/provider/ipvanish/filter.go
Normal file
29
internal/provider/ipvanish/filter.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package ipvanish
|
||||
|
||||
import (
|
||||
"github.com/qdm12/gluetun/internal/configuration"
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
"github.com/qdm12/gluetun/internal/provider/utils"
|
||||
)
|
||||
|
||||
func (i *Ipvanish) filterServers(selection configuration.ServerSelection) (
|
||||
servers []models.IpvanishServer, err error) {
|
||||
for _, server := range i.servers {
|
||||
switch {
|
||||
case
|
||||
utils.FilterByPossibilities(server.Country, selection.Countries),
|
||||
utils.FilterByPossibilities(server.City, selection.Cities),
|
||||
utils.FilterByPossibilities(server.Hostname, selection.Hostnames),
|
||||
selection.TCP && !server.TCP,
|
||||
!selection.TCP && !server.UDP:
|
||||
default:
|
||||
servers = append(servers, server)
|
||||
}
|
||||
}
|
||||
|
||||
if len(servers) == 0 {
|
||||
return nil, utils.NoServerFoundError(selection)
|
||||
}
|
||||
|
||||
return servers, nil
|
||||
}
|
||||
65
internal/provider/ipvanish/openvpnconf.go
Normal file
65
internal/provider/ipvanish/openvpnconf.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package ipvanish
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/configuration"
|
||||
"github.com/qdm12/gluetun/internal/constants"
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
"github.com/qdm12/gluetun/internal/provider/utils"
|
||||
)
|
||||
|
||||
func (i *Ipvanish) BuildConf(connection models.OpenVPNConnection,
|
||||
username string, settings configuration.OpenVPN) (lines []string) {
|
||||
if settings.Cipher == "" {
|
||||
settings.Cipher = constants.AES256cbc
|
||||
}
|
||||
if settings.Auth == "" {
|
||||
settings.Auth = constants.SHA256
|
||||
}
|
||||
|
||||
lines = []string{
|
||||
"client",
|
||||
"dev tun",
|
||||
"nobind",
|
||||
"persist-key",
|
||||
"ping-timer-rem",
|
||||
"tls-exit",
|
||||
|
||||
// Ipvanish specific
|
||||
"comp-lzo",
|
||||
"tls-cipher TLS-DHE-RSA-WITH-AES-256-CBC-SHA:TLS-DHE-DSS-WITH-AES-256-CBC-SHA:TLS-RSA-WITH-AES-256-CBC-SHA",
|
||||
"keysize 256",
|
||||
|
||||
// Added constant values
|
||||
"mute-replay-warnings",
|
||||
"auth-nocache",
|
||||
"pull-filter ignore \"auth-token\"", // prevent auth failed loops
|
||||
"auth-retry nointeract",
|
||||
"suppress-timestamps",
|
||||
|
||||
// Modified variables
|
||||
"verb " + strconv.Itoa(settings.Verbosity),
|
||||
"auth-user-pass " + constants.OpenVPNAuthConf,
|
||||
"proto " + connection.Protocol,
|
||||
connection.RemoteLine(),
|
||||
"verify-x509-name " + connection.Hostname, // + " name"
|
||||
"auth " + settings.Auth,
|
||||
}
|
||||
|
||||
lines = append(lines, utils.CipherLines(settings.Cipher, settings.Version)...)
|
||||
|
||||
if settings.MSSFix > 0 {
|
||||
lines = append(lines, "mssfix "+strconv.Itoa(int(settings.MSSFix)))
|
||||
}
|
||||
|
||||
if !settings.Root {
|
||||
lines = append(lines, "user "+username)
|
||||
}
|
||||
|
||||
lines = append(lines, utils.WrapOpenvpnCA(constants.IpvanishCA)...)
|
||||
|
||||
lines = append(lines, "")
|
||||
|
||||
return lines
|
||||
}
|
||||
17
internal/provider/ipvanish/portforward.go
Normal file
17
internal/provider/ipvanish/portforward.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package ipvanish
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/firewall"
|
||||
"github.com/qdm12/golibs/logging"
|
||||
"github.com/qdm12/golibs/os"
|
||||
)
|
||||
|
||||
func (i *Ipvanish) PortForward(ctx context.Context, client *http.Client,
|
||||
openFile os.OpenFileFunc, pfLogger logging.Logger, gateway net.IP,
|
||||
fw firewall.Configurator, syncState func(port uint16) (pfFilepath string)) {
|
||||
panic("port forwarding is not supported for Ipvanish")
|
||||
}
|
||||
19
internal/provider/ipvanish/provider.go
Normal file
19
internal/provider/ipvanish/provider.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package ipvanish
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
)
|
||||
|
||||
type Ipvanish struct {
|
||||
servers []models.IpvanishServer
|
||||
randSource rand.Source
|
||||
}
|
||||
|
||||
func New(servers []models.IpvanishServer, randSource rand.Source) *Ipvanish {
|
||||
return &Ipvanish{
|
||||
servers: servers,
|
||||
randSource: randSource,
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package ivpn
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/configuration"
|
||||
"github.com/qdm12/gluetun/internal/constants"
|
||||
@@ -15,6 +16,8 @@ func (i *Ivpn) BuildConf(connection models.OpenVPNConnection,
|
||||
settings.Cipher = constants.AES256cbc
|
||||
}
|
||||
|
||||
namePrefix := strings.Split(connection.Hostname, ".")[0]
|
||||
|
||||
lines = []string{
|
||||
"client",
|
||||
"dev tun",
|
||||
@@ -43,7 +46,7 @@ func (i *Ivpn) BuildConf(connection models.OpenVPNConnection,
|
||||
"auth-user-pass " + constants.OpenVPNAuthConf,
|
||||
"proto " + connection.Protocol,
|
||||
connection.RemoteLine(),
|
||||
"verify-x509-name " + connection.Hostname, // + " name-prefix"
|
||||
"verify-x509-name " + namePrefix + " name-prefix",
|
||||
}
|
||||
|
||||
lines = append(lines, utils.CipherLines(settings.Cipher, settings.Version)...)
|
||||
|
||||
@@ -2,7 +2,6 @@ package privateinternetaccess
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/configuration"
|
||||
"github.com/qdm12/gluetun/internal/constants"
|
||||
@@ -25,8 +24,8 @@ func (p *PIA) BuildConf(connection models.OpenVPNConnection,
|
||||
X509CRL = constants.PiaX509CRLStrong
|
||||
certificate = constants.PIACertificateStrong
|
||||
default: // no encryption preset
|
||||
defaultCipher = ""
|
||||
defaultAuth = ""
|
||||
defaultCipher = "none"
|
||||
defaultAuth = "none"
|
||||
X509CRL = constants.PiaX509CRLNormal
|
||||
certificate = constants.PIACertificateNormal
|
||||
}
|
||||
@@ -49,7 +48,8 @@ func (p *PIA) BuildConf(connection models.OpenVPNConnection,
|
||||
// PIA specific
|
||||
"reneg-sec 0",
|
||||
"disable-occ",
|
||||
"compress", // allow PIA server to choose the compression to use
|
||||
"compress", // allow PIA server to choose the compression to use
|
||||
"ncp-disable", // prevent from auto-upgrading cipher to aes-256-gcm
|
||||
|
||||
// Added constant values
|
||||
"auth-nocache",
|
||||
@@ -73,10 +73,6 @@ func (p *PIA) BuildConf(connection models.OpenVPNConnection,
|
||||
lines = append(lines, "auth "+settings.Auth)
|
||||
}
|
||||
|
||||
if strings.HasSuffix(settings.Cipher, "-gcm") {
|
||||
lines = append(lines, "ncp-disable")
|
||||
}
|
||||
|
||||
if !settings.Root {
|
||||
lines = append(lines, "user "+username)
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ var (
|
||||
ErrBindPort = errors.New("cannot bind port")
|
||||
)
|
||||
|
||||
// PortForward obtains a VPN server side port forwarded from PIA.
|
||||
//nolint:gocognit
|
||||
func (p *PIA) PortForward(ctx context.Context, client *http.Client,
|
||||
openFile os.OpenFileFunc, logger logging.Logger, gateway net.IP, fw firewall.Configurator,
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"github.com/qdm12/gluetun/internal/provider/cyberghost"
|
||||
"github.com/qdm12/gluetun/internal/provider/fastestvpn"
|
||||
"github.com/qdm12/gluetun/internal/provider/hidemyass"
|
||||
"github.com/qdm12/gluetun/internal/provider/ipvanish"
|
||||
"github.com/qdm12/gluetun/internal/provider/ivpn"
|
||||
"github.com/qdm12/gluetun/internal/provider/mullvad"
|
||||
"github.com/qdm12/gluetun/internal/provider/nordvpn"
|
||||
@@ -25,6 +26,7 @@ import (
|
||||
"github.com/qdm12/gluetun/internal/provider/purevpn"
|
||||
"github.com/qdm12/gluetun/internal/provider/surfshark"
|
||||
"github.com/qdm12/gluetun/internal/provider/torguard"
|
||||
"github.com/qdm12/gluetun/internal/provider/vpnunlimited"
|
||||
"github.com/qdm12/gluetun/internal/provider/vyprvpn"
|
||||
"github.com/qdm12/gluetun/internal/provider/windscribe"
|
||||
"github.com/qdm12/golibs/logging"
|
||||
@@ -49,6 +51,8 @@ func New(provider string, allServers models.AllServers, timeNow func() time.Time
|
||||
return fastestvpn.New(allServers.Fastestvpn.Servers, randSource)
|
||||
case constants.HideMyAss:
|
||||
return hidemyass.New(allServers.HideMyAss.Servers, randSource)
|
||||
case constants.Ipvanish:
|
||||
return ipvanish.New(allServers.Ipvanish.Servers, randSource)
|
||||
case constants.Ivpn:
|
||||
return ivpn.New(allServers.Ivpn.Servers, randSource)
|
||||
case constants.Mullvad:
|
||||
@@ -69,6 +73,8 @@ func New(provider string, allServers models.AllServers, timeNow func() time.Time
|
||||
return surfshark.New(allServers.Surfshark.Servers, randSource)
|
||||
case constants.Torguard:
|
||||
return torguard.New(allServers.Torguard.Servers, randSource)
|
||||
case constants.VPNUnlimited:
|
||||
return vpnunlimited.New(allServers.VPNUnlimited.Servers, randSource)
|
||||
case constants.Vyprvpn:
|
||||
return vyprvpn.New(allServers.Vyprvpn.Servers, randSource)
|
||||
case constants.Windscribe:
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
func (p *Purevpn) BuildConf(connection models.OpenVPNConnection,
|
||||
username string, settings configuration.OpenVPN) (lines []string) {
|
||||
if settings.Cipher == "" {
|
||||
settings.Cipher = constants.AES256cbc
|
||||
settings.Cipher = constants.AES256gcm
|
||||
}
|
||||
|
||||
lines = []string{
|
||||
|
||||
44
internal/provider/vpnunlimited/connection.go
Normal file
44
internal/provider/vpnunlimited/connection.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package vpnunlimited
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/configuration"
|
||||
"github.com/qdm12/gluetun/internal/constants"
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
"github.com/qdm12/gluetun/internal/provider/utils"
|
||||
)
|
||||
|
||||
var ErrProtocolUnsupported = errors.New("network protocol is not supported")
|
||||
|
||||
func (p *Provider) GetOpenVPNConnection(selection configuration.ServerSelection) (
|
||||
connection models.OpenVPNConnection, err error) {
|
||||
const port = 1194
|
||||
const protocol = constants.UDP
|
||||
if selection.TCP {
|
||||
return connection, ErrProtocolUnsupported
|
||||
}
|
||||
|
||||
servers, err := p.filterServers(selection)
|
||||
if err != nil {
|
||||
return connection, err
|
||||
}
|
||||
|
||||
var connections []models.OpenVPNConnection
|
||||
for _, server := range servers {
|
||||
for _, IP := range server.IPs {
|
||||
connection := models.OpenVPNConnection{
|
||||
IP: IP,
|
||||
Port: port,
|
||||
Protocol: protocol,
|
||||
}
|
||||
connections = append(connections, connection)
|
||||
}
|
||||
}
|
||||
|
||||
if selection.TargetIP != nil {
|
||||
return utils.GetTargetIPConnection(connections, selection.TargetIP)
|
||||
}
|
||||
|
||||
return utils.PickRandomConnection(connections, p.randSource), nil
|
||||
}
|
||||
31
internal/provider/vpnunlimited/filter.go
Normal file
31
internal/provider/vpnunlimited/filter.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package vpnunlimited
|
||||
|
||||
import (
|
||||
"github.com/qdm12/gluetun/internal/configuration"
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
"github.com/qdm12/gluetun/internal/provider/utils"
|
||||
)
|
||||
|
||||
func (p *Provider) filterServers(selection configuration.ServerSelection) (
|
||||
servers []models.VPNUnlimitedServer, err error) {
|
||||
for _, server := range p.servers {
|
||||
switch {
|
||||
case
|
||||
utils.FilterByPossibilities(server.Country, selection.Countries),
|
||||
utils.FilterByPossibilities(server.City, selection.Cities),
|
||||
utils.FilterByPossibilities(server.Hostname, selection.Hostnames),
|
||||
selection.FreeOnly && !server.Free,
|
||||
selection.StreamOnly && !server.Stream,
|
||||
selection.TCP && !server.TCP,
|
||||
!selection.TCP && !server.UDP:
|
||||
default:
|
||||
servers = append(servers, server)
|
||||
}
|
||||
}
|
||||
|
||||
if len(servers) == 0 {
|
||||
return nil, utils.NoServerFoundError(selection)
|
||||
}
|
||||
|
||||
return servers, nil
|
||||
}
|
||||
69
internal/provider/vpnunlimited/openvpnconf.go
Normal file
69
internal/provider/vpnunlimited/openvpnconf.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package vpnunlimited
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/configuration"
|
||||
"github.com/qdm12/gluetun/internal/constants"
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
"github.com/qdm12/gluetun/internal/provider/utils"
|
||||
)
|
||||
|
||||
func (p *Provider) BuildConf(connection models.OpenVPNConnection,
|
||||
username string, settings configuration.OpenVPN) (lines []string) {
|
||||
lines = []string{
|
||||
"client",
|
||||
"dev tun",
|
||||
"nobind",
|
||||
"persist-key",
|
||||
"tls-exit",
|
||||
"remote-cert-tls server",
|
||||
|
||||
// VPNUnlimited specific
|
||||
"reneg-sec 0",
|
||||
"ping 5",
|
||||
"ping-exit 30",
|
||||
"comp-lzo no",
|
||||
"route-metric 1",
|
||||
|
||||
// Added constant values
|
||||
"auth-nocache",
|
||||
"mute-replay-warnings",
|
||||
"pull-filter ignore \"auth-token\"", // prevent auth failed loops
|
||||
"auth-retry nointeract",
|
||||
"suppress-timestamps",
|
||||
|
||||
// Modified variables
|
||||
"verb " + strconv.Itoa(settings.Verbosity),
|
||||
// "auth-user-pass " + constants.OpenVPNAuthConf,
|
||||
connection.ProtoLine(),
|
||||
connection.RemoteLine(),
|
||||
}
|
||||
|
||||
if settings.Cipher != "" {
|
||||
lines = append(lines, utils.CipherLines(settings.Cipher, settings.Version)...)
|
||||
}
|
||||
|
||||
if settings.Auth != "" {
|
||||
lines = append(lines, "auth "+settings.Auth)
|
||||
}
|
||||
|
||||
if settings.MSSFix > 0 {
|
||||
lines = append(lines, "mssfix "+strconv.Itoa(int(settings.MSSFix)))
|
||||
}
|
||||
|
||||
if !settings.Root {
|
||||
lines = append(lines, "user "+username)
|
||||
}
|
||||
|
||||
lines = append(lines, utils.WrapOpenvpnCA(
|
||||
constants.VPNUnlimitedCertificateAuthority)...)
|
||||
lines = append(lines, utils.WrapOpenvpnCert(
|
||||
settings.Provider.ExtraConfigOptions.ClientCertificate)...)
|
||||
lines = append(lines, utils.WrapOpenvpnKey(
|
||||
settings.Provider.ExtraConfigOptions.ClientKey)...)
|
||||
|
||||
lines = append(lines, "")
|
||||
|
||||
return lines
|
||||
}
|
||||
17
internal/provider/vpnunlimited/portforward.go
Normal file
17
internal/provider/vpnunlimited/portforward.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package vpnunlimited
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/firewall"
|
||||
"github.com/qdm12/golibs/logging"
|
||||
"github.com/qdm12/golibs/os"
|
||||
)
|
||||
|
||||
func (p *Provider) PortForward(ctx context.Context, client *http.Client,
|
||||
openFile os.OpenFileFunc, pfLogger logging.Logger, gateway net.IP,
|
||||
fw firewall.Configurator, syncState func(port uint16) (pfFilepath string)) {
|
||||
panic("port forwarding is not supported for VPN Unlimited")
|
||||
}
|
||||
19
internal/provider/vpnunlimited/provider.go
Normal file
19
internal/provider/vpnunlimited/provider.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package vpnunlimited
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
)
|
||||
|
||||
type Provider struct {
|
||||
servers []models.VPNUnlimitedServer
|
||||
randSource rand.Source
|
||||
}
|
||||
|
||||
func New(servers []models.VPNUnlimitedServer, randSource rand.Source) *Provider {
|
||||
return &Provider{
|
||||
servers: servers,
|
||||
randSource: randSource,
|
||||
}
|
||||
}
|
||||
@@ -31,11 +31,7 @@ func (r *routing) setOutboundRoutes(outboundSubnets []net.IPNet,
|
||||
}
|
||||
|
||||
r.removeOutboundSubnets(subnetsToRemove, defaultInterfaceName, defaultGateway)
|
||||
if err := r.addOutboundSubnets(subnetsToAdd, defaultInterfaceName, defaultGateway); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return r.addOutboundSubnets(subnetsToAdd, defaultInterfaceName, defaultGateway)
|
||||
}
|
||||
|
||||
func (r *routing) removeOutboundSubnets(subnets []net.IPNet,
|
||||
|
||||
@@ -139,6 +139,9 @@ func (l *looper) Run(ctx context.Context, done chan<- struct{}) {
|
||||
case err := <-waitError: // unexpected error
|
||||
shadowsocksCancel()
|
||||
close(waitError)
|
||||
if ctx.Err() != nil {
|
||||
return
|
||||
}
|
||||
l.state.setStatusWithLock(constants.Crashed)
|
||||
l.logAndWait(ctx, err)
|
||||
crashed = true
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
package shutdown
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/qdm12/golibs/logging"
|
||||
)
|
||||
|
||||
type Order interface {
|
||||
Append(waves ...Wave)
|
||||
Shutdown(timeout time.Duration, logger logging.Logger) (err error)
|
||||
}
|
||||
|
||||
type order struct {
|
||||
waves []Wave
|
||||
}
|
||||
|
||||
func NewOrder() Order {
|
||||
return &order{}
|
||||
}
|
||||
|
||||
var ErrIncomplete = errors.New("one or more routines did not terminate gracefully")
|
||||
|
||||
func (o *order) Append(waves ...Wave) {
|
||||
o.waves = append(o.waves, waves...)
|
||||
}
|
||||
|
||||
func (o *order) Shutdown(timeout time.Duration, logger logging.Logger) (err error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
|
||||
total := 0
|
||||
incomplete := 0
|
||||
|
||||
for _, wave := range o.waves {
|
||||
total += wave.size()
|
||||
incomplete += wave.shutdown(ctx, logger)
|
||||
}
|
||||
|
||||
if incomplete == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("%w: %d not terminated on %d routines",
|
||||
ErrIncomplete, incomplete, total)
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package shutdown
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type routine struct {
|
||||
name string
|
||||
cancel context.CancelFunc
|
||||
done <-chan struct{}
|
||||
timeout time.Duration
|
||||
}
|
||||
|
||||
func (r *routine) shutdown(ctx context.Context) (err error) {
|
||||
ctx, cancel := context.WithTimeout(ctx, r.timeout)
|
||||
defer cancel()
|
||||
|
||||
r.cancel()
|
||||
|
||||
select {
|
||||
case <-r.done:
|
||||
return nil
|
||||
case <-ctx.Done():
|
||||
return fmt.Errorf("for routine %q: %w", r.name, ctx.Err())
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
package shutdown
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/qdm12/golibs/logging"
|
||||
)
|
||||
|
||||
type Wave interface {
|
||||
Add(name string, timeout time.Duration) (
|
||||
ctx context.Context, done chan struct{})
|
||||
size() int
|
||||
shutdown(ctx context.Context, logger logging.Logger) (incomplete int)
|
||||
}
|
||||
|
||||
type wave struct {
|
||||
name string
|
||||
routines []routine
|
||||
}
|
||||
|
||||
func NewWave(name string) Wave {
|
||||
return &wave{
|
||||
name: name,
|
||||
}
|
||||
}
|
||||
|
||||
func (w *wave) Add(name string, timeout time.Duration) (ctx context.Context, done chan struct{}) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
done = make(chan struct{})
|
||||
routine := routine{
|
||||
name: name,
|
||||
cancel: cancel,
|
||||
done: done,
|
||||
timeout: timeout,
|
||||
}
|
||||
w.routines = append(w.routines, routine)
|
||||
return ctx, done
|
||||
}
|
||||
|
||||
func (w *wave) size() int { return len(w.routines) }
|
||||
|
||||
func (w *wave) shutdown(ctx context.Context, logger logging.Logger) (incomplete int) {
|
||||
completed := make(chan bool)
|
||||
|
||||
for _, r := range w.routines {
|
||||
go func(r routine) {
|
||||
if err := r.shutdown(ctx); err != nil {
|
||||
logger.Warn(w.name + " routines: " + err.Error() + " ⚠️")
|
||||
completed <- false
|
||||
} else {
|
||||
logger.Info(w.name + " routines: " + r.name + " terminated ✔️")
|
||||
completed <- err == nil
|
||||
}
|
||||
}(r)
|
||||
}
|
||||
|
||||
for range w.routines {
|
||||
c := <-completed
|
||||
if !c {
|
||||
incomplete++
|
||||
}
|
||||
}
|
||||
|
||||
return incomplete
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/constants"
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
)
|
||||
|
||||
@@ -31,22 +32,24 @@ 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),
|
||||
Fastestvpn: s.mergeFastestvpn(hardcoded.Fastestvpn, persisted.Fastestvpn),
|
||||
HideMyAss: s.mergeHideMyAss(hardcoded.HideMyAss, persisted.HideMyAss),
|
||||
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),
|
||||
Vyprvpn: s.mergeVyprvpn(hardcoded.Vyprvpn, persisted.Vyprvpn),
|
||||
Windscribe: s.mergeWindscribe(hardcoded.Windscribe, persisted.Windscribe),
|
||||
Version: hardcoded.Version,
|
||||
Cyberghost: s.mergeCyberghost(hardcoded.Cyberghost, persisted.Cyberghost),
|
||||
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),
|
||||
Windscribe: s.mergeWindscribe(hardcoded.Windscribe, persisted.Windscribe),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +94,19 @@ func (s *storage) mergeHideMyAss(hardcoded, persisted models.HideMyAssServers) m
|
||||
return persisted
|
||||
}
|
||||
|
||||
func (s *storage) mergeIpvanish(hardcoded, persisted models.IpvanishServers) models.IpvanishServers {
|
||||
if persisted.Timestamp <= hardcoded.Timestamp {
|
||||
return hardcoded
|
||||
}
|
||||
versionDiff := hardcoded.Version - persisted.Version
|
||||
if versionDiff > 0 {
|
||||
s.logVersionDiff("Ipvanish", versionDiff)
|
||||
return hardcoded
|
||||
}
|
||||
s.logTimeDiff("Ipvanish", persisted.Timestamp, hardcoded.Timestamp)
|
||||
return persisted
|
||||
}
|
||||
|
||||
func (s *storage) mergeIvpn(hardcoded, persisted models.IvpnServers) models.IvpnServers {
|
||||
if persisted.Timestamp <= hardcoded.Timestamp {
|
||||
return hardcoded
|
||||
@@ -234,6 +250,20 @@ func (s *storage) mergeTorguard(hardcoded, persisted models.TorguardServers) mod
|
||||
return persisted
|
||||
}
|
||||
|
||||
func (s *storage) mergeVPNUnlimited(hardcoded, persisted models.VPNUnlimitedServers) models.VPNUnlimitedServers {
|
||||
if persisted.Timestamp <= hardcoded.Timestamp {
|
||||
return hardcoded
|
||||
}
|
||||
versionDiff := hardcoded.Version - persisted.Version
|
||||
if versionDiff > 0 {
|
||||
s.logVersionDiff(constants.VPNUnlimited, versionDiff)
|
||||
return hardcoded
|
||||
}
|
||||
|
||||
s.logTimeDiff(constants.VPNUnlimited, persisted.Timestamp, hardcoded.Timestamp)
|
||||
return persisted
|
||||
}
|
||||
|
||||
func (s *storage) mergeVyprvpn(hardcoded, persisted models.VyprvpnServers) models.VyprvpnServers {
|
||||
if persisted.Timestamp <= hardcoded.Timestamp {
|
||||
return hardcoded
|
||||
|
||||
@@ -21,6 +21,7 @@ func countServers(allServers models.AllServers) int {
|
||||
return len(allServers.Cyberghost.Servers) +
|
||||
len(allServers.Fastestvpn.Servers) +
|
||||
len(allServers.HideMyAss.Servers) +
|
||||
len(allServers.Ipvanish.Servers) +
|
||||
len(allServers.Ivpn.Servers) +
|
||||
len(allServers.Mullvad.Servers) +
|
||||
len(allServers.Nordvpn.Servers) +
|
||||
@@ -31,6 +32,7 @@ func countServers(allServers models.AllServers) int {
|
||||
len(allServers.Purevpn.Servers) +
|
||||
len(allServers.Surfshark.Servers) +
|
||||
len(allServers.Torguard.Servers) +
|
||||
len(allServers.VPNUnlimited.Servers) +
|
||||
len(allServers.Vyprvpn.Servers) +
|
||||
len(allServers.Windscribe.Servers)
|
||||
}
|
||||
|
||||
@@ -5,5 +5,5 @@ import sysunix "golang.org/x/sys/unix"
|
||||
// Constants used for convenience so "os" does not have to be imported
|
||||
|
||||
const (
|
||||
S_IFCHR = sysunix.S_IFCHR //nolint:golint
|
||||
S_IFCHR = sysunix.S_IFCHR //nolint:revive
|
||||
)
|
||||
|
||||
@@ -4,9 +4,11 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/constants"
|
||||
"github.com/qdm12/gluetun/internal/updater/providers/cyberghost"
|
||||
"github.com/qdm12/gluetun/internal/updater/providers/fastestvpn"
|
||||
"github.com/qdm12/gluetun/internal/updater/providers/hidemyass"
|
||||
"github.com/qdm12/gluetun/internal/updater/providers/ipvanish"
|
||||
"github.com/qdm12/gluetun/internal/updater/providers/ivpn"
|
||||
"github.com/qdm12/gluetun/internal/updater/providers/mullvad"
|
||||
"github.com/qdm12/gluetun/internal/updater/providers/nordvpn"
|
||||
@@ -17,6 +19,7 @@ import (
|
||||
"github.com/qdm12/gluetun/internal/updater/providers/purevpn"
|
||||
"github.com/qdm12/gluetun/internal/updater/providers/surfshark"
|
||||
"github.com/qdm12/gluetun/internal/updater/providers/torguard"
|
||||
"github.com/qdm12/gluetun/internal/updater/providers/vpnunlimited"
|
||||
"github.com/qdm12/gluetun/internal/updater/providers/vyprvpn"
|
||||
"github.com/qdm12/gluetun/internal/updater/providers/windscribe"
|
||||
)
|
||||
@@ -75,6 +78,26 @@ func (u *updater) updateHideMyAss(ctx context.Context) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *updater) updateIpvanish(ctx context.Context) (err error) {
|
||||
minServers := getMinServers(len(u.servers.Ipvanish.Servers))
|
||||
servers, warnings, err := ipvanish.GetServers(
|
||||
ctx, u.unzipper, u.presolver, minServers)
|
||||
if u.options.CLI {
|
||||
for _, warning := range warnings {
|
||||
u.logger.Warn("Ipvanish: %s", warning)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if u.options.Stdout {
|
||||
u.println(ipvanish.Stringify(servers))
|
||||
}
|
||||
u.servers.Ipvanish.Timestamp = u.timeNow().Unix()
|
||||
u.servers.Ipvanish.Servers = servers
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *updater) updateIvpn(ctx context.Context) (err error) {
|
||||
minServers := getMinServers(len(u.servers.Ivpn.Servers))
|
||||
servers, warnings, err := ivpn.GetServers(
|
||||
@@ -261,6 +284,26 @@ func (u *updater) updateTorguard(ctx context.Context) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *updater) updateVPNUnlimited(ctx context.Context) (err error) {
|
||||
minServers := getMinServers(len(u.servers.VPNUnlimited.Servers))
|
||||
servers, warnings, err := vpnunlimited.GetServers(
|
||||
ctx, u.unzipper, u.presolver, minServers)
|
||||
if u.options.CLI {
|
||||
for _, warning := range warnings {
|
||||
u.logger.Warn(constants.VPNUnlimited + ": " + warning)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if u.options.Stdout {
|
||||
u.println(vpnunlimited.Stringify(servers))
|
||||
}
|
||||
u.servers.VPNUnlimited.Timestamp = u.timeNow().Unix()
|
||||
u.servers.VPNUnlimited.Servers = servers
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *updater) updateVyprvpn(ctx context.Context) (err error) {
|
||||
minServers := getMinServers(len(u.servers.Vyprvpn.Servers))
|
||||
servers, warnings, err := vyprvpn.GetServers(
|
||||
|
||||
@@ -13,9 +13,9 @@ func resolveHosts(ctx context.Context, presolver resolver.Parallel,
|
||||
hostToIPs map[string][]net.IP, err error) {
|
||||
const (
|
||||
maxFailRatio = 1
|
||||
maxDuration = 10 * time.Second
|
||||
betweenDuration = 500 * time.Millisecond
|
||||
maxNoNew = 2
|
||||
maxDuration = 20 * time.Second
|
||||
betweenDuration = time.Second
|
||||
maxNoNew = 4
|
||||
maxFails = 10
|
||||
)
|
||||
settings := resolver.ParallelSettings{
|
||||
|
||||
39
internal/updater/providers/ipvanish/filename.go
Normal file
39
internal/updater/providers/ipvanish/filename.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package ipvanish
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/constants"
|
||||
)
|
||||
|
||||
var errCountryCodeUnknown = errors.New("country code is unknown")
|
||||
|
||||
func parseFilename(fileName, hostname string) (
|
||||
country, city string, err error) {
|
||||
const prefix = "ipvanish-"
|
||||
s := strings.TrimPrefix(fileName, prefix)
|
||||
|
||||
const ext = ".ovpn"
|
||||
host := strings.Split(hostname, ".")[0]
|
||||
suffix := "-" + host + ext
|
||||
s = strings.TrimSuffix(s, suffix)
|
||||
|
||||
parts := strings.Split(s, "-")
|
||||
|
||||
countryCodes := constants.CountryCodes()
|
||||
countryCode := strings.ToLower(parts[0])
|
||||
country, ok := countryCodes[countryCode]
|
||||
if !ok {
|
||||
return "", "", fmt.Errorf("%w: %s", errCountryCodeUnknown, countryCode)
|
||||
}
|
||||
country = strings.Title(country)
|
||||
|
||||
if len(parts) > 1 {
|
||||
city = strings.Join(parts[1:], " ")
|
||||
city = strings.Title(city)
|
||||
}
|
||||
|
||||
return country, city, nil
|
||||
}
|
||||
54
internal/updater/providers/ipvanish/filename_test.go
Normal file
54
internal/updater/providers/ipvanish/filename_test.go
Normal file
@@ -0,0 +1,54 @@
|
||||
package ipvanish
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test_parseFilename(t *testing.T) {
|
||||
t.Parallel()
|
||||
testCases := map[string]struct {
|
||||
fileName string
|
||||
hostname string
|
||||
country string
|
||||
city string
|
||||
err error
|
||||
}{
|
||||
"unknown country code": {
|
||||
fileName: "ipvanish-unknown-host.ovpn",
|
||||
hostname: "host.ipvanish.com",
|
||||
err: errors.New("country code is unknown: unknown"),
|
||||
},
|
||||
"country code only": {
|
||||
fileName: "ipvanish-ca-host.ovpn",
|
||||
hostname: "host.ipvanish.com",
|
||||
country: "Canada",
|
||||
},
|
||||
"country code and city": {
|
||||
fileName: "ipvanish-ca-sao-paulo-host.ovpn",
|
||||
hostname: "host.ipvanish.com",
|
||||
country: "Canada",
|
||||
city: "Sao Paulo",
|
||||
},
|
||||
}
|
||||
for name, testCase := range testCases {
|
||||
testCase := testCase
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
country, city, err := parseFilename(testCase.fileName, testCase.hostname)
|
||||
|
||||
if testCase.err != nil {
|
||||
require.Error(t, err)
|
||||
assert.Equal(t, testCase.err.Error(), err.Error())
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
assert.Equal(t, testCase.country, country)
|
||||
assert.Equal(t, testCase.city, city)
|
||||
})
|
||||
}
|
||||
}
|
||||
58
internal/updater/providers/ipvanish/hosttoserver.go
Normal file
58
internal/updater/providers/ipvanish/hosttoserver.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package ipvanish
|
||||
|
||||
import (
|
||||
"net"
|
||||
"sort"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
)
|
||||
|
||||
type hostToServer map[string]models.IpvanishServer
|
||||
|
||||
func (hts hostToServer) add(host, country, city string, tcp, udp bool) {
|
||||
server, ok := hts[host]
|
||||
if !ok {
|
||||
server.Hostname = host
|
||||
server.Country = country
|
||||
server.City = city
|
||||
}
|
||||
if tcp {
|
||||
server.TCP = tcp
|
||||
}
|
||||
if udp {
|
||||
server.UDP = udp
|
||||
}
|
||||
hts[host] = server
|
||||
}
|
||||
|
||||
func (hts hostToServer) toHostsSlice() (hosts []string) {
|
||||
hosts = make([]string, 0, len(hts))
|
||||
for host := range hts {
|
||||
hosts = append(hosts, host)
|
||||
}
|
||||
sort.Slice(hosts, func(i, j int) bool {
|
||||
return hosts[i] < hosts[j]
|
||||
})
|
||||
return hosts
|
||||
}
|
||||
|
||||
func (hts hostToServer) adaptWithIPs(hostToIPs map[string][]net.IP) {
|
||||
for host, IPs := range hostToIPs {
|
||||
server := hts[host]
|
||||
server.IPs = IPs
|
||||
hts[host] = server
|
||||
}
|
||||
for host, server := range hts {
|
||||
if len(server.IPs) == 0 {
|
||||
delete(hts, host)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (hts hostToServer) toServersSlice() (servers []models.IpvanishServer) {
|
||||
servers = make([]models.IpvanishServer, 0, len(hts))
|
||||
for _, server := range hts {
|
||||
servers = append(servers, server)
|
||||
}
|
||||
return servers
|
||||
}
|
||||
211
internal/updater/providers/ipvanish/hosttoserver_test.go
Normal file
211
internal/updater/providers/ipvanish/hosttoserver_test.go
Normal file
@@ -0,0 +1,211 @@
|
||||
package ipvanish
|
||||
|
||||
import (
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_hostToServer_add(t *testing.T) {
|
||||
t.Parallel()
|
||||
testCases := map[string]struct {
|
||||
initialHTS hostToServer
|
||||
host string
|
||||
country string
|
||||
city string
|
||||
tcp bool
|
||||
udp bool
|
||||
expectedHTS hostToServer
|
||||
}{
|
||||
"empty host to server": {
|
||||
initialHTS: hostToServer{},
|
||||
host: "host",
|
||||
country: "country",
|
||||
city: "city",
|
||||
tcp: true,
|
||||
udp: true,
|
||||
expectedHTS: hostToServer{
|
||||
"host": {
|
||||
Hostname: "host",
|
||||
Country: "country",
|
||||
City: "city",
|
||||
TCP: true,
|
||||
UDP: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
"add server": {
|
||||
initialHTS: hostToServer{
|
||||
"existing host": {},
|
||||
},
|
||||
host: "host",
|
||||
country: "country",
|
||||
city: "city",
|
||||
tcp: true,
|
||||
udp: true,
|
||||
expectedHTS: hostToServer{
|
||||
"existing host": {},
|
||||
"host": models.IpvanishServer{
|
||||
Hostname: "host",
|
||||
Country: "country",
|
||||
City: "city",
|
||||
TCP: true,
|
||||
UDP: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
"extend existing server": {
|
||||
initialHTS: hostToServer{
|
||||
"host": models.IpvanishServer{
|
||||
Hostname: "host",
|
||||
Country: "country",
|
||||
City: "city",
|
||||
TCP: true,
|
||||
},
|
||||
},
|
||||
host: "host",
|
||||
country: "country",
|
||||
city: "city",
|
||||
tcp: false,
|
||||
udp: true,
|
||||
expectedHTS: hostToServer{
|
||||
"host": models.IpvanishServer{
|
||||
Hostname: "host",
|
||||
Country: "country",
|
||||
City: "city",
|
||||
TCP: true,
|
||||
UDP: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for name, testCase := range testCases {
|
||||
testCase := testCase
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
testCase.initialHTS.add(testCase.host, testCase.country, testCase.city, testCase.tcp, testCase.udp)
|
||||
assert.Equal(t, testCase.expectedHTS, testCase.initialHTS)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_hostToServer_toHostsSlice(t *testing.T) {
|
||||
t.Parallel()
|
||||
testCases := map[string]struct {
|
||||
hts hostToServer
|
||||
hosts []string
|
||||
}{
|
||||
"empty host to server": {
|
||||
hts: hostToServer{},
|
||||
hosts: []string{},
|
||||
},
|
||||
"single host": {
|
||||
hts: hostToServer{
|
||||
"A": {},
|
||||
},
|
||||
hosts: []string{"A"},
|
||||
},
|
||||
"multiple hosts": {
|
||||
hts: hostToServer{
|
||||
"A": {},
|
||||
"B": {},
|
||||
},
|
||||
hosts: []string{"A", "B"},
|
||||
},
|
||||
}
|
||||
for name, testCase := range testCases {
|
||||
testCase := testCase
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
hosts := testCase.hts.toHostsSlice()
|
||||
assert.ElementsMatch(t, testCase.hosts, hosts)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_hostToServer_adaptWithIPs(t *testing.T) {
|
||||
t.Parallel()
|
||||
testCases := map[string]struct {
|
||||
initialHTS hostToServer
|
||||
hostToIPs map[string][]net.IP
|
||||
expectedHTS hostToServer
|
||||
}{
|
||||
"create server": {
|
||||
initialHTS: hostToServer{},
|
||||
hostToIPs: map[string][]net.IP{
|
||||
"A": {{1, 2, 3, 4}},
|
||||
},
|
||||
expectedHTS: hostToServer{
|
||||
"A": models.IpvanishServer{
|
||||
IPs: []net.IP{{1, 2, 3, 4}},
|
||||
},
|
||||
},
|
||||
},
|
||||
"add IPs to existing server": {
|
||||
initialHTS: hostToServer{
|
||||
"A": models.IpvanishServer{
|
||||
Country: "country",
|
||||
},
|
||||
},
|
||||
hostToIPs: map[string][]net.IP{
|
||||
"A": {{1, 2, 3, 4}},
|
||||
},
|
||||
expectedHTS: hostToServer{
|
||||
"A": models.IpvanishServer{
|
||||
Country: "country",
|
||||
IPs: []net.IP{{1, 2, 3, 4}},
|
||||
},
|
||||
},
|
||||
},
|
||||
"remove server without IP": {
|
||||
initialHTS: hostToServer{
|
||||
"A": models.IpvanishServer{
|
||||
Country: "country",
|
||||
},
|
||||
},
|
||||
hostToIPs: map[string][]net.IP{},
|
||||
expectedHTS: hostToServer{},
|
||||
},
|
||||
}
|
||||
for name, testCase := range testCases {
|
||||
testCase := testCase
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
testCase.initialHTS.adaptWithIPs(testCase.hostToIPs)
|
||||
assert.Equal(t, testCase.expectedHTS, testCase.initialHTS)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_hostToServer_toServersSlice(t *testing.T) {
|
||||
t.Parallel()
|
||||
testCases := map[string]struct {
|
||||
hts hostToServer
|
||||
servers []models.IpvanishServer
|
||||
}{
|
||||
"empty host to server": {
|
||||
hts: hostToServer{},
|
||||
servers: []models.IpvanishServer{},
|
||||
},
|
||||
"multiple servers": {
|
||||
hts: hostToServer{
|
||||
"A": {Country: "A"},
|
||||
"B": {Country: "B"},
|
||||
},
|
||||
servers: []models.IpvanishServer{
|
||||
{Country: "A"},
|
||||
{Country: "B"},
|
||||
},
|
||||
},
|
||||
}
|
||||
for name, testCase := range testCases {
|
||||
testCase := testCase
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
servers := testCase.hts.toServersSlice()
|
||||
assert.ElementsMatch(t, testCase.servers, servers)
|
||||
})
|
||||
}
|
||||
}
|
||||
36
internal/updater/providers/ipvanish/resolve.go
Normal file
36
internal/updater/providers/ipvanish/resolve.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package ipvanish
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/updater/resolver"
|
||||
)
|
||||
|
||||
func getResolveSettings(minServers int) (settings resolver.ParallelSettings) {
|
||||
const (
|
||||
maxFailRatio = 0.1
|
||||
maxDuration = 20 * time.Second
|
||||
betweenDuration = time.Second
|
||||
maxNoNew = 2
|
||||
maxFails = 2
|
||||
)
|
||||
return resolver.ParallelSettings{
|
||||
MaxFailRatio: maxFailRatio,
|
||||
MinFound: minServers,
|
||||
Repeat: resolver.RepeatSettings{
|
||||
MaxDuration: maxDuration,
|
||||
BetweenDuration: betweenDuration,
|
||||
MaxNoNew: maxNoNew,
|
||||
MaxFails: maxFails,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resolveHosts(ctx context.Context, presolver resolver.Parallel,
|
||||
hosts []string, minServers int) (hostToIPs map[string][]net.IP,
|
||||
warnings []string, err error) {
|
||||
settings := getResolveSettings(minServers)
|
||||
return presolver.Resolve(ctx, hosts, settings)
|
||||
}
|
||||
56
internal/updater/providers/ipvanish/resolve_test.go
Normal file
56
internal/updater/providers/ipvanish/resolve_test.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package ipvanish
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/qdm12/gluetun/internal/updater/resolver"
|
||||
"github.com/qdm12/gluetun/internal/updater/resolver/mock_resolver"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_resolveHosts(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctrl := gomock.NewController(t)
|
||||
|
||||
ctx := context.Background()
|
||||
presolver := mock_resolver.NewMockParallel(ctrl)
|
||||
hosts := []string{"host1", "host2"}
|
||||
const minServers = 10
|
||||
|
||||
expectedHostToIPs := map[string][]net.IP{
|
||||
"host1": {{1, 2, 3, 4}},
|
||||
"host2": {{2, 3, 4, 5}},
|
||||
}
|
||||
expectedWarnings := []string{"warning1", "warning2"}
|
||||
expectedErr := errors.New("dummy")
|
||||
|
||||
const (
|
||||
maxFailRatio = 0.1
|
||||
maxDuration = 20 * time.Second
|
||||
betweenDuration = time.Second
|
||||
maxNoNew = 2
|
||||
maxFails = 2
|
||||
)
|
||||
expectedSettings := resolver.ParallelSettings{
|
||||
MaxFailRatio: maxFailRatio,
|
||||
MinFound: minServers,
|
||||
Repeat: resolver.RepeatSettings{
|
||||
MaxDuration: maxDuration,
|
||||
BetweenDuration: betweenDuration,
|
||||
MaxNoNew: maxNoNew,
|
||||
MaxFails: maxFails,
|
||||
},
|
||||
}
|
||||
presolver.EXPECT().Resolve(ctx, hosts, expectedSettings).
|
||||
Return(expectedHostToIPs, expectedWarnings, expectedErr)
|
||||
|
||||
hostToIPs, warnings, err := resolveHosts(ctx, presolver, hosts, minServers)
|
||||
assert.Equal(t, expectedHostToIPs, hostToIPs)
|
||||
assert.Equal(t, expectedWarnings, warnings)
|
||||
assert.Equal(t, expectedErr, err)
|
||||
}
|
||||
92
internal/updater/providers/ipvanish/servers.go
Normal file
92
internal/updater/providers/ipvanish/servers.go
Normal file
@@ -0,0 +1,92 @@
|
||||
// Package ipvanish contains code to obtain the server information
|
||||
// for the Surshark provider.
|
||||
package ipvanish
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
"github.com/qdm12/gluetun/internal/updater/openvpn"
|
||||
"github.com/qdm12/gluetun/internal/updater/resolver"
|
||||
"github.com/qdm12/gluetun/internal/updater/unzip"
|
||||
)
|
||||
|
||||
var ErrNotEnoughServers = errors.New("not enough servers found")
|
||||
|
||||
func GetServers(ctx context.Context, unzipper unzip.Unzipper,
|
||||
presolver resolver.Parallel, minServers int) (
|
||||
servers []models.IpvanishServer, warnings []string, err error) {
|
||||
const url = "https://www.ipvanish.com/software/configs/configs.zip"
|
||||
contents, err := unzipper.FetchAndExtract(ctx, url)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
} else if len(contents) < minServers {
|
||||
return nil, nil, fmt.Errorf("%w: %d and expected at least %d",
|
||||
ErrNotEnoughServers, len(contents), minServers)
|
||||
}
|
||||
|
||||
hts := make(hostToServer)
|
||||
|
||||
for fileName, content := range contents {
|
||||
if !strings.HasSuffix(fileName, ".ovpn") {
|
||||
continue // not an OpenVPN file
|
||||
}
|
||||
|
||||
tcp, udp, err := openvpn.ExtractProto(content)
|
||||
if err != nil {
|
||||
// treat error as warning and go to next file
|
||||
warning := err.Error() + ": in " + fileName
|
||||
warnings = append(warnings, warning)
|
||||
continue
|
||||
}
|
||||
|
||||
hostname, warning, err := openvpn.ExtractHost(content)
|
||||
if warning != "" {
|
||||
warnings = append(warnings, warning)
|
||||
}
|
||||
if err != nil {
|
||||
// treat error as warning and go to next file
|
||||
warning := err.Error() + " in " + fileName
|
||||
warnings = append(warnings, warning)
|
||||
continue
|
||||
}
|
||||
|
||||
country, city, err := parseFilename(fileName, hostname)
|
||||
if err != nil {
|
||||
// treat error as warning and go to next file
|
||||
warning := err.Error() + " in " + fileName
|
||||
warnings = append(warnings, warning)
|
||||
continue
|
||||
}
|
||||
|
||||
hts.add(hostname, country, city, tcp, udp)
|
||||
}
|
||||
|
||||
if len(hts) < minServers {
|
||||
return nil, warnings, fmt.Errorf("%w: %d and expected at least %d",
|
||||
ErrNotEnoughServers, len(hts), minServers)
|
||||
}
|
||||
|
||||
hosts := hts.toHostsSlice()
|
||||
hostToIPs, newWarnings, err := resolveHosts(ctx, presolver, hosts, minServers)
|
||||
warnings = append(warnings, newWarnings...)
|
||||
if err != nil {
|
||||
return nil, warnings, err
|
||||
}
|
||||
|
||||
hts.adaptWithIPs(hostToIPs)
|
||||
|
||||
servers = hts.toServersSlice()
|
||||
|
||||
if len(servers) < minServers {
|
||||
return nil, warnings, fmt.Errorf("%w: %d and expected at least %d",
|
||||
ErrNotEnoughServers, len(servers), minServers)
|
||||
}
|
||||
|
||||
sortServers(servers)
|
||||
|
||||
return servers, warnings, nil
|
||||
}
|
||||
150
internal/updater/providers/ipvanish/servers_test.go
Normal file
150
internal/updater/providers/ipvanish/servers_test.go
Normal file
@@ -0,0 +1,150 @@
|
||||
package ipvanish
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
"github.com/qdm12/gluetun/internal/updater/resolver"
|
||||
"github.com/qdm12/gluetun/internal/updater/resolver/mock_resolver"
|
||||
"github.com/qdm12/gluetun/internal/updater/unzip/mock_unzip"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test_GetServers(t *testing.T) {
|
||||
t.Parallel()
|
||||
testCases := map[string]struct {
|
||||
// Inputs
|
||||
minServers int
|
||||
|
||||
// Unzip
|
||||
unzipContents map[string][]byte
|
||||
unzipErr error
|
||||
|
||||
// Resolution
|
||||
expectResolve bool
|
||||
hostsToResolve []string
|
||||
resolveSettings resolver.ParallelSettings
|
||||
hostToIPs map[string][]net.IP
|
||||
resolveWarnings []string
|
||||
resolveErr error
|
||||
|
||||
// Output
|
||||
servers []models.IpvanishServer
|
||||
warnings []string
|
||||
err error
|
||||
}{
|
||||
"unzipper error": {
|
||||
unzipErr: errors.New("dummy"),
|
||||
err: errors.New("dummy"),
|
||||
},
|
||||
"not enough unzip contents": {
|
||||
minServers: 1,
|
||||
unzipContents: map[string][]byte{},
|
||||
err: errors.New("not enough servers found: 0 and expected at least 1"),
|
||||
},
|
||||
"no openvpn file": {
|
||||
minServers: 1,
|
||||
unzipContents: map[string][]byte{"somefile.txt": {}},
|
||||
err: errors.New("not enough servers found: 0 and expected at least 1"),
|
||||
},
|
||||
"invalid proto": {
|
||||
minServers: 1,
|
||||
unzipContents: map[string][]byte{"badproto.ovpn": []byte(`proto invalid`)},
|
||||
warnings: []string{"unknown protocol: invalid: in badproto.ovpn"},
|
||||
err: errors.New("not enough servers found: 0 and expected at least 1"),
|
||||
},
|
||||
"no host": {
|
||||
minServers: 1,
|
||||
unzipContents: map[string][]byte{"nohost.ovpn": []byte(``)},
|
||||
warnings: []string{"remote host not found in nohost.ovpn"},
|
||||
err: errors.New("not enough servers found: 0 and expected at least 1"),
|
||||
},
|
||||
"multiple hosts": {
|
||||
minServers: 1,
|
||||
unzipContents: map[string][]byte{
|
||||
"ipvanish-CA-City-A-hosta.ovpn": []byte("remote hosta\nremote hostb"),
|
||||
},
|
||||
expectResolve: true,
|
||||
hostsToResolve: []string{"hosta"},
|
||||
resolveSettings: getResolveSettings(1),
|
||||
warnings: []string{"only using the first host \"hosta\" and discarding 1 other hosts"},
|
||||
err: errors.New("not enough servers found: 0 and expected at least 1"),
|
||||
},
|
||||
"resolve error": {
|
||||
unzipContents: map[string][]byte{
|
||||
"ipvanish-CA-City-A-hosta.ovpn": []byte("remote hosta"),
|
||||
},
|
||||
expectResolve: true,
|
||||
hostsToResolve: []string{"hosta"},
|
||||
resolveSettings: getResolveSettings(0),
|
||||
resolveWarnings: []string{"resolve warning"},
|
||||
resolveErr: errors.New("dummy"),
|
||||
warnings: []string{"resolve warning"},
|
||||
err: errors.New("dummy"),
|
||||
},
|
||||
"filename parsing error": {
|
||||
minServers: 1,
|
||||
unzipContents: map[string][]byte{
|
||||
"ipvanish-unknown-City-A-hosta.ovpn": []byte("remote hosta"),
|
||||
},
|
||||
warnings: []string{"country code is unknown: unknown in ipvanish-unknown-City-A-hosta.ovpn"},
|
||||
err: errors.New("not enough servers found: 0 and expected at least 1"),
|
||||
},
|
||||
"success": {
|
||||
minServers: 1,
|
||||
unzipContents: map[string][]byte{
|
||||
"ipvanish-CA-City-A-hosta.ovpn": []byte("remote hosta"),
|
||||
"ipvanish-LU-City-B-hostb.ovpn": []byte("remote hostb"),
|
||||
},
|
||||
expectResolve: true,
|
||||
hostsToResolve: []string{"hosta", "hostb"},
|
||||
resolveSettings: getResolveSettings(1),
|
||||
hostToIPs: map[string][]net.IP{
|
||||
"hosta": {{1, 1, 1, 1}, {2, 2, 2, 2}},
|
||||
"hostb": {{3, 3, 3, 3}, {4, 4, 4, 4}},
|
||||
},
|
||||
resolveWarnings: []string{"resolve warning"},
|
||||
servers: []models.IpvanishServer{
|
||||
{Country: "Canada", City: "City A", Hostname: "hosta", UDP: true, IPs: []net.IP{{1, 1, 1, 1}, {2, 2, 2, 2}}},
|
||||
{Country: "Luxembourg", City: "City B", Hostname: "hostb", UDP: true, IPs: []net.IP{{3, 3, 3, 3}, {4, 4, 4, 4}}},
|
||||
},
|
||||
warnings: []string{"resolve warning"},
|
||||
},
|
||||
}
|
||||
for name, testCase := range testCases {
|
||||
testCase := testCase
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctrl := gomock.NewController(t)
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
unzipper := mock_unzip.NewMockUnzipper(ctrl)
|
||||
const zipURL = "https://www.ipvanish.com/software/configs/configs.zip"
|
||||
unzipper.EXPECT().FetchAndExtract(ctx, zipURL).
|
||||
Return(testCase.unzipContents, testCase.unzipErr)
|
||||
|
||||
presolver := mock_resolver.NewMockParallel(ctrl)
|
||||
if testCase.expectResolve {
|
||||
presolver.EXPECT().Resolve(ctx, testCase.hostsToResolve, testCase.resolveSettings).
|
||||
Return(testCase.hostToIPs, testCase.resolveWarnings, testCase.resolveErr)
|
||||
}
|
||||
|
||||
servers, warnings, err := GetServers(ctx, unzipper, presolver, testCase.minServers)
|
||||
|
||||
assert.Equal(t, testCase.servers, servers)
|
||||
assert.Equal(t, testCase.warnings, warnings)
|
||||
if testCase.err != nil {
|
||||
require.Error(t, err)
|
||||
assert.Equal(t, testCase.err.Error(), err.Error())
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
19
internal/updater/providers/ipvanish/sort.go
Normal file
19
internal/updater/providers/ipvanish/sort.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package ipvanish
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
)
|
||||
|
||||
func sortServers(servers []models.IpvanishServer) {
|
||||
sort.Slice(servers, func(i, j int) bool {
|
||||
if servers[i].Country == servers[j].Country {
|
||||
if servers[i].City == servers[j].City {
|
||||
return servers[i].Hostname < servers[j].Hostname
|
||||
}
|
||||
return servers[i].City < servers[j].City
|
||||
}
|
||||
return servers[i].Country < servers[j].Country
|
||||
})
|
||||
}
|
||||
40
internal/updater/providers/ipvanish/sort_test.go
Normal file
40
internal/updater/providers/ipvanish/sort_test.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package ipvanish
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_sortServers(t *testing.T) {
|
||||
t.Parallel()
|
||||
testCases := map[string]struct {
|
||||
initialServers []models.IpvanishServer
|
||||
sortedServers []models.IpvanishServer
|
||||
}{
|
||||
"no server": {},
|
||||
"sorted servers": {
|
||||
initialServers: []models.IpvanishServer{
|
||||
{Country: "B", City: "A", Hostname: "A"},
|
||||
{Country: "A", City: "A", Hostname: "B"},
|
||||
{Country: "A", City: "A", Hostname: "A"},
|
||||
{Country: "A", City: "B", Hostname: "A"},
|
||||
},
|
||||
sortedServers: []models.IpvanishServer{
|
||||
{Country: "A", City: "A", Hostname: "A"},
|
||||
{Country: "A", City: "A", Hostname: "B"},
|
||||
{Country: "A", City: "B", Hostname: "A"},
|
||||
{Country: "B", City: "A", Hostname: "A"},
|
||||
},
|
||||
},
|
||||
}
|
||||
for name, testCase := range testCases {
|
||||
testCase := testCase
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
sortServers(testCase.initialServers)
|
||||
assert.Equal(t, testCase.sortedServers, testCase.initialServers)
|
||||
})
|
||||
}
|
||||
}
|
||||
14
internal/updater/providers/ipvanish/string.go
Normal file
14
internal/updater/providers/ipvanish/string.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package ipvanish
|
||||
|
||||
import "github.com/qdm12/gluetun/internal/models"
|
||||
|
||||
func Stringify(servers []models.IpvanishServer) (s string) {
|
||||
s = "func IpvanishServers() []models.IpvanishServer {\n"
|
||||
s += " return []models.IpvanishServer{\n"
|
||||
for _, server := range servers {
|
||||
s += " " + server.String() + ",\n"
|
||||
}
|
||||
s += " }\n"
|
||||
s += "}"
|
||||
return s
|
||||
}
|
||||
43
internal/updater/providers/ipvanish/string_test.go
Normal file
43
internal/updater/providers/ipvanish/string_test.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package ipvanish
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_Stringify(t *testing.T) {
|
||||
t.Parallel()
|
||||
testCases := map[string]struct {
|
||||
servers []models.IpvanishServer
|
||||
s string
|
||||
}{
|
||||
"no server": {
|
||||
s: `func IpvanishServers() []models.IpvanishServer {
|
||||
return []models.IpvanishServer{
|
||||
}
|
||||
}`,
|
||||
},
|
||||
"multiple servers": {
|
||||
servers: []models.IpvanishServer{
|
||||
{Country: "A"},
|
||||
{Country: "B"},
|
||||
},
|
||||
s: `func IpvanishServers() []models.IpvanishServer {
|
||||
return []models.IpvanishServer{
|
||||
{Country: "A", City: "", Hostname: "", TCP: false, UDP: false, IPs: []net.IP{}},
|
||||
{Country: "B", City: "", Hostname: "", TCP: false, UDP: false, IPs: []net.IP{}},
|
||||
}
|
||||
}`,
|
||||
},
|
||||
}
|
||||
for name, testCase := range testCases {
|
||||
testCase := testCase
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
s := Stringify(testCase.servers)
|
||||
assert.Equal(t, testCase.s, s)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ func parseServerName(serverName string) (number uint16, err error) {
|
||||
}
|
||||
|
||||
idString := serverName[i+1:]
|
||||
idUint64, err := strconv.ParseUint(idString, 10, 16)
|
||||
idUint64, err := strconv.ParseUint(idString, 10, 16) //nolint:gomnd
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("%w: %s", ErrInvalidIDInServerName, serverName)
|
||||
}
|
||||
|
||||
160
internal/updater/providers/vpnunlimited/constants.go
Normal file
160
internal/updater/providers/vpnunlimited/constants.go
Normal file
@@ -0,0 +1,160 @@
|
||||
package vpnunlimited
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/constants"
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
)
|
||||
|
||||
func getHostToServer() (hts hostToServer, warnings []string) {
|
||||
shortHTS := map[string]models.VPNUnlimitedServer{
|
||||
"ae": {},
|
||||
"ar": {},
|
||||
"at": {},
|
||||
"au-syd": {
|
||||
City: "Sydney",
|
||||
},
|
||||
"ba": {},
|
||||
"be": {},
|
||||
"bg": {},
|
||||
"br": {},
|
||||
"by": {},
|
||||
"ca-tr": {
|
||||
City: "Toronto",
|
||||
},
|
||||
"ca-vn": {
|
||||
City: "Vancouver",
|
||||
},
|
||||
"ca": {},
|
||||
"ch": {},
|
||||
"cr": {},
|
||||
"cy": {},
|
||||
"cz": {},
|
||||
"de-dus": {
|
||||
City: "Düsseldorf",
|
||||
},
|
||||
"de": {},
|
||||
"dk": {},
|
||||
"ee": {},
|
||||
"es": {},
|
||||
"fi": {},
|
||||
"fr-rbx": {
|
||||
City: "Roubaix",
|
||||
},
|
||||
"fr": {},
|
||||
"gr": {},
|
||||
"hr": {},
|
||||
"hu": {},
|
||||
"ie-dub": {
|
||||
City: "Dublin",
|
||||
},
|
||||
"il": {},
|
||||
"im": {},
|
||||
"in-ka": {
|
||||
City: "Karnataka",
|
||||
},
|
||||
"in": {},
|
||||
"is": {},
|
||||
"it-mil": {
|
||||
City: "Milan",
|
||||
},
|
||||
"jp": {},
|
||||
"kr": {},
|
||||
"lt": {},
|
||||
"lu": {},
|
||||
"lv": {},
|
||||
"ly": {},
|
||||
"md": {},
|
||||
"mx": {},
|
||||
"mys": {},
|
||||
"nl": {},
|
||||
"no": {},
|
||||
"nz": {},
|
||||
"om": {},
|
||||
"pl": {},
|
||||
"pt": {},
|
||||
"ro": {},
|
||||
"rs": {},
|
||||
"se": {},
|
||||
"sg-free": {
|
||||
Free: true,
|
||||
},
|
||||
"sg": {},
|
||||
"si": {},
|
||||
"sk": {},
|
||||
"th": {},
|
||||
"tr": {},
|
||||
"uk-cv": {
|
||||
City: "London",
|
||||
},
|
||||
"uk-lon": {
|
||||
City: "London",
|
||||
},
|
||||
"uk": {},
|
||||
"us-chi": {
|
||||
City: "Chicago",
|
||||
},
|
||||
"us-dal": {
|
||||
City: "Dallas",
|
||||
},
|
||||
"us-den": {
|
||||
City: "Denver",
|
||||
},
|
||||
"us-hou": {
|
||||
City: "Houston",
|
||||
},
|
||||
"us-la": {
|
||||
City: "Los Angeles",
|
||||
},
|
||||
"us-lv": {
|
||||
City: "Las Vegas",
|
||||
},
|
||||
"us-mia": {
|
||||
City: "Miami",
|
||||
},
|
||||
"us-ny-free": {
|
||||
City: "New York",
|
||||
Free: true,
|
||||
},
|
||||
"us-ny": {
|
||||
City: "New York",
|
||||
},
|
||||
"us-sea": {
|
||||
City: "Seattle",
|
||||
},
|
||||
"us-sf": {
|
||||
City: "San Francisco",
|
||||
},
|
||||
"us-sl": {
|
||||
City: "Saint Louis",
|
||||
},
|
||||
"us-slc": {
|
||||
City: "Salt Lake City",
|
||||
},
|
||||
"us-stream": {
|
||||
Stream: true,
|
||||
},
|
||||
"us": {},
|
||||
"vn": {},
|
||||
"za": {},
|
||||
}
|
||||
|
||||
hts = make(hostToServer, len(shortHTS))
|
||||
|
||||
countryCodesMap := constants.CountryCodes()
|
||||
for shortHost, server := range shortHTS {
|
||||
server.UDP = true
|
||||
server.Hostname = shortHost + ".vpnunlimitedapp.com"
|
||||
countryCode := strings.Split(shortHost, "-")[0]
|
||||
country, ok := countryCodesMap[countryCode]
|
||||
if !ok {
|
||||
warnings = append(warnings, "country code not found: "+countryCode)
|
||||
continue
|
||||
}
|
||||
server.Country = country
|
||||
hts[server.Hostname] = server
|
||||
}
|
||||
|
||||
return hts, warnings
|
||||
}
|
||||
38
internal/updater/providers/vpnunlimited/hosttoserver.go
Normal file
38
internal/updater/providers/vpnunlimited/hosttoserver.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package vpnunlimited
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
)
|
||||
|
||||
type hostToServer map[string]models.VPNUnlimitedServer
|
||||
|
||||
func (hts hostToServer) toHostsSlice() (hosts []string) {
|
||||
hosts = make([]string, 0, len(hts))
|
||||
for host := range hts {
|
||||
hosts = append(hosts, host)
|
||||
}
|
||||
return hosts
|
||||
}
|
||||
|
||||
func (hts hostToServer) adaptWithIPs(hostToIPs map[string][]net.IP) {
|
||||
for host, IPs := range hostToIPs {
|
||||
server := hts[host]
|
||||
server.IPs = IPs
|
||||
hts[host] = server
|
||||
}
|
||||
for host, server := range hts {
|
||||
if len(server.IPs) == 0 {
|
||||
delete(hts, host)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (hts hostToServer) toServersSlice() (servers []models.VPNUnlimitedServer) {
|
||||
servers = make([]models.VPNUnlimitedServer, 0, len(hts))
|
||||
for _, server := range hts {
|
||||
servers = append(servers, server)
|
||||
}
|
||||
return servers
|
||||
}
|
||||
32
internal/updater/providers/vpnunlimited/resolve.go
Normal file
32
internal/updater/providers/vpnunlimited/resolve.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package vpnunlimited
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/updater/resolver"
|
||||
)
|
||||
|
||||
func resolveHosts(ctx context.Context, presolver resolver.Parallel,
|
||||
hosts []string, minServers int) (hostToIPs map[string][]net.IP,
|
||||
warnings []string, err error) {
|
||||
const (
|
||||
maxFailRatio = 0.1
|
||||
maxDuration = 20 * time.Second
|
||||
betweenDuration = time.Second
|
||||
maxNoNew = 2
|
||||
maxFails = 2
|
||||
)
|
||||
settings := resolver.ParallelSettings{
|
||||
MaxFailRatio: maxFailRatio,
|
||||
MinFound: minServers,
|
||||
Repeat: resolver.RepeatSettings{
|
||||
MaxDuration: maxDuration,
|
||||
BetweenDuration: betweenDuration,
|
||||
MaxNoNew: maxNoNew,
|
||||
MaxFails: maxFails,
|
||||
},
|
||||
}
|
||||
return presolver.Resolve(ctx, hosts, settings)
|
||||
}
|
||||
42
internal/updater/providers/vpnunlimited/servers.go
Normal file
42
internal/updater/providers/vpnunlimited/servers.go
Normal file
@@ -0,0 +1,42 @@
|
||||
// Package vpnunlimited contains code to obtain the server information
|
||||
// for the VPNUnlimited provider.
|
||||
package vpnunlimited
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
"github.com/qdm12/gluetun/internal/updater/resolver"
|
||||
"github.com/qdm12/gluetun/internal/updater/unzip"
|
||||
)
|
||||
|
||||
var ErrNotEnoughServers = errors.New("not enough servers found")
|
||||
|
||||
func GetServers(ctx context.Context, unzipper unzip.Unzipper,
|
||||
presolver resolver.Parallel, minServers int) (
|
||||
servers []models.VPNUnlimitedServer, warnings []string, err error) {
|
||||
// Hardcoded data from a user provided ZIP file since it's behind a login wall
|
||||
hts, warnings := getHostToServer()
|
||||
|
||||
hosts := hts.toHostsSlice()
|
||||
hostToIPs, newWarnings, err := resolveHosts(ctx, presolver, hosts, minServers)
|
||||
warnings = append(warnings, newWarnings...)
|
||||
if err != nil {
|
||||
return nil, warnings, err
|
||||
}
|
||||
|
||||
hts.adaptWithIPs(hostToIPs)
|
||||
|
||||
servers = hts.toServersSlice()
|
||||
|
||||
if len(servers) < minServers {
|
||||
return nil, warnings, fmt.Errorf("%w: %d and expected at least %d",
|
||||
ErrNotEnoughServers, len(servers), minServers)
|
||||
}
|
||||
|
||||
sortServers(servers)
|
||||
|
||||
return servers, warnings, nil
|
||||
}
|
||||
19
internal/updater/providers/vpnunlimited/sort.go
Normal file
19
internal/updater/providers/vpnunlimited/sort.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package vpnunlimited
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
)
|
||||
|
||||
func sortServers(servers []models.VPNUnlimitedServer) {
|
||||
sort.Slice(servers, func(i, j int) bool {
|
||||
if servers[i].Country == servers[j].Country {
|
||||
if servers[i].City == servers[j].City {
|
||||
return servers[i].Hostname < servers[j].Hostname
|
||||
}
|
||||
return servers[i].City < servers[j].City
|
||||
}
|
||||
return servers[i].Country < servers[j].Country
|
||||
})
|
||||
}
|
||||
14
internal/updater/providers/vpnunlimited/string.go
Normal file
14
internal/updater/providers/vpnunlimited/string.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package vpnunlimited
|
||||
|
||||
import "github.com/qdm12/gluetun/internal/models"
|
||||
|
||||
func Stringify(servers []models.VPNUnlimitedServer) (s string) {
|
||||
s = "func VPNUnlimitedServers() []models.VPNUnlimitedServer {\n"
|
||||
s += " return []models.VPNUnlimitedServer{\n"
|
||||
for _, server := range servers {
|
||||
s += " " + server.String() + ",\n"
|
||||
}
|
||||
s += " }\n"
|
||||
s += "}"
|
||||
return s
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/configuration"
|
||||
"github.com/qdm12/gluetun/internal/constants"
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
"github.com/qdm12/gluetun/internal/updater/resolver"
|
||||
"github.com/qdm12/gluetun/internal/updater/unzip"
|
||||
@@ -84,6 +85,16 @@ func (u *updater) UpdateServers(ctx context.Context) (allServers models.AllServe
|
||||
}
|
||||
}
|
||||
|
||||
if u.options.Ipvanish {
|
||||
u.logger.Info("updating Ipvanish servers...")
|
||||
if err := u.updateIpvanish(ctx); err != nil {
|
||||
u.logger.Error(err)
|
||||
}
|
||||
if err := ctx.Err(); err != nil {
|
||||
return allServers, err
|
||||
}
|
||||
}
|
||||
|
||||
if u.options.Ivpn {
|
||||
u.logger.Info("updating Ivpn servers...")
|
||||
if err := u.updateIvpn(ctx); err != nil {
|
||||
@@ -186,6 +197,16 @@ func (u *updater) UpdateServers(ctx context.Context) (allServers models.AllServe
|
||||
}
|
||||
}
|
||||
|
||||
if u.options.VPNUnlimited {
|
||||
u.logger.Info("updating " + constants.VPNUnlimited + " servers...")
|
||||
if err := u.updateVPNUnlimited(ctx); err != nil {
|
||||
if ctxErr := ctx.Err(); ctxErr != nil {
|
||||
return allServers, ctxErr
|
||||
}
|
||||
u.logger.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
if u.options.Vyprvpn {
|
||||
u.logger.Info("updating Vyprvpn servers...")
|
||||
if err := u.updateVyprvpn(ctx); err != nil {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user