Feat: IVPN supports TCP and custom port
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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}
|
||||
|
||||
|
||||
@@ -25971,14 +25971,14 @@
|
||||
},
|
||||
"ivpn": {
|
||||
"version": 2,
|
||||
"timestamp": 1629589118,
|
||||
"timestamp": 1629725441,
|
||||
"servers": [
|
||||
{
|
||||
"country": "Australia",
|
||||
"city": "Sydney",
|
||||
"isp": "M247",
|
||||
"hostname": "au-nsw1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"46.102.153.242"
|
||||
@@ -25989,7 +25989,7 @@
|
||||
"city": "Vienna",
|
||||
"isp": "M247",
|
||||
"hostname": "at1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"185.244.212.66"
|
||||
@@ -26000,7 +26000,7 @@
|
||||
"city": "Brussels",
|
||||
"isp": "M247",
|
||||
"hostname": "be1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"194.187.251.10"
|
||||
@@ -26011,7 +26011,7 @@
|
||||
"city": "Franca",
|
||||
"isp": "Qnax",
|
||||
"hostname": "br1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"45.162.229.130"
|
||||
@@ -26022,7 +26022,7 @@
|
||||
"city": "Sofia",
|
||||
"isp": "M247",
|
||||
"hostname": "bg1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"82.102.23.18"
|
||||
@@ -26033,7 +26033,7 @@
|
||||
"city": "Montreal",
|
||||
"isp": "M247",
|
||||
"hostname": "ca-qc1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"87.101.92.26"
|
||||
@@ -26044,7 +26044,7 @@
|
||||
"city": "Toronto",
|
||||
"isp": "Amanah",
|
||||
"hostname": "ca1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"104.254.90.178"
|
||||
@@ -26055,7 +26055,7 @@
|
||||
"city": "Toronto",
|
||||
"isp": "Amanah",
|
||||
"hostname": "ca2.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"172.86.186.170"
|
||||
@@ -26066,7 +26066,7 @@
|
||||
"city": "Prague",
|
||||
"isp": "Datapacket",
|
||||
"hostname": "cz1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"195.181.160.167"
|
||||
@@ -26077,7 +26077,7 @@
|
||||
"city": "Copenhagen",
|
||||
"isp": "M247",
|
||||
"hostname": "dk1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"185.245.84.226"
|
||||
@@ -26088,7 +26088,7 @@
|
||||
"city": "Helsinki",
|
||||
"isp": "Creanova",
|
||||
"hostname": "fi1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"185.112.82.12"
|
||||
@@ -26099,7 +26099,7 @@
|
||||
"city": "Paris",
|
||||
"isp": "Datapacket",
|
||||
"hostname": "fr1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"185.246.211.179"
|
||||
@@ -26110,7 +26110,7 @@
|
||||
"city": "Frankfurt",
|
||||
"isp": "Leaseweb",
|
||||
"hostname": "de1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"178.162.222.40"
|
||||
@@ -26121,7 +26121,7 @@
|
||||
"city": "Frankfurt",
|
||||
"isp": "Leaseweb",
|
||||
"hostname": "de2.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"178.162.211.114"
|
||||
@@ -26132,7 +26132,7 @@
|
||||
"city": "Hong Kong",
|
||||
"isp": "Leaseweb",
|
||||
"hostname": "hk1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"209.58.189.163"
|
||||
@@ -26143,7 +26143,7 @@
|
||||
"city": "Hong Kong",
|
||||
"isp": "Leaseweb",
|
||||
"hostname": "hk2.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"209.58.188.13"
|
||||
@@ -26154,7 +26154,7 @@
|
||||
"city": "Budapest",
|
||||
"isp": "M247",
|
||||
"hostname": "hu1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"185.189.114.186"
|
||||
@@ -26165,7 +26165,7 @@
|
||||
"city": "Reykjavik",
|
||||
"isp": "Advania",
|
||||
"hostname": "is1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"82.221.107.178"
|
||||
@@ -26176,7 +26176,7 @@
|
||||
"city": "Holon, Tel Aviv",
|
||||
"isp": "HQServ",
|
||||
"hostname": "il1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"185.191.207.194"
|
||||
@@ -26187,7 +26187,7 @@
|
||||
"city": "Milan",
|
||||
"isp": "SEFlow",
|
||||
"hostname": "it1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"158.58.172.73"
|
||||
@@ -26198,7 +26198,7 @@
|
||||
"city": "Tokyo",
|
||||
"isp": "M247",
|
||||
"hostname": "jp1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"91.207.174.234"
|
||||
@@ -26209,7 +26209,7 @@
|
||||
"city": "Luxembourg",
|
||||
"isp": "Evoluso",
|
||||
"hostname": "lu1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"92.223.89.53"
|
||||
@@ -26220,7 +26220,7 @@
|
||||
"city": "Amsterdam",
|
||||
"isp": "Leaseweb",
|
||||
"hostname": "nl3.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"95.211.172.68"
|
||||
@@ -26231,7 +26231,7 @@
|
||||
"city": "Amsterdam",
|
||||
"isp": "Leaseweb",
|
||||
"hostname": "nl4.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"95.211.172.95"
|
||||
@@ -26242,7 +26242,7 @@
|
||||
"city": "Amsterdam",
|
||||
"isp": "Leaseweb",
|
||||
"hostname": "nl5.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"95.211.187.222"
|
||||
@@ -26253,7 +26253,7 @@
|
||||
"city": "Amsterdam",
|
||||
"isp": "Leaseweb",
|
||||
"hostname": "nl6.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"95.211.187.228"
|
||||
@@ -26264,7 +26264,7 @@
|
||||
"city": "Amsterdam",
|
||||
"isp": "Leaseweb",
|
||||
"hostname": "nl7.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"95.211.95.22"
|
||||
@@ -26275,7 +26275,7 @@
|
||||
"city": "Amsterdam",
|
||||
"isp": "Leaseweb",
|
||||
"hostname": "nl8.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"95.211.172.18"
|
||||
@@ -26286,7 +26286,7 @@
|
||||
"city": "Oslo",
|
||||
"isp": "Servethewrld",
|
||||
"hostname": "no1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"194.242.10.150"
|
||||
@@ -26297,7 +26297,7 @@
|
||||
"city": "Warsaw",
|
||||
"isp": "Datapacket",
|
||||
"hostname": "pl1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"185.246.208.86"
|
||||
@@ -26308,7 +26308,7 @@
|
||||
"city": "Lisbon",
|
||||
"isp": "Hostwebis",
|
||||
"hostname": "pt1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"94.46.175.112"
|
||||
@@ -26319,7 +26319,7 @@
|
||||
"city": "Bucharest",
|
||||
"isp": "M247",
|
||||
"hostname": "ro1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"37.120.206.50"
|
||||
@@ -26330,7 +26330,7 @@
|
||||
"city": "Belgrade",
|
||||
"isp": "M247",
|
||||
"hostname": "rs1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"141.98.103.250"
|
||||
@@ -26341,7 +26341,7 @@
|
||||
"city": "Singapore",
|
||||
"isp": "M247",
|
||||
"hostname": "sg1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"185.128.24.186"
|
||||
@@ -26352,7 +26352,7 @@
|
||||
"city": "Bratislava",
|
||||
"isp": "M247",
|
||||
"hostname": "sk1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"185.245.85.250"
|
||||
@@ -26363,7 +26363,7 @@
|
||||
"city": "Madrid",
|
||||
"isp": "Datapacket",
|
||||
"hostname": "es1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"185.93.3.193"
|
||||
@@ -26374,7 +26374,7 @@
|
||||
"city": "Stockholm",
|
||||
"isp": "GleSyS",
|
||||
"hostname": "se1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"80.67.10.138"
|
||||
@@ -26385,7 +26385,7 @@
|
||||
"city": "Zurich",
|
||||
"isp": "M247",
|
||||
"hostname": "ch1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"185.212.170.138"
|
||||
@@ -26396,7 +26396,7 @@
|
||||
"city": "Zurich",
|
||||
"isp": "Privatelayer",
|
||||
"hostname": "ch3.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"141.255.166.194"
|
||||
@@ -26407,7 +26407,7 @@
|
||||
"city": "Kharkiv",
|
||||
"isp": "Xservers",
|
||||
"hostname": "ua1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"193.203.48.54"
|
||||
@@ -26418,7 +26418,7 @@
|
||||
"city": "London",
|
||||
"isp": "Datapacket",
|
||||
"hostname": "gb1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"185.59.221.133"
|
||||
@@ -26429,7 +26429,7 @@
|
||||
"city": "London",
|
||||
"isp": "Datapacket",
|
||||
"hostname": "gb2.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"185.59.221.88"
|
||||
@@ -26440,7 +26440,7 @@
|
||||
"city": "Manchester",
|
||||
"isp": "M247",
|
||||
"hostname": "gb-man1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"89.238.141.228"
|
||||
@@ -26451,7 +26451,7 @@
|
||||
"city": "Atlanta, GA",
|
||||
"isp": "Quadranet",
|
||||
"hostname": "us-ga1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"104.129.24.146"
|
||||
@@ -26462,7 +26462,7 @@
|
||||
"city": "Atlanta, GA",
|
||||
"isp": "Quadranet",
|
||||
"hostname": "us-ga2.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"107.150.22.74"
|
||||
@@ -26473,7 +26473,7 @@
|
||||
"city": "Chicago, IL",
|
||||
"isp": "Quadranet",
|
||||
"hostname": "us-il1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"107.150.28.82"
|
||||
@@ -26484,7 +26484,7 @@
|
||||
"city": "Chicago, IL",
|
||||
"isp": "Quadranet",
|
||||
"hostname": "us-il2.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"72.11.137.146"
|
||||
@@ -26495,7 +26495,7 @@
|
||||
"city": "Dallas, TX",
|
||||
"isp": "Quadranet",
|
||||
"hostname": "us-tx1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"96.44.189.194"
|
||||
@@ -26506,7 +26506,7 @@
|
||||
"city": "Dallas, TX",
|
||||
"isp": "Quadranet",
|
||||
"hostname": "us-tx2.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"96.44.142.74"
|
||||
@@ -26517,7 +26517,7 @@
|
||||
"city": "Las Vegas, NV",
|
||||
"isp": "M247",
|
||||
"hostname": "us-nv1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"185.242.5.34"
|
||||
@@ -26528,7 +26528,7 @@
|
||||
"city": "Los Angeles, CA",
|
||||
"isp": "Quadranet",
|
||||
"hostname": "us-ca1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"173.254.196.58"
|
||||
@@ -26539,7 +26539,7 @@
|
||||
"city": "Los Angeles, CA",
|
||||
"isp": "Quadranet",
|
||||
"hostname": "us-ca2.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"69.12.80.146"
|
||||
@@ -26550,7 +26550,7 @@
|
||||
"city": "Los Angeles, CA",
|
||||
"isp": "Leaseweb",
|
||||
"hostname": "us-ca3.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"209.58.130.196"
|
||||
@@ -26561,7 +26561,7 @@
|
||||
"city": "Los Angeles, CA",
|
||||
"isp": "Quadranet",
|
||||
"hostname": "us-ca4.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"173.254.204.202"
|
||||
@@ -26572,7 +26572,7 @@
|
||||
"city": "Miami, FL",
|
||||
"isp": "Quadranet",
|
||||
"hostname": "us-fl1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"173.44.49.90"
|
||||
@@ -26583,7 +26583,7 @@
|
||||
"city": "New Jersey, NJ",
|
||||
"isp": "Quadranet",
|
||||
"hostname": "us-nj3.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"23.226.128.18"
|
||||
@@ -26594,7 +26594,7 @@
|
||||
"city": "New Jersey, NJ",
|
||||
"isp": "M247",
|
||||
"hostname": "us-nj4.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"194.36.111.50"
|
||||
@@ -26605,7 +26605,7 @@
|
||||
"city": "New York, NY",
|
||||
"isp": "Leaseweb",
|
||||
"hostname": "us-ny1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"64.120.44.114"
|
||||
@@ -26616,7 +26616,7 @@
|
||||
"city": "New York, NY",
|
||||
"isp": "Leaseweb",
|
||||
"hostname": "us-ny2.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"173.234.153.130"
|
||||
@@ -26627,7 +26627,7 @@
|
||||
"city": "Phoenix, AZ",
|
||||
"isp": "M247",
|
||||
"hostname": "us-az1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"193.37.254.130"
|
||||
@@ -26638,7 +26638,7 @@
|
||||
"city": "Salt Lake City, UT",
|
||||
"isp": "100TB",
|
||||
"hostname": "us-ut1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"198.105.216.28"
|
||||
@@ -26649,7 +26649,7 @@
|
||||
"city": "Seattle, WA",
|
||||
"isp": "Leaseweb",
|
||||
"hostname": "us-wa1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"23.19.87.209"
|
||||
@@ -26660,7 +26660,7 @@
|
||||
"city": "Washington, DC",
|
||||
"isp": "Leaseweb",
|
||||
"hostname": "us-dc1.gw.ivpn.net",
|
||||
"tcp": false,
|
||||
"tcp": true,
|
||||
"udp": true,
|
||||
"ips": [
|
||||
"207.244.108.207"
|
||||
|
||||
@@ -1,23 +1,16 @@
|
||||
package ivpn
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/configuration"
|
||||
"github.com/qdm12/gluetun/internal/constants"
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
"github.com/qdm12/gluetun/internal/provider/utils"
|
||||
)
|
||||
|
||||
var ErrProtocolUnsupported = errors.New("network protocol is not supported")
|
||||
|
||||
func (i *Ivpn) GetConnection(selection configuration.ServerSelection) (
|
||||
connection models.Connection, err error) {
|
||||
const port = 2049
|
||||
const protocol = constants.UDP
|
||||
if selection.OpenVPN.TCP {
|
||||
return connection, ErrProtocolUnsupported
|
||||
}
|
||||
port := getPort(selection)
|
||||
protocol := getProtocol(selection.OpenVPN.TCP)
|
||||
|
||||
servers, err := i.filterServers(selection)
|
||||
if err != nil {
|
||||
@@ -44,3 +37,22 @@ func (i *Ivpn) GetConnection(selection configuration.ServerSelection) (
|
||||
|
||||
return utils.PickRandomConnection(connections, i.randSource), nil
|
||||
}
|
||||
|
||||
func getPort(selection configuration.ServerSelection) (port uint16) {
|
||||
customPort := selection.OpenVPN.CustomPort
|
||||
if customPort > 0 {
|
||||
return customPort
|
||||
}
|
||||
port = 1194
|
||||
if selection.OpenVPN.TCP {
|
||||
port = 443
|
||||
}
|
||||
return port
|
||||
}
|
||||
|
||||
func getProtocol(tcp bool) (protocol string) {
|
||||
if tcp {
|
||||
return constants.TCP
|
||||
}
|
||||
return constants.UDP
|
||||
}
|
||||
|
||||
173
internal/provider/ivpn/connection_test.go
Normal file
173
internal/provider/ivpn/connection_test.go
Normal file
@@ -0,0 +1,173 @@
|
||||
package ivpn
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math/rand"
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/configuration"
|
||||
"github.com/qdm12/gluetun/internal/constants"
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test_Ivpn_GetConnection(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := map[string]struct {
|
||||
servers []models.IvpnServer
|
||||
selection configuration.ServerSelection
|
||||
connection models.Connection
|
||||
err error
|
||||
}{
|
||||
"no server available": {
|
||||
selection: configuration.ServerSelection{
|
||||
VPN: constants.OpenVPN,
|
||||
},
|
||||
err: errors.New("no server found: for VPN openvpn; protocol udp"),
|
||||
},
|
||||
"no filter": {
|
||||
servers: []models.IvpnServer{
|
||||
{IPs: []net.IP{net.IPv4(1, 1, 1, 1)}, UDP: true},
|
||||
{IPs: []net.IP{net.IPv4(2, 2, 2, 2)}, UDP: true},
|
||||
{IPs: []net.IP{net.IPv4(3, 3, 3, 3)}, UDP: true},
|
||||
},
|
||||
connection: models.Connection{
|
||||
IP: net.IPv4(1, 1, 1, 1),
|
||||
Port: 1194,
|
||||
Protocol: constants.UDP,
|
||||
},
|
||||
},
|
||||
"target IP": {
|
||||
selection: configuration.ServerSelection{
|
||||
TargetIP: net.IPv4(2, 2, 2, 2),
|
||||
},
|
||||
servers: []models.IvpnServer{
|
||||
{IPs: []net.IP{net.IPv4(1, 1, 1, 1)}, UDP: true},
|
||||
{IPs: []net.IP{net.IPv4(2, 2, 2, 2)}, UDP: true},
|
||||
{IPs: []net.IP{net.IPv4(3, 3, 3, 3)}, UDP: true},
|
||||
},
|
||||
connection: models.Connection{
|
||||
IP: net.IPv4(2, 2, 2, 2),
|
||||
Port: 1194,
|
||||
Protocol: constants.UDP,
|
||||
},
|
||||
},
|
||||
"with filter": {
|
||||
selection: configuration.ServerSelection{
|
||||
Hostnames: []string{"b"},
|
||||
},
|
||||
servers: []models.IvpnServer{
|
||||
{Hostname: "a", IPs: []net.IP{net.IPv4(1, 1, 1, 1)}, UDP: true},
|
||||
{Hostname: "b", IPs: []net.IP{net.IPv4(2, 2, 2, 2)}, UDP: true},
|
||||
{Hostname: "a", IPs: []net.IP{net.IPv4(3, 3, 3, 3)}, UDP: true},
|
||||
},
|
||||
connection: models.Connection{
|
||||
IP: net.IPv4(2, 2, 2, 2),
|
||||
Port: 1194,
|
||||
Protocol: constants.UDP,
|
||||
Hostname: "b",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for name, testCase := range testCases {
|
||||
testCase := testCase
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
randSource := rand.NewSource(0)
|
||||
|
||||
m := New(testCase.servers, randSource)
|
||||
|
||||
connection, err := m.GetConnection(testCase.selection)
|
||||
|
||||
if testCase.err != nil {
|
||||
require.Error(t, err)
|
||||
assert.Equal(t, testCase.err.Error(), err.Error())
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
assert.Equal(t, testCase.connection, connection)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_getPort(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := map[string]struct {
|
||||
selection configuration.ServerSelection
|
||||
port uint16
|
||||
}{
|
||||
"default": {
|
||||
port: 1194,
|
||||
},
|
||||
"OpenVPN UDP": {
|
||||
selection: configuration.ServerSelection{
|
||||
VPN: constants.OpenVPN,
|
||||
},
|
||||
port: 1194,
|
||||
},
|
||||
"OpenVPN TCP": {
|
||||
selection: configuration.ServerSelection{
|
||||
VPN: constants.OpenVPN,
|
||||
OpenVPN: configuration.OpenVPNSelection{
|
||||
TCP: true,
|
||||
},
|
||||
},
|
||||
port: 443,
|
||||
},
|
||||
"OpenVPN custom port": {
|
||||
selection: configuration.ServerSelection{
|
||||
VPN: constants.OpenVPN,
|
||||
OpenVPN: configuration.OpenVPNSelection{
|
||||
CustomPort: 1234,
|
||||
},
|
||||
},
|
||||
port: 1234,
|
||||
},
|
||||
}
|
||||
|
||||
for name, testCase := range testCases {
|
||||
testCase := testCase
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
port := getPort(testCase.selection)
|
||||
|
||||
assert.Equal(t, testCase.port, port)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_getProtocol(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := map[string]struct {
|
||||
tcp bool
|
||||
protocol string
|
||||
}{
|
||||
"UDP": {
|
||||
protocol: constants.UDP,
|
||||
},
|
||||
"TCP": {
|
||||
tcp: true,
|
||||
protocol: constants.TCP,
|
||||
},
|
||||
}
|
||||
|
||||
for name, testCase := range testCases {
|
||||
testCase := testCase
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
protocol := getProtocol(testCase.tcp)
|
||||
|
||||
assert.Equal(t, testCase.protocol, protocol)
|
||||
})
|
||||
}
|
||||
}
|
||||
132
internal/provider/ivpn/filter_test.go
Normal file
132
internal/provider/ivpn/filter_test.go
Normal file
@@ -0,0 +1,132 @@
|
||||
package ivpn
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/qdm12/gluetun/internal/configuration"
|
||||
"github.com/qdm12/gluetun/internal/constants"
|
||||
"github.com/qdm12/gluetun/internal/models"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test_Ivpn_filterServers(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := map[string]struct {
|
||||
servers []models.IvpnServer
|
||||
selection configuration.ServerSelection
|
||||
filtered []models.IvpnServer
|
||||
err error
|
||||
}{
|
||||
"no server available": {
|
||||
selection: configuration.ServerSelection{
|
||||
VPN: constants.OpenVPN,
|
||||
},
|
||||
err: errors.New("no server found: for VPN openvpn; protocol udp"),
|
||||
},
|
||||
"no filter": {
|
||||
servers: []models.IvpnServer{
|
||||
{Hostname: "a", UDP: true},
|
||||
{Hostname: "b", UDP: true},
|
||||
{Hostname: "c", UDP: true},
|
||||
},
|
||||
filtered: []models.IvpnServer{
|
||||
{Hostname: "a", UDP: true},
|
||||
{Hostname: "b", UDP: true},
|
||||
{Hostname: "c", UDP: true},
|
||||
},
|
||||
},
|
||||
"filter by country": {
|
||||
selection: configuration.ServerSelection{
|
||||
Countries: []string{"b"},
|
||||
},
|
||||
servers: []models.IvpnServer{
|
||||
{Country: "a", UDP: true},
|
||||
{Country: "b", UDP: true},
|
||||
{Country: "c", UDP: true},
|
||||
},
|
||||
filtered: []models.IvpnServer{
|
||||
{Country: "b", UDP: true},
|
||||
},
|
||||
},
|
||||
"filter by city": {
|
||||
selection: configuration.ServerSelection{
|
||||
Cities: []string{"b"},
|
||||
},
|
||||
servers: []models.IvpnServer{
|
||||
{City: "a", UDP: true},
|
||||
{City: "b", UDP: true},
|
||||
{City: "c", UDP: true},
|
||||
},
|
||||
filtered: []models.IvpnServer{
|
||||
{City: "b", UDP: true},
|
||||
},
|
||||
},
|
||||
"filter by ISP": {
|
||||
selection: configuration.ServerSelection{
|
||||
ISPs: []string{"b"},
|
||||
},
|
||||
servers: []models.IvpnServer{
|
||||
{ISP: "a", UDP: true},
|
||||
{ISP: "b", UDP: true},
|
||||
{ISP: "c", UDP: true},
|
||||
},
|
||||
filtered: []models.IvpnServer{
|
||||
{ISP: "b", UDP: true},
|
||||
},
|
||||
},
|
||||
"filter by hostname": {
|
||||
selection: configuration.ServerSelection{
|
||||
Hostnames: []string{"b"},
|
||||
},
|
||||
servers: []models.IvpnServer{
|
||||
{Hostname: "a", UDP: true},
|
||||
{Hostname: "b", UDP: true},
|
||||
{Hostname: "c", UDP: true},
|
||||
},
|
||||
filtered: []models.IvpnServer{
|
||||
{Hostname: "b", UDP: true},
|
||||
},
|
||||
},
|
||||
"filter by protocol": {
|
||||
selection: configuration.ServerSelection{
|
||||
OpenVPN: configuration.OpenVPNSelection{
|
||||
TCP: true,
|
||||
},
|
||||
},
|
||||
servers: []models.IvpnServer{
|
||||
{Hostname: "a", UDP: true},
|
||||
{Hostname: "b", UDP: true, TCP: true},
|
||||
{Hostname: "c", UDP: true},
|
||||
},
|
||||
filtered: []models.IvpnServer{
|
||||
{Hostname: "b", UDP: true, TCP: true},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for name, testCase := range testCases {
|
||||
testCase := testCase
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
randSource := rand.NewSource(0)
|
||||
|
||||
m := New(testCase.servers, randSource)
|
||||
|
||||
servers, err := m.filterServers(testCase.selection)
|
||||
|
||||
if testCase.err != nil {
|
||||
require.Error(t, err)
|
||||
assert.Equal(t, testCase.err.Error(), err.Error())
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
assert.Equal(t, testCase.filtered, servers)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -59,9 +59,9 @@ func GetServers(ctx context.Context, client *http.Client,
|
||||
City: serverData.City,
|
||||
ISP: serverData.ISP,
|
||||
Hostname: serverData.Hostnames.OpenVPN,
|
||||
// TCP is not supported
|
||||
UDP: true,
|
||||
IPs: hostToIPs[host],
|
||||
TCP: true,
|
||||
UDP: true,
|
||||
IPs: hostToIPs[host],
|
||||
}
|
||||
servers = append(servers, server)
|
||||
}
|
||||
|
||||
@@ -83,8 +83,10 @@ func Test_GetServers(t *testing.T) {
|
||||
},
|
||||
resolveWarnings: []string{"resolve warning"},
|
||||
servers: []models.IvpnServer{
|
||||
{Country: "Country1", City: "City A", Hostname: "hosta", UDP: true, IPs: []net.IP{{1, 1, 1, 1}, {2, 2, 2, 2}}},
|
||||
{Country: "Country2", City: "City B", Hostname: "hostb", UDP: true, IPs: []net.IP{{3, 3, 3, 3}, {4, 4, 4, 4}}},
|
||||
{Country: "Country1", City: "City A", Hostname: "hosta",
|
||||
TCP: true, UDP: true, IPs: []net.IP{{1, 1, 1, 1}, {2, 2, 2, 2}}},
|
||||
{Country: "Country2", City: "City B", Hostname: "hostb",
|
||||
TCP: true, UDP: true, IPs: []net.IP{{3, 3, 3, 3}, {4, 4, 4, 4}}},
|
||||
},
|
||||
warnings: []string{"resolve warning"},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user