feat(ipv6): use ipv6 endpoint IPs if supported

This commit is contained in:
Quentin McGaw
2022-09-12 21:31:37 +00:00
parent dd7630997b
commit 7fdc7de210
35 changed files with 92 additions and 62 deletions

View File

@@ -71,7 +71,8 @@ func (c *CLI) OpenvpnConfig(logger OpenvpnConfigLogger, source Source,
providers := provider.NewProviders(storage, time.Now, warner, client,
unzipper, parallelResolver, ipFetcher, openvpnFileExtractor)
providerConf := providers.Get(*allSettings.VPN.Provider.Name)
connection, err := providerConf.GetConnection(allSettings.VPN.Provider.ServerSelection)
connection, err := providerConf.GetConnection(
allSettings.VPN.Provider.ServerSelection, ipv6Supported)
if err != nil {
return err
}

View File

@@ -15,7 +15,7 @@ var (
)
// GetConnection gets the connection from the OpenVPN configuration file.
func (p *Provider) GetConnection(selection settings.ServerSelection) (
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
connection models.Connection, err error) {
switch selection.VPN {
case vpn.OpenVPN:

View File

@@ -6,9 +6,9 @@ import (
"github.com/qdm12/gluetun/internal/provider/utils"
)
func (p *Provider) GetConnection(selection settings.ServerSelection) (
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
connection models.Connection, err error) {
defaults := utils.NewConnectionDefaults(443, 443, 0) //nolint:gomnd
return utils.GetConnection(p.Name(),
p.storage, selection, defaults, p.randSource)
p.storage, selection, defaults, ipv6Supported, p.randSource)
}

View File

@@ -6,11 +6,11 @@ import (
"github.com/qdm12/gluetun/internal/provider/utils"
)
func (p *Provider) GetConnection(selection settings.ServerSelection) (
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
connection models.Connection, err error) {
// TODO: Set the default ports for each VPN protocol+network protocol
// combination. If one combination is not supported, set it to `0`.
defaults := utils.NewConnectionDefaults(443, 1194, 51820) //nolint:gomnd
return utils.GetConnection(p.Name(),
p.storage, selection, defaults, p.randSource)
p.storage, selection, defaults, ipv6Supported, p.randSource)
}

View File

@@ -6,9 +6,9 @@ import (
"github.com/qdm12/gluetun/internal/provider/utils"
)
func (p *Provider) GetConnection(selection settings.ServerSelection) (
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
connection models.Connection, err error) {
defaults := utils.NewConnectionDefaults(0, 1195, 0) //nolint:gomnd
return utils.GetConnection(p.Name(),
p.storage, selection, defaults, p.randSource)
p.storage, selection, defaults, ipv6Supported, p.randSource)
}

View File

@@ -28,6 +28,7 @@ func Test_Provider_GetConnection(t *testing.T) {
filteredServers []models.Server
storageErr error
selection settings.ServerSelection
ipv6Supported bool
connection models.Connection
errWrapped error
errMessage string
@@ -94,12 +95,12 @@ func Test_Provider_GetConnection(t *testing.T) {
if testCase.panicMessage != "" {
assert.PanicsWithValue(t, testCase.panicMessage, func() {
_, _ = provider.GetConnection(testCase.selection)
_, _ = provider.GetConnection(testCase.selection, testCase.ipv6Supported)
})
return
}
connection, err := provider.GetConnection(testCase.selection)
connection, err := provider.GetConnection(testCase.selection, testCase.ipv6Supported)
assert.ErrorIs(t, err, testCase.errWrapped)
if testCase.errWrapped != nil {

View File

@@ -6,9 +6,9 @@ import (
"github.com/qdm12/gluetun/internal/provider/utils"
)
func (p *Provider) GetConnection(selection settings.ServerSelection) (
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
connection models.Connection, err error) {
defaults := utils.NewConnectionDefaults(4443, 4443, 0) //nolint:gomnd
return utils.GetConnection(p.Name(),
p.storage, selection, defaults, p.randSource)
p.storage, selection, defaults, ipv6Supported, p.randSource)
}

View File

@@ -6,9 +6,9 @@ import (
"github.com/qdm12/gluetun/internal/provider/utils"
)
func (p *Provider) GetConnection(selection settings.ServerSelection) (
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
connection models.Connection, err error) {
defaults := utils.NewConnectionDefaults(8080, 553, 0) //nolint:gomnd
return utils.GetConnection(p.Name(),
p.storage, selection, defaults, p.randSource)
p.storage, selection, defaults, ipv6Supported, p.randSource)
}

View File

@@ -6,9 +6,9 @@ import (
"github.com/qdm12/gluetun/internal/provider/utils"
)
func (p *Provider) GetConnection(selection settings.ServerSelection) (
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
connection models.Connection, err error) {
defaults := utils.NewConnectionDefaults(0, 443, 0) //nolint:gomnd
return utils.GetConnection(p.Name(),
p.storage, selection, defaults, p.randSource)
p.storage, selection, defaults, ipv6Supported, p.randSource)
}

