Feat: IVPN supports TCP and custom port

This commit is contained in:
Quentin McGaw (desktop)
2021-08-23 13:34:00 +00:00
parent c348343b22
commit f41fec57ed
8 changed files with 454 additions and 86 deletions

View File

@@ -4,6 +4,7 @@ import (
"fmt"
"github.com/qdm12/gluetun/internal/constants"
"github.com/qdm12/golibs/params"
)
func (settings *Provider) readIvpn(r reader) (err error) {
@@ -34,5 +35,20 @@ func (settings *Provider) readIvpn(r reader) (err error) {
return fmt.Errorf("environment variable SERVER_HOSTNAME: %w", err)
}
return settings.ServerSelection.OpenVPN.readProtocolOnly(r.env)
return settings.ServerSelection.OpenVPN.readIVPN(r.env)
}
func (settings *OpenVPNSelection) readIVPN(env params.Interface) (err error) {
settings.TCP, err = readProtocol(env)
if err != nil {
return err
}
settings.CustomPort, err = readOpenVPNCustomPort(env, settings.TCP,
[]uint16{80, 443, 1443}, []uint16{53, 1194, 2049, 2050})
if err != nil {
return err
}
return nil
}

View File

@@ -23,6 +23,12 @@ func Test_Provider_readIvpn(t *testing.T) {
err error
}
type singleUint16Call struct {
call bool
value uint16
err error
}
type sliceStringCall struct {
call bool
values []string
@@ -30,12 +36,14 @@ func Test_Provider_readIvpn(t *testing.T) {
}
testCases := map[string]struct {
protocol singleStringCall
targetIP singleStringCall
countries sliceStringCall
cities sliceStringCall
isps sliceStringCall
hostnames sliceStringCall
protocol singleStringCall
portGet singleStringCall
portPort singleUint16Call
settings Provider
err error
}{
@@ -96,6 +104,19 @@ func Test_Provider_readIvpn(t *testing.T) {
},
err: errors.New("environment variable PROTOCOL: dummy test error"),
},
"custom port error": {
targetIP: singleStringCall{call: true},
countries: sliceStringCall{call: true},
cities: sliceStringCall{call: true},
isps: sliceStringCall{call: true},
hostnames: sliceStringCall{call: true},
protocol: singleStringCall{call: true},
portGet: singleStringCall{call: true, err: errDummy},
settings: Provider{
Name: constants.Ivpn,
},
err: errors.New("environment variable PORT: dummy test error"),
},
"default settings": {
targetIP: singleStringCall{call: true},
countries: sliceStringCall{call: true},
@@ -103,6 +124,7 @@ func Test_Provider_readIvpn(t *testing.T) {
isps: sliceStringCall{call: true},
hostnames: sliceStringCall{call: true},
protocol: singleStringCall{call: true},
portGet: singleStringCall{call: true, value: "0"},
settings: Provider{
Name: constants.Ivpn,
},
@@ -114,11 +136,14 @@ func Test_Provider_readIvpn(t *testing.T) {
isps: sliceStringCall{call: true, values: []string{"ISP 1"}},
hostnames: sliceStringCall{call: true, values: []string{"E", "F"}},
protocol: singleStringCall{call: true, value: constants.TCP},
portGet: singleStringCall{call: true},
portPort: singleUint16Call{call: true, value: 443},
settings: Provider{
Name: constants.Ivpn,
ServerSelection: ServerSelection{
OpenVPN: OpenVPNSelection{
TCP: true,
TCP: true,
CustomPort: 443,
},
TargetIP: net.IPv4(1, 2, 3, 4),
Countries: []string{"A", "B"},
@@ -136,10 +161,6 @@ func Test_Provider_readIvpn(t *testing.T) {
ctrl := gomock.NewController(t)
env := mock_params.NewMockInterface(ctrl)
if testCase.protocol.call {
env.EXPECT().Inside("PROTOCOL", []string{constants.TCP, constants.UDP}, gomock.Any()).
Return(testCase.protocol.value, testCase.protocol.err)
}
if testCase.targetIP.call {
env.EXPECT().Get("OPENVPN_TARGET_IP").
Return(testCase.targetIP.value, testCase.targetIP.err)
@@ -160,6 +181,18 @@ func Test_Provider_readIvpn(t *testing.T) {
env.EXPECT().CSVInside("SERVER_HOSTNAME", constants.IvpnHostnameChoices()).
Return(testCase.hostnames.values, testCase.hostnames.err)
}
if testCase.protocol.call {
env.EXPECT().Inside("PROTOCOL", []string{constants.TCP, constants.UDP}, gomock.Any()).
Return(testCase.protocol.value, testCase.protocol.err)
}
if testCase.portGet.call {
env.EXPECT().Get("PORT", gomock.Any()).
Return(testCase.portGet.value, testCase.portGet.err)
}
if testCase.portPort.call {
env.EXPECT().Port("PORT").
Return(testCase.portPort.value, testCase.portPort.err)
}
r := reader{env: env}