location/gateway/port selection in v5
Hey, I'm currently implementing/integrating v5 (bitmaks-core/menshen) into the desktop client (#758 (closed)).
If we start the desktop client, we see a list of locations and the quality of each location. Currently, this is hardcoded in my branch:
available locations
locationLabels := make(map[string][]string)
locationLabels["Paris"] = []string{"Paris", "Fr"}
locationLabels["Seattle"] = []string{"Seattle", "US"}
return locationLabels
quality
cm := make(map[string]float64)
cm["Paris"] = 0.84
cm["Seattle"] = 0.3
return cm
best location
return "Paris"
Now I want to fill this with logic. Therefore, we need to agree on how to implement this. This is my proposal on how to implement this:
- menshen does not give us a list of availabale locations
- we only get a list of gateways
- each gateway has a field: location
- PROPOSAL: we keep it as it is. No need for an /locations endpoint
UPDATE:
- there is a /Service endpoint in menshen. I think it's only meant for v3-backwards compatiblity
- this endpoint also returns locations
- bitmask-core has Locations() that gives us the locations, but we have to call FetchService() before (not very intuitive)
- quality of a location
- definition of quality: latency + load
- latency: calculate the latency to each gateway (on the client side, already implemented in bitmask-core)
- edge case: what if (only) icmp is blocked => ignore this host vs enqueue at the end to the list of gateways per location
- load: needs to be differentiated
- We have a load per gateway and a load for each openvpn process of a gateway
- total load of the gateway: there is a load field in the api response for every gateway => just use this value
- load of multiple openvpn processes per gateway: handled by the ports returned to the api client (prefered port or ordered list of ports)
- open issue about this: menshen#30
- We have a load per gateway and a load for each openvpn process of a gateway
- calculation proposal
- for each location: check latency for all gateways and calculate average
- ignore load of single gateways (easy to implment, load will be considered later)
If the user connects/clicks on a location
- connect to 2? gateways of the selected location (check QUESTIONS (2) below)
- the latency of gateways in a single location should not differ much => ignore
- connection order of gateways: by total load of the gateway
- honor load of openvpn processes per host
- prefer udp over tcp
So for example menshen gives us the following information:
paris01 lat=0.5 load=1 port1=80-tcp-0.7 port2=443-tcp-0.8
paris02 lat=0.3 load=2 ...
paris03 lat=0.1 load=1.5 ...
paris04 lat=0.8 load=0.4 port1=53-udp-0.3 port2=1194-udp-0.5 port3=80-tcp-0.7
connection order
- ignore latency of gateway
- order by total gateway load: paris04, paris01 paris03, paris02 (but only use the first 2?)
- for each host: order ports (honor load, then udp over tcp - that's conflicting, see QUESTIONS below)
Start openvpn with the following arguments
--remote paris04 53 udp4
--remote paris04 1194 udp4
--remote paris04 80 tcp4
--remote paris01 80 tcp4
--remote paris01 443 tcp4
QUESTIONS
-
Definition of load (only relevant for implementation in menshen)
- load of a gateway:
- just the system load given by uptime?
- Or current network bandwith used?
- Or bandwith utilization?
- load of a gateway process:
- connected users?
- network traffic per process?
- How to get this information?
- load of a gateway:
-
How many gateways per location to connect with
- what if we can't connect to 2 gateways of a single location
- probably the whole location (all gateways of this country) is blocked
- tell the user OpenVPN failed and they should use a different location?
- to calculate the latency, we ping the host => we know if we can reach them
- what if only icmp is blocked?
- what if we can't connect to 2 gateways of a single location
-
If we have a gateway with 6 listening openvpn ports
- how many ports do we try to connect (regarding --remote argument)
- when do we want to switch to the next gateway
- what's likely to fail (or blocked): OpenVPN process or gateway
- what if we use the first two, but they are only UDP and UDP is blocked
-
We want poeple to use UDP
- this means: UDP openvpn processes have a higher load
- if we order ports just by load of openvpn processes => menshen will people tell to use the TCP port because the load is lower
-
UPDATE: In bitmask-core, there is code about Geolocation
- looks like this: get location by third party api
- ask menshen for gateways in this area
It would be nice if people could think about this and then let's have a call to decide. @kali @cyberta @jkito @sgk