View File

@@ -6,9 +6,9 @@ import (
"github.com/qdm12/gluetun/internal/provider/utils"
)
func (p *Provider) GetConnection(selection settings.ServerSelection) (
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
connection models.Connection, err error) {
defaults := utils.NewConnectionDefaults(443, 1194, 58237) //nolint:gomnd
return utils.GetConnection(p.Name(),
p.storage, selection, defaults, p.randSource)
p.storage, selection, defaults, ipv6Supported, p.randSource)
}

View File

@@ -29,6 +29,7 @@ func Test_Provider_GetConnection(t *testing.T) {
filteredServers []models.Server
storageErr error
selection settings.ServerSelection
ipv6Supported bool
connection models.Connection
errWrapped error
errMessage string
@@ -103,7 +104,7 @@ func Test_Provider_GetConnection(t *testing.T) {
parallelResolver := (common.ParallelResolver)(nil)
provider := New(storage, randSource, client, warner, parallelResolver)
connection, err := provider.GetConnection(testCase.selection)
connection, err := provider.GetConnection(testCase.selection, testCase.ipv6Supported)
assert.ErrorIs(t, err, testCase.errWrapped)
if testCase.errWrapped != nil {

View File

@@ -6,9 +6,9 @@ import (
"github.com/qdm12/gluetun/internal/provider/utils"
)
func (p *Provider) GetConnection(selection settings.ServerSelection) (
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
connection models.Connection, err error) {
defaults := utils.NewConnectionDefaults(443, 1194, 51820) //nolint:gomnd
return utils.GetConnection(p.Name(),
p.storage, selection, defaults, p.randSource)
p.storage, selection, defaults, ipv6Supported, p.randSource)
}

View File

@@ -29,6 +29,7 @@ func Test_Provider_GetConnection(t *testing.T) {
filteredServers []models.Server
storageErr error
selection settings.ServerSelection
ipv6Supported bool
connection models.Connection
errWrapped error
errMessage string
@@ -101,7 +102,7 @@ func Test_Provider_GetConnection(t *testing.T) {
client := (*http.Client)(nil)
provider := New(storage, randSource, client)
connection, err := provider.GetConnection(testCase.selection)
connection, err := provider.GetConnection(testCase.selection, testCase.ipv6Supported)
assert.ErrorIs(t, err, testCase.errWrapped)
if testCase.errWrapped != nil {

View File

@@ -6,9 +6,9 @@ import (
"github.com/qdm12/gluetun/internal/provider/utils"
)
func (p *Provider) GetConnection(selection settings.ServerSelection) (
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
connection models.Connection, err error) {
defaults := utils.NewConnectionDefaults(443, 1194, 0) //nolint:gomnd
return utils.GetConnection(p.Name(),
p.storage, selection, defaults, p.randSource)
p.storage, selection, defaults, ipv6Supported, p.randSource)
}

View File

@@ -6,9 +6,9 @@ import (
"github.com/qdm12/gluetun/internal/provider/utils"
)
func (p *Provider) GetConnection(selection settings.ServerSelection) (
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
connection models.Connection, err error) {
defaults := utils.NewConnectionDefaults(443, 443, 0) //nolint:gomnd
return utils.GetConnection(p.Name(),
p.storage, selection, defaults, p.randSource)
p.storage, selection, defaults, ipv6Supported, p.randSource)
}

View File

@@ -6,9 +6,9 @@ import (
"github.com/qdm12/gluetun/internal/provider/utils"
)
func (p *Provider) GetConnection(selection settings.ServerSelection) (
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
connection models.Connection, err error) {
defaults := utils.NewConnectionDefaults(0, 1194, 0) //nolint:gomnd
return utils.GetConnection(p.Name(),
p.storage, selection, defaults, p.randSource)
p.storage, selection, defaults, ipv6Supported, p.randSource)
}

View File

@@ -7,7 +7,7 @@ import (
"github.com/qdm12/gluetun/internal/provider/utils"
)
func (p *Provider) GetConnection(selection settings.ServerSelection) (
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
connection models.Connection, err error) {
// Set port defaults depending on encryption preset.
var defaults utils.ConnectionDefaults
@@ -21,5 +21,5 @@ func (p *Provider) GetConnection(selection settings.ServerSelection) (
}
return utils.GetConnection(p.Name(),
p.storage, selection, defaults, p.randSource)
p.storage, selection, defaults, ipv6Supported, p.randSource)
}

View File

@@ -6,9 +6,9 @@ import (
"github.com/qdm12/gluetun/internal/provider/utils"
)
func (p *Provider) GetConnection(selection settings.ServerSelection) (
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
connection models.Connection, err error) {
defaults := utils.NewConnectionDefaults(443, 1194, 0) //nolint:gomnd
return utils.GetConnection(p.Name(),
p.storage, selection, defaults, p.randSource)
p.storage, selection, defaults, ipv6Supported, p.randSource)
}

