Compare commits

..

1 Commits

Author SHA1 Message Date
Quentin McGaw
78bf5ddc2b stash 2024-11-08 17:29:12 +00:00
14 changed files with 61 additions and 253 deletions

View File

@@ -66,33 +66,6 @@ jobs:
- name: Build final image
run: docker build -t final-image .
- name: Run Wireguard
if: |
github.repository == 'qdm12/gluetun' &&
(
github.event_name == 'push' ||
(github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository)
)
run: |
docker run -it --rm --cap-add=NET_ADMIN -e VPNSP=mullvad -e VPN_TYPE=wireguard \
-e WIREGUARD_PRIVATE_KEY=${{ secrets.WIREGUARD_PRIVATE_KEY }} \
-e WIREGUARD_ADDRESS=${{ secrets.WIREGUARD_ADDRESS }} \
final-image \
exit-once-connected
- name: Run OpenVPN
if: |
github.repository == 'qdm12/gluetun' &&
(
github.event_name == 'push' ||
(github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository)
)
run: |
docker run -it --rm --cap-add=NET_ADMIN -e VPNSP=mullvad -e VPN_TYPE=openvpn \
-e OPENVPN_PASSWORD=${{ secrets.OPENVPN_PASSWORD }} \
final-image \
exit-once-connected
codeql:
runs-on: ubuntu-latest
permissions:

View File

