updater: refactoring and set DNS server correctly

- Fix CLI operation not setting DNS server
- Fix periodic operation not setting DNS server
- Set DNS address for resolution once at start for both CLI and periodic operation
- Inject resolver to each provider instead of creating it within
- Use resolver settings on every call to `.Resolve` method, instead of passing it to constructor
- Move out minServers check from resolver
This commit is contained in:
Quentin McGaw
2022-06-11 17:41:57 +00:00
parent 1bd355ab96
commit 447a7c9891
70 changed files with 366 additions and 229 deletions

View File

@@ -12,6 +12,7 @@ import (
gomock "github.com/golang/mock/gomock"
settings "github.com/qdm12/gluetun/internal/configuration/settings"
models "github.com/qdm12/gluetun/internal/models"
resolver "github.com/qdm12/gluetun/internal/updater/resolver"
)
// MockParallelResolver is a mock of ParallelResolver interface.
@@ -38,9 +39,9 @@ func (m *MockParallelResolver) EXPECT() *MockParallelResolverMockRecorder {
}
// Resolve mocks base method.
func (m *MockParallelResolver) Resolve(arg0 context.Context, arg1 []string, arg2 int) (map[string][]net.IP, []string, error) {
func (m *MockParallelResolver) Resolve(arg0 context.Context, arg1 resolver.ParallelSettings) (map[string][]net.IP, []string, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Resolve", arg0, arg1, arg2)
ret := m.ctrl.Call(m, "Resolve", arg0, arg1)
ret0, _ := ret[0].(map[string][]net.IP)
ret1, _ := ret[1].([]string)
ret2, _ := ret[2].(error)
@@ -48,9 +49,9 @@ func (m *MockParallelResolver) Resolve(arg0 context.Context, arg1 []string, arg2
}
// Resolve indicates an expected call of Resolve.
func (mr *MockParallelResolverMockRecorder) Resolve(arg0, arg1, arg2 interface{}) *gomock.Call {
func (mr *MockParallelResolverMockRecorder) Resolve(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Resolve", reflect.TypeOf((*MockParallelResolver)(nil).Resolve), arg0, arg1, arg2)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Resolve", reflect.TypeOf((*MockParallelResolver)(nil).Resolve), arg0, arg1)
}
// MockStorage is a mock of Storage interface.

View File

@@ -6,6 +6,7 @@ import (
"net"
"github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/updater/resolver"
)
var ErrNotEnoughServers = errors.New("not enough servers found")
@@ -15,7 +16,7 @@ type Fetcher interface {
}
type ParallelResolver interface {
Resolve(ctx context.Context, hosts []string, minToFind int) (
Resolve(ctx context.Context, settings resolver.ParallelSettings) (
hostToIPs map[string][]net.IP, warnings []string, err error)
}

View File

@@ -16,12 +16,13 @@ type Provider struct {
common.Fetcher
}
func New(storage common.Storage, randSource rand.Source) *Provider {
func New(storage common.Storage, randSource rand.Source,
parallelResolver common.ParallelResolver) *Provider {
return &Provider{
storage: storage,
randSource: randSource,
NoPortForwarder: utils.NewNoPortForwarding(providers.Cyberghost),
Fetcher: updater.New(),
Fetcher: updater.New(parallelResolver),
}
}

View File

@@ -6,7 +6,7 @@ import (
"github.com/qdm12/gluetun/internal/updater/resolver"
)
func newParallelResolver() (parallelResolver *resolver.Parallel) {
func parallelResolverSettings(hosts []string) (settings resolver.ParallelSettings) {
const (
maxFailRatio = 1
maxDuration = 20 * time.Second
@@ -14,7 +14,8 @@ func newParallelResolver() (parallelResolver *resolver.Parallel) {
maxNoNew = 4
maxFails = 10
)
settings := resolver.ParallelSettings{
return resolver.ParallelSettings{
Hosts: hosts,
MaxFailRatio: maxFailRatio,
Repeat: resolver.RepeatSettings{
MaxDuration: maxDuration,
@@ -24,5 +25,4 @@ func newParallelResolver() (parallelResolver *resolver.Parallel) {
SortIPs: true,
},
}
return resolver.NewParallelResolver(settings)
}

View File

@@ -4,9 +4,11 @@ package updater
import (
"context"
"fmt"
"sort"
"github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/provider/common"
)
func (u *Updater) FetchServers(ctx context.Context, minServers int) (
@@ -14,11 +16,17 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
possibleServers := getPossibleServers()
possibleHosts := possibleServers.hostsSlice()
hostToIPs, _, err := u.presolver.Resolve(ctx, possibleHosts, minServers)
resolveSettings := parallelResolverSettings(possibleHosts)
hostToIPs, _, err := u.presolver.Resolve(ctx, resolveSettings)
if err != nil {
return nil, err
}
if len(hostToIPs) < minServers {
return nil, fmt.Errorf("%w: %d and expected at least %d",
common.ErrNotEnoughServers, len(servers), minServers)
}
possibleServers.adaptWithIPs(hostToIPs)
servers = possibleServers.toSlice()

View File

@@ -8,8 +8,8 @@ type Updater struct {
presolver common.ParallelResolver
}
func New() *Updater {
func New(parallelResolver common.ParallelResolver) *Updater {
return &Updater{
presolver: newParallelResolver(),
presolver: parallelResolver,
}
}

View File

@@ -89,7 +89,8 @@ func Test_Provider_GetConnection(t *testing.T) {
unzipper := (common.Unzipper)(nil)
warner := (common.Warner)(nil)
provider := New(storage, randSource, unzipper, warner)
parallelResolver := (common.ParallelResolver)(nil)
provider := New(storage, randSource, unzipper, warner, parallelResolver)
if testCase.panicMessage != "" {
assert.PanicsWithValue(t, testCase.panicMessage, func() {

View File

@@ -17,12 +17,13 @@ type Provider struct {
}
func New(storage common.Storage, randSource rand.Source,
unzipper common.Unzipper, updaterWarner common.Warner) *Provider {
unzipper common.Unzipper, updaterWarner common.Warner,
parallelResolver common.ParallelResolver) *Provider {
return &Provider{
storage: storage,
randSource: randSource,
NoPortForwarder: utils.NewNoPortForwarding(providers.Expressvpn),
Fetcher: updater.New(unzipper, updaterWarner),
Fetcher: updater.New(unzipper, updaterWarner, parallelResolver),
}
}

View File

@@ -6,13 +6,14 @@ import (
"github.com/qdm12/gluetun/internal/updater/resolver"
)
func newParallelResolver() *resolver.Parallel {
func parallelResolverSettings(hosts []string) (settings resolver.ParallelSettings) {
const (
maxFailRatio = 0.1
maxNoNew = 1
maxFails = 2
)
settings := resolver.ParallelSettings{
return resolver.ParallelSettings{
Hosts: hosts,
MaxFailRatio: maxFailRatio,
Repeat: resolver.RepeatSettings{
MaxDuration: time.Second,
@@ -21,5 +22,4 @@ func newParallelResolver() *resolver.Parallel {
SortIPs: true,
},
}
return resolver.NewParallelResolver(settings)
}

View File

@@ -21,7 +21,8 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
hosts[i] = servers[i].Hostname
}
hostToIPs, warnings, err := u.presolver.Resolve(ctx, hosts, minServers)
resolveSettings := parallelResolverSettings(hosts)
hostToIPs, warnings, err := u.presolver.Resolve(ctx, resolveSettings)
for _, warning := range warnings {
u.warner.Warn(warning)
}

View File

@@ -10,10 +10,11 @@ type Updater struct {
warner common.Warner
}
func New(unzipper common.Unzipper, warner common.Warner) *Updater {
func New(unzipper common.Unzipper, warner common.Warner,
parallelResolver common.ParallelResolver) *Updater {
return &Updater{
unzipper: unzipper,
presolver: newParallelResolver(),
presolver: parallelResolver,
warner: warner,
}
}

View File

@@ -17,12 +17,13 @@ type Provider struct {
}
func New(storage common.Storage, randSource rand.Source,
unzipper common.Unzipper, updaterWarner common.Warner) *Provider {
unzipper common.Unzipper, updaterWarner common.Warner,
parallelResolver common.ParallelResolver) *Provider {
return &Provider{
storage: storage,
randSource: randSource,
NoPortForwarder: utils.NewNoPortForwarding(providers.Fastestvpn),
Fetcher: updater.New(unzipper, updaterWarner),
Fetcher: updater.New(unzipper, updaterWarner, parallelResolver),
}
}

View File

@@ -6,13 +6,14 @@ import (
"github.com/qdm12/gluetun/internal/updater/resolver"
)
func newParallelResolver() *resolver.Parallel {
func parallelResolverSettings(hosts []string) (settings resolver.ParallelSettings) {
const (
maxFailRatio = 0.1
maxNoNew = 1
maxFails = 2
)
settings := resolver.ParallelSettings{
return resolver.ParallelSettings{
Hosts: hosts,
MaxFailRatio: maxFailRatio,
Repeat: resolver.RepeatSettings{
MaxDuration: time.Second,
@@ -21,5 +22,4 @@ func newParallelResolver() *resolver.Parallel {
SortIPs: true,
},
}
return resolver.NewParallelResolver(settings)
}

View File

@@ -56,7 +56,8 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
}
hosts := hts.toHostsSlice()
hostToIPs, warnings, err := u.presolver.Resolve(ctx, hosts, minServers)
resolveSettings := parallelResolverSettings(hosts)
hostToIPs, warnings, err := u.presolver.Resolve(ctx, resolveSettings)
for _, warning := range warnings {
u.warner.Warn(warning)
}
@@ -64,15 +65,15 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
return nil, err
}
hts.adaptWithIPs(hostToIPs)
servers = hts.toServersSlice()
if len(servers) < minServers {
if len(hostToIPs) < minServers {
return nil, fmt.Errorf("%w: %d and expected at least %d",
common.ErrNotEnoughServers, len(servers), minServers)
}
hts.adaptWithIPs(hostToIPs)
servers = hts.toServersSlice()
sort.Sort(models.SortableServers(servers))
return servers, nil

View File

@@ -10,10 +10,11 @@ type Updater struct {
warner common.Warner
}
func New(unzipper common.Unzipper, warner common.Warner) *Updater {
func New(unzipper common.Unzipper, warner common.Warner,
parallelResolver common.ParallelResolver) *Updater {
return &Updater{
unzipper: unzipper,
presolver: newParallelResolver(),
presolver: parallelResolver,
warner: warner,
}
}

View File

@@ -18,12 +18,13 @@ type Provider struct {
}
func New(storage common.Storage, randSource rand.Source,
client *http.Client, updaterWarner common.Warner) *Provider {
client *http.Client, updaterWarner common.Warner,
parallelResolver common.ParallelResolver) *Provider {
return &Provider{
storage: storage,
randSource: randSource,
NoPortForwarder: utils.NewNoPortForwarding(providers.HideMyAss),
Fetcher: updater.New(client, updaterWarner),
Fetcher: updater.New(client, updaterWarner, parallelResolver),
}
}

View File

@@ -6,7 +6,7 @@ import (
"github.com/qdm12/gluetun/internal/updater/resolver"
)
func newParallelResolver() *resolver.Parallel {
func parallelResolverSettings(hosts []string) (settings resolver.ParallelSettings) {
const (
maxFailRatio = 0.1
maxDuration = 15 * time.Second
@@ -14,7 +14,8 @@ func newParallelResolver() *resolver.Parallel {
maxNoNew = 2
maxFails = 2
)
settings := resolver.ParallelSettings{
return resolver.ParallelSettings{
Hosts: hosts,
MaxFailRatio: maxFailRatio,
Repeat: resolver.RepeatSettings{
MaxDuration: maxDuration,
@@ -24,5 +25,4 @@ func newParallelResolver() *resolver.Parallel {
SortIPs: true,
},
}
return resolver.NewParallelResolver(settings)
}

View File

@@ -26,7 +26,8 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
common.ErrNotEnoughServers, len(hosts), minServers)
}
hostToIPs, warnings, err := u.presolver.Resolve(ctx, hosts, minServers)
resolveSettings := parallelResolverSettings(hosts)
hostToIPs, warnings, err := u.presolver.Resolve(ctx, resolveSettings)
for _, warning := range warnings {
u.warner.Warn(warning)
}
@@ -34,6 +35,11 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
return nil, err
}
if len(hostToIPs) < minServers {
return nil, fmt.Errorf("%w: %d and expected at least %d",
common.ErrNotEnoughServers, len(servers), minServers)
}
servers = make([]models.Server, 0, len(hostToIPs))
for host, IPs := range hostToIPs {
tcpURL, tcp := tcpHostToURL[host]

View File

@@ -12,10 +12,11 @@ type Updater struct {
warner common.Warner
}
func New(client *http.Client, warner common.Warner) *Updater {
func New(client *http.Client, warner common.Warner,
parallelResolver common.ParallelResolver) *Updater {
return &Updater{
client: client,
presolver: newParallelResolver(),
presolver: parallelResolver,
warner: warner,
}
}

View File

@@ -17,12 +17,13 @@ type Provider struct {
}
func New(storage common.Storage, randSource rand.Source,
unzipper common.Unzipper, updaterWarner common.Warner) *Provider {
unzipper common.Unzipper, updaterWarner common.Warner,
parallelResolver common.ParallelResolver) *Provider {
return &Provider{
storage: storage,
randSource: randSource,
NoPortForwarder: utils.NewNoPortForwarding(providers.Ipvanish),
Fetcher: updater.New(unzipper, updaterWarner),
Fetcher: updater.New(unzipper, updaterWarner, parallelResolver),
}
}

View File

@@ -6,7 +6,7 @@ import (
"github.com/qdm12/gluetun/internal/updater/resolver"
)
func newParallelResolver() (parallelResolver *resolver.Parallel) {
func parallelResolverSettings(hosts []string) (settings resolver.ParallelSettings) {
const (
maxFailRatio = 0.1
maxDuration = 20 * time.Second
@@ -14,7 +14,8 @@ func newParallelResolver() (parallelResolver *resolver.Parallel) {
maxNoNew = 2
maxFails = 2
)
settings := resolver.ParallelSettings{
return resolver.ParallelSettings{
Hosts: hosts,
MaxFailRatio: maxFailRatio,
Repeat: resolver.RepeatSettings{
MaxDuration: maxDuration,
@@ -24,5 +25,4 @@ func newParallelResolver() (parallelResolver *resolver.Parallel) {
SortIPs: true,
},
}
return resolver.NewParallelResolver(settings)
}

View File

@@ -67,7 +67,8 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
}
hosts := hts.toHostsSlice()
hostToIPs, warnings, err := u.presolver.Resolve(ctx, hosts, minServers)
resolveSettings := parallelResolverSettings(hosts)
hostToIPs, warnings, err := u.presolver.Resolve(ctx, resolveSettings)
for _, warning := range warnings {
u.warner.Warn(warning)
}
@@ -75,15 +76,15 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
return nil, err
}
hts.adaptWithIPs(hostToIPs)
servers = hts.toServersSlice()
if len(servers) < minServers {
if len(hostToIPs) < minServers {
return nil, fmt.Errorf("%w: %d and expected at least %d",
common.ErrNotEnoughServers, len(servers), minServers)
}
hts.adaptWithIPs(hostToIPs)
servers = hts.toServersSlice()
sort.Sort(models.SortableServers(servers))
return servers, nil

View File

@@ -5,11 +5,13 @@ import (
"errors"
"net"
"testing"
"time"
"github.com/golang/mock/gomock"
"github.com/qdm12/gluetun/internal/constants/vpn"
"github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/provider/common"
"github.com/qdm12/gluetun/internal/updater/resolver"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@@ -28,11 +30,11 @@ func Test_Updater_GetServers(t *testing.T) {
unzipErr error
// Resolution
expectResolve bool
hostsToResolve []string
hostToIPs map[string][]net.IP
resolveWarnings []string
resolveErr error
expectResolve bool
resolverSettings resolver.ParallelSettings
hostToIPs map[string][]net.IP
resolveWarnings []string
resolveErr error
// Output
servers []models.Server
@@ -85,9 +87,19 @@ func Test_Updater_GetServers(t *testing.T) {
unzipContents: map[string][]byte{
"ipvanish-CA-City-A-hosta.ovpn": []byte("remote hosta\nremote hostb"),
},
expectResolve: true,
hostsToResolve: []string{"hosta"},
err: errors.New("not enough servers found: 0 and expected at least 1"),
expectResolve: true,
resolverSettings: resolver.ParallelSettings{
Hosts: []string{"hosta"},
MaxFailRatio: 0.1,
Repeat: resolver.RepeatSettings{
MaxDuration: 20 * time.Second,
BetweenDuration: time.Second,
MaxNoNew: 2,
MaxFails: 2,
SortIPs: true,
},
},
err: errors.New("not enough servers found: 0 and expected at least 1"),
},
"resolve error": {
warnerBuilder: func(ctrl *gomock.Controller) common.Warner {
@@ -98,8 +110,18 @@ func Test_Updater_GetServers(t *testing.T) {
unzipContents: map[string][]byte{
"ipvanish-CA-City-A-hosta.ovpn": []byte("remote hosta"),
},
expectResolve: true,
hostsToResolve: []string{"hosta"},
expectResolve: true,
resolverSettings: resolver.ParallelSettings{
Hosts: []string{"hosta"},
MaxFailRatio: 0.1,
Repeat: resolver.RepeatSettings{
MaxDuration: 20 * time.Second,
BetweenDuration: time.Second,
MaxNoNew: 2,
MaxFails: 2,
SortIPs: true,
},
},
resolveWarnings: []string{"resolve warning"},
resolveErr: errors.New("dummy"),
err: errors.New("dummy"),
@@ -127,8 +149,18 @@ func Test_Updater_GetServers(t *testing.T) {
"ipvanish-CA-City-A-hosta.ovpn": []byte("remote hosta"),
"ipvanish-LU-City-B-hostb.ovpn": []byte("remote hostb"),
},
expectResolve: true,
hostsToResolve: []string{"hosta", "hostb"},
expectResolve: true,
resolverSettings: resolver.ParallelSettings{
Hosts: []string{"hosta", "hostb"},
MaxFailRatio: 0.1,
Repeat: resolver.RepeatSettings{
MaxDuration: 20 * time.Second,
BetweenDuration: time.Second,
MaxNoNew: 2,
MaxFails: 2,
SortIPs: true,
},
},
hostToIPs: map[string][]net.IP{
"hosta": {{1, 1, 1, 1}, {2, 2, 2, 2}},
"hostb": {{3, 3, 3, 3}, {4, 4, 4, 4}},
@@ -169,7 +201,7 @@ func Test_Updater_GetServers(t *testing.T) {
presolver := common.NewMockParallelResolver(ctrl)
if testCase.expectResolve {
presolver.EXPECT().Resolve(ctx, testCase.hostsToResolve, testCase.minServers).
presolver.EXPECT().Resolve(ctx, testCase.resolverSettings).
Return(testCase.hostToIPs, testCase.resolveWarnings, testCase.resolveErr)
}

View File

@@ -10,10 +10,11 @@ type Updater struct {
presolver common.ParallelResolver
}
func New(unzipper common.Unzipper, warner common.Warner) *Updater {
func New(unzipper common.Unzipper, warner common.Warner,
parallelResolver common.ParallelResolver) *Updater {
return &Updater{
unzipper: unzipper,
warner: warner,
presolver: newParallelResolver(),
presolver: parallelResolver,
}
}

View File

@@ -99,7 +99,8 @@ func Test_Provider_GetConnection(t *testing.T) {
client := (*http.Client)(nil)
warner := (common.Warner)(nil)
provider := New(storage, randSource, client, warner)
parallelResolver := (common.ParallelResolver)(nil)
provider := New(storage, randSource, client, warner, parallelResolver)
connection, err := provider.GetConnection(testCase.selection)

View File

@@ -18,12 +18,13 @@ type Provider struct {
}
func New(storage common.Storage, randSource rand.Source,
client *http.Client, updaterWarner common.Warner) *Provider {
client *http.Client, updaterWarner common.Warner,
parallelResolver common.ParallelResolver) *Provider {
return &Provider{
storage: storage,
randSource: randSource,
NoPortForwarder: utils.NewNoPortForwarding(providers.Ivpn),
Fetcher: updater.New(client, updaterWarner),
Fetcher: updater.New(client, updaterWarner, parallelResolver),
}
}

View File

@@ -6,7 +6,7 @@ import (
"github.com/qdm12/gluetun/internal/updater/resolver"
)
func newParallelResolver() (parallelResolver *resolver.Parallel) {
func parallelResolverSettings(hosts []string) (settings resolver.ParallelSettings) {
const (
maxFailRatio = 0.1
maxDuration = 20 * time.Second
@@ -14,7 +14,8 @@ func newParallelResolver() (parallelResolver *resolver.Parallel) {
maxNoNew = 2
maxFails = 2
)
settings := resolver.ParallelSettings{
return resolver.ParallelSettings{
Hosts: hosts,
MaxFailRatio: maxFailRatio,
Repeat: resolver.RepeatSettings{
MaxDuration: maxDuration,
@@ -24,5 +25,4 @@ func newParallelResolver() (parallelResolver *resolver.Parallel) {
SortIPs: true,
},
}
return resolver.NewParallelResolver(settings)
}

View File

@@ -38,7 +38,8 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
common.ErrNotEnoughServers, len(hosts), minServers)
}
hostToIPs, warnings, err := u.presolver.Resolve(ctx, hosts, minServers)
resolveSettings := parallelResolverSettings(hosts)
hostToIPs, warnings, err := u.presolver.Resolve(ctx, resolveSettings)
for _, warning := range warnings {
u.warner.Warn(warning)
}
@@ -46,6 +47,11 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
return nil, err
}
if len(hostToIPs) < minServers {
return nil, fmt.Errorf("%w: %d and expected at least %d",
common.ErrNotEnoughServers, len(servers), minServers)
}
servers = make([]models.Server, 0, len(hosts))
for _, serverData := range data.Servers {
vpnType := vpn.OpenVPN

View File

@@ -8,11 +8,13 @@ import (
"net/http"
"strings"
"testing"
"time"
"github.com/golang/mock/gomock"
"github.com/qdm12/gluetun/internal/constants/vpn"
"github.com/qdm12/gluetun/internal/models"
"github.com/qdm12/gluetun/internal/provider/common"
"github.com/qdm12/gluetun/internal/updater/resolver"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@@ -33,7 +35,7 @@ func Test_Updater_GetServers(t *testing.T) {
// Resolution
expectResolve bool
hostsToResolve []string
resolveSettings resolver.ParallelSettings
hostToIPs map[string][]net.IP
resolveWarnings []string
resolveErr error
@@ -56,9 +58,19 @@ func Test_Updater_GetServers(t *testing.T) {
responseBody: `{"servers":[
{"hostnames":{"openvpn":"hosta"}}
]}`,
responseStatus: http.StatusOK,
expectResolve: true,
hostsToResolve: []string{"hosta"},
responseStatus: http.StatusOK,
expectResolve: true,
resolveSettings: resolver.ParallelSettings{
Hosts: []string{"hosta"},
MaxFailRatio: 0.1,
Repeat: resolver.RepeatSettings{
MaxDuration: 20 * time.Second,
BetweenDuration: time.Second,
MaxNoNew: 2,
MaxFails: 2,
SortIPs: true,
},
},
resolveWarnings: []string{"resolve warning"},
resolveErr: errors.New("dummy"),
err: errors.New("dummy"),
@@ -86,7 +98,17 @@ func Test_Updater_GetServers(t *testing.T) {
]}`,
responseStatus: http.StatusOK,
expectResolve: true,
hostsToResolve: []string{"hosta", "hostb", "hostc"},
resolveSettings: resolver.ParallelSettings{
Hosts: []string{"hosta", "hostb", "hostc"},
MaxFailRatio: 0.1,
Repeat: resolver.RepeatSettings{
MaxDuration: 20 * time.Second,
BetweenDuration: time.Second,
MaxNoNew: 2,
MaxFails: 2,
SortIPs: true,
},
},
hostToIPs: map[string][]net.IP{
"hosta": {{1, 1, 1, 1}, {2, 2, 2, 2}},
"hostb": {{3, 3, 3, 3}, {4, 4, 4, 4}},
@@ -130,7 +152,7 @@ func Test_Updater_GetServers(t *testing.T) {
presolver := common.NewMockParallelResolver(ctrl)
if testCase.expectResolve {
presolver.EXPECT().Resolve(ctx, testCase.hostsToResolve, testCase.minServers).
presolver.EXPECT().Resolve(ctx, testCase.resolveSettings).
Return(testCase.hostToIPs, testCase.resolveWarnings, testCase.resolveErr)
}

View File

@@ -12,10 +12,11 @@ type Updater struct {
warner common.Warner
}
func New(client *http.Client, warner common.Warner) *Updater {
func New(client *http.Client, warner common.Warner,
parallelResolver common.ParallelResolver) *Updater {
return &Updater{
client: client,
presolver: newParallelResolver(),
presolver: parallelResolver,
warner: warner,
}
}

View File

@@ -19,12 +19,13 @@ type Provider struct {
func New(storage common.Storage, randSource rand.Source,
client *http.Client, unzipper common.Unzipper,
updaterWarner common.Warner) *Provider {
updaterWarner common.Warner,
parallelResolver common.ParallelResolver) *Provider {
return &Provider{
storage: storage,
randSource: randSource,
NoPortForwarder: utils.NewNoPortForwarding(providers.Privado),
Fetcher: updater.New(client, unzipper, updaterWarner),
Fetcher: updater.New(client, unzipper, updaterWarner, parallelResolver),
}
}

View File

@@ -6,14 +6,15 @@ import (
"github.com/qdm12/gluetun/internal/updater/resolver"
)
func newParallelResolver() (parallelResolver *resolver.Parallel) {
func parallelResolverSettings(hosts []string) (settings resolver.ParallelSettings) {
const (
maxFailRatio = 0.1
maxDuration = 30 * time.Second
maxNoNew = 2
maxFails = 2
)
settings := resolver.ParallelSettings{
return resolver.ParallelSettings{
Hosts: hosts,
MaxFailRatio: maxFailRatio,
Repeat: resolver.RepeatSettings{
MaxDuration: maxDuration,
@@ -22,5 +23,4 @@ func newParallelResolver() (parallelResolver *resolver.Parallel) {
SortIPs: true,
},
}
return resolver.NewParallelResolver(settings)
}

View File

@@ -50,7 +50,8 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
}
hosts := hts.toHostsSlice()
hostToIPs, warnings, err := u.presolver.Resolve(ctx, hosts, minServers)
resolveSettings := parallelResolverSettings(hosts)
hostToIPs, warnings, err := u.presolver.Resolve(ctx, resolveSettings)
for _, warning := range warnings {
u.warner.Warn(warning)
}
@@ -58,6 +59,11 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
return nil, err
}
if len(hostToIPs) < minServers {
return nil, fmt.Errorf("%w: %d and expected at least %d",
common.ErrNotEnoughServers, len(servers), minServers)
}
hts.adaptWithIPs(hostToIPs)
servers = hts.toServersSlice()

View File

@@ -14,11 +14,11 @@ type Updater struct {
}
func New(client *http.Client, unzipper common.Unzipper,
warner common.Warner) *Updater {
warner common.Warner, parallelResolver common.ParallelResolver) *Updater {
return &Updater{
client: client,
unzipper: unzipper,
presolver: newParallelResolver(),
presolver: parallelResolver,
warner: warner,
}
}

View File

@@ -17,12 +17,13 @@ type Provider struct {
}
func New(storage common.Storage, randSource rand.Source,
unzipper common.Unzipper, updaterWarner common.Warner) *Provider {
unzipper common.Unzipper, updaterWarner common.Warner,
parallelResolver common.ParallelResolver) *Provider {
return &Provider{
storage: storage,
randSource: randSource,
NoPortForwarder: utils.NewNoPortForwarding(providers.Privatevpn),
Fetcher: updater.New(unzipper, updaterWarner),
Fetcher: updater.New(unzipper, updaterWarner, parallelResolver),
}
}

View File

@@ -6,7 +6,7 @@ import (
"github.com/qdm12/gluetun/internal/updater/resolver"
)
func newParallelResolver() (parallelResolver *resolver.Parallel) {
func parallelResolverSettings(hosts []string) (settings resolver.ParallelSettings) {
const (
maxFailRatio = 0.1
maxDuration = 6 * time.Second
@@ -14,7 +14,8 @@ func newParallelResolver() (parallelResolver *resolver.Parallel) {
maxNoNew = 2
maxFails = 2
)
settings := resolver.ParallelSettings{
return resolver.ParallelSettings{
Hosts: hosts,
MaxFailRatio: maxFailRatio,
Repeat: resolver.RepeatSettings{
MaxDuration: maxDuration,
@@ -24,5 +25,4 @@ func newParallelResolver() (parallelResolver *resolver.Parallel) {
SortIPs: true,
},
}
return resolver.NewParallelResolver(settings)
}

View File

@@ -82,7 +82,8 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
hosts := hts.toHostsSlice()
hostToIPs, warnings, err := u.presolver.Resolve(ctx, hosts, minServers)
resolveSettings := parallelResolverSettings(hosts)
hostToIPs, warnings, err := u.presolver.Resolve(ctx, resolveSettings)
for _, warning := range warnings {
u.warner.Warn(warning)
}
@@ -90,6 +91,11 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
return nil, err
}
if len(noHostnameServers)+len(hostToIPs) < minServers {
return nil, fmt.Errorf("%w: %d and expected at least %d",
common.ErrNotEnoughServers, len(servers), minServers)
}
hts.adaptWithIPs(hostToIPs)
servers = hts.toServersSlice()

View File

@@ -10,10 +10,11 @@ type Updater struct {
warner common.Warner
}
func New(unzipper common.Unzipper, warner common.Warner) *Updater {
func New(unzipper common.Unzipper, warner common.Warner,
parallelResolver common.ParallelResolver) *Updater {
return &Updater{
unzipper: unzipper,
presolver: newParallelResolver(),
presolver: parallelResolver,
warner: warner,
}
}

View File

@@ -18,7 +18,8 @@ type Provider struct {
}
func New(storage common.Storage, randSource rand.Source,
client *http.Client, updaterWarner common.Warner) *Provider {
client *http.Client, updaterWarner common.Warner,
parallelResolver common.ParallelResolver) *Provider {
return &Provider{
storage: storage,
randSource: randSource,

View File

@@ -44,33 +44,36 @@ type Storage interface {
}
func NewProviders(storage Storage, timeNow func() time.Time,
updaterWarner common.Warner, client *http.Client, unzipper common.Unzipper) *Providers {
updaterWarner common.Warner, client *http.Client, unzipper common.Unzipper,
parallelResolver common.ParallelResolver) *Providers {
randSource := rand.NewSource(timeNow().UnixNano())
targetLength := len(providers.AllWithCustom())
providerNameToProvider := make(map[string]Provider, targetLength)
providerNameToProvider[providers.Custom] = custom.New()
providerNameToProvider[providers.Cyberghost] = cyberghost.New(storage, randSource)
providerNameToProvider[providers.Expressvpn] = expressvpn.New(storage, randSource, unzipper, updaterWarner)
providerNameToProvider[providers.Fastestvpn] = fastestvpn.New(storage, randSource, unzipper, updaterWarner)
providerNameToProvider[providers.HideMyAss] = hidemyass.New(storage, randSource, client, updaterWarner)
providerNameToProvider[providers.Ipvanish] = ipvanish.New(storage, randSource, unzipper, updaterWarner)
providerNameToProvider[providers.Ivpn] = ivpn.New(storage, randSource, client, updaterWarner)
providerNameToProvider[providers.Mullvad] = mullvad.New(storage, randSource, client)
providerNameToProvider[providers.Nordvpn] = nordvpn.New(storage, randSource, client, updaterWarner)
providerNameToProvider[providers.Perfectprivacy] = perfectprivacy.New(storage, randSource, unzipper, updaterWarner)
providerNameToProvider[providers.Privado] = privado.New(storage, randSource, client, unzipper, updaterWarner)
providerNameToProvider[providers.PrivateInternetAccess] = privateinternetaccess.New(storage, randSource, timeNow, client) //nolint:lll
providerNameToProvider[providers.Privatevpn] = privatevpn.New(storage, randSource, unzipper, updaterWarner)
providerNameToProvider[providers.Protonvpn] = protonvpn.New(storage, randSource, client, updaterWarner)
providerNameToProvider[providers.Purevpn] = purevpn.New(storage, randSource, client, unzipper, updaterWarner)
providerNameToProvider[providers.Surfshark] = surfshark.New(storage, randSource, client, unzipper, updaterWarner)
providerNameToProvider[providers.Torguard] = torguard.New(storage, randSource, unzipper, updaterWarner)
providerNameToProvider[providers.VPNUnlimited] = vpnunlimited.New(storage, randSource, unzipper, updaterWarner)
providerNameToProvider[providers.Vyprvpn] = vyprvpn.New(storage, randSource, unzipper, updaterWarner)
providerNameToProvider[providers.Wevpn] = wevpn.New(storage, randSource, updaterWarner)
providerNameToProvider[providers.Windscribe] = windscribe.New(storage, randSource, client, updaterWarner)
//nolint:lll
providerNameToProvider := map[string]Provider{
providers.Custom: custom.New(),
providers.Cyberghost: cyberghost.New(storage, randSource, parallelResolver),
providers.Expressvpn: expressvpn.New(storage, randSource, unzipper, updaterWarner, parallelResolver),
providers.Fastestvpn: fastestvpn.New(storage, randSource, unzipper, updaterWarner, parallelResolver),
providers.HideMyAss: hidemyass.New(storage, randSource, client, updaterWarner, parallelResolver),
providers.Ipvanish: ipvanish.New(storage, randSource, unzipper, updaterWarner, parallelResolver),
providers.Ivpn: ivpn.New(storage, randSource, client, updaterWarner, parallelResolver),
providers.Mullvad: mullvad.New(storage, randSource, client),
providers.Nordvpn: nordvpn.New(storage, randSource, client, updaterWarner),
providers.Perfectprivacy: perfectprivacy.New(storage, randSource, unzipper, updaterWarner),
providers.Privado: privado.New(storage, randSource, client, unzipper, updaterWarner, parallelResolver),
providers.PrivateInternetAccess: privateinternetaccess.New(storage, randSource, timeNow, client),
providers.Privatevpn: privatevpn.New(storage, randSource, unzipper, updaterWarner, parallelResolver),
providers.Protonvpn: protonvpn.New(storage, randSource, client, updaterWarner, parallelResolver),
providers.Purevpn: purevpn.New(storage, randSource, client, unzipper, updaterWarner, parallelResolver),
providers.Surfshark: surfshark.New(storage, randSource, client, unzipper, updaterWarner, parallelResolver),
providers.Torguard: torguard.New(storage, randSource, unzipper, updaterWarner, parallelResolver),
providers.VPNUnlimited: vpnunlimited.New(storage, randSource, unzipper, updaterWarner, parallelResolver),
providers.Vyprvpn: vyprvpn.New(storage, randSource, unzipper, updaterWarner, parallelResolver),
providers.Wevpn: wevpn.New(storage, randSource, updaterWarner, parallelResolver),
providers.Windscribe: windscribe.New(storage, randSource, client, updaterWarner),
}
targetLength := len(providers.AllWithCustom())
if len(providerNameToProvider) != targetLength {
// Programming sanity check
panic(fmt.Sprintf("invalid number of providers, expected %d but got %d",

View File

@@ -18,12 +18,13 @@ type Provider struct {
}
func New(storage common.Storage, randSource rand.Source,
client *http.Client, unzipper common.Unzipper, updaterWarner common.Warner) *Provider {
client *http.Client, unzipper common.Unzipper, updaterWarner common.Warner,
parallelResolver common.ParallelResolver) *Provider {
return &Provider{
storage: storage,
randSource: randSource,
NoPortForwarder: utils.NewNoPortForwarding(providers.Purevpn),
Fetcher: updater.New(client, unzipper, updaterWarner),
Fetcher: updater.New(client, unzipper, updaterWarner, parallelResolver),
}
}

View File

@@ -6,7 +6,7 @@ import (
"github.com/qdm12/gluetun/internal/updater/resolver"
)
func newParallelResolver() (parallelResolver *resolver.Parallel) {
func parallelResolverSettings(hosts []string) (settings resolver.ParallelSettings) {
const (
maxFailRatio = 0.1
maxDuration = 20 * time.Second
@@ -14,7 +14,8 @@ func newParallelResolver() (parallelResolver *resolver.Parallel) {
maxNoNew = 2
maxFails = 2
)
settings := resolver.ParallelSettings{
return resolver.ParallelSettings{
Hosts: hosts,
MaxFailRatio: maxFailRatio,
Repeat: resolver.RepeatSettings{
MaxDuration: maxDuration,
@@ -24,5 +25,4 @@ func newParallelResolver() (parallelResolver *resolver.Parallel) {
SortIPs: true,
},
}
return resolver.NewParallelResolver(settings)
}

View File

@@ -60,7 +60,8 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
}
hosts := hts.toHostsSlice()
hostToIPs, warnings, err := u.presolver.Resolve(ctx, hosts, minServers)
resolveSettings := parallelResolverSettings(hosts)
hostToIPs, warnings, err := u.presolver.Resolve(ctx, resolveSettings)
for _, warning := range warnings {
u.warner.Warn(warning)
}
@@ -68,15 +69,15 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
return nil, err
}
hts.adaptWithIPs(hostToIPs)
servers = hts.toServersSlice()
if len(servers) < minServers {
if len(hostToIPs) < minServers {
return nil, fmt.Errorf("%w: %d and expected at least %d",
common.ErrNotEnoughServers, len(servers), minServers)
}
hts.adaptWithIPs(hostToIPs)
servers = hts.toServersSlice()
// Get public IP address information
ipsToGetInfo := make([]net.IP, len(servers))
for i := range servers {

View File

@@ -14,11 +14,11 @@ type Updater struct {
}
func New(client *http.Client, unzipper common.Unzipper,
warner common.Warner) *Updater {
warner common.Warner, parallelResolver common.ParallelResolver) *Updater {
return &Updater{
client: client,
unzipper: unzipper,
presolver: newParallelResolver(),
presolver: parallelResolver,
warner: warner,
}
}

View File

@@ -18,12 +18,13 @@ type Provider struct {
}
func New(storage common.Storage, randSource rand.Source,
client *http.Client, unzipper common.Unzipper, updaterWarner common.Warner) *Provider {
client *http.Client, unzipper common.Unzipper, updaterWarner common.Warner,
parallelResolver common.ParallelResolver) *Provider {
return &Provider{
storage: storage,
randSource: randSource,
NoPortForwarder: utils.NewNoPortForwarding(providers.Surfshark),
Fetcher: updater.New(client, unzipper, updaterWarner),
Fetcher: updater.New(client, unzipper, updaterWarner, parallelResolver),
}
}

View File

@@ -6,7 +6,7 @@ import (
"github.com/qdm12/gluetun/internal/updater/resolver"
)
func newParallelResolver() (parallelResolver *resolver.Parallel) {
func parallelResolverSettings(hosts []string) (settings resolver.ParallelSettings) {
const (
maxFailRatio = 0.1
maxDuration = 20 * time.Second
@@ -14,7 +14,8 @@ func newParallelResolver() (parallelResolver *resolver.Parallel) {
maxNoNew = 2
maxFails = 2
)
settings := resolver.ParallelSettings{
return resolver.ParallelSettings{
Hosts: hosts,
MaxFailRatio: maxFailRatio,
Repeat: resolver.RepeatSettings{
MaxDuration: maxDuration,
@@ -24,5 +25,4 @@ func newParallelResolver() (parallelResolver *resolver.Parallel) {
SortIPs: true,
},
}
return resolver.NewParallelResolver(settings)
}

View File

@@ -31,7 +31,8 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
getRemainingServers(hts)
hosts := hts.toHostsSlice()
hostToIPs, warnings, err := u.presolver.Resolve(ctx, hosts, minServers)
resolveSettings := parallelResolverSettings(hosts)
hostToIPs, warnings, err := u.presolver.Resolve(ctx, resolveSettings)
for _, warning := range warnings {
u.warner.Warn(warning)
}
@@ -39,15 +40,15 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
return nil, err
}
hts.adaptWithIPs(hostToIPs)
servers = hts.toServersSlice()
if len(servers) < minServers {
if len(hostToIPs) < minServers {
return nil, fmt.Errorf("%w: %d and expected at least %d",
common.ErrNotEnoughServers, len(servers), minServers)
}
hts.adaptWithIPs(hostToIPs)
servers = hts.toServersSlice()
sort.Sort(models.SortableServers(servers))
return servers, nil

View File

@@ -14,11 +14,11 @@ type Updater struct {
}
func New(client *http.Client, unzipper common.Unzipper,
warner common.Warner) *Updater {
warner common.Warner, parallelResolver common.ParallelResolver) *Updater {
return &Updater{
client: client,
unzipper: unzipper,
presolver: newParallelResolver(),
presolver: parallelResolver,
warner: warner,
}
}

View File

@@ -17,12 +17,13 @@ type Provider struct {
}
func New(storage common.Storage, randSource rand.Source,
unzipper common.Unzipper, updaterWarner common.Warner) *Provider {
unzipper common.Unzipper, updaterWarner common.Warner,
parallelResolver common.ParallelResolver) *Provider {
return &Provider{
storage: storage,
randSource: randSource,
NoPortForwarder: utils.NewNoPortForwarding(providers.Torguard),
Fetcher: updater.New(unzipper, updaterWarner),
Fetcher: updater.New(unzipper, updaterWarner, parallelResolver),
}
}

View File

@@ -6,7 +6,7 @@ import (
"github.com/qdm12/gluetun/internal/updater/resolver"
)
func newParallelResolver() (parallelResolver *resolver.Parallel) {
func parallelResolverSettings(hosts []string) (settings resolver.ParallelSettings) {
const (
maxFailRatio = 0.1
maxDuration = 20 * time.Second
@@ -14,7 +14,8 @@ func newParallelResolver() (parallelResolver *resolver.Parallel) {
maxNoNew = 2
maxFails = 2
)
settings := resolver.ParallelSettings{
return resolver.ParallelSettings{
Hosts: hosts,
MaxFailRatio: maxFailRatio,
Repeat: resolver.RepeatSettings{
MaxDuration: maxDuration,
@@ -24,5 +25,4 @@ func newParallelResolver() (parallelResolver *resolver.Parallel) {
SortIPs: true,
},
}
return resolver.NewParallelResolver(settings)
}

View File

@@ -50,12 +50,18 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
}
hosts := hts.toHostsSlice()
hostToIPs, warnings, err := u.presolver.Resolve(ctx, hosts, minServers)
resolveSettings := parallelResolverSettings(hosts)
hostToIPs, warnings, err := u.presolver.Resolve(ctx, resolveSettings)
u.warnWarnings(warnings)
if err != nil {
return nil, err
}
if len(hostToIPs) < minServers {
return nil, fmt.Errorf("%w: %d and expected at least %d",
common.ErrNotEnoughServers, len(servers), minServers)
}
hts.adaptWithIPs(hostToIPs)
servers = hts.toServersSlice()

View File

@@ -10,10 +10,11 @@ type Updater struct {
warner common.Warner
}
func New(unzipper common.Unzipper, warner common.Warner) *Updater {
func New(unzipper common.Unzipper, warner common.Warner,
parallelResolver common.ParallelResolver) *Updater {
return &Updater{
unzipper: unzipper,
presolver: newParallelResolver(),
presolver: parallelResolver,
warner: warner,
}
}

View File

@@ -17,12 +17,13 @@ type Provider struct {
}
func New(storage common.Storage, randSource rand.Source,
unzipper common.Unzipper, updaterWarner common.Warner) *Provider {
unzipper common.Unzipper, updaterWarner common.Warner,
parallelResolver common.ParallelResolver) *Provider {
return &Provider{
storage: storage,
randSource: randSource,
NoPortForwarder: utils.NewNoPortForwarding(providers.VPNUnlimited),
Fetcher: updater.New(unzipper, updaterWarner),
Fetcher: updater.New(unzipper, updaterWarner, parallelResolver),
}
}

View File

@@ -6,7 +6,7 @@ import (
"github.com/qdm12/gluetun/internal/updater/resolver"
)
func newParallelResolver() (parallelResolver *resolver.Parallel) {
func parallelResolverSettings(hosts []string) (settings resolver.ParallelSettings) {
const (
maxFailRatio = 0.1
maxDuration = 20 * time.Second
@@ -14,7 +14,8 @@ func newParallelResolver() (parallelResolver *resolver.Parallel) {
maxNoNew = 2
maxFails = 2
)
settings := resolver.ParallelSettings{
return resolver.ParallelSettings{
Hosts: hosts,
MaxFailRatio: maxFailRatio,
Repeat: resolver.RepeatSettings{
MaxDuration: maxDuration,
@@ -24,5 +25,4 @@ func newParallelResolver() (parallelResolver *resolver.Parallel) {
SortIPs: true,
},
}
return resolver.NewParallelResolver(settings)
}

View File

@@ -20,7 +20,8 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
}
hosts := hts.toHostsSlice()
hostToIPs, warnings, err := u.presolver.Resolve(ctx, hosts, minServers)
resolveSettings := parallelResolverSettings(hosts)
hostToIPs, warnings, err := u.presolver.Resolve(ctx, resolveSettings)
for _, warning := range warnings {
u.warner.Warn(warning)
}
@@ -28,15 +29,15 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
return nil, err
}
hts.adaptWithIPs(hostToIPs)
servers = hts.toServersSlice()
if len(servers) < minServers {
if len(hostToIPs) < minServers {
return nil, fmt.Errorf("%w: %d and expected at least %d",
common.ErrNotEnoughServers, len(servers), minServers)
}
hts.adaptWithIPs(hostToIPs)
servers = hts.toServersSlice()
sort.Sort(models.SortableServers(servers))
return servers, nil

View File

@@ -10,10 +10,11 @@ type Updater struct {
warner common.Warner
}
func New(unzipper common.Unzipper, warner common.Warner) *Updater {
func New(unzipper common.Unzipper, warner common.Warner,
parallelResolver common.ParallelResolver) *Updater {
return &Updater{
unzipper: unzipper,
presolver: newParallelResolver(),
presolver: parallelResolver,
warner: warner,
}
}

View File

@@ -17,12 +17,13 @@ type Provider struct {
}
func New(storage common.Storage, randSource rand.Source,
unzipper common.Unzipper, updaterWarner common.Warner) *Provider {
unzipper common.Unzipper, updaterWarner common.Warner,
parallelResolver common.ParallelResolver) *Provider {
return &Provider{
storage: storage,
randSource: randSource,
NoPortForwarder: utils.NewNoPortForwarding(providers.Vyprvpn),
Fetcher: updater.New(unzipper, updaterWarner),
Fetcher: updater.New(unzipper, updaterWarner, parallelResolver),
}
}

View File

@@ -6,7 +6,7 @@ import (
"github.com/qdm12/gluetun/internal/updater/resolver"
)
func newParallelResolver() (parallelResolver *resolver.Parallel) {
func parallelResolverSettings(hosts []string) (settings resolver.ParallelSettings) {
const (
maxFailRatio = 0.1
maxDuration = 5 * time.Second
@@ -14,7 +14,8 @@ func newParallelResolver() (parallelResolver *resolver.Parallel) {
maxNoNew = 2
maxFails = 2
)
settings := resolver.ParallelSettings{
return resolver.ParallelSettings{
Hosts: hosts,
MaxFailRatio: maxFailRatio,
Repeat: resolver.RepeatSettings{
MaxDuration: maxDuration,
@@ -24,5 +25,4 @@ func newParallelResolver() (parallelResolver *resolver.Parallel) {
SortIPs: true,
},
}
return resolver.NewParallelResolver(settings)
}

View File

@@ -64,7 +64,8 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
}
hosts := hts.toHostsSlice()
hostToIPs, warnings, err := u.presolver.Resolve(ctx, hosts, minServers)
resolveSettings := parallelResolverSettings(hosts)
hostToIPs, warnings, err := u.presolver.Resolve(ctx, resolveSettings)
for _, warning := range warnings {
u.warner.Warn(warning)
}
@@ -72,15 +73,15 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
return nil, err
}
hts.adaptWithIPs(hostToIPs)
servers = hts.toServersSlice()
if len(servers) < minServers {
if len(hostToIPs) < minServers {
return nil, fmt.Errorf("%w: %d and expected at least %d",
common.ErrNotEnoughServers, len(servers), minServers)
}
hts.adaptWithIPs(hostToIPs)
servers = hts.toServersSlice()
sort.Sort(models.SortableServers(servers))
return servers, nil

View File

@@ -10,10 +10,11 @@ type Updater struct {
warner common.Warner
}
func New(unzipper common.Unzipper, warner common.Warner) *Updater {
func New(unzipper common.Unzipper, warner common.Warner,
parallelResolver common.ParallelResolver) *Updater {
return &Updater{
unzipper: unzipper,
presolver: newParallelResolver(),
presolver: parallelResolver,
warner: warner,
}
}

View File

@@ -93,7 +93,8 @@ func Test_Provider_GetConnection(t *testing.T) {
randSource := rand.NewSource(0)
warner := (common.Warner)(nil)
provider := New(storage, randSource, warner)
parallelResolver := (common.ParallelResolver)(nil)
provider := New(storage, randSource, warner, parallelResolver)
if testCase.panicMessage != "" {
assert.PanicsWithValue(t, testCase.panicMessage, func() {

View File

@@ -17,12 +17,13 @@ type Provider struct {
}
func New(storage common.Storage, randSource rand.Source,
updaterWarner common.Warner) *Provider {
updaterWarner common.Warner,
parallelResolver common.ParallelResolver) *Provider {
return &Provider{
storage: storage,
randSource: randSource,
NoPortForwarder: utils.NewNoPortForwarding(providers.Wevpn),
Fetcher: updater.New(updaterWarner),
Fetcher: updater.New(updaterWarner, parallelResolver),
}
}

View File

@@ -6,7 +6,7 @@ import (
"github.com/qdm12/gluetun/internal/updater/resolver"
)
func newParallelResolver() (parallelResolver *resolver.Parallel) {
func parallelResolverSettings(hosts []string) (settings resolver.ParallelSettings) {
const (
maxFailRatio = 0.1
maxDuration = 20 * time.Second
@@ -14,7 +14,8 @@ func newParallelResolver() (parallelResolver *resolver.Parallel) {
maxNoNew = 2
maxFails = 2
)
settings := resolver.ParallelSettings{
return resolver.ParallelSettings{
Hosts: hosts,
MaxFailRatio: maxFailRatio,
Repeat: resolver.RepeatSettings{
MaxDuration: maxDuration,
@@ -24,5 +25,4 @@ func newParallelResolver() (parallelResolver *resolver.Parallel) {
SortIPs: true,
},
}
return resolver.NewParallelResolver(settings)
}

View File

@@ -31,7 +31,8 @@ func (u *Updater) FetchServers(ctx context.Context, minServers int) (
hostnameToCity[hostname] = city
}
hostnameToIPs, warnings, err := u.presolver.Resolve(ctx, hostnames, minServers)
resolverSettings := parallelResolverSettings(hostnames)
hostnameToIPs, warnings, err := u.presolver.Resolve(ctx, resolverSettings)
for _, warning := range warnings {
u.warner.Warn(warning)
}

View File

@@ -7,9 +7,9 @@ type Updater struct {
warner common.Warner
}
func New(warner common.Warner) *Updater {
func New(warner common.Warner, parallelResolver common.ParallelResolver) *Updater {
return &Updater{
presolver: newParallelResolver(),
presolver: parallelResolver,
warner: warner,
}
}