View File

@@ -6,9 +6,9 @@ import (
"github.com/qdm12/gluetun/internal/provider/utils"
)
func (p *Provider) GetConnection(selection settings.ServerSelection) (
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
connection models.Connection, err error) {
defaults := utils.NewConnectionDefaults(443, 1194, 0) //nolint:gomnd
return utils.GetConnection(p.Name(),
p.storage, selection, defaults, p.randSource)
p.storage, selection, defaults, ipv6Supported, p.randSource)
}

View File

@@ -12,7 +12,7 @@ import (
// Provider contains methods to read and modify the openvpn configuration to connect as a client.
type Provider interface {
GetConnection(selection settings.ServerSelection) (connection models.Connection, err error)
GetConnection(selection settings.ServerSelection, ipv6Supported bool) (connection models.Connection, err error)
OpenVPNConfig(connection models.Connection, settings settings.OpenVPN, ipv6Supported bool) (lines []string)
Name() string
PortForwarder

View File

@@ -6,9 +6,9 @@ import (
"github.com/qdm12/gluetun/internal/provider/utils"
)
func (p *Provider) GetConnection(selection settings.ServerSelection) (
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
connection models.Connection, err error) {
defaults := utils.NewConnectionDefaults(80, 53, 0) //nolint:gomnd
return utils.GetConnection(p.Name(),
p.storage, selection, defaults, p.randSource)
p.storage, selection, defaults, ipv6Supported, p.randSource)
}

View File

@@ -6,8 +6,8 @@ import (
"github.com/qdm12/gluetun/internal/provider/utils"
)
func (p *Provider) GetConnection(selection settings.ServerSelection) (
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
connection models.Connection, err error) {
defaults := utils.NewConnectionDefaults(0, 443, 0) //nolint:gomnd
return utils.GetConnection(p.Name(), p.storage, selection, defaults, p.randSource)
return utils.GetConnection(p.Name(), p.storage, selection, defaults, ipv6Supported, p.randSource)
}

View File

@@ -6,9 +6,9 @@ import (
"github.com/qdm12/gluetun/internal/provider/utils"
)
func (p *Provider) GetConnection(selection settings.ServerSelection) (
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
connection models.Connection, err error) {
defaults := utils.NewConnectionDefaults(1443, 1194, 51820) //nolint:gomnd
return utils.GetConnection(p.Name(),
p.storage, selection, defaults, p.randSource)
p.storage, selection, defaults, ipv6Supported, p.randSource)
}