@@ -145,7 +145,6 @@ func _main(ctx context.Context, buildInfo models.BuildInformation,
tun Tun, netLinker netLinker, cmder RunStarter,
cli clier,
) error {
var exitOnceConnected bool
if len(args) > 1 { // cli operation
switch args[1] {
case "healthcheck":
@@ -160,8 +159,6 @@ func _main(ctx context.Context, buildInfo models.BuildInformation,
return cli.FormatServers(args[2:])
case "genkey":
return cli.GenKey(args[2:])
case "exit-once-connected":
exitOnceConnected = true
default:
return fmt.Errorf("%w: %s", errCommandUnknown, args[1])
}
@@ -480,8 +477,7 @@ func _main(ctx context.Context, buildInfo models.BuildInformation,
controlGroupHandler.Add(httpServerHandler)
healthLogger := logger.New(log.SetComponent("healthcheck"))
healthcheckServer := healthcheck.NewServer(allSettings.Health, healthLogger, vpnLooper,
exitOnceConnected)
healthcheckServer := healthcheck.NewServer(allSettings.Health, healthLogger, vpnLooper)
healthServerHandler, healthServerCtx, healthServerDone := goshutdown.NewGoRoutineHandler(
"HTTP health server", goroutine.OptionTimeout(defaultShutdownTimeout))
go healthcheckServer.Run(healthServerCtx, healthServerDone)

4
go.mod
View File

@@ -8,7 +8,7 @@ require (
github.com/golang/mock v1.6.0
github.com/klauspost/compress v1.17.11
github.com/klauspost/pgzip v1.2.6
github.com/pelletier/go-toml/v2 v2.2.3
github.com/pelletier/go-toml/v2 v2.2.2
github.com/qdm12/dns/v2 v2.0.0-rc8
github.com/qdm12/gosettings v0.4.3
github.com/qdm12/goshutdown v0.3.0
@@ -22,7 +22,7 @@ require (
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c
golang.org/x/net v0.30.0
golang.org/x/sys v0.27.0
golang.org/x/sys v0.26.0
golang.org/x/text v0.19.0
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6

17
go.sum
View File

@@ -4,6 +4,7 @@ github.com/breml/rootcerts v0.2.18 h1:KjZaNT7AX/akUjzpStuwTMQs42YHlPyc6NmdwShVba
github.com/breml/rootcerts v0.2.18/go.mod h1:S/PKh+4d1HUn4HQovEB8hPJZO6pUZYrIhmXBhsegfXw=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
@@ -41,8 +42,8 @@ github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721 h1:RlZweED6sbSArvlE9
github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721/go.mod h1:Ickgr2WtCLZ2MDGd4Gr0geeCH5HybhRJbonOgQpvSxc=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
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/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
@@ -73,6 +74,13 @@ github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8=
@@ -112,8 +120,8 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@@ -142,6 +150,7 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gvisor.dev/gvisor v0.0.0-20230927004350-cbd86285d259 h1:TbRPT0HtzFP3Cno1zZo7yPzEEnfu8EjLfl6IU9VfqkQ=

View File

@@ -22,14 +22,15 @@ func (l *Loop) SetSettings(ctx context.Context, settings settings.DNS) (
return l.state.SetSettings(ctx, settings)
}
func buildDoTSettings(settings settings.DNS,
func buildServerSettings(settings settings.DNS,
filter *mapfilter.Filter, logger Logger) (
serverSettings server.Settings, err error,
) {
serverSettings.Logger = logger
providersData := provider.NewProviders()
var dotSettings dot.Settings
providersData := provider.NewProviders()
dotSettings.Warner = logger
dotSettings.UpstreamResolvers = make([]provider.Provider, len(settings.DoT.Providers))
for i := range settings.DoT.Providers {
var err error

View File

@@ -20,7 +20,7 @@ func (l *Loop) setupServer(ctx context.Context) (runError <-chan error, err erro
settings := l.GetSettings()
dotSettings, err := buildDoTSettings(settings, l.filter, l.logger)
dotSettings, err := buildServerSettings(settings, l.filter, l.logger)
if err != nil {
return nil, fmt.Errorf("building DoT settings: %w", err)
}

View File

@@ -9,16 +9,15 @@ import (
)
type Server struct {
logger Logger
handler *handler
dialer *net.Dialer
config settings.Health
vpn vpnHealth
exitOnceConnected bool
logger Logger
handler *handler
dialer *net.Dialer
config settings.Health
vpn vpnHealth
}
func NewServer(config settings.Health,
logger Logger, vpnLoop StatusApplier, exitOnceConnected bool,
logger Logger, vpnLoop StatusApplier,
) *Server {
return &Server{
logger: logger,

View File

@@ -1,13 +0,0 @@
package netlink
import (
"testing"
"github.com/qdm12/log"
)
func Test_IsIPv6Supported(t *testing.T) {
n := New(log.New(log.SetLevel(log.LevelDebug)))
supported, err := n.IsIPv6Supported()
t.Log(supported, err)
}

View File

@@ -32,7 +32,6 @@ func hardcodedServers() (servers []models.Server) {
{Country: "Canada", City: "Montreal", Hostname: "canada-montreal-ca-version-2.expressnetw.com"},
{Country: "Canada", City: "Toronto", Hostname: "canada-toronto-2-ca-version-2.expressnetw.com"},
{Country: "Canada", City: "Toronto", Hostname: "canada-toronto-ca-version-2.expressnetw.com"},
{Country: "Canada", City: "Vancouver", Hostname: "canada-vancouver-ca-version-2.expressnetw.com"},
{Country: "Chile", Hostname: "chile-ca-version-2.expressnetw.com"},
{Country: "Colombia", Hostname: "colombia-ca-version-2.expressnetw.com"},
{Country: "Costa Rica", City: "Costa Rica", Hostname: "costarica-ca-version-2.expressnetw.com"},
@@ -49,17 +48,13 @@ func hardcodedServers() (servers []models.Server) {
{Country: "France", City: "Strasbourg", Hostname: "france-strasbourg-ca-version-2.expressnetw.com"},
{Country: "Georgia", Hostname: "georgia-ca-version-2.expressnetw.com"},
{Country: "Germany", City: "Frankfurt", Hostname: "germany-frankfurt-1-ca-version-2.expressnetw.com"},
{Country: "Germany", City: "Frankfurt", Hostname: "germany-frankfurt-2-ca-version-2.expressnetw.com"},
{Country: "Germany", City: "Frankfurt", Hostname: "germany-darmstadt-ca-version-2.expressnetw.com"},
{Country: "Germany", City: "Nuremberg", Hostname: "germany-nuremberg-ca-version-2.expressnetw.com"},
{Country: "Greece", Hostname: "greece-ca-version-2.expressnetw.com"},
{Country: "Guatemala", Hostname: "guatemala-ca-version-2.expressnetw.com"},
{Country: "Hong Kong", City: "Hong Kong", Hostname: "hongkong-2-ca-version-2.expressnetw.com"},
{Country: "Hong Kong", City: "Hong Kong", Hostname: "hongkong4-ca-version-2.expressnetw.com"},
{Country: "Hungary", Hostname: "hungary-ca-version-2.expressnetw.com"},
{Country: "Iceland", Hostname: "iceland-ca-version-2.expressnetw.com"},
{Country: "India", City: "Chennai", Hostname: "india-chennai-ca-version-2.expressnetw.com"},
{Country: "India", City: "Mumbai", Hostname: "india-mumbai-1-ca-version-2.expressnetw.com"},
{Country: "Indonesia", Hostname: "indonesia-ca-version-2.expressnetw.com"},
{Country: "Ireland", Hostname: "ireland-ca-version-2.expressnetw.com"},
{Country: "Isle Of Man", City: "Isle Of Man", Hostname: "isleofman-ca-version-2.expressnetw.com"},
@@ -72,7 +67,6 @@ func hardcodedServers() (servers []models.Server) {
{Country: "Jersey", Hostname: "jersey-ca-version-2.expressnetw.com"},
{Country: "Kazakhstan", Hostname: "kazakhstan-ca-version-2.expressnetw.com"},
{Country: "Kenya", Hostname: "kenya-ca-version-2.expressnetw.com"},
{Country: "Kyrgyzstan", Hostname: "kyrgyzstan-ca-version-2.expressnetw.com"},
{Country: "Laos", Hostname: "laos-ca-version-2.expressnetw.com"},
{Country: "Latvia", Hostname: "latvia-ca-version-2.expressnetw.com"},
{Country: "Liechtenstein", Hostname: "liechtenstein-ca-version-2.expressnetw.com"},
@@ -88,7 +82,6 @@ func hardcodedServers() (servers []models.Server) {
{Country: "Montenegro", Hostname: "montenegro-ca-version-2.expressnetw.com"},
{Country: "Myanmar", Hostname: "myanmar-ca-version-2.expressnetw.com"},
{Country: "Nepal", Hostname: "nepal-ca-version-2.expressnetw.com"},
{Country: "Netherlands", City: "Amsterdam", Hostname: "netherlands-amsterdam-2-ca-version-2.expressnetw.com"},
{Country: "Netherlands", City: "Amsterdam", Hostname: "netherlands-amsterdam-ca-version-2.expressnetw.com"},
{Country: "Netherlands", City: "Rotterdam", Hostname: "netherlands-rotterdam-ca-version-2.expressnetw.com"},
{Country: "Netherlands", City: "The Hague", Hostname: "netherlands-thehague-ca-version-2.expressnetw.com"},
@@ -129,7 +122,6 @@ func hardcodedServers() (servers []models.Server) {
{Country: "USA", City: "Dallas", Hostname: "usa-dallas-2-ca-version-2.expressnetw.com"},
{Country: "USA", City: "Dallas", Hostname: "usa-dallas-ca-version-2.expressnetw.com"},
{Country: "USA", City: "Denver", Hostname: "usa-denver-ca-version-2.expressnetw.com"},
{Country: "USA", City: "Los Angeles", Hostname: "usa-losangeles-1-ca-version-2.expressnetw.com"},
{Country: "USA", City: "Los Angeles", Hostname: "usa-losangeles-2-ca-version-2.expressnetw.com"},
{Country: "USA", City: "Los Angeles", Hostname: "usa-losangeles-3-ca-version-2.expressnetw.com"},
{Country: "USA", City: "Los Angeles", Hostname: "usa-losangeles5-ca-version-2.expressnetw.com"},
@@ -138,7 +130,6 @@ func hardcodedServers() (servers []models.Server) {
{Country: "USA", City: "New Jersey", Hostname: "usa-newjersey-1-ca-version-2.expressnetw.com"},
{Country: "USA", City: "New Jersey", Hostname: "usa-newjersey2-ca-version-2.expressnetw.com"},
{Country: "USA", City: "New Jersey", Hostname: "usa-newjersey-3-ca-version-2.expressnetw.com"},
{Country: "USA", City: "New York", Hostname: "us-new-york-2-ca-version-2.expressnetw.com"},
{Country: "USA", City: "New York", Hostname: "usa-newyork-ca-version-2.expressnetw.com"},
{Country: "USA", City: "Salt Lake City", Hostname: "usa-saltlakecity-ca-version-2.expressnetw.com"},
{Country: "USA", City: "San Francisco", Hostname: "usa-sanfrancisco-ca-version-2.expressnetw.com"},

View File

@@ -3,11 +3,7 @@ package api
import (
"errors"
"fmt"
"maps"
"net/http"
"net/url"
"regexp"
"slices"
"strings"
)
@@ -20,8 +16,6 @@ const (
IP2Location Provider = "ip2location"
)
const echoipPrefix = "echoip#"
type NameToken struct {
Name string
Token string
@@ -36,19 +30,15 @@ func New(nameTokenPairs []NameToken, client *http.Client) (
if err != nil {
return nil, fmt.Errorf("parsing API name: %w", err)
}
switch {
case provider == Cloudflare:
switch provider {
case Cloudflare:
fetchers[i] = newCloudflare(client)
case provider == IfConfigCo:
const ifConfigCoURL = "https://ifconfig.co"
fetchers[i] = newEchoip(client, ifConfigCoURL)
case provider == IPInfo:
case IfConfigCo:
fetchers[i] = newIfConfigCo(client)
case IPInfo:
fetchers[i] = newIPInfo(client, nameTokenPair.Token)
case provider == IP2Location:
case IP2Location:
fetchers[i] = newIP2Location(client, nameTokenPair.Token)
case strings.HasPrefix(string(provider), echoipPrefix):
url := strings.TrimPrefix(string(provider), echoipPrefix)
fetchers[i] = newEchoip(client, url)
default:
panic("provider not valid: " + provider)
}
@@ -56,88 +46,20 @@ func New(nameTokenPairs []NameToken, client *http.Client) (
return fetchers, nil
}
var regexEchoipURL = regexp.MustCompile(`^http(s|):\/\/.+$`)
var ErrProviderNotValid = errors.New("API name is not valid")
func ParseProvider(s string) (provider Provider, err error) {
possibleProviders := []Provider{
Cloudflare,
IfConfigCo,
IP2Location,
IPInfo,
switch strings.ToLower(s) {
case "cloudflare":
return Cloudflare, nil
case string(IfConfigCo):
return IfConfigCo, nil
case "ipinfo":
return IPInfo, nil
case "ip2location":
return IP2Location, nil
default:
return "", fmt.Errorf(`%w: %q can only be "cloudflare", "ifconfigco", "ip2location" or "ipinfo"`,
ErrProviderNotValid, s)
}
stringToProvider := make(map[string]Provider, len(possibleProviders))
for _, provider := range possibleProviders {
stringToProvider[string(provider)] = provider
}
provider, ok := stringToProvider[strings.ToLower(s)]
if ok {
return provider, nil
}
customPrefixToURLRegex := map[string]*regexp.Regexp{
echoipPrefix: regexEchoipURL,
}
for prefix, urlRegex := range customPrefixToURLRegex {
match, err := checkCustomURL(s, prefix, urlRegex)
if !match {
continue
} else if err != nil {
return "", err
}
return Provider(s), nil
}
providerStrings := make([]string, 0, len(stringToProvider)+len(customPrefixToURLRegex))
for _, providerString := range slices.Sorted(maps.Keys(stringToProvider)) {
providerStrings = append(providerStrings, `"`+providerString+`"`)
}
for _, prefix := range slices.Sorted(maps.Keys(customPrefixToURLRegex)) {
providerStrings = append(providerStrings, "a custom "+prefix+" url")
}
return "", fmt.Errorf(`%w: %q can only be %s`,
ErrProviderNotValid, s, orStrings(providerStrings))
}
var ErrCustomURLNotValid = errors.New("custom URL is not valid")
func checkCustomURL(s, prefix string, regex *regexp.Regexp) (match bool, err error) {
if !strings.HasPrefix(s, prefix) {
return false, nil
}
s = strings.TrimPrefix(s, prefix)
_, err = url.Parse(s)
if err != nil {
return true, fmt.Errorf("%s %w: %w", prefix, ErrCustomURLNotValid, err)
}
if regex.MatchString(s) {
return true, nil
}
return true, fmt.Errorf("%s %w: %q does not match regular expression: %s",
prefix, ErrCustomURLNotValid, s, regex)
}
func orStrings(strings []string) (result string) {
return joinStrings(strings, "or")
}
func joinStrings(strings []string, lastJoin string) (result string) {
if len(strings) == 0 {
return ""
}
result = strings[0]
for i := 1; i < len(strings); i++ {
if i < len(strings)-1 {
result += ", " + strings[i]
} else {
result += " " + lastJoin + " " + strings[i]
}
}
return result
}

View File

@@ -1,68 +0,0 @@
package api
import (
"testing"
"github.com/stretchr/testify/assert"
)
func Test_ParseProvider(t *testing.T) {
t.Parallel()
testCases := map[string]struct {
s string
provider Provider
errWrapped error
errMessage string
}{
"empty": {
errWrapped: ErrProviderNotValid,
errMessage: `API name is not valid: "" can only be ` +
`"cloudflare", "ifconfigco", "ip2location", "ipinfo" or a custom echoip# url`,
},
"invalid": {
s: "xyz",
errWrapped: ErrProviderNotValid,
errMessage: `API name is not valid: "xyz" can only be ` +
`"cloudflare", "ifconfigco", "ip2location", "ipinfo" or a custom echoip# url`,
},
"ipinfo": {
s: "ipinfo",
provider: IPInfo,
},
"IpInfo": {
s: "IpInfo",
provider: IPInfo,
},
"echoip_url_empty": {
s: "echoip#",
errWrapped: ErrCustomURLNotValid,
errMessage: `echoip# custom URL is not valid: "" ` +
`does not match regular expression: ^http(s|):\/\/.+$`,
},
"echoip_url_invalid": {
s: "echoip#postgres://localhost:3451",
errWrapped: ErrCustomURLNotValid,
errMessage: `echoip# custom URL is not valid: "postgres://localhost:3451" ` +
`does not match regular expression: ^http(s|):\/\/.+$`,
},
"echoip_url_valid": {
s: "echoip#http://localhost:3451",
provider: Provider("echoip#http://localhost:3451"),
},
}
for name, testCase := range testCases {
t.Run(name, func(t *testing.T) {
t.Parallel()
provider, err := ParseProvider(testCase.s)
assert.Equal(t, testCase.provider, provider)
assert.ErrorIs(t, err, testCase.errWrapped)
if testCase.errWrapped != nil {
assert.EqualError(t, err, testCase.errMessage)
}
})
}
}

View File

@@ -6,45 +6,39 @@ import (
"fmt"
"net/http"
"net/netip"
"strings"
"github.com/qdm12/gluetun/internal/models"
)
type echoip struct {
type ifConfigCo struct {
client *http.Client
url string
}
func newEchoip(client *http.Client, url string) *echoip {
return &echoip{
func newIfConfigCo(client *http.Client) *ifConfigCo {
return &ifConfigCo{
client: client,
url: url,
}
}
func (e *echoip) String() string {
s := e.url
s = strings.TrimPrefix(s, "http://")
s = strings.TrimPrefix(s, "https://")
return s
func (i *ifConfigCo) String() string {
return string(IfConfigCo)
}
func (e *echoip) CanFetchAnyIP() bool {
func (i *ifConfigCo) CanFetchAnyIP() bool {
return true
}
func (e *echoip) Token() string {
func (i *ifConfigCo) Token() string {
return ""
}
// FetchInfo obtains information on the ip address provided
// using the echoip API at the url given. If the ip is the zero value,
// using the ifconfig.co/json API. If the ip is the zero value,
// the public IP address of the machine is used as the IP.
func (e *echoip) FetchInfo(ctx context.Context, ip netip.Addr) (
func (i *ifConfigCo) FetchInfo(ctx context.Context, ip netip.Addr) (
result models.PublicIP, err error,
) {
url := e.url + "/json"
url := "https://ifconfig.co/json"
if ip.IsValid() {
url += "?ip=" + ip.String()
}
@@ -54,7 +48,7 @@ func (e *echoip) FetchInfo(ctx context.Context, ip netip.Addr) (
return result, err
}
response, err := e.client.Do(request)
response, err := i.client.Do(request)
if err != nil {
return result, err
}

View File

@@ -5,10 +5,12 @@ import (
"errors"
"fmt"
"net/netip"
"time"
)
type Parallel struct {
repeatResolver *Repeat
lastRequestTime time.Time
repeatResolver *Repeat
}
func NewParallelResolver(resolverAddress string) *Parallel {

View File

@@ -1,6 +1,8 @@
# Maintenance
- Rename `UNBLOCK` to `DNS_HOSTNAMES_UNBLOCKED`
<https://github.com/macvk/dnsleaktest/blob/master/dnsleaktest.go>
- Rename `UNBLOCK` to `DNS_ALLOWED_HOSTNAMES`
- Change `Run` methods to `Start`+`Stop`, returning channels rather than injecting them
- Go 1.18
- gofumpt