Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af358f777b | ||
|
|
c0d27b4bfc | ||
|
|
7e50c95823 | ||
|
|
39068dda17 | ||
|
|
8185979ca4 | ||
|
|
7c44188130 | ||
|
|
c2d527bbd3 | ||
|
|
ac3ff095a1 | ||
|
|
0ed738cd61 | ||
|
|
6bbb7c8f7d | ||
|
|
d29429808c | ||
|
|
09eccd7cd9 | ||
|
|
bb2b8b4514 | ||
|
|
e20b9c5774 | ||
|
|
3badfa197a | ||
|
|
dee372e71b | ||
|
|
679be6e1bd | ||
|
|
92212fdd11 | ||
|
|
a6fb1ad9ef | ||
|
|
87d712fbd7 | ||
|
|
023809f099 | ||
|
|
ace37370d1 | ||
|
|
8efbd4fac1 |
13
Dockerfile
13
Dockerfile
@@ -1,15 +1,18 @@
|
||||
ARG ALPINE_VERSION=3.13
|
||||
ARG ALPINE_VERSION=3.14
|
||||
ARG GO_ALPINE_VERSION=3.13
|
||||
ARG GO_VERSION=1.16
|
||||
ARG XCPUTRANSLATE_VERSION=v0.6.0
|
||||
ARG GOLANGCI_LINT_VERSION=v1.41.1
|
||||
ARG BUILDPLATFORM=linux/amd64
|
||||
|
||||
FROM --platform=$BUILDPLATFORM qmcgaw/xcputranslate:v0.6.0 AS xcputranslate
|
||||
FROM --platform=$BUILDPLATFORM qmcgaw/xcputranslate:${XCPUTRANSLATE_VERSION} AS xcputranslate
|
||||
FROM --platform=${BUILDPLATFORM} qmcgaw/binpot:golangci-lint-${GOLANGCI_LINT_VERSION} AS golangci-lint
|
||||
|
||||
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS base
|
||||
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine${GO_ALPINE_VERSION} AS base
|
||||
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}
|
||||
COPY --from=golangci-lint /bin /go/bin/golangci-lint
|
||||
WORKDIR /tmp/gobuild
|
||||
COPY go.mod go.sum ./
|
||||
RUN go mod download
|
||||
|
||||
55
README.md
55
README.md
@@ -7,22 +7,36 @@ using Go, OpenVPN, iptables, DNS over TLS, ShadowSocks and an HTTP proxy*
|
||||
|
||||
**ANNOUNCEMENT**:
|
||||
|
||||
<img height="250" src="https://raw.githubusercontent.com/qdm12/gluetun/master/title.svg?sanitize=true">
|
||||