View File

@@ -6,9 +6,9 @@ import (
"github.com/qdm12/gluetun/internal/provider/utils"
)
func (p *Provider) GetConnection(selection settings.ServerSelection) (
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
connection models.Connection, err error) {
defaults := utils.NewConnectionDefaults(1912, 1912, 0) //nolint:gomnd
return utils.GetConnection(p.Name(),
p.storage, selection, defaults, p.randSource)
p.storage, selection, defaults, ipv6Supported, p.randSource)
}

View File

@@ -33,6 +33,7 @@ func GetConnection(provider string,
storage Storage,
selection settings.ServerSelection,
defaults ConnectionDefaults,
ipv6Supported bool,
randSource rand.Source) (
connection models.Connection, err error) {
servers, err := storage.FilterServers(provider, selection)
@@ -47,8 +48,7 @@ func GetConnection(provider string,
connections := make([]models.Connection, 0, len(servers))
for _, server := range servers {
for _, ip := range server.IPs {
if ip.To4() == nil {
// do not use IPv6 connections for now
if !ipv6Supported && ip.To4() == nil {
continue
}

View File

@@ -27,6 +27,7 @@ func Test_GetConnection(t *testing.T) {
filterError error
serverSelection settings.ServerSelection
defaults ConnectionDefaults
ipv6Supported bool
randSource rand.Source
connection models.Connection
errWrapped error
@@ -122,6 +123,29 @@ func Test_GetConnection(t *testing.T) {
Port: 1194,
},
},
"server with IPv4 and IPv6 and ipv6 supported": {
filteredServers: []models.Server{
{
VPN: vpn.OpenVPN,
UDP: true,
IPs: []net.IP{
net.IPv6zero,
net.IPv4(1, 1, 1, 1),
},
},
},
serverSelection: settings.ServerSelection{}.
WithDefaults(providers.Mullvad),
defaults: NewConnectionDefaults(443, 1194, 58820),
ipv6Supported: true,
randSource: rand.NewSource(0),
connection: models.Connection{
Type: vpn.OpenVPN,
IP: net.IPv6zero,
Protocol: constants.UDP,
Port: 1194,
},
},
"mixed servers": {
filteredServers: []models.Server{
{
@@ -172,7 +196,7 @@ func Test_GetConnection(t *testing.T) {
Return(testCase.filteredServers, testCase.filterError)
connection, err := GetConnection(testCase.provider, storage,
testCase.serverSelection, testCase.defaults,
testCase.serverSelection, testCase.defaults, testCase.ipv6Supported,
testCase.randSource)
assert.Equal(t, testCase.connection, connection)

View File

@@ -6,9 +6,9 @@ import (
"github.com/qdm12/gluetun/internal/provider/utils"
)
func (p *Provider) GetConnection(selection settings.ServerSelection) (
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
connection models.Connection, err error) {
defaults := utils.NewConnectionDefaults(110, 1282, 0) //nolint:gomnd
return utils.GetConnection(p.Name(),
p.storage, selection, defaults, p.randSource)
p.storage, selection, defaults, ipv6Supported, p.randSource)
}

View File

@@ -6,9 +6,9 @@ import (
"github.com/qdm12/gluetun/internal/provider/utils"
)
func (p *Provider) GetConnection(selection settings.ServerSelection) (
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
connection models.Connection, err error) {
defaults := utils.NewConnectionDefaults(0, 1194, 0) //nolint:gomnd
return utils.GetConnection(p.Name(),
p.storage, selection, defaults, p.randSource)
p.storage, selection, defaults, ipv6Supported, p.randSource)
}

View File

@@ -6,9 +6,9 @@ import (
"github.com/qdm12/gluetun/internal/provider/utils"
)
func (p *Provider) GetConnection(selection settings.ServerSelection) (
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
connection models.Connection, err error) {
defaults := utils.NewConnectionDefaults(0, 443, 0) //nolint:gomnd
return utils.GetConnection(p.Name(),
p.storage, selection, defaults, p.randSource)
p.storage, selection, defaults, ipv6Supported, p.randSource)
}

View File

@@ -6,9 +6,9 @@ import (
"github.com/qdm12/gluetun/internal/provider/utils"
)
func (p *Provider) GetConnection(selection settings.ServerSelection) (
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
connection models.Connection, err error) {
defaults := utils.NewConnectionDefaults(1195, 1194, 0) //nolint:gomnd
return utils.GetConnection(p.Name(),
p.storage, selection, defaults, p.randSource)
p.storage, selection, defaults, ipv6Supported, p.randSource)
}

View File

@@ -28,6 +28,7 @@ func Test_Provider_GetConnection(t *testing.T) {
filteredServers []models.Server
storageErr error
selection settings.ServerSelection
ipv6Supported bool
connection models.Connection
errWrapped error
errMessage string
@@ -98,12 +99,12 @@ func Test_Provider_GetConnection(t *testing.T) {
if testCase.panicMessage != "" {
assert.PanicsWithValue(t, testCase.panicMessage, func() {
_, _ = provider.GetConnection(testCase.selection)
_, _ = provider.GetConnection(testCase.selection, testCase.ipv6Supported)
})
return
}
connection, err := provider.GetConnection(testCase.selection)
connection, err := provider.GetConnection(testCase.selection, testCase.ipv6Supported)
assert.ErrorIs(t, err, testCase.errWrapped)
if testCase.errWrapped != nil {

View File

@@ -6,9 +6,9 @@ import (
"github.com/qdm12/gluetun/internal/provider/utils"
)
func (p *Provider) GetConnection(selection settings.ServerSelection) (
func (p *Provider) GetConnection(selection settings.ServerSelection, ipv6Supported bool) (
connection models.Connection, err error) {
defaults := utils.NewConnectionDefaults(443, 1194, 1194) //nolint:gomnd
return utils.GetConnection(p.Name(),
p.storage, selection, defaults, p.randSource)
p.storage, selection, defaults, ipv6Supported, p.randSource)
}

View File

@@ -29,6 +29,7 @@ func Test_Provider_GetConnection(t *testing.T) {
filteredServers []models.Server
storageErr error
selection settings.ServerSelection
ipv6Supported bool
connection models.Connection
errWrapped error
errMessage string
@@ -105,12 +106,12 @@ func Test_Provider_GetConnection(t *testing.T) {
if testCase.panicMessage != "" {
assert.PanicsWithValue(t, testCase.panicMessage, func() {
_, _ = provider.GetConnection(testCase.selection)
_, _ = provider.GetConnection(testCase.selection, testCase.ipv6Supported)
})
return
}
connection, err := provider.GetConnection(testCase.selection)
connection, err := provider.GetConnection(testCase.selection, testCase.ipv6Supported)
assert.ErrorIs(t, err, testCase.errWrapped)
if testCase.errWrapped != nil {

View File

@@ -16,7 +16,7 @@ func setupOpenVPN(ctx context.Context, fw Firewall,
openvpnConf OpenVPN, providerConf provider.Provider,
settings settings.VPN, ipv6Supported bool, starter command.Starter,
logger openvpn.Logger) (runner *openvpn.Runner, serverName string, err error) {
connection, err := providerConf.GetConnection(settings.Provider.ServerSelection)
connection, err := providerConf.GetConnection(settings.Provider.ServerSelection, ipv6Supported)
if err != nil {
return nil, "", fmt.Errorf("failed finding a valid server connection: %w", err)
}

View File

@@ -16,7 +16,7 @@ func setupWireguard(ctx context.Context, netlinker NetLinker,
fw Firewall, providerConf provider.Provider,
settings settings.VPN, ipv6Supported bool, logger wireguard.Logger) (
wireguarder *wireguard.Wireguard, serverName string, err error) {
connection, err := providerConf.GetConnection(settings.Provider.ServerSelection)
connection, err := providerConf.GetConnection(settings.Provider.ServerSelection, ipv6Supported)
if err != nil {
return nil, "", fmt.Errorf("failed finding a VPN server: %w", err)
}