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

@@ -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,
}
}