|
||||
|
||||
[](https://hub.docker.com/r/qmcgaw/gluetun/tags?page=1&ordering=last_updated)
|
||||
[](https://hub.docker.com/r/qmcgaw/gluetun/tags)
|
||||
[](https://github.com/qdm12/gluetun/actions?query=workflow%3ACI)
|
||||
|
||||
[](https://hub.docker.com/r/qmcgaw/private-internet-access)
|
||||
[](https://hub.docker.com/r/qmcgaw/gluetun)
|
||||
[](https://hub.docker.com/r/qmcgaw/gluetun)
|
||||
[](https://hub.docker.com/r/qmcgaw/gluetun)
|
||||
|
||||
[](https://hub.docker.com/r/qmcgaw/gluetun)
|
||||
[](https://hub.docker.com/r/qmcgaw/gluetun)
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
[](https://hub.docker.com/r/qmcgaw/gluetun/tags?page=1&ordering=last_updated)
|
||||

|
||||

|
||||
[](https://github.com/qdm12/gluetun/commits)
|
||||
|
||||
[](https://hub.docker.com/r/qmcgaw/gluetun/tags)
|
||||
|
||||
[](https://github.com/qdm12/gluetun/commits/master)
|
||||
[](https://github.com/qdm12/gluetun/graphs/contributors)
|
||||
[](https://github.com/qdm12/gluetun/pulls?q=is%3Apr+is%3Aclosed)
|
||||
[](https://github.com/qdm12/gluetun/issues)
|
||||
[](https://github.com/qdm12/gluetun/issues?q=is%3Aissue+is%3Aclosed)
|
||||
|
||||
[](https://github.com/qdm12/gluetun)
|
||||

|
||||

|
||||

|
||||
|
||||

|
||||
|
||||
## Quick links
|
||||
|
||||
@@ -35,6 +49,9 @@ using Go, OpenVPN, iptables, DNS over TLS, ShadowSocks and an HTTP proxy*
|
||||
- Sponsor me on [github.com/sponsors/qdm12](https://github.com/sponsors/qdm12)
|
||||
- Donate to [paypal.me/qmcgaw](https://www.paypal.me/qmcgaw)
|
||||
- Drop me [an email](mailto:quentin.mcgaw@gmail.com)
|
||||
- Video:
|
||||
|
||||
[](https://youtu.be/0F6I03LQcI4)
|
||||
|
||||
## Features
|
||||
|
||||
@@ -101,25 +118,3 @@ The following points are all optional but should give you insights on all the po
|
||||
## License
|
||||
|
||||
[](https://github.com/qdm12/gluetun/master/LICENSE)
|
||||
|
||||
## Metadata
|
||||
|
||||
[](https://github.com/qdm12/gluetun/commits)
|
||||
[](https://github.com/qdm12/gluetun/pulls?q=is%3Apr+is%3Aclosed)
|
||||
|
||||
[](https://github.com/qdm12/gluetun/issues)
|
||||
[](https://github.com/qdm12/gluetun/issues?q=is%3Aissue+is%3Aclosed)
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
[](https://hub.docker.com/r/qmcgaw/gluetun)
|
||||
|
||||

|
||||

|
||||
|
||||
@@ -275,8 +275,6 @@ func _main(ctx context.Context, buildInfo models.BuildInformation,
|
||||
}
|
||||
} // TODO move inside firewall?
|
||||
|
||||
healthy := make(chan bool)
|
||||
|
||||
// Shutdown settings
|
||||
const defaultShutdownTimeout = 400 * time.Millisecond
|
||||
defaultShutdownOnSuccess := func(goRoutineName string) {
|
||||
@@ -288,7 +286,6 @@ func _main(ctx context.Context, buildInfo models.BuildInformation,
|
||||
defaultGoRoutineSettings := goshutdown.GoRoutineSettings{Timeout: defaultShutdownTimeout}
|
||||
defaultGroupSettings := goshutdown.GroupSettings{
|
||||
Timeout: defaultShutdownTimeout,
|
||||
OnFailure: defaultShutdownOnFailure,
|
||||
OnSuccess: defaultShutdownOnSuccess,
|
||||
}
|
||||
|
||||
@@ -297,7 +294,7 @@ func _main(ctx context.Context, buildInfo models.BuildInformation,
|
||||
otherGroupHandler := goshutdown.NewGroupHandler("other", defaultGroupSettings)
|
||||
|
||||
openvpnLooper := openvpn.NewLooper(allSettings.OpenVPN, nonRootUsername, puid, pgid, allServers,
|
||||
ovpnConf, firewallConf, routingConf, logger, httpClient, os.OpenFile, tunnelReadyCh, healthy)
|
||||
ovpnConf, firewallConf, routingConf, logger, httpClient, os.OpenFile, tunnelReadyCh)
|
||||
openvpnHandler, openvpnCtx, openvpnDone := goshutdown.NewGoRoutineHandler(
|
||||
"openvpn", goshutdown.GoRoutineSettings{Timeout: time.Second})
|
||||
// wait for restartOpenvpn
|
||||
@@ -359,19 +356,20 @@ func _main(ctx context.Context, buildInfo models.BuildInformation,
|
||||
|
||||
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)
|
||||
httpServerHandler, httpServerCtx, httpServerDone := goshutdown.NewGoRoutineHandler(
|
||||
"http server", defaultGoRoutineSettings)
|
||||
httpServer := server.New(httpServerCtx, controlServerAddress, controlServerLogging,
|
||||
logger.NewChild(logging.Settings{Prefix: "http server: "}),
|
||||
buildInfo, openvpnLooper, unboundLooper, updaterLooper, publicIPLooper)
|
||||
go httpServer.Run(httpServerCtx, httpServerDone)
|
||||
controlGroupHandler.Add(httpServerHandler)
|
||||
|
||||
healthcheckServer := healthcheck.NewServer(constants.HealthcheckAddress,
|
||||
logger.NewChild(logging.Settings{Prefix: "healthcheck: "}))
|
||||
healthLogger := logger.NewChild(logging.Settings{Prefix: "healthcheck: "})
|
||||
healthcheckServer := healthcheck.NewServer(
|
||||
constants.HealthcheckAddress, healthLogger, openvpnLooper)
|
||||
healthServerHandler, healthServerCtx, healthServerDone := goshutdown.NewGoRoutineHandler(
|
||||
"HTTP health server", defaultGoRoutineSettings)
|
||||
go healthcheckServer.Run(healthServerCtx, healthy, healthServerDone)
|
||||
go healthcheckServer.Run(healthServerCtx, healthServerDone)
|
||||
|
||||
const orderShutdownTimeout = 3 * time.Second
|
||||
orderSettings := goshutdown.OrderSettings{
|
||||
@@ -385,7 +383,7 @@ func _main(ctx context.Context, buildInfo models.BuildInformation,
|
||||
|
||||
// Start openvpn for the first time in a blocking call
|
||||
// until openvpn is launched
|
||||
_, _ = openvpnLooper.SetStatus(constants.Running) // TODO option to disable with variable
|
||||
_, _ = openvpnLooper.ApplyStatus(ctx, constants.Running) // TODO option to disable with variable
|
||||
|
||||
<-ctx.Done()
|
||||
|
||||
@@ -454,7 +452,7 @@ func routeReadyEvents(ctx context.Context, done chan<- struct{}, buildInfo model
|
||||
}
|
||||
|
||||
if unboundLooper.GetSettings().Enabled {
|
||||
_, _ = unboundLooper.SetStatus(constants.Running)
|
||||
_, _ = unboundLooper.ApplyStatus(ctx, constants.Running)
|
||||
}
|
||||
|
||||
restartTickerCancel() // stop previous restart tickers
|
||||
@@ -463,12 +461,8 @@ func routeReadyEvents(ctx context.Context, done chan<- struct{}, buildInfo model
|
||||
restartTickerContext, restartTickerCancel = context.WithCancel(ctx)
|
||||
|
||||
// Runs the Public IP getter job once
|
||||
_, _ = publicIPLooper.SetStatus(constants.Running)
|
||||
if !versionInformation {
|
||||
break
|
||||
}
|
||||
|
||||
if first {
|
||||
_, _ = publicIPLooper.SetStatus(ctx, constants.Running)
|
||||
if versionInformation && first {
|
||||
first = false
|
||||
message, err := versionpkg.GetMessage(ctx, buildInfo, httpClient)
|
||||
if err != nil {
|
||||
|
||||
4
go.mod
4
go.mod
@@ -5,8 +5,8 @@ go 1.16
|
||||
require (
|
||||
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/dns v1.9.0
|
||||
github.com/qdm12/golibs v0.0.0-20210716185557-66793f4ddd80
|
||||
github.com/qdm12/goshutdown v0.1.0
|
||||
github.com/qdm12/ss-server v0.2.0
|
||||
github.com/qdm12/updated v0.0.0-20210603204757-205acfe6937e
|
||||
|
||||
7
go.sum
7
go.sum
@@ -63,10 +63,11 @@ github.com/phayes/permbits v0.0.0-20190612203442-39d7c581d2ee/go.mod h1:3uODdxMg
|
||||
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.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/dns v1.9.0 h1:p4g/BfbpQ+gJRpQdklDAnybkjds+OuenF0wEGoZ8/AI=
|
||||
github.com/qdm12/dns v1.9.0/go.mod h1:fqZoDf3VzddnKBMNI/OzZUp5H4dO0VBw1fp4qPkolOg=
|
||||
github.com/qdm12/golibs v0.0.0-20210603202746-e5494e9c2ebb/go.mod h1:15RBzkun0i8XB7ADIoLJWp9ITRgsz3LroEI2FiOXLRg=
|
||||
github.com/qdm12/golibs v0.0.0-20210716185557-66793f4ddd80 h1:rvH2MSs8RXEfuXivzoYCim6tRNPzdqjBzqJq8w4Tc0k=
|
||||
github.com/qdm12/golibs v0.0.0-20210716185557-66793f4ddd80/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=
|
||||
|
||||
@@ -18,6 +18,12 @@ var (
|
||||
ErrFilesDoNotExist = errors.New("files do not exist")
|
||||
)
|
||||
|
||||
func cleanSuffix(value string) string {
|
||||
value = strings.TrimSuffix(value, "\n")
|
||||
value = strings.TrimSuffix(value, "\r")
|
||||
return value
|
||||
}
|
||||
|
||||
func (r *reader) getFromEnvOrSecretFile(envKey string, compulsory bool, retroKeys []string) (value string, err error) {
|
||||
envOptions := []params.OptionSetter{
|
||||
params.Compulsory(), // to fallback on file reading
|
||||
@@ -27,6 +33,7 @@ func (r *reader) getFromEnvOrSecretFile(envKey string, compulsory bool, retroKey
|
||||
}
|
||||
value, envErr := r.env.Get(envKey, envOptions...)
|
||||
if envErr == nil {
|
||||
value = cleanSuffix(value)
|
||||
return value, nil
|
||||
}
|
||||
|
||||
@@ -55,7 +62,7 @@ func (r *reader) getFromEnvOrSecretFile(envKey string, compulsory bool, retroKey
|
||||
}
|
||||
|
||||
value = string(b)
|
||||
value = strings.TrimSuffix(value, "\n")
|
||||
value = cleanSuffix(value)
|
||||
if compulsory && len(value) == 0 {
|
||||
return "", ErrSecretFileIsEmpty
|
||||
}
|
||||
|
||||
@@ -45,7 +45,6 @@ func IpvanishServers() []models.IpvanishServer {
|
||||
{Country: "Albania", City: "Tirana", Hostname: "tia-c02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{80, 246, 28, 3}}},
|
||||
{Country: "Albania", City: "Tirana", Hostname: "tia-c03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{80, 246, 28, 5}}},
|
||||
{Country: "Albania", City: "Tirana", Hostname: "tia-c04.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{80, 246, 28, 7}}},
|
||||
{Country: "Albania", City: "Tirana", Hostname: "tia-c05.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{80, 246, 28, 9}}},
|
||||
{Country: "Argentina", City: "Buenos Aires", Hostname: "eze-c01.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{199, 33, 69, 10}}},
|
||||
{Country: "Argentina", City: "Buenos Aires", Hostname: "eze-c02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{199, 33, 69, 16}}},
|
||||
{Country: "Argentina", City: "Buenos Aires", Hostname: "eze-c03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{199, 33, 69, 22}}},
|
||||
@@ -63,7 +62,6 @@ func IpvanishServers() []models.IpvanishServer {
|
||||
{Country: "Australia", City: "Melbourne", Hostname: "mel-a02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{103, 209, 252, 17}}},
|
||||
{Country: "Australia", City: "Melbourne", Hostname: "mel-a03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{103, 209, 252, 11}}},
|
||||
{Country: "Australia", City: "Melbourne", Hostname: "mel-a04.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{103, 209, 252, 19}}},
|
||||
{Country: "Australia", City: "Melbourne", Hostname: "mel-a05.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{103, 209, 252, 13}}},
|
||||
{Country: "Australia", City: "Melbourne", Hostname: "mel-a06.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{103, 209, 252, 21}}},
|
||||
{Country: "Australia", City: "Melbourne", Hostname: "mel-a07.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{103, 209, 252, 15}}},
|
||||
{Country: "Australia", City: "Perth", Hostname: "per-c01.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{103, 107, 197, 36}}},
|
||||
@@ -102,19 +100,18 @@ func IpvanishServers() []models.IpvanishServer {
|
||||
{Country: "Australia", City: "Sydney", Hostname: "syd-a28.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{173, 245, 209, 164}}},
|
||||
{Country: "Australia", City: "Sydney", Hostname: "syd-a29.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{173, 245, 209, 170}}},
|
||||
{Country: "Australia", City: "Sydney", Hostname: "syd-a30.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{173, 245, 209, 176}}},
|
||||
{Country: "Austria", City: "Vienna", Hostname: "vie-c04.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{104, 238, 44, 2}}},
|
||||
{Country: "Austria", City: "Vienna", Hostname: "vie-c05.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{104, 238, 44, 8}}},
|
||||
{Country: "Austria", City: "Vienna", Hostname: "vie-c06.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{104, 238, 44, 14}}},
|
||||
{Country: "Austria", City: "Vienna", Hostname: "vie-c07.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{104, 238, 44, 20}}},
|
||||
{Country: "Austria", City: "Vienna", Hostname: "vie-c08.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{104, 238, 44, 26}}},
|
||||
{Country: "Austria", City: "Vienna", Hostname: "vie-c09.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{104, 238, 44, 32}}},
|
||||
{Country: "Austria", City: "Vienna", Hostname: "vie-c10.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{104, 238, 44, 140}}},
|
||||
{Country: "Austria", City: "Vienna", Hostname: "vie-c11.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{104, 238, 44, 150}}},
|
||||
{Country: "Austria", City: "Vienna", Hostname: "vie-c12.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{104, 238, 44, 160}}},
|
||||
{Country: "Austria", City: "Vienna", Hostname: "vie-c13.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{104, 238, 44, 170}}},
|
||||
{Country: "Austria", City: "Vienna", Hostname: "vie-c14.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{104, 238, 44, 180}}},
|
||||
{Country: "Austria", City: "Vienna", Hostname: "vie-c15.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{104, 238, 44, 190}}},
|
||||
{Country: "Austria", City: "Vienna", Hostname: "vie-c16.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{104, 238, 44, 200}}},
|
||||
{Country: "Austria", City: "Vienna", Hostname: "vie-c01.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 110, 2}}},
|
||||
{Country: "Austria", City: "Vienna", Hostname: "vie-c02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 110, 8}}},
|
||||
{Country: "Austria", City: "Vienna", Hostname: "vie-c03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 110, 14}}},
|
||||
{Country: "Austria", City: "Vienna", Hostname: "vie-c04.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 110, 20}}},
|
||||
{Country: "Austria", City: "Vienna", Hostname: "vie-c05.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 110, 26}}},
|
||||
{Country: "Austria", City: "Vienna", Hostname: "vie-c06.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 110, 130}}},
|
||||
{Country: "Austria", City: "Vienna", Hostname: "vie-c07.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 110, 136}}},
|
||||
{Country: "Austria", City: "Vienna", Hostname: "vie-c08.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 110, 142}}},
|
||||
{Country: "Austria", City: "Vienna", Hostname: "vie-c09.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 110, 148}}},
|
||||
{Country: "Austria", City: "Vienna", Hostname: "vie-c10.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 110, 154}}},
|
||||
{Country: "Austria", City: "Vienna", Hostname: "vie-c11.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 110, 160}}},
|
||||
{Country: "Austria", City: "Vienna", Hostname: "vie-c12.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 110, 166}}},
|
||||
{Country: "Belgium", City: "Brussels", Hostname: "bru-c01.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{37, 120, 218, 99}}},
|
||||
{Country: "Belgium", City: "Brussels", Hostname: "bru-c02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{37, 120, 218, 101}}},
|
||||
{Country: "Belgium", City: "Brussels", Hostname: "bru-c03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{37, 120, 218, 103}}},
|
||||
@@ -201,6 +198,11 @@ func IpvanishServers() []models.IpvanishServer {
|
||||
{Country: "Canada", City: "Vancouver", Hostname: "yvr-c05.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{107, 181, 189, 138}}},
|
||||
{Country: "Canada", City: "Vancouver", Hostname: "yvr-c06.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{107, 181, 189, 186}}},
|
||||
{Country: "Canada", City: "Vancouver", Hostname: "yvr-c07.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{107, 181, 189, 227}}},
|
||||
{Country: "Chile", City: "Santiago", Hostname: "scl-c01.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{191, 101, 28, 5}}},
|
||||
{Country: "Chile", City: "Santiago", Hostname: "scl-c02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{191, 101, 28, 9}}},
|
||||
{Country: "Chile", City: "Santiago", Hostname: "scl-c03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{191, 101, 28, 13}}},
|
||||
{Country: "Chile", City: "Santiago", Hostname: "scl-c04.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{191, 101, 28, 17}}},
|
||||
{Country: "Chile", City: "Santiago", Hostname: "scl-c05.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{191, 101, 28, 21}}},
|
||||
{Country: "Colombia", City: "Bogota", Hostname: "bog-c01.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{199, 33, 68, 11}}},
|
||||
{Country: "Colombia", City: "Bogota", Hostname: "bog-c02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{199, 33, 68, 17}}},
|
||||
{Country: "Colombia", City: "Bogota", Hostname: "bog-c03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{199, 33, 68, 23}}},
|
||||
@@ -213,20 +215,23 @@ func IpvanishServers() []models.IpvanishServer {
|
||||
{Country: "Croatia", City: "Zagreb", Hostname: "zag-c06.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{85, 10, 57, 221}}},
|
||||
{Country: "Croatia", City: "Zagreb", Hostname: "zag-c07.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{85, 10, 57, 227}}},
|
||||
{Country: "Croatia", City: "Zagreb", Hostname: "zag-c08.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{85, 10, 57, 233}}},
|
||||
{Country: "Czech Republic", City: "Prague", Hostname: "prg-c10.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{104, 238, 39, 150}}},
|
||||
{Country: "Czech Republic", City: "Prague", Hostname: "prg-c11.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{104, 238, 39, 170}}},
|
||||
{Country: "Czech Republic", City: "Prague", Hostname: "prg-c12.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{104, 238, 39, 190}}},
|
||||
{Country: "Czech Republic", City: "Prague", Hostname: "prg-c13.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{104, 238, 39, 210}}},
|
||||
{Country: "Czech Republic", City: "Prague", Hostname: "prg-c15.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{104, 238, 39, 2}}},
|
||||
{Country: "Czech Republic", City: "Prague", Hostname: "prg-c16.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{104, 238, 39, 8}}},
|
||||
{Country: "Czech Republic", City: "Prague", Hostname: "prg-c17.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{104, 238, 39, 14}}},
|
||||
{Country: "Czech Republic", City: "Prague", Hostname: "prg-c18.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{104, 238, 39, 20}}},
|
||||
{Country: "Czech Republic", City: "Prague", Hostname: "prg-c21.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{104, 238, 39, 39}}},
|
||||
{Country: "Czech Republic", City: "Prague", Hostname: "prg-c22.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{104, 238, 39, 45}}},
|
||||
{Country: "Czech Republic", City: "Prague", Hostname: "prg-c23.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{104, 238, 39, 51}}},
|
||||
{Country: "Czech Republic", City: "Prague", Hostname: "prg-c24.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{104, 238, 39, 57}}},
|
||||
{Country: "Czech Republic", City: "Prague", Hostname: "prg-c25.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{104, 238, 39, 63}}},
|
||||
{Country: "Czech Republic", City: "Prague", Hostname: "prg-c26.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{104, 238, 39, 69}}},
|
||||
{Country: "Czech Republic", City: "Prague", Hostname: "prg-c09.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 109, 39}}},
|
||||
{Country: "Czech Republic", City: "Prague", Hostname: "prg-c10.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 109, 45}}},
|
||||
{Country: "Czech Republic", City: "Prague", Hostname: "prg-c11.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 109, 51}}},
|
||||
{Country: "Czech Republic", City: "Prague", Hostname: "prg-c12.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 109, 57}}},
|
||||
{Country: "Czech Republic", City: "Prague", Hostname: "prg-c13.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 109, 63}}},
|
||||
{Country: "Czech Republic", City: "Prague", Hostname: "prg-c15.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 109, 130}}},
|
||||
{Country: "Czech Republic", City: "Prague", Hostname: "prg-c16.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 109, 136}}},
|
||||
{Country: "Czech Republic", City: "Prague", Hostname: "prg-c17.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 109, 142}}},
|
||||
{Country: "Czech Republic", City: "Prague", Hostname: "prg-c18.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 109, 148}}},
|
||||
{Country: "Czech Republic", City: "Prague", Hostname: "prg-c19.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 109, 154}}},
|
||||
{Country: "Czech Republic", City: "Prague", Hostname: "prg-c20.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 109, 160}}},
|
||||
{Country: "Czech Republic", City: "Prague", Hostname: "prg-c21.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 109, 3}}},
|
||||
{Country: "Czech Republic", City: "Prague", Hostname: "prg-c22.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 109, 9}}},
|
||||
{Country: "Czech Republic", City: "Prague", Hostname: "prg-c23.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 109, 15}}},
|
||||
{Country: "Czech Republic", City: "Prague", Hostname: "prg-c24.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 109, 21}}},
|
||||
{Country: "Czech Republic", City: "Prague", Hostname: "prg-c25.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 109, 27}}},
|
||||
{Country: "Czech Republic", City: "Prague", Hostname: "prg-c26.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 109, 33}}},
|
||||
{Country: "Denmark", City: "Copenhagen", Hostname: "cph-c09.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 245, 84, 8}}},
|
||||
{Country: "Denmark", City: "Copenhagen", Hostname: "cph-c10.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 245, 84, 10}}},
|
||||
{Country: "Denmark", City: "Copenhagen", Hostname: "cph-c11.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 245, 84, 12}}},
|
||||
@@ -268,20 +273,20 @@ func IpvanishServers() []models.IpvanishServer {
|
||||
{Country: "France", City: "Marseille", Hostname: "mrs-c06.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{176, 67, 82, 8}}},
|
||||
{Country: "France", City: "Marseille", Hostname: "mrs-c07.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{176, 67, 82, 14}}},
|
||||
{Country: "France", City: "Marseille", Hostname: "mrs-c08.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{176, 67, 82, 20}}},
|
||||
{Country: "France", City: "Paris", Hostname: "par-a01.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 10, 232, 13}}},
|
||||
{Country: "France", City: "Paris", Hostname: "par-a02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 10, 232, 19}}},
|
||||
{Country: "France", City: "Paris", Hostname: "par-a03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 10, 232, 25}}},
|
||||
{Country: "France", City: "Paris", Hostname: "par-a04.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 10, 232, 31}}},
|
||||
{Country: "France", City: "Paris", Hostname: "par-a05.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 10, 232, 37}}},
|
||||
{Country: "France", City: "Paris", Hostname: "par-a06.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 10, 232, 43}}},
|
||||
{Country: "France", City: "Paris", Hostname: "par-a07.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 10, 232, 49}}},
|
||||
{Country: "France", City: "Paris", Hostname: "par-a08.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 10, 232, 55}}},
|
||||
{Country: "France", City: "Paris", Hostname: "par-a09.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 10, 232, 61}}},
|
||||
{Country: "France", City: "Paris", Hostname: "par-a10.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 10, 232, 67}}},
|
||||
{Country: "France", City: "Paris", Hostname: "par-a11.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 10, 232, 73}}},
|
||||
{Country: "France", City: "Paris", Hostname: "par-a12.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 10, 232, 79}}},
|
||||
{Country: "France", City: "Paris", Hostname: "par-a13.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 10, 232, 85}}},
|
||||
{Country: "France", City: "Paris", Hostname: "par-a14.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 10, 232, 91}}},
|
||||
{Country: "France", City: "Paris", Hostname: "par-a01.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 147, 212, 17}}},
|
||||
{Country: "France", City: "Paris", Hostname: "par-a02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 147, 212, 21}}},
|
||||
{Country: "France", City: "Paris", Hostname: "par-a03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 147, 212, 25}}},
|
||||
{Country: "France", City: "Paris", Hostname: "par-a04.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 147, 212, 29}}},
|
||||
{Country: "France", City: "Paris", Hostname: "par-a05.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 147, 212, 33}}},
|
||||
{Country: "France", City: "Paris", Hostname: "par-a06.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 147, 212, 37}}},
|
||||
{Country: "France", City: "Paris", Hostname: "par-a07.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 147, 212, 41}}},
|
||||
{Country: "France", City: "Paris", Hostname: "par-a08.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 147, 212, 45}}},
|
||||
{Country: "France", City: "Paris", Hostname: "par-a09.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 147, 212, 49}}},
|
||||
{Country: "France", City: "Paris", Hostname: "par-a10.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 147, 212, 53}}},
|
||||
{Country: "France", City: "Paris", Hostname: "par-a11.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 147, 212, 57}}},
|
||||
{Country: "France", City: "Paris", Hostname: "par-a12.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 147, 212, 61}}},
|
||||
{Country: "France", City: "Paris", Hostname: "par-a13.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 147, 212, 65}}},
|
||||
{Country: "France", City: "Paris", Hostname: "par-a14.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 147, 212, 69}}},
|
||||
{Country: "France", City: "Paris", Hostname: "par-a15.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 10, 232, 97}}},
|
||||
{Country: "France", City: "Paris", Hostname: "par-a16.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 10, 232, 103}}},
|
||||
{Country: "France", City: "Paris", Hostname: "par-a17.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 10, 232, 109}}},
|
||||
@@ -338,22 +343,22 @@ func IpvanishServers() []models.IpvanishServer {
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-a42.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 183, 93, 19}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-a43.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 183, 93, 25}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-a44.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 183, 93, 31}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-c01.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 183, 94, 2}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-c02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 183, 94, 4}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-c03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 183, 94, 6}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-c04.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 183, 94, 8}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-c05.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 183, 94, 10}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-c06.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 183, 94, 12}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-c07.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 183, 94, 38}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-c09.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 183, 94, 42}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-c10.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 183, 94, 44}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-c11.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 183, 94, 46}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-c12.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 183, 94, 48}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-c13.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 183, 94, 74}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-c14.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 183, 94, 76}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-c15.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 183, 94, 78}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-c16.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 183, 94, 80}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-c17.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 183, 94, 82}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-c01.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 111, 2}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-c02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 111, 8}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-c03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 111, 14}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-c04.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 111, 20}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-c05.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 111, 26}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-c06.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 111, 32}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-c07.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 111, 38}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-c08.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 111, 44}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-c09.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 111, 130}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-c10.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 111, 136}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-c11.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 111, 142}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-c12.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 111, 148}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-c13.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 111, 154}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-c14.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 111, 160}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-c15.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 111, 166}}},
|
||||
{Country: "Germany", City: "Frankfurt", Hostname: "fra-c16.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 111, 172}}},
|
||||
{Country: "Greece", City: "Athens", Hostname: "ath-c01.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{194, 150, 167, 98}}},
|
||||
{Country: "Greece", City: "Athens", Hostname: "ath-c02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{194, 150, 167, 100}}},
|
||||
{Country: "Greece", City: "Athens", Hostname: "ath-c03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{194, 150, 167, 102}}},
|
||||
@@ -393,18 +398,32 @@ func IpvanishServers() []models.IpvanishServer {
|
||||
{Country: "Israel", City: "Tel Aviv", Hostname: "tlv-c08.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{87, 239, 255, 73}}},
|
||||
{Country: "Israel", City: "Tel Aviv", Hostname: "tlv-c09.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{87, 239, 255, 75}}},
|
||||
{Country: "Israel", City: "Tel Aviv", Hostname: "tlv-c10.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{87, 239, 255, 77}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a01.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 56, 137, 24}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 56, 137, 26}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 56, 137, 4}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a04.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 56, 137, 6}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a05.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 56, 137, 44}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a06.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 56, 137, 46}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a07.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 56, 137, 48}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a08.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 56, 137, 50}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a09.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 56, 137, 76}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a10.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 56, 137, 78}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a11.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 56, 137, 80}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a12.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 56, 137, 82}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a13.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{69, 16, 157, 4}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a14.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{69, 16, 157, 10}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a15.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{69, 16, 157, 16}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a16.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{69, 16, 157, 22}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a17.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{69, 16, 157, 28}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a18.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{69, 16, 157, 34}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a19.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{69, 16, 157, 40}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a20.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{69, 16, 157, 46}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a21.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{69, 16, 157, 52}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a22.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{69, 16, 157, 58}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a23.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{69, 16, 157, 64}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a24.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{69, 16, 157, 70}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a25.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{69, 16, 157, 76}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a26.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{69, 16, 157, 82}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a27.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{69, 16, 157, 88}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a28.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{69, 16, 157, 94}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a29.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{69, 16, 157, 100}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a30.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{69, 16, 157, 106}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a31.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{69, 16, 157, 112}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a32.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{69, 16, 157, 118}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a33.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{69, 16, 157, 124}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a34.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{69, 16, 157, 130}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a35.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{69, 16, 157, 136}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a36.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{69, 16, 157, 142}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a37.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{69, 16, 157, 148}}},
|
||||
{Country: "Italy", City: "Milan", Hostname: "lin-a38.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{69, 16, 157, 154}}},
|
||||
{Country: "Japan", City: "Tokyo", Hostname: "nrt-a01.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{173, 245, 217, 3}}},
|
||||
{Country: "Japan", City: "Tokyo", Hostname: "nrt-a02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{173, 245, 217, 7}}},
|
||||
{Country: "Japan", City: "Tokyo", Hostname: "nrt-a03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{173, 245, 217, 11}}},
|
||||
@@ -435,7 +454,6 @@ func IpvanishServers() []models.IpvanishServer {
|
||||
{Country: "Latvia", City: "Riga", Hostname: "rix-c04.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{80, 246, 31, 23}}},
|
||||
{Country: "Latvia", City: "Riga", Hostname: "rix-c05.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{80, 246, 31, 25}}},
|
||||
{Country: "Luxembourg", City: "Luxembourg", Hostname: "lux-c02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 153, 151, 3}}},
|
||||
{Country: "Luxembourg", City: "Luxembourg", Hostname: "lux-c03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 153, 151, 5}}},
|
||||
{Country: "Malaysia", City: "Kuala Lumpur", Hostname: "kul-c01.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{202, 73, 14, 57}}},
|
||||
{Country: "Malaysia", City: "Kuala Lumpur", Hostname: "kul-c02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{202, 73, 14, 53}}},
|
||||
{Country: "Malaysia", City: "Kuala Lumpur", Hostname: "kul-c03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{103, 246, 112, 197}}},
|
||||
@@ -448,56 +466,52 @@ func IpvanishServers() []models.IpvanishServer {
|
||||
{Country: "Mexico", City: "Guadalajara", Hostname: "gdl-c12.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{143, 255, 58, 53}}},
|
||||
{Country: "Moldova", City: "Chisinau", Hostname: "kiv-c02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 163, 46, 147}}},
|
||||
{Country: "Moldova", City: "Chisinau", Hostname: "kiv-c03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 163, 46, 153}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 24}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a04.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 30}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a05.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 36}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a06.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 42}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a07.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 48}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a08.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 54}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a09.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 60}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a10.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 66}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a11.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 72}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a12.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 78}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a13.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 84}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a14.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 90}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a15.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 96}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a16.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 102}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a17.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 108}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a18.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 114}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a19.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 120}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a20.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 126}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a21.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 132}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a22.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 138}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a23.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 144}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a24.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 150}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a25.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 156}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a26.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 162}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a27.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 168}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a28.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 174}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a29.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 180}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a30.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 186}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a31.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 192}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a32.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 198}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a33.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 204}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a34.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 210}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a35.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 216}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a36.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 222}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a37.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 228}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a38.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 234}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a39.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 240}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a01.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 3}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 9}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 15}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a04.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 21}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a05.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 27}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a06.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 33}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a07.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 39}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a08.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 45}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a09.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 51}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a10.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 57}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a11.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 63}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a12.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 69}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a13.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 75}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a14.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 81}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a15.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 87}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a16.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 91}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a17.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 97}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a18.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 103}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a19.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 109}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a20.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 115}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a21.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 121}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a22.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 127}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a23.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 133}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a24.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 139}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a25.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 145}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a26.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 151}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a27.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 157}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a28.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 163}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a29.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 170}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a30.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 176}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a31.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 182}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a32.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 188}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a33.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 194}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a34.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 200}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a35.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 206}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a36.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 212}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a37.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 218}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a38.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 224}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a39.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 88, 230}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a40.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 12, 246}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a41.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 13, 7}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a50.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 13, 61}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a51.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 13, 67}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a52.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 13, 73}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a54.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 13, 85}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a55.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 13, 91}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a56.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 13, 97}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a57.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 13, 103}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a58.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 13, 109}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a59.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 13, 115}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a60.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 13, 121}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-a61.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{2, 58, 13, 127}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-c37.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{172, 83, 45, 131}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-c38.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{172, 83, 45, 137}}},
|
||||
{Country: "Netherlands", City: "Amsterdam", Hostname: "ams-c39.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{172, 83, 45, 143}}},
|
||||
@@ -590,7 +604,6 @@ func IpvanishServers() []models.IpvanishServer {
|
||||
{Country: "Slovakia", City: "Bratislava", Hostname: "bts-c07.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{176, 67, 87, 28}}},
|
||||
{Country: "Slovakia", City: "Bratislava", Hostname: "bts-c08.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{176, 67, 87, 38}}},
|
||||
{Country: "Slovakia", City: "Bratislava", Hostname: "bts-c09.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{176, 67, 87, 48}}},
|
||||
{Country: "Slovenia", City: "Ljubljana", Hostname: "lju-c01.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{195, 158, 249, 68}}},
|
||||
{Country: "Slovenia", City: "Ljubljana", Hostname: "lju-c02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{195, 158, 249, 70}}},
|
||||
{Country: "Slovenia", City: "Ljubljana", Hostname: "lju-c03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{195, 158, 249, 72}}},
|
||||
{Country: "Slovenia", City: "Ljubljana", Hostname: "lju-c04.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{195, 158, 249, 74}}},
|
||||
@@ -632,6 +645,10 @@ func IpvanishServers() []models.IpvanishServer {
|
||||
{Country: "Spain", City: "Madrid", Hostname: "mad-a28.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 147, 214, 182}}},
|
||||
{Country: "Spain", City: "Madrid", Hostname: "mad-a29.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 147, 214, 188}}},
|
||||
{Country: "Spain", City: "Madrid", Hostname: "mad-a30.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 147, 214, 194}}},
|
||||
{Country: "Spain", City: "Valencia", Hostname: "vlc-c03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 153, 150, 3}}},
|
||||
{Country: "Spain", City: "Valencia", Hostname: "vlc-c04.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 153, 150, 5}}},
|
||||
{Country: "Spain", City: "Valencia", Hostname: "vlc-c05.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 153, 150, 7}}},
|
||||
{Country: "Spain", City: "Valencia", Hostname: "vlc-c06.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 153, 150, 9}}},
|
||||
{Country: "Sweden", City: "Stockholm", Hostname: "sto-a01.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 147, 213, 18}}},
|
||||
{Country: "Sweden", City: "Stockholm", Hostname: "sto-a02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 147, 213, 24}}},
|
||||
{Country: "Sweden", City: "Stockholm", Hostname: "sto-a03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 147, 213, 30}}},
|
||||
@@ -662,18 +679,18 @@ func IpvanishServers() []models.IpvanishServer {
|
||||
{Country: "Sweden", City: "Stockholm", Hostname: "sto-a28.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 147, 213, 180}}},
|
||||
{Country: "Sweden", City: "Stockholm", Hostname: "sto-a29.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 147, 213, 186}}},
|
||||
{Country: "Sweden", City: "Stockholm", Hostname: "sto-a30.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 147, 213, 192}}},
|
||||
{Country: "Switzerland", City: "Zurich", Hostname: "zrh-c02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 82, 223, 5}}},
|
||||
{Country: "Switzerland", City: "Zurich", Hostname: "zrh-c03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 82, 223, 7}}},
|
||||
{Country: "Switzerland", City: "Zurich", Hostname: "zrh-c04.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 82, 223, 9}}},
|
||||
{Country: "Switzerland", City: "Zurich", Hostname: "zrh-c05.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 82, 223, 11}}},
|
||||
{Country: "Switzerland", City: "Zurich", Hostname: "zrh-c07.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 82, 223, 15}}},
|
||||
{Country: "Switzerland", City: "Zurich", Hostname: "zrh-c10.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 82, 223, 121}}},
|
||||
{Country: "Switzerland", City: "Zurich", Hostname: "zrh-c12.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 82, 223, 141}}},
|
||||
{Country: "Switzerland", City: "Zurich", Hostname: "zrh-c13.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 82, 223, 151}}},
|
||||
{Country: "Switzerland", City: "Zurich", Hostname: "zrh-c14.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 82, 223, 161}}},
|
||||
{Country: "Switzerland", City: "Zurich", Hostname: "zrh-c15.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 82, 223, 171}}},
|
||||
{Country: "Switzerland", City: "Zurich", Hostname: "zrh-c16.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 82, 223, 181}}},
|
||||
{Country: "Switzerland", City: "Zurich", Hostname: "zrh-c17.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 82, 223, 191}}},
|
||||
{Country: "Switzerland", City: "Zurich", Hostname: "zrh-c01.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 108, 2}}},
|
||||
{Country: "Switzerland", City: "Zurich", Hostname: "zrh-c02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 108, 8}}},
|
||||
{Country: "Switzerland", City: "Zurich", Hostname: "zrh-c03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 108, 14}}},
|
||||
{Country: "Switzerland", City: "Zurich", Hostname: "zrh-c04.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 108, 20}}},
|
||||
{Country: "Switzerland", City: "Zurich", Hostname: "zrh-c05.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 108, 26}}},
|
||||
{Country: "Switzerland", City: "Zurich", Hostname: "zrh-c06.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 108, 32}}},
|
||||
{Country: "Switzerland", City: "Zurich", Hostname: "zrh-c07.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 108, 130}}},
|
||||
{Country: "Switzerland", City: "Zurich", Hostname: "zrh-c08.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 108, 136}}},
|
||||
{Country: "Switzerland", City: "Zurich", Hostname: "zrh-c09.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 108, 142}}},
|
||||
{Country: "Switzerland", City: "Zurich", Hostname: "zrh-c10.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 108, 148}}},
|
||||
{Country: "Switzerland", City: "Zurich", Hostname: "zrh-c11.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 108, 154}}},
|
||||
{Country: "Switzerland", City: "Zurich", Hostname: "zrh-c12.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 108, 160}}},
|
||||
{Country: "Taiwan", City: "Taipei", Hostname: "tpe-c01.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{103, 4, 31, 133}}},
|
||||
{Country: "Taiwan", City: "Taipei", Hostname: "tpe-c02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{103, 4, 31, 135}}},
|
||||
{Country: "Ukraine", City: "Kiev", Hostname: "iev-c01.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{139, 28, 38, 28}}},
|
||||
@@ -701,65 +718,68 @@ func IpvanishServers() []models.IpvanishServer {
|
||||
{Country: "United Kingdom", City: "Glasgow", Hostname: "gla-c01.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 108, 105, 164}}},
|
||||
{Country: "United Kingdom", City: "Glasgow", Hostname: "gla-c02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 108, 105, 170}}},
|
||||
{Country: "United Kingdom", City: "Glasgow", Hostname: "gla-c03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 108, 105, 176}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a01.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 9}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 15}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 21}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a04.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 27}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a05.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 33}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a06.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 39}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a07.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 45}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a08.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 51}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a09.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 57}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a10.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 63}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a11.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 69}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a12.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 75}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a13.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 81}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a14.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 87}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a15.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 93}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a16.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 99}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a17.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 105}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a18.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 111}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a19.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 117}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a20.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 123}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a21.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 129}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a22.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 135}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a23.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 141}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a24.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 147}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a25.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 153}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a26.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 159}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a27.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 165}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a28.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 171}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a29.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 177}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a30.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 183}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a31.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 189}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a32.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 195}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a33.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 201}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a34.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 207}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a35.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 213}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a36.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 219}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a37.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 225}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a38.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 231}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a39.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 237}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a40.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 220, 243}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a41.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 221, 4}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a42.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 221, 10}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a43.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 221, 16}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a44.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 221, 22}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a45.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 221, 28}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a46.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 221, 34}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a47.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 221, 40}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a48.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 221, 46}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a49.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 221, 52}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a50.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 221, 58}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a51.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 221, 64}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a52.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 221, 70}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a53.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 221, 76}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a54.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 221, 82}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a55.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 221, 88}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a56.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 221, 94}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a57.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 221, 100}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a58.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 221, 106}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a59.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{5, 180, 221, 112}}},
|
||||
{Country: "United Kingdom", City: "Glasgow", Hostname: "gla-c04.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 108, 105, 196}}},
|
||||
{Country: "United Kingdom", City: "Glasgow", Hostname: "gla-c05.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 108, 105, 202}}},
|
||||
{Country: "United Kingdom", City: "Glasgow", Hostname: "gla-c06.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 108, 105, 208}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a01.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 86}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 92}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 98}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a04.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 104}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a05.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 110}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a06.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 116}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a07.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 122}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a08.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 128}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a09.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 134}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a10.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 140}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a11.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 2}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a12.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 8}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a13.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 14}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a14.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 20}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a15.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 26}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a16.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 32}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a17.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 38}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a18.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 44}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a19.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 50}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a20.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 56}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a21.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 62}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a22.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 68}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a23.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 74}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a24.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 80}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a25.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 146}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a26.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 152}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a27.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 158}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a28.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 164}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a29.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 170}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a30.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 176}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a31.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 182}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a32.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 188}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a33.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 194}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a34.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 200}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a35.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 206}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a36.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 212}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a37.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 218}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a38.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 224}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a39.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 230}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a40.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 236}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a41.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 242}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a42.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 248}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a43.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 116, 254}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a44.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 117, 6}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a45.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 117, 12}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a46.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 117, 18}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a47.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 117, 24}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a48.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 117, 30}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a49.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 117, 36}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a50.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 117, 42}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a51.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 117, 48}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a52.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 117, 54}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a53.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 117, 60}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a54.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 117, 66}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a55.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 117, 72}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a56.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 117, 78}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a57.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 117, 84}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a58.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 117, 90}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a59.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 117, 96}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a60.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{176, 67, 85, 10}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a61.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{176, 67, 85, 12}}},
|
||||
{Country: "United Kingdom", City: "London", Hostname: "lon-a62.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{176, 67, 85, 14}}},
|
||||
@@ -783,15 +803,15 @@ func IpvanishServers() []models.IpvanishServer {
|
||||
{Country: "United Kingdom", City: "Manchester", Hostname: "man-c07.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 242, 7, 10}}},
|
||||
{Country: "United Kingdom", City: "Manchester", Hostname: "man-c08.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{89, 238, 142, 242}}},
|
||||
{Country: "United Kingdom", City: "Manchester", Hostname: "man-c09.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{89, 238, 142, 244}}},
|
||||
{Country: "United Kingdom", City: "Manchester", Hostname: "man-c10.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 244, 9, 5}}},
|
||||
{Country: "United Kingdom", City: "Manchester", Hostname: "man-c11.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 244, 9, 7}}},
|
||||
{Country: "United Kingdom", City: "Manchester", Hostname: "man-c12.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 244, 9, 9}}},
|
||||
{Country: "United Kingdom", City: "Manchester", Hostname: "man-c13.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 244, 9, 11}}},
|
||||
{Country: "United Kingdom", City: "Manchester", Hostname: "man-c14.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 244, 9, 13}}},
|
||||
{Country: "United Kingdom", City: "Manchester", Hostname: "man-c15.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 244, 9, 15}}},
|
||||
{Country: "United Kingdom", City: "Manchester", Hostname: "man-c16.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 244, 9, 17}}},
|
||||
{Country: "United Kingdom", City: "Manchester", Hostname: "man-c17.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 244, 9, 19}}},
|
||||
{Country: "United Kingdom", City: "Manchester", Hostname: "man-c18.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{185, 244, 9, 21}}},
|
||||
{Country: "United Kingdom", City: "Manchester", Hostname: "man-c10.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 121, 50}}},
|
||||
{Country: "United Kingdom", City: "Manchester", Hostname: "man-c11.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 121, 44}}},
|
||||
{Country: "United Kingdom", City: "Manchester", Hostname: "man-c12.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 121, 38}}},
|
||||
{Country: "United Kingdom", City: "Manchester", Hostname: "man-c13.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 121, 32}}},
|
||||
{Country: "United Kingdom", City: "Manchester", Hostname: "man-c14.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 121, 26}}},
|
||||
{Country: "United Kingdom", City: "Manchester", Hostname: "man-c15.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 121, 20}}},
|
||||
{Country: "United Kingdom", City: "Manchester", Hostname: "man-c16.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 121, 14}}},
|
||||
{Country: "United Kingdom", City: "Manchester", Hostname: "man-c17.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 121, 8}}},
|
||||
{Country: "United Kingdom", City: "Manchester", Hostname: "man-c18.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 121, 2}}},
|
||||
{Country: "United States", City: "Ashburn", Hostname: "iad-a01.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{173, 245, 203, 2}}},
|
||||
{Country: "United States", City: "Ashburn", Hostname: "iad-a02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{173, 245, 203, 8}}},
|
||||
{Country: "United States", City: "Ashburn", Hostname: "iad-a03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{173, 245, 203, 14}}},
|
||||
@@ -898,6 +918,7 @@ func IpvanishServers() []models.IpvanishServer {
|
||||
{Country: "United States", City: "Ashburn", Hostname: "iad-b26.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 73, 69}}},
|
||||
{Country: "United States", City: "Ashburn", Hostname: "iad-b27.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 73, 75}}},
|
||||
{Country: "United States", City: "Ashburn", Hostname: "iad-b28.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 73, 81}}},
|
||||
{Country: "United States", City: "Atlanta", Hostname: "atl-a01.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{64, 145, 67, 7}}},
|
||||
{Country: "United States", City: "Atlanta", Hostname: "atl-a02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{64, 145, 67, 21}}},
|
||||
{Country: "United States", City: "Atlanta", Hostname: "atl-a03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{64, 145, 67, 30}}},
|
||||
{Country: "United States", City: "Atlanta", Hostname: "atl-a04.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{64, 145, 67, 36}}},
|
||||
@@ -919,6 +940,7 @@ func IpvanishServers() []models.IpvanishServer {
|
||||
{Country: "United States", City: "Atlanta", Hostname: "atl-a20.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{209, 107, 196, 32}}},
|
||||
{Country: "United States", City: "Atlanta", Hostname: "atl-a21.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{209, 107, 196, 38}}},
|
||||
{Country: "United States", City: "Atlanta", Hostname: "atl-a22.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{209, 107, 196, 44}}},
|
||||
{Country: "United States", City: "Atlanta", Hostname: "atl-a23.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{209, 107, 196, 128}}},
|
||||
{Country: "United States", City: "Atlanta", Hostname: "atl-a24.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{209, 107, 196, 134}}},
|
||||
{Country: "United States", City: "Atlanta", Hostname: "atl-a25.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{209, 107, 196, 140}}},
|
||||
{Country: "United States", City: "Atlanta", Hostname: "atl-a26.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{209, 107, 196, 146}}},
|
||||
@@ -1069,7 +1091,6 @@ func IpvanishServers() []models.IpvanishServer {
|
||||
{Country: "United States", City: "Boston", Hostname: "bos-c49.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{198, 181, 163, 169}}},
|
||||
{Country: "United States", City: "Boston", Hostname: "bos-c50.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{198, 181, 163, 171}}},
|
||||
{Country: "United States", City: "Boston", Hostname: "bos-c51.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{198, 181, 163, 209}}},
|
||||
{Country: "United States", City: "Boston", Hostname: "bos-c52.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{198, 181, 163, 211}}},
|
||||
{Country: "United States", City: "Boston", Hostname: "bos-c54.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{198, 181, 163, 215}}},
|
||||
{Country: "United States", City: "Boston", Hostname: "bos-c55.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{198, 181, 163, 217}}},
|
||||
{Country: "United States", City: "Boston", Hostname: "bos-c56.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{198, 181, 163, 219}}},
|
||||
@@ -1086,8 +1107,6 @@ func IpvanishServers() []models.IpvanishServer {
|
||||
{Country: "United States", City: "Boston", Hostname: "bos-c68.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 56, 171, 20}}},
|
||||
{Country: "United States", City: "Boston", Hostname: "bos-c69.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 56, 171, 22}}},
|
||||
{Country: "United States", City: "Boston", Hostname: "bos-c70.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 56, 171, 24}}},
|
||||
{Country: "United States", City: "Boston", Hostname: "bos-c71.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 56, 171, 26}}},
|
||||
{Country: "United States", City: "Boston", Hostname: "bos-c72.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{45, 56, 171, 28}}},
|
||||
{Country: "United States", City: "Charlotte", Hostname: "clt-c01.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{173, 213, 88, 2}}},
|
||||
{Country: "United States", City: "Charlotte", Hostname: "clt-c02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{173, 213, 88, 4}}},
|
||||
{Country: "United States", City: "Charlotte", Hostname: "clt-c03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{173, 213, 88, 6}}},
|
||||
@@ -1214,31 +1233,26 @@ func IpvanishServers() []models.IpvanishServer {
|
||||
{Country: "United States", City: "Chicago", Hostname: "chi-b39.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 77, 68}}},
|
||||
{Country: "United States", City: "Chicago", Hostname: "chi-b40.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 77, 74}}},
|
||||
{Country: "United States", City: "Chicago", Hostname: "chi-b41.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 77, 80}}},
|
||||
{Country: "United States", City: "Chicago", Hostname: "chi-c17.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{205, 185, 193, 2}}},
|
||||
{Country: "United States", City: "Chicago", Hostname: "chi-c18.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{205, 185, 193, 4}}},
|
||||
{Country: "United States", City: "Chicago", Hostname: "chi-c19.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{205, 185, 193, 6}}},
|
||||
{Country: "United States", City: "Chicago", Hostname: "chi-c20.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{205, 185, 193, 8}}},
|
||||
{Country: "United States", City: "Chicago", Hostname: "chi-c21.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{205, 185, 193, 26}}},
|
||||
{Country: "United States", City: "Chicago", Hostname: "chi-c22.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{205, 185, 193, 28}}},
|
||||
{Country: "United States", City: "Chicago", Hostname: "chi-c23.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{205, 185, 193, 30}}},
|
||||
{Country: "United States", City: "Chicago", Hostname: "chi-c24.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{205, 185, 193, 44}}},
|
||||
{Country: "United States", City: "Chicago", Hostname: "chi-c25.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{205, 185, 193, 46}}},
|
||||
{Country: "United States", City: "Chicago", Hostname: "chi-c26.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{205, 185, 193, 48}}},
|
||||
{Country: "United States", City: "Chicago", Hostname: "chi-c27.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{205, 185, 193, 50}}},
|
||||
{Country: "United States", City: "Chicago", Hostname: "chi-c28.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{205, 185, 193, 52}}},
|
||||
{Country: "United States", City: "Chicago", Hostname: "chi-c29.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{205, 185, 193, 54}}},
|
||||
{Country: "United States", City: "Chicago", Hostname: "chi-c30.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{205, 185, 193, 80}}},
|
||||
{Country: "United States", City: "Chicago", Hostname: "chi-c31.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{205, 185, 193, 82}}},
|
||||
{Country: "United States", City: "Chicago", Hostname: "chi-c32.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{205, 185, 193, 84}}},
|
||||
{Country: "United States", City: "Chicago", Hostname: "chi-c33.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{205, 185, 193, 86}}},
|
||||
{Country: "United States", City: "Chicago", Hostname: "chi-c34.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{205, 185, 193, 88}}},
|
||||
{Country: "United States", City: "Chicago", Hostname: "chi-c35.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{205, 185, 193, 90}}},
|
||||
{Country: "United States", City: "Chicago", Hostname: "chi-c36.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{205, 185, 193, 116}}},
|
||||
{Country: "United States", City: "Chicago", Hostname: "chi-c37.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{205, 185, 193, 118}}},
|
||||
{Country: "United States", City: "Chicago", Hostname: "chi-c38.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{205, 185, 193, 120}}},
|
||||
{Country: "United States", City: "Chicago", Hostname: "chi-c39.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{205, 185, 193, 122}}},
|
||||
{Country: "United States", City: "Chicago", Hostname: "chi-c40.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{205, 185, 193, 124}}},
|
||||
{Country: "United States", City: "Chicago", Hostname: "chi-c41.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{205, 185, 193, 126}}},
|
||||
{Country: "United States", City: "Cincinnati", Hostname: "cvg-b01.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 84, 7}}},
|
||||
{Country: "United States", City: "Cincinnati", Hostname: "cvg-b02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 84, 13}}},
|
||||
{Country: "United States", City: "Cincinnati", Hostname: "cvg-b03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 84, 19}}},
|
||||
{Country: "United States", City: "Cincinnati", Hostname: "cvg-b04.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 84, 25}}},
|
||||
{Country: "United States", City: "Cincinnati", Hostname: "cvg-b05.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 84, 31}}},
|
||||
{Country: "United States", City: "Cincinnati", Hostname: "cvg-b06.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 84, 37}}},
|
||||
{Country: "United States", City: "Cincinnati", Hostname: "cvg-b08.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 84, 49}}},
|
||||
{Country: "United States", City: "Cincinnati", Hostname: "cvg-b09.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 84, 55}}},
|
||||
{Country: "United States", City: "Cincinnati", Hostname: "cvg-b10.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 84, 61}}},
|
||||
{Country: "United States", City: "Cincinnati", Hostname: "cvg-b11.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 84, 67}}},
|
||||
{Country: "United States", City: "Cincinnati", Hostname: "cvg-b12.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 84, 73}}},
|
||||
{Country: "United States", City: "Cincinnati", Hostname: "cvg-b13.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 84, 79}}},
|
||||
{Country: "United States", City: "Cincinnati", Hostname: "cvg-b14.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 84, 85}}},
|
||||
{Country: "United States", City: "Cincinnati", Hostname: "cvg-b15.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 84, 91}}},
|
||||
{Country: "United States", City: "Cincinnati", Hostname: "cvg-b16.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 84, 97}}},
|
||||
{Country: "United States", City: "Cincinnati", Hostname: "cvg-b17.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 84, 103}}},
|
||||
{Country: "United States", City: "Cincinnati", Hostname: "cvg-b18.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 84, 109}}},
|
||||
{Country: "United States", City: "Cincinnati", Hostname: "cvg-b19.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 84, 115}}},
|
||||
{Country: "United States", City: "Cincinnati", Hostname: "cvg-b20.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 84, 121}}},
|
||||
{Country: "United States", City: "Cincinnati", Hostname: "cvg-b21.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 84, 127}}},
|
||||
{Country: "United States", City: "Dallas", Hostname: "dal-a01.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{205, 185, 214, 48}}},
|
||||
{Country: "United States", City: "Dallas", Hostname: "dal-a02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{205, 185, 214, 52}}},
|
||||
{Country: "United States", City: "Dallas", Hostname: "dal-a03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{205, 185, 214, 5}}},
|
||||
@@ -1592,7 +1606,6 @@ func IpvanishServers() []models.IpvanishServer {
|
||||
{Country: "United States", City: "Miami", Hostname: "mia-a51.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{173, 255, 191, 2}}},
|
||||
{Country: "United States", City: "Miami", Hostname: "mia-a52.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{173, 255, 191, 4}}},
|
||||
{Country: "United States", City: "Miami", Hostname: "mia-a53.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{173, 255, 191, 6}}},
|
||||
{Country: "United States", City: "Miami", Hostname: "mia-a54.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{173, 255, 191, 20}}},
|
||||
{Country: "United States", City: "Miami", Hostname: "mia-b01.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 87, 3}}},
|
||||
{Country: "United States", City: "Miami", Hostname: "mia-b02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 87, 9}}},
|
||||
{Country: "United States", City: "Miami", Hostname: "mia-b03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 87, 15}}},
|
||||
@@ -1861,6 +1874,20 @@ func IpvanishServers() []models.IpvanishServer {
|
||||
{Country: "United States", City: "San Jose", Hostname: "sjc-a39.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 151, 183, 230}}},
|
||||
{Country: "United States", City: "San Jose", Hostname: "sjc-a40.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 151, 183, 236}}},
|
||||
{Country: "United States", City: "San Jose", Hostname: "sjc-a41.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 151, 183, 242}}},
|
||||
{Country: "United States", City: "San Jose", Hostname: "sjc-a42.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 122, 7}}},
|
||||
{Country: "United States", City: "San Jose", Hostname: "sjc-a43.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 122, 8}}},
|
||||
{Country: "United States", City: "San Jose", Hostname: "sjc-a44.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 122, 14}}},
|
||||
{Country: "United States", City: "San Jose", Hostname: "sjc-a45.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 122, 20}}},
|
||||
{Country: "United States", City: "San Jose", Hostname: "sjc-a46.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 122, 26}}},
|
||||
{Country: "United States", City: "San Jose", Hostname: "sjc-a47.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 122, 32}}},
|
||||
{Country: "United States", City: "San Jose", Hostname: "sjc-a48.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 122, 38}}},
|
||||
{Country: "United States", City: "San Jose", Hostname: "sjc-a49.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 122, 44}}},
|
||||
{Country: "United States", City: "San Jose", Hostname: "sjc-a50.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 122, 50}}},
|
||||
{Country: "United States", City: "San Jose", Hostname: "sjc-a51.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 122, 56}}},
|
||||
{Country: "United States", City: "San Jose", Hostname: "sjc-a52.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 122, 62}}},
|
||||
{Country: "United States", City: "San Jose", Hostname: "sjc-a53.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 122, 68}}},
|
||||
{Country: "United States", City: "San Jose", Hostname: "sjc-a54.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{216, 131, 122, 74}}},
|
||||
{Country: "United States", City: "Seattle", Hostname: "sea-a01.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{205, 185, 223, 2}}},
|
||||
{Country: "United States", City: "Seattle", Hostname: "sea-a02.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{205, 185, 223, 8}}},
|
||||
{Country: "United States", City: "Seattle", Hostname: "sea-a03.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{205, 185, 223, 14}}},
|
||||
{Country: "United States", City: "Seattle", Hostname: "sea-a04.ipvanish.com", TCP: false, UDP: true, IPs: []net.IP{{205, 185, 223, 35}}},
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -23,7 +23,7 @@ func GetAllServers() (allServers models.AllServers) {
|
||||
},
|
||||
Ipvanish: models.IpvanishServers{
|
||||
Version: 1,
|
||||
Timestamp: 1622430497,
|
||||
Timestamp: 1625164062,
|
||||
Servers: IpvanishServers(),
|
||||
},
|
||||
Ivpn: models.IvpnServers{
|
||||
@@ -53,7 +53,7 @@ func GetAllServers() (allServers models.AllServers) {
|
||||
},
|
||||
Protonvpn: models.ProtonvpnServers{
|
||||
Version: 1,
|
||||
Timestamp: 1621791438,
|
||||
Timestamp: 1624894186,
|
||||
Servers: ProtonvpnServers(),
|
||||
},
|
||||
Pia: models.PiaServers{
|
||||
|
||||
@@ -175,7 +175,7 @@ func Test_timestamps(t *testing.T) {
|
||||
"Ipvanish": {
|
||||
servers: allServers.Ipvanish.Servers,
|
||||
timestamp: allServers.Ipvanish.Timestamp,
|
||||
digest: "c62dcf98",
|
||||
digest: "7c60dc5d",
|
||||
},
|
||||
"Ivpn": {
|
||||
servers: allServers.Ivpn.Servers,
|
||||
@@ -210,7 +210,7 @@ func Test_timestamps(t *testing.T) {
|
||||
"Protonvpn": {
|
||||
servers: allServers.Protonvpn.Servers,
|
||||
timestamp: allServers.Protonvpn.Timestamp,
|
||||
digest: "e7180296",
|
||||
digest: "3b86393e",
|
||||
},
|
||||
"Purevpn": {
|
||||
servers: allServers.Purevpn.Servers,
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"errors"
|
||||
"net"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/qdm12/dns/pkg/blacklist"
|
||||
@@ -24,23 +23,25 @@ type Looper interface {
|
||||
Run(ctx context.Context, done chan<- struct{})
|
||||
RunRestartTicker(ctx context.Context, done chan<- struct{})
|
||||
GetStatus() (status models.LoopStatus)
|
||||
SetStatus(status models.LoopStatus) (outcome string, err error)
|
||||
ApplyStatus(ctx context.Context, status models.LoopStatus) (
|
||||
outcome string, err error)
|
||||
GetSettings() (settings configuration.DNS)
|
||||
SetSettings(settings configuration.DNS) (outcome string)
|
||||
SetSettings(ctx context.Context, settings configuration.DNS) (
|
||||
outcome string)
|
||||
}
|
||||
|
||||
type looper struct {
|
||||
state state
|
||||
state *state
|
||||
conf unbound.Configurator
|
||||
blockBuilder blacklist.Builder
|
||||
client *http.Client
|
||||
logger logging.Logger
|
||||
loopLock sync.Mutex
|
||||
start chan struct{}
|
||||
running chan models.LoopStatus
|
||||
stop chan struct{}
|
||||
stopped chan struct{}
|
||||
updateTicker chan struct{}
|
||||
userTrigger bool
|
||||
start <-chan struct{}
|
||||
running chan<- models.LoopStatus
|
||||
stop <-chan struct{}
|
||||
stopped chan<- struct{}
|
||||
updateTicker <-chan struct{}
|
||||
backoffTime time.Duration
|
||||
timeNow func() time.Time
|
||||
timeSince func(time.Time) time.Duration
|
||||
@@ -51,20 +52,26 @@ const defaultBackoffTime = 10 * time.Second
|
||||
|
||||
func NewLooper(conf unbound.Configurator, settings configuration.DNS, client *http.Client,
|
||||
logger logging.Logger, openFile os.OpenFileFunc) Looper {
|
||||
start := make(chan struct{})
|
||||
running := make(chan models.LoopStatus)
|
||||
stop := make(chan struct{})
|
||||
stopped := make(chan struct{})
|
||||
updateTicker := make(chan struct{})
|
||||
|
||||
state := newState(constants.Stopped, settings, start, running, stop, stopped, updateTicker)
|
||||
|
||||
return &looper{
|
||||
state: state{
|
||||
status: constants.Stopped,
|
||||
settings: settings,
|
||||
},
|
||||
state: state,
|
||||
conf: conf,
|
||||
blockBuilder: blacklist.NewBuilder(client),
|
||||
client: client,
|
||||
logger: logger,
|
||||
start: make(chan struct{}),
|
||||
running: make(chan models.LoopStatus),
|
||||
stop: make(chan struct{}),
|
||||
stopped: make(chan struct{}),
|
||||
updateTicker: make(chan struct{}),
|
||||
userTrigger: true,
|
||||
start: start,
|
||||
running: running,
|
||||
stop: stop,
|
||||
stopped: stopped,
|
||||
updateTicker: updateTicker,
|
||||
backoffTime: defaultBackoffTime,
|
||||
timeNow: time.Now,
|
||||
timeSince: time.Since,
|
||||
@@ -76,7 +83,7 @@ func (l *looper) logAndWait(ctx context.Context, err error) {
|
||||
if err != nil {
|
||||
l.logger.Warn(err)
|
||||
}
|
||||
l.logger.Info("attempting restart in %s", l.backoffTime)
|
||||
l.logger.Info("attempting restart in " + l.backoffTime.String())
|
||||
timer := time.NewTimer(l.backoffTime)
|
||||
l.backoffTime *= 2
|
||||
select {
|
||||
@@ -88,6 +95,18 @@ func (l *looper) logAndWait(ctx context.Context, err error) {
|
||||
}
|
||||
}
|
||||
|
||||
func (l *looper) signalOrSetStatus(status models.LoopStatus) {
|
||||
if l.userTrigger {
|
||||
l.userTrigger = false
|
||||
select {
|
||||
case l.running <- status:
|
||||
default: // receiver droppped out - avoid deadlock on events routing when shutting down
|
||||
}
|
||||
} else {
|
||||
l.state.SetStatus(status)
|
||||
}
|
||||
}
|
||||
|
||||
func (l *looper) Run(ctx context.Context, done chan<- struct{}) {
|
||||
defer close(done)
|
||||
|
||||
@@ -101,43 +120,43 @@ func (l *looper) Run(ctx context.Context, done chan<- struct{}) {
|
||||
return
|
||||
}
|
||||
|
||||
crashed := false
|
||||
l.backoffTime = defaultBackoffTime
|
||||
|
||||
for ctx.Err() == nil {
|
||||
// Upper scope variables for Unbound only
|
||||
// Their values are to be used if DOT=off
|
||||
var waitError chan error
|
||||
var unboundCancel context.CancelFunc
|
||||
var closeStreams func()
|
||||
waitError := make(chan error)
|
||||
unboundCancel := func() { waitError <- nil }
|
||||
closeStreams := func() {}
|
||||
|
||||
for l.GetSettings().Enabled {
|
||||
var err error
|
||||
unboundCancel, waitError, closeStreams, err = l.setupUnbound(ctx)
|
||||
if err == nil {
|
||||
l.backoffTime = defaultBackoffTime
|
||||
l.logger.Info("ready")
|
||||
l.signalOrSetStatus(constants.Running)
|
||||
break
|
||||
}
|
||||
|
||||
l.signalOrSetStatus(constants.Crashed)
|
||||
|
||||
if ctx.Err() != nil {
|
||||
if !crashed {
|
||||
l.running <- constants.Stopped
|
||||
}
|
||||
return
|
||||
}
|
||||
var err error
|
||||
unboundCancel, waitError, closeStreams, err = l.setupUnbound(ctx, crashed)
|
||||
if err != nil {
|
||||
if !errors.Is(err, errUpdateFiles) {
|
||||
const fallback = true
|
||||
l.useUnencryptedDNS(fallback)
|
||||
}
|
||||
l.logAndWait(ctx, err)
|
||||
continue
|
||||
|
||||
if !errors.Is(err, errUpdateFiles) {
|
||||
const fallback = true
|
||||
l.useUnencryptedDNS(fallback)
|
||||
}
|
||||
break
|
||||
l.logAndWait(ctx, err)
|
||||
}
|
||||
|
||||
if !l.GetSettings().Enabled {
|
||||
const fallback = false
|
||||
l.useUnencryptedDNS(fallback)
|
||||
waitError := make(chan error)
|
||||
unboundCancel = func() { waitError <- nil }
|
||||
closeStreams = func() {}
|
||||
}
|
||||
|
||||
l.userTrigger = false
|
||||
|
||||
stayHere := true
|
||||
for stayHere {
|
||||
select {
|
||||
@@ -148,31 +167,32 @@ func (l *looper) Run(ctx context.Context, done chan<- struct{}) {
|
||||
closeStreams()
|
||||
return
|
||||
case <-l.stop:
|
||||
l.userTrigger = true
|
||||
l.logger.Info("stopping")
|
||||
const fallback = false
|
||||
l.useUnencryptedDNS(fallback)
|
||||
unboundCancel()
|
||||
<-waitError
|
||||
// do not close waitError or the waitError
|
||||
// select case will trigger
|
||||
closeStreams()
|
||||
l.stopped <- struct{}{}
|
||||
case <-l.start:
|
||||
l.userTrigger = true
|
||||
l.logger.Info("starting")
|
||||
stayHere = false
|
||||
case err := <-waitError: // unexpected error
|
||||
close(waitError)
|
||||
closeStreams()
|
||||
|
||||
unboundCancel()
|
||||
if ctx.Err() != nil {
|
||||
close(waitError)
|
||||
closeStreams()
|
||||
return
|
||||
}
|
||||
l.state.setStatusWithLock(constants.Crashed)
|
||||
l.state.SetStatus(constants.Crashed)
|
||||
const fallback = true
|
||||
l.useUnencryptedDNS(fallback)
|
||||
l.logAndWait(ctx, err)
|
||||
stayHere = false
|
||||
}
|
||||
}
|
||||
close(waitError)
|
||||
closeStreams()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,11 +201,10 @@ var errUpdateFiles = errors.New("cannot update files")
|
||||
// Returning cancel == nil signals we want to re-run setupUnbound
|
||||
// Returning err == errUpdateFiles signals we should not fall back
|
||||
// on the plaintext DNS as DOT is still up and running.
|
||||
func (l *looper) setupUnbound(ctx context.Context, previousCrashed bool) (
|
||||
func (l *looper) setupUnbound(ctx context.Context) (
|
||||
cancel context.CancelFunc, waitError chan error, closeStreams func(), err error) {
|
||||
err = l.updateFiles(ctx)
|
||||
if err != nil {
|
||||
l.state.setStatusWithLock(constants.Crashed)
|
||||
return nil, nil, nil, errUpdateFiles
|
||||
}
|
||||
|
||||
@@ -195,14 +214,16 @@ func (l *looper) setupUnbound(ctx context.Context, previousCrashed bool) (
|
||||
stdoutLines, stderrLines, waitError, err := l.conf.Start(unboundCtx, settings.Unbound.VerbosityDetailsLevel)
|
||||
if err != nil {
|
||||
cancel()
|
||||
if !previousCrashed {
|
||||
l.running <- constants.Crashed
|
||||
}
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
collectLinesDone := make(chan struct{})
|
||||
go l.collectLines(stdoutLines, stderrLines, collectLinesDone)
|
||||
closeStreams = func() {
|
||||
close(stdoutLines)
|
||||
close(stderrLines)
|
||||
<-collectLinesDone
|
||||
}
|
||||
|
||||
// use Unbound
|
||||
nameserver.UseDNSInternally(net.IP{127, 0, 0, 1})
|
||||
@@ -213,32 +234,13 @@ func (l *looper) setupUnbound(ctx context.Context, previousCrashed bool) (
|
||||
}
|
||||
|
||||
if err := check.WaitForDNS(ctx, net.DefaultResolver); err != nil {
|
||||
if !previousCrashed {
|
||||
l.running <- constants.Crashed
|
||||
}
|
||||
cancel()
|
||||
<-waitError
|
||||
close(waitError)
|
||||
close(stdoutLines)
|
||||
close(stderrLines)
|
||||
<-collectLinesDone
|
||||
closeStreams()
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
l.logger.Info("ready")
|
||||
if !previousCrashed {
|
||||
l.running <- constants.Running
|
||||
} else {
|
||||
l.backoffTime = defaultBackoffTime
|
||||
l.state.setStatusWithLock(constants.Running)
|
||||
}
|
||||
|
||||
closeStreams = func() {
|
||||
close(stdoutLines)
|
||||
close(stderrLines)
|
||||
<-collectLinesDone
|
||||
}
|
||||
|
||||
return cancel, waitError, closeStreams, nil
|
||||
}
|
||||
|
||||
@@ -299,15 +301,15 @@ func (l *looper) RunRestartTicker(ctx context.Context, done chan<- struct{}) {
|
||||
status := l.GetStatus()
|
||||
if status == constants.Running {
|
||||
if err := l.updateFiles(ctx); err != nil {
|
||||
l.state.setStatusWithLock(constants.Crashed)
|
||||
l.state.SetStatus(constants.Crashed)
|
||||
l.logger.Error(err)
|
||||
l.logger.Warn("skipping Unbound restart due to failed files update")
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
_, _ = l.SetStatus(constants.Stopped)
|
||||
_, _ = l.SetStatus(constants.Running)
|
||||
_, _ = l.ApplyStatus(ctx, constants.Stopped)
|
||||
_, _ = l.ApplyStatus(ctx, constants.Running)
|
||||
|
||||
settings := l.GetSettings()
|
||||
timer.Reset(settings.UpdatePeriod)
|
||||
@@ -353,3 +355,14 @@ func (l *looper) updateFiles(ctx context.Context) (err error) {
|
||||
|
||||
return l.conf.MakeUnboundConf(settings.Unbound)
|
||||
}
|
||||
|
||||
func (l *looper) GetStatus() (status models.LoopStatus) { return l.state.GetStatus() }
|
||||
func (l *looper) ApplyStatus(ctx context.Context, status models.LoopStatus) (
|
||||
outcome string, err error) {
|
||||
return l.state.ApplyStatus(ctx, status)
|
||||
}
|
||||
func (l *looper) GetSettings() (settings configuration.DNS) { return l.state.GetSettings() }
|
||||
func (l *looper) SetSettings(ctx context.Context, settings configuration.DNS) (
|
||||
outcome string) {
|
||||
return l.state.SetSettings(ctx, settings)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package dns
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
@@ -11,92 +12,153 @@ import (
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
)
|
||||
|
||||
type state struct {
|
||||
status models.LoopStatus
|
||||
settings configuration.DNS
|
||||
statusMu sync.RWMutex
|
||||
settingsMu sync.RWMutex
|
||||
func newState(status models.LoopStatus, settings configuration.DNS,
|
||||
start chan<- struct{}, running <-chan models.LoopStatus,
|
||||
stop chan<- struct{}, stopped <-chan struct{},
|
||||
updateTicker chan<- struct{}) *state {
|
||||
return &state{
|
||||
status: status,
|
||||
settings: settings,
|
||||
start: start,
|
||||
running: running,
|
||||
stop: stop,
|
||||
stopped: stopped,
|
||||
updateTicker: updateTicker,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *state) setStatusWithLock(status models.LoopStatus) {
|
||||
type state struct {
|
||||
loopMu sync.RWMutex
|
||||
|
||||
status models.LoopStatus
|
||||
statusMu sync.RWMutex
|
||||
|
||||
settings configuration.DNS
|
||||
settingsMu sync.RWMutex
|
||||
|
||||
start chan<- struct{}
|
||||
running <-chan models.LoopStatus
|
||||
stop chan<- struct{}
|
||||
stopped <-chan struct{}
|
||||
|
||||
updateTicker chan<- struct{}
|
||||
}
|
||||
|
||||
func (s *state) Lock() { s.loopMu.Lock() }
|
||||
func (s *state) Unlock() { s.loopMu.Unlock() }
|
||||
|
||||
// SetStatus sets the status thread safely.
|
||||
// It should only be called by the loop internal code since
|
||||
// it does not interact with the loop code directly.
|
||||
func (s *state) SetStatus(status models.LoopStatus) {
|
||||
s.statusMu.Lock()
|
||||
defer s.statusMu.Unlock()
|
||||
s.status = status
|
||||
}
|
||||
|
||||
func (l *looper) GetStatus() (status models.LoopStatus) {
|
||||
l.state.statusMu.RLock()
|
||||
defer l.state.statusMu.RUnlock()
|
||||
return l.state.status
|
||||
// GetStatus gets the status thread safely.
|
||||
func (s *state) GetStatus() (status models.LoopStatus) {
|
||||
s.statusMu.RLock()
|
||||
defer s.statusMu.RUnlock()
|
||||
return s.status
|
||||
}
|
||||
|
||||
var ErrInvalidStatus = errors.New("invalid status")
|
||||
|
||||
func (l *looper) SetStatus(status models.LoopStatus) (outcome string, err error) {
|
||||
l.state.statusMu.Lock()
|
||||
defer l.state.statusMu.Unlock()
|
||||
existingStatus := l.state.status
|
||||
// ApplyStatus sends signals to the running loop depending on the
|
||||
// current status and status requested, such that its next status
|
||||
// matches the requested one. It is thread safe and a synchronous call
|
||||
// since it waits to the loop to fully change its status.
|
||||
func (s *state) ApplyStatus(ctx context.Context, status models.LoopStatus) (
|
||||
outcome string, err error) {
|
||||
// prevent simultaneous loop changes by restricting
|
||||
// multiple SetStatus calls to run sequentially.
|
||||
s.loopMu.Lock()
|
||||
defer s.loopMu.Unlock()
|
||||
|
||||
// not a read lock as we want to modify it eventually in
|
||||
// the code below before any other call.
|
||||
s.statusMu.Lock()
|
||||
existingStatus := s.status
|
||||
|
||||
switch status {
|
||||
case constants.Running:
|
||||
switch existingStatus {
|
||||
case constants.Starting, constants.Running, constants.Stopping, constants.Crashed:
|
||||
return fmt.Sprintf("already %s", existingStatus), nil
|
||||
if existingStatus != constants.Stopped {
|
||||
// starting, running, stopping, crashed
|
||||
s.statusMu.Unlock()
|
||||
return "already " + existingStatus.String(), nil
|
||||
}
|
||||
l.loopLock.Lock()
|
||||
defer l.loopLock.Unlock()
|
||||
l.state.status = constants.Starting
|
||||
l.state.statusMu.Unlock()
|
||||
l.start <- struct{}{}
|
||||
newStatus := <-l.running
|
||||
l.state.statusMu.Lock()
|
||||
l.state.status = newStatus
|
||||
|
||||
s.status = constants.Starting
|
||||
s.statusMu.Unlock()
|
||||
s.start <- struct{}{}
|
||||
|
||||
// Wait for the loop to react to the start signal
|
||||
newStatus := constants.Starting // for canceled context
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
case newStatus = <-s.running:
|
||||
}
|
||||
s.SetStatus(newStatus)
|
||||
|
||||
return newStatus.String(), nil
|
||||
case constants.Stopped:
|
||||
switch existingStatus {
|
||||
case constants.Starting, constants.Stopping, constants.Stopped, constants.Crashed:
|
||||
return fmt.Sprintf("already %s", existingStatus), nil
|
||||
if existingStatus != constants.Running {
|
||||
return "already " + existingStatus.String(), nil
|
||||
}
|
||||
l.loopLock.Lock()
|
||||
defer l.loopLock.Unlock()
|
||||
l.state.status = constants.Stopping
|
||||
l.state.statusMu.Unlock()
|
||||
l.stop <- struct{}{}
|
||||
<-l.stopped
|
||||
l.state.statusMu.Lock()
|
||||
l.state.status = constants.Stopped
|
||||
return status.String(), nil
|
||||
|
||||
s.status = constants.Stopping
|
||||
s.statusMu.Unlock()
|
||||
s.stop <- struct{}{}
|
||||
|
||||
// Wait for the loop to react to the stop signal
|
||||
newStatus := constants.Stopping // for canceled context
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
case <-s.stopped:
|
||||
newStatus = constants.Stopped
|
||||
}
|
||||
s.SetStatus(newStatus)
|
||||
|
||||
return newStatus.String(), nil
|
||||
default:
|
||||
return "", fmt.Errorf("%w: %s: it can only be one of: %s, %s",
|
||||
ErrInvalidStatus, status, constants.Running, constants.Stopped)
|
||||
}
|
||||
}
|
||||
|
||||
func (l *looper) GetSettings() (settings configuration.DNS) {
|
||||
l.state.settingsMu.RLock()
|
||||
defer l.state.settingsMu.RUnlock()
|
||||
return l.state.settings
|
||||
func (s *state) GetSettings() (settings configuration.DNS) {
|
||||
s.settingsMu.RLock()
|
||||
defer s.settingsMu.RUnlock()
|
||||
return s.settings
|
||||
}
|
||||
|
||||
func (l *looper) SetSettings(settings configuration.DNS) (outcome string) {
|
||||
l.state.settingsMu.Lock()
|
||||
settingsUnchanged := reflect.DeepEqual(l.state.settings, settings)
|
||||
func (s *state) SetSettings(ctx context.Context, settings configuration.DNS) (
|
||||
outcome string) {
|
||||
s.settingsMu.Lock()
|
||||
defer s.settingsMu.Unlock()
|
||||
|
||||
settingsUnchanged := reflect.DeepEqual(s.settings, settings)
|
||||
if settingsUnchanged {
|
||||
l.state.settingsMu.Unlock()
|
||||
return "settings left unchanged"
|
||||
}
|
||||
tempSettings := l.state.settings
|
||||
|
||||
// Check for only update period change
|
||||
tempSettings := s.settings
|
||||
tempSettings.UpdatePeriod = settings.UpdatePeriod
|
||||
onlyUpdatePeriodChanged := reflect.DeepEqual(tempSettings, settings)
|
||||
l.state.settings = settings
|
||||
l.state.settingsMu.Unlock()
|
||||
|
||||
s.settings = settings
|
||||
|
||||
if onlyUpdatePeriodChanged {
|
||||
l.updateTicker <- struct{}{}
|
||||
s.updateTicker <- struct{}{}
|
||||
return "update period changed"
|
||||
}
|
||||
_, _ = l.SetStatus(constants.Stopped)
|
||||
|
||||
// Restart
|
||||
_, _ = s.ApplyStatus(ctx, constants.Stopped)
|
||||
if settings.Enabled {
|
||||
outcome, _ = l.SetStatus(constants.Running)
|
||||
outcome, _ = s.ApplyStatus(ctx, constants.Running)
|
||||
}
|
||||
return outcome
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/qdm12/golibs/command"
|
||||
@@ -15,7 +16,8 @@ var (
|
||||
)
|
||||
|
||||
func ip6tablesSupported(ctx context.Context, commander command.Commander) (supported bool) {
|
||||
if _, err := commander.Run(ctx, "ip6tables", "-L"); err != nil {
|
||||
cmd := exec.CommandContext(ctx, "ip6tables", "-L")
|
||||
if _, err := commander.Run(cmd); err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
@@ -40,7 +42,8 @@ func (c *configurator) runIP6tablesInstruction(ctx context.Context, instruction
|
||||
fmt.Println("ip6tables " + instruction)
|
||||
}
|
||||
flags := strings.Fields(instruction)
|
||||
if output, err := c.commander.Run(ctx, "ip6tables", flags...); err != nil {
|
||||
cmd := exec.CommandContext(ctx, "ip6tables", flags...)
|
||||
if output, err := c.commander.Run(cmd); err != nil {
|
||||
return fmt.Errorf("%w: \"ip6tables %s\": %s: %s", ErrIP6Tables, instruction, output, err)
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
@@ -46,7 +47,8 @@ func flipRule(rule string) string {
|
||||
|
||||
// Version obtains the version of the installed iptables.
|
||||
func (c *configurator) Version(ctx context.Context) (string, error) {
|
||||
output, err := c.commander.Run(ctx, "iptables", "--version")
|
||||
cmd := exec.CommandContext(ctx, "iptables", "--version")
|
||||
output, err := c.commander.Run(cmd)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -74,7 +76,8 @@ func (c *configurator) runIptablesInstruction(ctx context.Context, instruction s
|
||||
fmt.Printf("iptables %s\n", instruction)
|
||||
}
|
||||
flags := strings.Fields(instruction)
|
||||
if output, err := c.commander.Run(ctx, "iptables", flags...); err != nil {
|
||||
cmd := exec.CommandContext(ctx, "iptables", flags...)
|
||||
if output, err := c.commander.Run(cmd); err != nil {
|
||||
return fmt.Errorf("%w \"iptables %s\": %s: %s", ErrIPTables, instruction, output, err)
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -9,24 +9,24 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
func (s *server) runHealthcheckLoop(ctx context.Context, healthy chan<- bool, done chan<- struct{}) {
|
||||
func (s *server) runHealthcheckLoop(ctx context.Context, done chan<- struct{}) {
|
||||
defer close(done)
|
||||
|
||||
s.openvpn.healthyTimer = time.NewTimer(defaultOpenvpnHealthyWaitTime)
|
||||
|
||||
for {
|
||||
previousErr := s.handler.getErr()
|
||||
|
||||
err := healthCheck(ctx, s.resolver)
|
||||
s.handler.setErr(err)
|
||||
|
||||
// Notify the healthy channel, or not if it's already full
|
||||
select {
|
||||
case healthy <- err == nil:
|
||||
default:
|
||||
}
|
||||
|
||||
if previousErr != nil && err == nil {
|
||||
s.logger.Info("healthy!")
|
||||
s.openvpn.healthyTimer.Stop()
|
||||
s.openvpn.healthyWaitTime = defaultOpenvpnHealthyWaitTime
|
||||
} else if previousErr == nil && err != nil {
|
||||
s.logger.Info("unhealthy: " + err.Error())
|
||||
s.openvpn.healthyTimer = time.NewTimer(s.openvpn.healthyWaitTime)
|
||||
}
|
||||
|
||||
if err != nil { // try again after 1 second
|
||||
@@ -38,9 +38,12 @@ func (s *server) runHealthcheckLoop(ctx context.Context, healthy chan<- bool, do
|
||||
}
|
||||
return
|
||||
case <-timer.C:
|
||||
case <-s.openvpn.healthyTimer.C:
|
||||
s.onUnhealthyOpenvpn(ctx)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// Success, check again in 5 seconds
|
||||
const period = 5 * time.Second
|
||||
timer := time.NewTimer(period)
|
||||
|
||||
17
internal/healthcheck/openvpn.go
Normal file
17
internal/healthcheck/openvpn.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package healthcheck
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/constants"
|
||||
)
|
||||
|
||||
func (s *server) onUnhealthyOpenvpn(ctx context.Context) {
|
||||
s.logger.Info("program has been unhealthy for " +
|
||||
s.openvpn.healthyWaitTime.String() + ": restarting OpenVPN")
|
||||
_, _ = s.openvpn.looper.ApplyStatus(ctx, constants.Stopped)
|
||||
_, _ = s.openvpn.looper.ApplyStatus(ctx, constants.Running)
|
||||
s.openvpn.healthyWaitTime += openvpnHealthyWaitTimeAdd
|
||||
s.openvpn.healthyTimer = time.NewTimer(s.openvpn.healthyWaitTime)
|
||||
}
|
||||
@@ -7,11 +7,12 @@ import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/openvpn"
|
||||
"github.com/qdm12/golibs/logging"
|
||||
)
|
||||
|
||||
type Server interface {
|
||||
Run(ctx context.Context, healthy chan<- bool, done chan<- struct{})
|
||||
Run(ctx context.Context, done chan<- struct{})
|
||||
}
|
||||
|
||||
type server struct {
|
||||
@@ -19,22 +20,40 @@ type server struct {
|
||||
logger logging.Logger
|
||||
handler *handler
|
||||
resolver *net.Resolver
|
||||
openvpn openvpnHealth
|
||||
}
|
||||
|
||||
func NewServer(address string, logger logging.Logger) Server {
|
||||
type openvpnHealth struct {
|
||||
looper openvpn.Looper
|
||||
healthyWaitTime time.Duration
|
||||
healthyTimer *time.Timer
|
||||
}
|
||||
|
||||
const (
|
||||
defaultOpenvpnHealthyWaitTime = 6 * time.Second
|
||||
openvpnHealthyWaitTimeAdd = 5 * time.Second
|
||||
)
|
||||
|
||||
func NewServer(address string, logger logging.Logger,
|
||||
openvpnLooper openvpn.Looper) Server {
|
||||
return &server{
|
||||
address: address,
|
||||
logger: logger,
|
||||
handler: newHandler(logger),
|
||||
resolver: net.DefaultResolver,
|
||||
openvpn: openvpnHealth{
|
||||
looper: openvpnLooper,
|
||||
healthyWaitTime: defaultOpenvpnHealthyWaitTime,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (s *server) Run(ctx context.Context, healthy chan<- bool, done chan<- struct{}) {
|
||||
func (s *server) Run(ctx context.Context, done chan<- struct{}) {
|
||||
defer close(done)
|
||||
s.logger.Debug("here 0")
|
||||
|
||||
loopDone := make(chan struct{})
|
||||
go s.runHealthcheckLoop(ctx, healthy, loopDone)
|
||||
go s.runHealthcheckLoop(ctx, loopDone)
|
||||
|
||||
server := http.Server{
|
||||
Addr: s.address,
|
||||
|
||||
@@ -15,10 +15,12 @@ import (
|
||||
|
||||
type Looper interface {
|
||||
Run(ctx context.Context, done chan<- struct{})
|
||||
SetStatus(status models.LoopStatus) (outcome string, err error)
|
||||
SetStatus(ctx context.Context, status models.LoopStatus) (
|
||||
outcome string, err error)
|
||||
GetStatus() (status models.LoopStatus)
|
||||
GetSettings() (settings configuration.HTTPProxy)
|
||||
SetSettings(settings configuration.HTTPProxy) (outcome string)
|
||||
SetSettings(ctx context.Context, settings configuration.HTTPProxy) (
|
||||
outcome string)
|
||||
}
|
||||
|
||||
type looper struct {
|
||||
@@ -57,7 +59,7 @@ func (l *looper) Run(ctx context.Context, done chan<- struct{}) {
|
||||
|
||||
if l.GetSettings().Enabled {
|
||||
go func() {
|
||||
_, _ = l.SetStatus(constants.Running)
|
||||
_, _ = l.SetStatus(ctx, constants.Running)
|
||||
}()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package httpproxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
@@ -32,7 +33,8 @@ func (l *looper) GetStatus() (status models.LoopStatus) {
|
||||
|
||||
var ErrInvalidStatus = errors.New("invalid status")
|
||||
|
||||
func (l *looper) SetStatus(status models.LoopStatus) (outcome string, err error) {
|
||||
func (l *looper) SetStatus(ctx context.Context, status models.LoopStatus) (
|
||||
outcome string, err error) {
|
||||
l.state.statusMu.Lock()
|
||||
defer l.state.statusMu.Unlock()
|
||||
existingStatus := l.state.status
|
||||
@@ -48,7 +50,12 @@ func (l *looper) SetStatus(status models.LoopStatus) (outcome string, err error)
|
||||
l.state.status = constants.Starting
|
||||
l.state.statusMu.Unlock()
|
||||
l.start <- struct{}{}
|
||||
newStatus := <-l.running
|
||||
|
||||
newStatus := constants.Starting // for canceled context
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
case newStatus = <-l.running:
|
||||
}
|
||||
l.state.statusMu.Lock()
|
||||
l.state.status = newStatus
|
||||
return newStatus.String(), nil
|
||||
@@ -62,9 +69,15 @@ func (l *looper) SetStatus(status models.LoopStatus) (outcome string, err error)
|
||||
l.state.status = constants.Stopping
|
||||
l.state.statusMu.Unlock()
|
||||
l.stop <- struct{}{}
|
||||
<-l.stopped
|
||||
|
||||
newStatus := constants.Stopping // for canceled context
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
case <-l.stopped:
|
||||
newStatus = constants.Stopped
|
||||
}
|
||||
l.state.statusMu.Lock()
|
||||
l.state.status = status
|
||||
l.state.status = newStatus
|
||||
return status.String(), nil
|
||||
default:
|
||||
return "", fmt.Errorf("%w: %s: it can only be one of: %s, %s",
|
||||
@@ -78,7 +91,8 @@ func (l *looper) GetSettings() (settings configuration.HTTPProxy) {
|
||||
return l.state.settings
|
||||
}
|
||||
|
||||
func (l *looper) SetSettings(settings configuration.HTTPProxy) (outcome string) {
|
||||
func (l *looper) SetSettings(ctx context.Context, settings configuration.HTTPProxy) (
|
||||
outcome string) {
|
||||
l.state.settingsMu.Lock()
|
||||
settingsUnchanged := reflect.DeepEqual(settings, l.state.settings)
|
||||
if settingsUnchanged {
|
||||
@@ -93,12 +107,12 @@ func (l *looper) SetSettings(settings configuration.HTTPProxy) (outcome string)
|
||||
switch {
|
||||
case !newEnabled && !previousEnabled:
|
||||
case newEnabled && previousEnabled:
|
||||
_, _ = l.SetStatus(constants.Stopped)
|
||||
_, _ = l.SetStatus(constants.Running)
|
||||
_, _ = l.SetStatus(ctx, constants.Stopped)
|
||||
_, _ = l.SetStatus(ctx, constants.Running)
|
||||
case newEnabled && !previousEnabled:
|
||||
_, _ = l.SetStatus(constants.Running)
|
||||
_, _ = l.SetStatus(ctx, constants.Running)
|
||||
case !newEnabled && previousEnabled:
|
||||
_, _ = l.SetStatus(constants.Stopped)
|
||||
_, _ = l.SetStatus(ctx, constants.Stopped)
|
||||
}
|
||||
return "settings updated"
|
||||
}
|
||||
|
||||
@@ -4,7 +4,9 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/constants"
|
||||
)
|
||||
@@ -30,7 +32,10 @@ func (c *configurator) Start(ctx context.Context, version string) (
|
||||
|
||||
c.logger.Info("starting OpenVPN " + version)
|
||||
|
||||
return c.commander.Start(ctx, bin, "--config", constants.OpenVPNConf)
|
||||
cmd := exec.CommandContext(ctx, bin, "--config", constants.OpenVPNConf)
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
||||
|
||||
return c.commander.Start(cmd)
|
||||
}
|
||||
|
||||
func (c *configurator) Version24(ctx context.Context) (version string, err error) {
|
||||
@@ -44,7 +49,8 @@ func (c *configurator) Version25(ctx context.Context) (version string, err error
|
||||
var ErrVersionTooShort = errors.New("version output is too short")
|
||||
|
||||
func (c *configurator) version(ctx context.Context, binName string) (version string, err error) {
|
||||
output, err := c.commander.Run(ctx, binName, "--version")
|
||||
cmd := exec.CommandContext(ctx, binName, "--version")
|
||||
output, err := c.commander.Run(cmd)
|
||||
if err != nil && err.Error() != "exit status 1" {
|
||||
return "", err
|
||||
}
|
||||
|
||||
@@ -72,8 +72,6 @@ func processLogLine(s string) (filtered string, level logging.Level) {
|
||||
|
||||
Your credentials might be wrong 🤨
|
||||
|
||||
💡 If you use Private Internet Access, check https://github.com/qdm12/gluetun/issues/265
|
||||
|
||||
`
|
||||
level = logging.LevelError
|
||||
case strings.Contains(s, "TLS Error: TLS key negotiation failed to occur within 60 seconds (check your network connectivity)"): //nolint:lll
|
||||
|
||||
@@ -42,7 +42,7 @@ func Test_processLogLine(t *testing.T) {
|
||||
logging.LevelInfo},
|
||||
"openvpn auth failed": {
|
||||
"AUTH: Received control message: AUTH_FAILED",
|
||||
"AUTH: Received control message: AUTH_FAILED\n\nYour credentials might be wrong 🤨\n\n💡 If you use Private Internet Access, check https://github.com/qdm12/gluetun/issues/265\n\n", //nolint:lll
|
||||
"AUTH: Received control message: AUTH_FAILED\n\nYour credentials might be wrong 🤨\n\n",
|
||||
logging.LevelError},
|
||||
}
|
||||
for name, tc := range tests {
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/configuration"
|
||||
@@ -21,9 +20,11 @@ import (
|
||||
type Looper interface {
|
||||
Run(ctx context.Context, done chan<- struct{})
|
||||
GetStatus() (status models.LoopStatus)
|
||||
SetStatus(status models.LoopStatus) (outcome string, err error)
|
||||
ApplyStatus(ctx context.Context, status models.LoopStatus) (
|
||||
outcome string, err error)
|
||||
GetSettings() (settings configuration.OpenVPN)
|
||||
SetSettings(settings configuration.OpenVPN) (outcome string)
|
||||
SetSettings(ctx context.Context, settings configuration.OpenVPN) (
|
||||
outcome string)
|
||||
GetServers() (servers models.AllServers)
|
||||
SetServers(servers models.AllServers)
|
||||
GetPortForwarded() (port uint16)
|
||||
@@ -31,7 +32,7 @@ type Looper interface {
|
||||
}
|
||||
|
||||
type looper struct {
|
||||
state state
|
||||
state *state
|
||||
// Fixed parameters
|
||||
username string
|
||||
puid int
|
||||
@@ -45,34 +46,36 @@ type looper struct {
|
||||
client *http.Client
|
||||
openFile os.OpenFileFunc
|
||||
tunnelReady chan<- struct{}
|
||||
healthy <-chan bool
|
||||
// Internal channels and locks
|
||||
loopLock sync.Mutex
|
||||
running chan models.LoopStatus
|
||||
stop, stopped chan struct{}
|
||||
start chan struct{}
|
||||
// Internal channels and values
|
||||
stop <-chan struct{}
|
||||
stopped chan<- struct{}
|
||||
start <-chan struct{}
|
||||
running chan<- models.LoopStatus
|
||||
portForwardSignals chan net.IP
|
||||
crashed bool
|
||||
backoffTime time.Duration
|
||||
healthWaitTime time.Duration
|
||||
userTrigger bool
|
||||
// Internal constant values
|
||||
backoffTime time.Duration
|
||||
}
|
||||
|
||||
const (
|
||||
defaultBackoffTime = 15 * time.Second
|
||||
defaultHealthWaitTime = 6 * time.Second
|
||||
defaultBackoffTime = 15 * time.Second
|
||||
)
|
||||
|
||||
func NewLooper(settings configuration.OpenVPN,
|
||||
username string, puid, pgid int, allServers models.AllServers,
|
||||
conf Configurator, fw firewall.Configurator, routing routing.Routing,
|
||||
logger logging.ParentLogger, client *http.Client, openFile os.OpenFileFunc,
|
||||
tunnelReady chan<- struct{}, healthy <-chan bool) Looper {
|
||||
tunnelReady chan<- struct{}) Looper {
|
||||
start := make(chan struct{})
|
||||
running := make(chan models.LoopStatus)
|
||||
stop := make(chan struct{})
|
||||
stopped := make(chan struct{})
|
||||
|
||||
state := newState(constants.Stopped, settings, allServers,
|
||||
start, running, stop, stopped)
|
||||
|
||||
return &looper{
|
||||
state: state{
|
||||
status: constants.Stopped,
|
||||
settings: settings,
|
||||
allServers: allServers,
|
||||
},
|
||||
state: state,
|
||||
username: username,
|
||||
puid: puid,
|
||||
pgid: pgid,
|
||||
@@ -84,28 +87,33 @@ func NewLooper(settings configuration.OpenVPN,
|
||||
client: client,
|
||||
openFile: openFile,
|
||||
tunnelReady: tunnelReady,
|
||||
healthy: healthy,
|
||||
start: make(chan struct{}),
|
||||
running: make(chan models.LoopStatus),
|
||||
stop: make(chan struct{}),
|
||||
stopped: make(chan struct{}),
|
||||
start: start,
|
||||
running: running,
|
||||
stop: stop,
|
||||
stopped: stopped,
|
||||
portForwardSignals: make(chan net.IP),
|
||||
userTrigger: true,
|
||||
backoffTime: defaultBackoffTime,
|
||||
healthWaitTime: defaultHealthWaitTime,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *looper) PortForward(vpnGateway net.IP) { l.portForwardSignals <- vpnGateway }
|
||||
|
||||
func (l *looper) signalCrashedStatus() {
|
||||
if !l.crashed {
|
||||
l.crashed = true
|
||||
l.running <- constants.Crashed
|
||||
func (l *looper) signalOrSetStatus(status models.LoopStatus) {
|
||||
if l.userTrigger {
|
||||
l.userTrigger = false
|
||||
select {
|
||||
case l.running <- status:
|
||||
default: // receiver calling ApplyStatus droppped out
|
||||
}
|
||||
} else {
|
||||
l.state.SetStatus(status)
|
||||
}
|
||||
}
|
||||
|
||||
func (l *looper) Run(ctx context.Context, done chan<- struct{}) { //nolint:gocognit
|
||||
func (l *looper) Run(ctx context.Context, done chan<- struct{}) {
|
||||
defer close(done)
|
||||
|
||||
select {
|
||||
case <-l.start:
|
||||
case <-ctx.Done():
|
||||
@@ -113,17 +121,17 @@ func (l *looper) Run(ctx context.Context, done chan<- struct{}) { //nolint:gocog
|
||||
}
|
||||
|
||||
for ctx.Err() == nil {
|
||||
settings, allServers := l.state.getSettingsAndServers()
|
||||
settings, allServers := l.state.GetSettingsAndServers()
|
||||
|
||||
providerConf := provider.New(settings.Provider.Name, allServers, time.Now)
|
||||
|
||||
var connection models.OpenVPNConnection
|
||||
var lines []string
|
||||
var err error
|
||||
if len(settings.Config) == 0 {
|
||||
if settings.Config == "" {
|
||||
connection, err = providerConf.GetOpenVPNConnection(settings.Provider.ServerSelection)
|
||||
if err != nil {
|
||||
l.signalCrashedStatus()
|
||||
l.signalOrSetStatus(constants.Crashed)
|
||||
l.logAndWait(ctx, err)
|
||||
continue
|
||||
}
|
||||
@@ -131,28 +139,30 @@ func (l *looper) Run(ctx context.Context, done chan<- struct{}) { //nolint:gocog
|
||||
} else {
|
||||
lines, connection, err = l.processCustomConfig(settings)
|
||||
if err != nil {
|
||||
l.signalCrashedStatus()
|
||||
l.signalOrSetStatus(constants.Crashed)
|
||||
l.logAndWait(ctx, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if err := writeOpenvpnConf(lines, l.openFile); err != nil {
|
||||
l.signalCrashedStatus()
|
||||
l.signalOrSetStatus(constants.Crashed)
|
||||
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()
|
||||
err := l.conf.WriteAuthFile(
|
||||
settings.User, settings.Password, l.puid, l.pgid)
|
||||
if err != nil {
|
||||
l.signalOrSetStatus(constants.Crashed)
|
||||
l.logAndWait(ctx, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if err := l.fw.SetVPNConnection(ctx, connection); err != nil {
|
||||
l.signalCrashedStatus()
|
||||
l.signalOrSetStatus(constants.Crashed)
|
||||
l.logAndWait(ctx, err)
|
||||
continue
|
||||
}
|
||||
@@ -162,13 +172,18 @@ func (l *looper) Run(ctx context.Context, done chan<- struct{}) { //nolint:gocog
|
||||
stdoutLines, stderrLines, waitError, err := l.conf.Start(openvpnCtx, settings.Version)
|
||||
if err != nil {
|
||||
openvpnCancel()
|
||||
l.signalCrashedStatus()
|
||||
l.signalOrSetStatus(constants.Crashed)
|
||||
l.logAndWait(ctx, err)
|
||||
continue
|
||||
}
|
||||
|
||||
lineCollectionDone := make(chan struct{})
|
||||
go l.collectLines(stdoutLines, stderrLines, lineCollectionDone)
|
||||
closeStreams := func() {
|
||||
close(stdoutLines)
|
||||
close(stderrLines)
|
||||
<-lineCollectionDone
|
||||
}
|
||||
|
||||
// Needs the stream line from main.go to know when the tunnel is up
|
||||
portForwardDone := make(chan struct{})
|
||||
@@ -183,13 +198,8 @@ func (l *looper) Run(ctx context.Context, done chan<- struct{}) { //nolint:gocog
|
||||
}
|
||||
}(openvpnCtx)
|
||||
|
||||
if l.crashed {
|
||||
l.crashed = false
|
||||
l.backoffTime = defaultBackoffTime
|
||||
l.state.setStatusWithLock(constants.Running)
|
||||
} else {
|
||||
l.running <- constants.Running
|
||||
}
|
||||
l.backoffTime = defaultBackoffTime
|
||||
l.signalOrSetStatus(constants.Running)
|
||||
|
||||
stayHere := true
|
||||
for stayHere {
|
||||
@@ -198,55 +208,39 @@ func (l *looper) Run(ctx context.Context, done chan<- struct{}) { //nolint:gocog
|
||||
openvpnCancel()
|
||||
<-waitError
|
||||
close(waitError)
|
||||
close(stdoutLines)
|
||||
close(stderrLines)
|
||||
<-lineCollectionDone
|
||||
closeStreams()
|
||||
<-portForwardDone
|
||||
return
|
||||
case <-l.stop:
|
||||
l.userTrigger = true
|
||||
l.logger.Info("stopping")
|
||||
openvpnCancel()
|
||||
<-waitError
|
||||
// do not close waitError or the waitError
|
||||
// select case will trigger
|
||||
closeStreams()
|
||||
<-portForwardDone
|
||||
l.stopped <- struct{}{}
|
||||
case <-l.start:
|
||||
l.userTrigger = true
|
||||
l.logger.Info("starting")
|
||||
stayHere = false
|
||||
case err := <-waitError: // unexpected error
|
||||
close(waitError)
|
||||
closeStreams()
|
||||
|
||||
l.state.Lock() // prevent SetStatus from running in parallel
|
||||
|
||||
openvpnCancel()
|
||||
if ctx.Err() != nil {
|
||||
close(waitError)
|
||||
close(stdoutLines)
|
||||
close(stderrLines)
|
||||
<-lineCollectionDone
|
||||
<-portForwardDone
|
||||
return
|
||||
}
|
||||
l.state.setStatusWithLock(constants.Crashed)
|
||||
l.state.SetStatus(constants.Crashed)
|
||||
<-portForwardDone
|
||||
l.logAndWait(ctx, err)
|
||||
l.crashed = true
|
||||
stayHere = false
|
||||
case healthy := <-l.healthy:
|
||||
if healthy {
|
||||
continue
|
||||
}
|
||||
// ensure it stays unhealthy for some time before restarting it
|
||||
healthy = l.waitForHealth(ctx)
|
||||
if healthy || ctx.Err() != nil {
|
||||
continue
|
||||
}
|
||||
l.crashed = true // flag as crashed
|
||||
l.state.setStatusWithLock(constants.Stopping)
|
||||
l.logger.Warn("unhealthy program: restarting openvpn")
|
||||
openvpnCancel()
|
||||
<-waitError
|
||||
l.state.setStatusWithLock(constants.Stopped)
|
||||
stayHere = false
|
||||
|
||||
l.state.Unlock()
|
||||
}
|
||||
}
|
||||
close(waitError)
|
||||
close(stdoutLines)
|
||||
close(stderrLines)
|
||||
openvpnCancel() // just for the linter
|
||||
openvpnCancel()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,7 +248,7 @@ func (l *looper) logAndWait(ctx context.Context, err error) {
|
||||
if err != nil {
|
||||
l.logger.Error(err)
|
||||
}
|
||||
l.logger.Info("retrying in %s", l.backoffTime)
|
||||
l.logger.Info("retrying in " + l.backoffTime.String())
|
||||
timer := time.NewTimer(l.backoffTime)
|
||||
l.backoffTime *= 2
|
||||
select {
|
||||
@@ -266,35 +260,6 @@ func (l *looper) logAndWait(ctx context.Context, err error) {
|
||||
}
|
||||
}
|
||||
|
||||
// waitForHealth waits for a true healthy signal
|
||||
// after restarting openvpn in order to avoid restarting
|
||||
// openvpn in a loop as it requires a few seconds to connect.
|
||||
func (l *looper) waitForHealth(ctx context.Context) (healthy bool) {
|
||||
l.logger.Info("unhealthy program: waiting %s for it to change to healthy", l.healthWaitTime)
|
||||
timer := time.NewTimer(l.healthWaitTime)
|
||||
l.healthWaitTime *= 2
|
||||
for {
|
||||
select {
|
||||
case healthy = <-l.healthy:
|
||||
if !healthy {
|
||||
break
|
||||
}
|
||||
if !timer.Stop() {
|
||||
<-timer.C
|
||||
}
|
||||
l.healthWaitTime = defaultHealthWaitTime
|
||||
return true
|
||||
case <-timer.C:
|
||||
return false
|
||||
case <-ctx.Done():
|
||||
if !timer.Stop() {
|
||||
<-timer.C
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// portForward is a blocking operation which may or may not be infinite.
|
||||
// You should therefore always call it in a goroutine.
|
||||
func (l *looper) portForward(ctx context.Context,
|
||||
@@ -329,3 +294,27 @@ func writeOpenvpnConf(lines []string, openFile os.OpenFileFunc) error {
|
||||
}
|
||||
return file.Close()
|
||||
}
|
||||
|
||||
func (l *looper) GetStatus() (status models.LoopStatus) {
|
||||
return l.state.GetStatus()
|
||||
}
|
||||
func (l *looper) ApplyStatus(ctx context.Context, status models.LoopStatus) (
|
||||
outcome string, err error) {
|
||||
return l.state.ApplyStatus(ctx, status)
|
||||
}
|
||||
func (l *looper) GetSettings() (settings configuration.OpenVPN) {
|
||||
return l.state.GetSettings()
|
||||
}
|
||||
func (l *looper) SetSettings(ctx context.Context, settings configuration.OpenVPN) (
|
||||
outcome string) {
|
||||
return l.state.SetSettings(ctx, settings)
|
||||
}
|
||||
func (l *looper) GetServers() (servers models.AllServers) {
|
||||
return l.state.GetServers()
|
||||
}
|
||||
func (l *looper) SetServers(servers models.AllServers) {
|
||||
l.state.SetServers(servers)
|
||||
}
|
||||
func (l *looper) GetPortForwarded() (port uint16) {
|
||||
return l.state.GetPortForwarded()
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package openvpn
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
@@ -11,24 +12,63 @@ import (
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
)
|
||||
|
||||
type state struct {
|
||||
status models.LoopStatus
|
||||
settings configuration.OpenVPN
|
||||
allServers models.AllServers
|
||||
portForwarded uint16
|
||||
statusMu sync.RWMutex
|
||||
settingsMu sync.RWMutex
|
||||
allServersMu sync.RWMutex
|
||||
portForwardedMu sync.RWMutex
|
||||
func newState(status models.LoopStatus,
|
||||
settings configuration.OpenVPN, allServers models.AllServers,
|
||||
start chan<- struct{}, running <-chan models.LoopStatus,
|
||||
stop chan<- struct{}, stopped <-chan struct{}) *state {
|
||||
return &state{
|
||||
status: status,
|
||||
settings: settings,
|
||||
allServers: allServers,
|
||||
start: start,
|
||||
running: running,
|
||||
stop: stop,
|
||||
stopped: stopped,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *state) setStatusWithLock(status models.LoopStatus) {
|
||||
type state struct {
|
||||
loopMu sync.RWMutex
|
||||
|
||||
status models.LoopStatus
|
||||
statusMu sync.RWMutex
|
||||
|
||||
settings configuration.OpenVPN
|
||||
settingsMu sync.RWMutex
|
||||
|
||||
allServers models.AllServers
|
||||
allServersMu sync.RWMutex
|
||||
|
||||
portForwarded uint16
|
||||
portForwardedMu sync.RWMutex
|
||||
|
||||
start chan<- struct{}
|
||||
running <-chan models.LoopStatus
|
||||
stop chan<- struct{}
|
||||
stopped <-chan struct{}
|
||||
}
|
||||
|
||||
func (s *state) Lock() { s.loopMu.Lock() }
|
||||
func (s *state) Unlock() { s.loopMu.Unlock() }
|
||||
|
||||
// SetStatus sets the status thread safely.
|
||||
// It should only be called by the loop internal code since
|
||||
// it does not interact with the loop code directly.
|
||||
func (s *state) SetStatus(status models.LoopStatus) {
|
||||
s.statusMu.Lock()
|
||||
defer s.statusMu.Unlock()
|
||||
s.status = status
|
||||
}
|
||||
|
||||
func (s *state) getSettingsAndServers() (settings configuration.OpenVPN, allServers models.AllServers) {
|
||||
// GetStatus gets the status thread safely.
|
||||
func (s *state) GetStatus() (status models.LoopStatus) {
|
||||
s.statusMu.RLock()
|
||||
defer s.statusMu.RUnlock()
|
||||
return s.status
|
||||
}
|
||||
|
||||
func (s *state) GetSettingsAndServers() (settings configuration.OpenVPN,
|
||||
allServers models.AllServers) {
|
||||
s.settingsMu.RLock()
|
||||
s.allServersMu.RLock()
|
||||
settings = s.settings
|
||||
@@ -38,87 +78,102 @@ func (s *state) getSettingsAndServers() (settings configuration.OpenVPN, allServ
|
||||
return settings, allServers
|
||||
}
|
||||
|
||||
func (l *looper) GetStatus() (status models.LoopStatus) {
|
||||
l.state.statusMu.RLock()
|
||||
defer l.state.statusMu.RUnlock()
|
||||
return l.state.status
|
||||
}
|
||||
|
||||
var ErrInvalidStatus = errors.New("invalid status")
|
||||
|
||||
func (l *looper) SetStatus(status models.LoopStatus) (outcome string, err error) {
|
||||
l.state.statusMu.Lock()
|
||||
defer l.state.statusMu.Unlock()
|
||||
existingStatus := l.state.status
|
||||
// ApplyStatus sends signals to the running loop depending on the
|
||||
// current status and status requested, such that its next status
|
||||
// matches the requested one. It is thread safe and a synchronous call
|
||||
// since it waits to the loop to fully change its status.
|
||||
func (s *state) ApplyStatus(ctx context.Context, status models.LoopStatus) (
|
||||
outcome string, err error) {
|
||||
// prevent simultaneous loop changes by restricting
|
||||
// multiple SetStatus calls to run sequentially.
|
||||
s.loopMu.Lock()
|
||||
defer s.loopMu.Unlock()
|
||||
|
||||
// not a read lock as we want to modify it eventually in
|
||||
// the code below before any other call.
|
||||
s.statusMu.Lock()
|
||||
existingStatus := s.status
|
||||
|
||||
switch status {
|
||||
case constants.Running:
|
||||
switch existingStatus {
|
||||
case constants.Starting, constants.Running, constants.Stopping, constants.Crashed:
|
||||
return fmt.Sprintf("already %s", existingStatus), nil
|
||||
if existingStatus != constants.Stopped {
|
||||
return "already " + existingStatus.String(), nil
|
||||
}
|
||||
l.loopLock.Lock()
|
||||
defer l.loopLock.Unlock()
|
||||
l.state.status = constants.Starting
|
||||
l.state.statusMu.Unlock()
|
||||
l.start <- struct{}{}
|
||||
newStatus := <-l.running
|
||||
l.state.statusMu.Lock()
|
||||
l.state.status = newStatus
|
||||
|
||||
s.status = constants.Starting
|
||||
s.statusMu.Unlock()
|
||||
s.start <- struct{}{}
|
||||
|
||||
// Wait for the loop to react to the start signal
|
||||
newStatus := constants.Starting // for canceled context
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
case newStatus = <-s.running:
|
||||
}
|
||||
s.SetStatus(newStatus)
|
||||
|
||||
return newStatus.String(), nil
|
||||
case constants.Stopped:
|
||||
switch existingStatus {
|
||||
case constants.Starting, constants.Stopping, constants.Stopped, constants.Crashed:
|
||||
return fmt.Sprintf("already %s", existingStatus), nil
|
||||
if existingStatus != constants.Running {
|
||||
return "already " + existingStatus.String(), nil
|
||||
}
|
||||
l.loopLock.Lock()
|
||||
defer l.loopLock.Unlock()
|
||||
l.state.status = constants.Stopping
|
||||
l.state.statusMu.Unlock()
|
||||
l.stop <- struct{}{}
|
||||
<-l.stopped
|
||||
l.state.statusMu.Lock()
|
||||
l.state.status = constants.Stopped
|
||||
return status.String(), nil
|
||||
|
||||
s.status = constants.Stopping
|
||||
s.statusMu.Unlock()
|
||||
s.stop <- struct{}{}
|
||||
|
||||
// Wait for the loop to react to the stop signal
|
||||
newStatus := constants.Stopping // for canceled context
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
case <-s.stopped:
|
||||
newStatus = constants.Stopped
|
||||
}
|
||||
s.SetStatus(newStatus)
|
||||
|
||||
return newStatus.String(), nil
|
||||
default:
|
||||
return "", fmt.Errorf("%w: %s: it can only be one of: %s, %s",
|
||||
ErrInvalidStatus, status, constants.Running, constants.Stopped)
|
||||
}
|
||||
}
|
||||
|
||||
func (l *looper) GetSettings() (settings configuration.OpenVPN) {
|
||||
l.state.settingsMu.RLock()
|
||||
defer l.state.settingsMu.RUnlock()
|
||||
return l.state.settings
|
||||
func (s *state) GetSettings() (settings configuration.OpenVPN) {
|
||||
s.settingsMu.RLock()
|
||||
defer s.settingsMu.RUnlock()
|
||||
return s.settings
|
||||
}
|
||||
|
||||
func (l *looper) SetSettings(settings configuration.OpenVPN) (outcome string) {
|
||||
l.state.settingsMu.Lock()
|
||||
settingsUnchanged := reflect.DeepEqual(l.state.settings, settings)
|
||||
func (s *state) SetSettings(ctx context.Context, settings configuration.OpenVPN) (
|
||||
outcome string) {
|
||||
s.settingsMu.Lock()
|
||||
defer s.settingsMu.Unlock()
|
||||
settingsUnchanged := reflect.DeepEqual(s.settings, settings)
|
||||
if settingsUnchanged {
|
||||
l.state.settingsMu.Unlock()
|
||||
return "settings left unchanged"
|
||||
}
|
||||
l.state.settings = settings
|
||||
_, _ = l.SetStatus(constants.Stopped)
|
||||
outcome, _ = l.SetStatus(constants.Running)
|
||||
s.settings = settings
|
||||
_, _ = s.ApplyStatus(ctx, constants.Stopped)
|
||||
outcome, _ = s.ApplyStatus(ctx, constants.Running)
|
||||
return outcome
|
||||
}
|
||||
|
||||
func (l *looper) GetServers() (servers models.AllServers) {
|
||||
l.state.allServersMu.RLock()
|
||||
defer l.state.allServersMu.RUnlock()
|
||||
return l.state.allServers
|
||||
func (s *state) GetServers() (servers models.AllServers) {
|
||||
s.allServersMu.RLock()
|
||||
defer s.allServersMu.RUnlock()
|
||||
return s.allServers
|
||||
}
|
||||
|
||||
func (l *looper) SetServers(servers models.AllServers) {
|
||||
l.state.allServersMu.Lock()
|
||||
defer l.state.allServersMu.Unlock()
|
||||
l.state.allServers = servers
|
||||
func (s *state) SetServers(servers models.AllServers) {
|
||||
s.allServersMu.Lock()
|
||||
defer s.allServersMu.Unlock()
|
||||
s.allServers = servers
|
||||
}
|
||||
|
||||
func (l *looper) GetPortForwarded() (port uint16) {
|
||||
l.state.portForwardedMu.RLock()
|
||||
defer l.state.portForwardedMu.RUnlock()
|
||||
return l.state.portForwarded
|
||||
func (s *state) GetPortForwarded() (port uint16) {
|
||||
s.portForwardedMu.RLock()
|
||||
defer s.portForwardedMu.RUnlock()
|
||||
return s.portForwarded
|
||||
}
|
||||
|
||||
@@ -68,6 +68,13 @@ func (c *Cyberghost) BuildConf(connection models.OpenVPNConnection,
|
||||
lines = append(lines, "mssfix "+strconv.Itoa(int(settings.MSSFix)))
|
||||
}
|
||||
|
||||
if settings.Provider.ExtraConfigOptions.OpenVPNIPv6 {
|
||||
lines = append(lines, "tun-ipv6")
|
||||
} else {
|
||||
lines = append(lines, `pull-filter ignore "route-ipv6"`)
|
||||
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
|
||||
}
|
||||
|
||||
lines = append(lines, utils.WrapOpenvpnCA(
|
||||
constants.CyberghostCertificate)...)
|
||||
lines = append(lines, utils.WrapOpenvpnCert(
|
||||
|
||||
@@ -62,6 +62,13 @@ func (f *Fastestvpn) BuildConf(connection models.OpenVPNConnection,
|
||||
lines = append(lines, "user "+username)
|
||||
}
|
||||
|
||||
if settings.Provider.ExtraConfigOptions.OpenVPNIPv6 {
|
||||
lines = append(lines, "tun-ipv6")
|
||||
} else {
|
||||
lines = append(lines, `pull-filter ignore "route-ipv6"`)
|
||||
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
|
||||
}
|
||||
|
||||
lines = append(lines, utils.WrapOpenvpnCA(
|
||||
constants.FastestvpnCertificate)...)
|
||||
lines = append(lines, utils.WrapOpenvpnTLSAuth(
|
||||
|
||||
@@ -59,6 +59,13 @@ func (h *HideMyAss) BuildConf(connection models.OpenVPNConnection,
|
||||
lines = append(lines, "user "+username)
|
||||
}
|
||||
|
||||
if settings.Provider.ExtraConfigOptions.OpenVPNIPv6 {
|
||||
lines = append(lines, "tun-ipv6")
|
||||
} else {
|
||||
lines = append(lines, `pull-filter ignore "route-ipv6"`)
|
||||
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
|
||||
}
|
||||
|
||||
lines = append(lines, utils.WrapOpenvpnCA(
|
||||
constants.HideMyAssCA)...)
|
||||
lines = append(lines, utils.WrapOpenvpnCert(
|
||||
|
||||
@@ -57,6 +57,13 @@ func (i *Ipvanish) BuildConf(connection models.OpenVPNConnection,
|
||||
lines = append(lines, "user "+username)
|
||||
}
|
||||
|
||||
if settings.Provider.ExtraConfigOptions.OpenVPNIPv6 {
|
||||
lines = append(lines, "tun-ipv6")
|
||||
} else {
|
||||
lines = append(lines, `pull-filter ignore "route-ipv6"`)
|
||||
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
|
||||
}
|
||||
|
||||
lines = append(lines, utils.WrapOpenvpnCA(constants.IpvanishCA)...)
|
||||
|
||||
lines = append(lines, "")
|
||||
|
||||
@@ -63,6 +63,13 @@ func (i *Ivpn) BuildConf(connection models.OpenVPNConnection,
|
||||
lines = append(lines, "user "+username)
|
||||
}
|
||||
|
||||
if settings.Provider.ExtraConfigOptions.OpenVPNIPv6 {
|
||||
lines = append(lines, "tun-ipv6")
|
||||
} else {
|
||||
lines = append(lines, `pull-filter ignore "route-ipv6"`)
|
||||
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
|
||||
}
|
||||
|
||||
lines = append(lines, utils.WrapOpenvpnCA(
|
||||
constants.IvpnCA)...)
|
||||
lines = append(lines, utils.WrapOpenvpnTLSAuth(
|
||||
|
||||
@@ -71,6 +71,13 @@ func (m *Mullvad) BuildConf(connection models.OpenVPNConnection,
|
||||
lines = append(lines, "mssfix "+strconv.Itoa(int(settings.MSSFix)))
|
||||
}
|
||||
|
||||
if settings.Provider.ExtraConfigOptions.OpenVPNIPv6 {
|
||||
lines = append(lines, "tun-ipv6")
|
||||
} else {
|
||||
lines = append(lines, `pull-filter ignore "route-ipv6"`)
|
||||
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
|
||||
}
|
||||
|
||||
lines = append(lines, utils.WrapOpenvpnCA(
|
||||
constants.MullvadCertificate)...)
|
||||
|
||||
|
||||
@@ -67,6 +67,13 @@ func (n *Nordvpn) BuildConf(connection models.OpenVPNConnection,
|
||||
lines = append(lines, "user "+username)
|
||||
}
|
||||
|
||||
if settings.Provider.ExtraConfigOptions.OpenVPNIPv6 {
|
||||
lines = append(lines, "tun-ipv6")
|
||||
} else {
|
||||
lines = append(lines, `pull-filter ignore "route-ipv6"`)
|
||||
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
|
||||
}
|
||||
|
||||
lines = append(lines, utils.WrapOpenvpnCA(
|
||||
constants.NordvpnCertificate)...)
|
||||
lines = append(lines, utils.WrapOpenvpnTLSAuth(
|
||||
|
||||
@@ -58,6 +58,13 @@ func (p *Privado) BuildConf(connection models.OpenVPNConnection,
|
||||
lines = append(lines, "mssfix "+strconv.Itoa(int(settings.MSSFix)))
|
||||
}
|
||||
|
||||
if settings.Provider.ExtraConfigOptions.OpenVPNIPv6 {
|
||||
lines = append(lines, "tun-ipv6")
|
||||
} else {
|
||||
lines = append(lines, `pull-filter ignore "route-ipv6"`)
|
||||
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
|
||||
}
|
||||
|
||||
lines = append(lines, utils.WrapOpenvpnCA(
|
||||
constants.PrivadoCertificate)...)
|
||||
|
||||
|
||||
@@ -81,6 +81,13 @@ func (p *PIA) BuildConf(connection models.OpenVPNConnection,
|
||||
lines = append(lines, "mssfix "+strconv.Itoa(int(settings.MSSFix)))
|
||||
}
|
||||
|
||||
if settings.Provider.ExtraConfigOptions.OpenVPNIPv6 {
|
||||
lines = append(lines, "tun-ipv6")
|
||||
} else {
|
||||
lines = append(lines, `pull-filter ignore "route-ipv6"`)
|
||||
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
|
||||
}
|
||||
|
||||
lines = append(lines, utils.WrapOpenvpnCA(certificate)...)
|
||||
lines = append(lines, utils.WrapOpenvpnCRLVerify(X509CRL)...)
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@ func (p *Privatevpn) BuildConf(connection models.OpenVPNConnection,
|
||||
|
||||
// Privatevpn specific
|
||||
"comp-lzo",
|
||||
"tun-ipv6",
|
||||
|
||||
// Added constant values
|
||||
"auth-nocache",
|
||||
@@ -60,6 +59,13 @@ func (p *Privatevpn) BuildConf(connection models.OpenVPNConnection,
|
||||
lines = append(lines, "mssfix "+strconv.Itoa(int(settings.MSSFix)))
|
||||
}
|
||||
|
||||
if settings.Provider.ExtraConfigOptions.OpenVPNIPv6 {
|
||||
lines = append(lines, "tun-ipv6")
|
||||
} else {
|
||||
lines = append(lines, `pull-filter ignore "route-ipv6"`)
|
||||
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
|
||||
}
|
||||
|
||||
lines = append(lines, utils.WrapOpenvpnCA(
|
||||
constants.PrivatevpnCertificate)...)
|
||||
lines = append(lines, utils.WrapOpenvpnTLSCrypt(
|
||||
|
||||
@@ -66,6 +66,13 @@ func (p *Protonvpn) BuildConf(connection models.OpenVPNConnection,
|
||||
lines = append(lines, "user "+username)
|
||||
}
|
||||
|
||||
if settings.Provider.ExtraConfigOptions.OpenVPNIPv6 {
|
||||
lines = append(lines, "tun-ipv6")
|
||||
} else {
|
||||
lines = append(lines, `pull-filter ignore "route-ipv6"`)
|
||||
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
|
||||
}
|
||||
|
||||
lines = append(lines, utils.WrapOpenvpnCA(
|
||||
constants.ProtonvpnCertificate)...)
|
||||
lines = append(lines, utils.WrapOpenvpnTLSAuth(
|
||||
|
||||
@@ -66,6 +66,13 @@ func (p *Purevpn) BuildConf(connection models.OpenVPNConnection,
|
||||
lines = append(lines, "user "+username)
|
||||
}
|
||||
|
||||
if settings.Provider.ExtraConfigOptions.OpenVPNIPv6 {
|
||||
lines = append(lines, "tun-ipv6")
|
||||
} else {
|
||||
lines = append(lines, `pull-filter ignore "route-ipv6"`)
|
||||
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
|
||||
}
|
||||
|
||||
lines = append(lines, utils.WrapOpenvpnCA(
|
||||
constants.PurevpnCertificateAuthority)...)
|
||||
lines = append(lines, utils.WrapOpenvpnCert(
|
||||
|
||||
@@ -64,6 +64,13 @@ func (s *Surfshark) BuildConf(connection models.OpenVPNConnection,
|
||||
lines = append(lines, "user "+username)
|
||||
}
|
||||
|
||||
if settings.Provider.ExtraConfigOptions.OpenVPNIPv6 {
|
||||
lines = append(lines, "tun-ipv6")
|
||||
} else {
|
||||
lines = append(lines, `pull-filter ignore "route-ipv6"`)
|
||||
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
|
||||
}
|
||||
|
||||
lines = append(lines, utils.WrapOpenvpnCA(
|
||||
constants.SurfsharkCertificate)...)
|
||||
lines = append(lines, utils.WrapOpenvpnTLSAuth(
|
||||
|
||||
@@ -70,6 +70,13 @@ func (t *Torguard) BuildConf(connection models.OpenVPNConnection,
|
||||
lines = append(lines, "fast-io")
|
||||
}
|
||||
|
||||
if settings.Provider.ExtraConfigOptions.OpenVPNIPv6 {
|
||||
lines = append(lines, "tun-ipv6")
|
||||
} else {
|
||||
lines = append(lines, `pull-filter ignore "route-ipv6"`)
|
||||
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
|
||||
}
|
||||
|
||||
lines = append(lines, utils.WrapOpenvpnCA(
|
||||
constants.TorguardCertificate)...)
|
||||
lines = append(lines, utils.WrapOpenvpnTLSAuth(
|
||||
|
||||
@@ -35,7 +35,6 @@ func (p *Provider) BuildConf(connection models.OpenVPNConnection,
|
||||
|
||||
// Modified variables
|
||||
"verb " + strconv.Itoa(settings.Verbosity),
|
||||
// "auth-user-pass " + constants.OpenVPNAuthConf,
|
||||
connection.ProtoLine(),
|
||||
connection.RemoteLine(),
|
||||
}
|
||||
@@ -56,6 +55,13 @@ func (p *Provider) BuildConf(connection models.OpenVPNConnection,
|
||||
lines = append(lines, "user "+username)
|
||||
}
|
||||
|
||||
if settings.Provider.ExtraConfigOptions.OpenVPNIPv6 {
|
||||
lines = append(lines, "tun-ipv6")
|
||||
} else {
|
||||
lines = append(lines, `pull-filter ignore "route-ipv6"`)
|
||||
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
|
||||
}
|
||||
|
||||
lines = append(lines, utils.WrapOpenvpnCA(
|
||||
constants.VPNUnlimitedCertificateAuthority)...)
|
||||
lines = append(lines, utils.WrapOpenvpnCert(
|
||||
|
||||
@@ -67,6 +67,13 @@ func (w *Windscribe) BuildConf(connection models.OpenVPNConnection,
|
||||
lines = append(lines, "mssfix "+strconv.Itoa(int(settings.MSSFix)))
|
||||
}
|
||||
|
||||
if settings.Provider.ExtraConfigOptions.OpenVPNIPv6 {
|
||||
lines = append(lines, "tun-ipv6")
|
||||
} else {
|
||||
lines = append(lines, `pull-filter ignore "route-ipv6"`)
|
||||
lines = append(lines, `pull-filter ignore "ifconfig-ipv6"`)
|
||||
}
|
||||
|
||||
lines = append(lines, utils.WrapOpenvpnCA(
|
||||
constants.WindscribeCertificate)...)
|
||||
lines = append(lines, utils.WrapOpenvpnTLSAuth(
|
||||
|
||||
@@ -18,7 +18,8 @@ type Looper interface {
|
||||
Run(ctx context.Context, done chan<- struct{})
|
||||
RunRestartTicker(ctx context.Context, done chan<- struct{})
|
||||
GetStatus() (status models.LoopStatus)
|
||||
SetStatus(status models.LoopStatus) (outcome string, err error)
|
||||
SetStatus(ctx context.Context, status models.LoopStatus) (
|
||||
outcome string, err error)
|
||||
GetSettings() (settings configuration.PublicIP)
|
||||
SetSettings(settings configuration.PublicIP) (outcome string)
|
||||
GetPublicIP() (publicIP net.IP)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package publicip
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
@@ -35,7 +36,8 @@ func (l *looper) GetStatus() (status models.LoopStatus) {
|
||||
|
||||
var ErrInvalidStatus = errors.New("invalid status")
|
||||
|
||||
func (l *looper) SetStatus(status models.LoopStatus) (outcome string, err error) {
|
||||
func (l *looper) SetStatus(ctx context.Context, status models.LoopStatus) (
|
||||
outcome string, err error) {
|
||||
l.state.statusMu.Lock()
|
||||
defer l.state.statusMu.Unlock()
|
||||
existingStatus := l.state.status
|
||||
@@ -51,7 +53,12 @@ func (l *looper) SetStatus(status models.LoopStatus) (outcome string, err error)
|
||||
l.state.status = constants.Starting
|
||||
l.state.statusMu.Unlock()
|
||||
l.start <- struct{}{}
|
||||
newStatus := <-l.running
|
||||
|
||||
newStatus := constants.Starting // for canceled context
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
case newStatus = <-l.running:
|
||||
}
|
||||
l.state.statusMu.Lock()
|
||||
l.state.status = newStatus
|
||||
return newStatus.String(), nil
|
||||
@@ -65,9 +72,15 @@ func (l *looper) SetStatus(status models.LoopStatus) (outcome string, err error)
|
||||
l.state.status = constants.Stopping
|
||||
l.state.statusMu.Unlock()
|
||||
l.stop <- struct{}{}
|
||||
<-l.stopped
|
||||
|
||||
newStatus := constants.Stopping // for canceled context
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
case <-l.stopped:
|
||||
newStatus = constants.Stopped
|
||||
}
|
||||
l.state.statusMu.Lock()
|
||||
l.state.status = status
|
||||
l.state.status = newStatus
|
||||
return status.String(), nil
|
||||
default:
|
||||
return "", fmt.Errorf("%w: %s: it can only be one of: %s, %s",
|
||||
@@ -81,7 +94,8 @@ func (l *looper) GetSettings() (settings configuration.PublicIP) {
|
||||
return l.state.settings
|
||||
}
|
||||
|
||||
func (l *looper) SetSettings(settings configuration.PublicIP) (outcome string) {
|
||||
func (l *looper) SetSettings(settings configuration.PublicIP) (
|
||||
outcome string) {
|
||||
l.state.settingsMu.Lock()
|
||||
defer l.state.settingsMu.Unlock()
|
||||
settingsUnchanged := reflect.DeepEqual(settings, l.state.settings)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strings"
|
||||
@@ -9,14 +10,17 @@ import (
|
||||
"github.com/qdm12/golibs/logging"
|
||||
)
|
||||
|
||||
func newDNSHandler(looper dns.Looper, logger logging.Logger) http.Handler {
|
||||
func newDNSHandler(ctx context.Context, looper dns.Looper,
|
||||
logger logging.Logger) http.Handler {
|
||||
return &dnsHandler{
|
||||
ctx: ctx,
|
||||
looper: looper,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
type dnsHandler struct {
|
||||
ctx context.Context
|
||||
looper dns.Looper
|
||||
logger logging.Logger
|
||||
}
|
||||
@@ -61,7 +65,7 @@ func (h *dnsHandler) setStatus(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
outcome, err := h.looper.SetStatus(status)
|
||||
outcome, err := h.looper.ApplyStatus(h.ctx, status)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
@@ -12,7 +13,7 @@ import (
|
||||
"github.com/qdm12/golibs/logging"
|
||||
)
|
||||
|
||||
func newHandler(logger logging.Logger, logging bool,
|
||||
func newHandler(ctx context.Context, logger logging.Logger, logging bool,
|
||||
buildInfo models.BuildInformation,
|
||||
openvpnLooper openvpn.Looper,
|
||||
unboundLooper dns.Looper,
|
||||
@@ -21,12 +22,12 @@ func newHandler(logger logging.Logger, logging bool,
|
||||
) http.Handler {
|
||||
handler := &handler{}
|
||||
|
||||
openvpn := newOpenvpnHandler(openvpnLooper, logger)
|
||||
dns := newDNSHandler(unboundLooper, logger)
|
||||
updater := newUpdaterHandler(updaterLooper, logger)
|
||||
openvpn := newOpenvpnHandler(ctx, openvpnLooper, logger)
|
||||
dns := newDNSHandler(ctx, unboundLooper, logger)
|
||||
updater := newUpdaterHandler(ctx, updaterLooper, logger)
|
||||
publicip := newPublicIPHandler(publicIPLooper, logger)
|
||||
|
||||
handler.v0 = newHandlerV0(logger, openvpnLooper, unboundLooper, updaterLooper)
|
||||
handler.v0 = newHandlerV0(ctx, logger, openvpnLooper, unboundLooper, updaterLooper)
|
||||
handler.v1 = newHandlerV1(logger, buildInfo, openvpn, dns, updater, publicip)
|
||||
|
||||
handlerWithLog := withLogMiddleware(handler, logger, logging)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/constants"
|
||||
@@ -10,9 +11,10 @@ import (
|
||||
"github.com/qdm12/golibs/logging"
|
||||
)
|
||||
|
||||
func newHandlerV0(logger logging.Logger,
|
||||
func newHandlerV0(ctx context.Context, logger logging.Logger,
|
||||
openvpn openvpn.Looper, dns dns.Looper, updater updater.Looper) http.Handler {
|
||||
return &handlerV0{
|
||||
ctx: ctx,
|
||||
logger: logger,
|
||||
openvpn: openvpn,
|
||||
dns: dns,
|
||||
@@ -21,6 +23,7 @@ func newHandlerV0(logger logging.Logger,
|
||||
}
|
||||
|
||||
type handlerV0 struct {
|
||||
ctx context.Context
|
||||
logger logging.Logger
|
||||
openvpn openvpn.Looper
|
||||
dns dns.Looper
|
||||
@@ -36,17 +39,17 @@ func (h *handlerV0) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
case "/version":
|
||||
http.Redirect(w, r, "/v1/version", http.StatusPermanentRedirect)
|
||||
case "/openvpn/actions/restart":
|
||||
outcome, _ := h.openvpn.SetStatus(constants.Stopped)
|
||||
outcome, _ := h.openvpn.ApplyStatus(h.ctx, constants.Stopped)
|
||||
h.logger.Info("openvpn: %s", outcome)
|
||||
outcome, _ = h.openvpn.SetStatus(constants.Running)
|
||||
outcome, _ = h.openvpn.ApplyStatus(h.ctx, constants.Running)
|
||||
h.logger.Info("openvpn: %s", outcome)
|
||||
if _, err := w.Write([]byte("openvpn restarted, please consider using the /v1/ API in the future.")); err != nil {
|
||||
h.logger.Warn(err)
|
||||
}
|
||||
case "/unbound/actions/restart":
|
||||
outcome, _ := h.dns.SetStatus(constants.Stopped)
|
||||
outcome, _ := h.dns.ApplyStatus(h.ctx, constants.Stopped)
|
||||
h.logger.Info("dns: %s", outcome)
|
||||
outcome, _ = h.dns.SetStatus(constants.Running)
|
||||
outcome, _ = h.dns.ApplyStatus(h.ctx, constants.Running)
|
||||
h.logger.Info("dns: %s", outcome)
|
||||
if _, err := w.Write([]byte("dns restarted, please consider using the /v1/ API in the future.")); err != nil {
|
||||
h.logger.Warn(err)
|
||||
@@ -56,9 +59,9 @@ func (h *handlerV0) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
case "/openvpn/settings":
|
||||
http.Redirect(w, r, "/v1/openvpn/settings", http.StatusPermanentRedirect)
|
||||
case "/updater/restart":
|
||||
outcome, _ := h.updater.SetStatus(constants.Stopped)
|
||||
outcome, _ := h.updater.SetStatus(h.ctx, constants.Stopped)
|
||||
h.logger.Info("updater: %s", outcome)
|
||||
outcome, _ = h.updater.SetStatus(constants.Running)
|
||||
outcome, _ = h.updater.SetStatus(h.ctx, constants.Running)
|
||||
h.logger.Info("updater: %s", outcome)
|
||||
if _, err := w.Write([]byte("updater restarted, please consider using the /v1/ API in the future.")); err != nil {
|
||||
h.logger.Warn(err)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strings"
|
||||
@@ -9,14 +10,17 @@ import (
|
||||
"github.com/qdm12/golibs/logging"
|
||||
)
|
||||
|
||||
func newOpenvpnHandler(looper openvpn.Looper, logger logging.Logger) http.Handler {
|
||||
func newOpenvpnHandler(ctx context.Context, looper openvpn.Looper,
|
||||
logger logging.Logger) http.Handler {
|
||||
return &openvpnHandler{
|
||||
ctx: ctx,
|
||||
looper: looper,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
type openvpnHandler struct {
|
||||
ctx context.Context
|
||||
looper openvpn.Looper
|
||||
logger logging.Logger
|
||||
}
|
||||
@@ -75,7 +79,7 @@ func (h *openvpnHandler) setStatus(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
outcome, err := h.looper.SetStatus(status)
|
||||
outcome, err := h.looper.ApplyStatus(h.ctx, status)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
|
||||
@@ -25,11 +25,11 @@ type server struct {
|
||||
handler http.Handler
|
||||
}
|
||||
|
||||
func New(address string, logEnabled bool, logger logging.Logger,
|
||||
func New(ctx context.Context, address string, logEnabled bool, logger logging.Logger,
|
||||
buildInfo models.BuildInformation,
|
||||
openvpnLooper openvpn.Looper, unboundLooper dns.Looper,
|
||||
updaterLooper updater.Looper, publicIPLooper publicip.Looper) Server {
|
||||
handler := newHandler(logger, logEnabled, buildInfo,
|
||||
handler := newHandler(ctx, logger, logEnabled, buildInfo,
|
||||
openvpnLooper, unboundLooper, updaterLooper, publicIPLooper)
|
||||
return &server{
|
||||
address: address,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strings"
|
||||
@@ -10,15 +11,18 @@ import (
|
||||
)
|
||||
|
||||
func newUpdaterHandler(
|
||||
ctx context.Context,
|
||||
looper updater.Looper,
|
||||
logger logging.Logger) http.Handler {
|
||||
return &updaterHandler{
|
||||
ctx: ctx,
|
||||
looper: looper,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
type updaterHandler struct {
|
||||
ctx context.Context
|
||||
looper updater.Looper
|
||||
logger logging.Logger
|
||||
}
|
||||
@@ -63,7 +67,7 @@ func (h *updaterHandler) setStatus(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
outcome, err := h.looper.SetStatus(status)
|
||||
outcome, err := h.looper.SetStatus(h.ctx, status)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
|
||||
@@ -16,10 +16,12 @@ import (
|
||||
|
||||
type Looper interface {
|
||||
Run(ctx context.Context, done chan<- struct{})
|
||||
SetStatus(status models.LoopStatus) (outcome string, err error)
|
||||
SetStatus(ctx context.Context, status models.LoopStatus) (
|
||||
outcome string, err error)
|
||||
GetStatus() (status models.LoopStatus)
|
||||
GetSettings() (settings configuration.ShadowSocks)
|
||||
SetSettings(settings configuration.ShadowSocks) (outcome string)
|
||||
SetSettings(ctx context.Context, settings configuration.ShadowSocks) (
|
||||
outcome string)
|
||||
}
|
||||
|
||||
type looper struct {
|
||||
@@ -74,7 +76,7 @@ func (l *looper) Run(ctx context.Context, done chan<- struct{}) {
|
||||
|
||||
if l.GetSettings().Enabled {
|
||||
go func() {
|
||||
_, _ = l.SetStatus(constants.Running)
|
||||
_, _ = l.SetStatus(ctx, constants.Running)
|
||||
}()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package shadowsocks
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
@@ -32,7 +33,8 @@ func (l *looper) GetStatus() (status models.LoopStatus) {
|
||||
|
||||
var ErrInvalidStatus = errors.New("invalid status")
|
||||
|
||||
func (l *looper) SetStatus(status models.LoopStatus) (outcome string, err error) {
|
||||
func (l *looper) SetStatus(ctx context.Context, status models.LoopStatus) (
|
||||
outcome string, err error) {
|
||||
l.state.statusMu.Lock()
|
||||
defer l.state.statusMu.Unlock()
|
||||
existingStatus := l.state.status
|
||||
@@ -48,7 +50,12 @@ func (l *looper) SetStatus(status models.LoopStatus) (outcome string, err error)
|
||||
l.state.status = constants.Starting
|
||||
l.state.statusMu.Unlock()
|
||||
l.start <- struct{}{}
|
||||
newStatus := <-l.running
|
||||
|
||||
newStatus := constants.Starting // for canceled context
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
case newStatus = <-l.running:
|
||||
}
|
||||
l.state.statusMu.Lock()
|
||||
l.state.status = newStatus
|
||||
return newStatus.String(), nil
|
||||
@@ -62,9 +69,14 @@ func (l *looper) SetStatus(status models.LoopStatus) (outcome string, err error)
|
||||
l.state.status = constants.Stopping
|
||||
l.state.statusMu.Unlock()
|
||||
l.stop <- struct{}{}
|
||||
<-l.stopped
|
||||
newStatus := constants.Stopping // for canceled context
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
case <-l.stopped:
|
||||
newStatus = constants.Stopped
|
||||
}
|
||||
l.state.statusMu.Lock()
|
||||
l.state.status = status
|
||||
l.state.status = newStatus
|
||||
return status.String(), nil
|
||||
default:
|
||||
return "", fmt.Errorf("%w: %s: it can only be one of: %s, %s",
|
||||
@@ -78,7 +90,8 @@ func (l *looper) GetSettings() (settings configuration.ShadowSocks) {
|
||||
return l.state.settings
|
||||
}
|
||||
|
||||
func (l *looper) SetSettings(settings configuration.ShadowSocks) (outcome string) {
|
||||
func (l *looper) SetSettings(ctx context.Context, settings configuration.ShadowSocks) (
|
||||
outcome string) {
|
||||
l.state.settingsMu.Lock()
|
||||
settingsUnchanged := reflect.DeepEqual(settings, l.state.settings)
|
||||
if settingsUnchanged {
|
||||
@@ -93,12 +106,12 @@ func (l *looper) SetSettings(settings configuration.ShadowSocks) (outcome string
|
||||
switch {
|
||||
case !newEnabled && !previousEnabled:
|
||||
case newEnabled && previousEnabled:
|
||||
_, _ = l.SetStatus(constants.Stopped)
|
||||
_, _ = l.SetStatus(constants.Running)
|
||||
_, _ = l.SetStatus(ctx, constants.Stopped)
|
||||
_, _ = l.SetStatus(ctx, constants.Running)
|
||||
case newEnabled && !previousEnabled:
|
||||
_, _ = l.SetStatus(constants.Running)
|
||||
_, _ = l.SetStatus(ctx, constants.Running)
|
||||
case !newEnabled && previousEnabled:
|
||||
_, _ = l.SetStatus(constants.Stopped)
|
||||
_, _ = l.SetStatus(ctx, constants.Stopped)
|
||||
}
|
||||
return "settings updated"
|
||||
}
|
||||
|
||||
@@ -17,7 +17,8 @@ type Looper interface {
|
||||
Run(ctx context.Context, done chan<- struct{})
|
||||
RunRestartTicker(ctx context.Context, done chan<- struct{})
|
||||
GetStatus() (status models.LoopStatus)
|
||||
SetStatus(status models.LoopStatus) (outcome string, err error)
|
||||
SetStatus(ctx context.Context, status models.LoopStatus) (
|
||||
outcome string, err error)
|
||||
GetSettings() (settings configuration.Updater)
|
||||
SetSettings(settings configuration.Updater) (outcome string)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package updater
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
@@ -32,7 +33,7 @@ func (l *looper) GetStatus() (status models.LoopStatus) {
|
||||
|
||||
var ErrInvalidStatus = errors.New("invalid status")
|
||||
|
||||
func (l *looper) SetStatus(status models.LoopStatus) (outcome string, err error) {
|
||||
func (l *looper) SetStatus(ctx context.Context, status models.LoopStatus) (outcome string, err error) {
|
||||
l.state.statusMu.Lock()
|
||||
defer l.state.statusMu.Unlock()
|
||||
existingStatus := l.state.status
|
||||
@@ -48,7 +49,12 @@ func (l *looper) SetStatus(status models.LoopStatus) (outcome string, err error)
|
||||
l.state.status = constants.Starting
|
||||
l.state.statusMu.Unlock()
|
||||
l.start <- struct{}{}
|
||||
newStatus := <-l.running
|
||||
|
||||
newStatus := constants.Starting // for canceled context
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
case newStatus = <-l.running:
|
||||
}
|
||||
l.state.statusMu.Lock()
|
||||
l.state.status = newStatus
|
||||
return newStatus.String(), nil
|
||||
@@ -62,9 +68,15 @@ func (l *looper) SetStatus(status models.LoopStatus) (outcome string, err error)
|
||||
l.state.status = constants.Stopping
|
||||
l.state.statusMu.Unlock()
|
||||
l.stop <- struct{}{}
|
||||
<-l.stopped
|
||||
|
||||
newStatus := constants.Stopping // for canceled context
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
case <-l.stopped:
|
||||
newStatus = constants.Stopped
|
||||
}
|
||||
l.state.statusMu.Lock()
|
||||
l.state.status = status
|
||||
l.state.status = newStatus
|
||||
return status.String(), nil
|
||||
default:
|
||||
return "", fmt.Errorf("%w: %s: it can only be one of: %s, %s",
|
||||
|
||||
Reference in New Issue
Block a user