summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuben Pollan <meskio@sindominio.net>2021-03-26 15:48:58 +0100
committerkali kaneko (leap communications) <kali@leap.se>2021-05-04 14:58:39 +0200
commit67a68be2290b3af6e7d2897e52b3cd19d1f4450d (patch)
tree60f477042a7764186e39db51f13a0733afd9bffd
parent4e1f3a4f88136e497962e4f976d5c7f216c31a15 (diff)
Location selection more responsive
-rw-r--r--gui/backend.go5
-rw-r--r--gui/handlers.cpp5
-rw-r--r--gui/handlers.h1
-rw-r--r--gui/qml/VpnState.qml41
-rw-r--r--gui/qml/main.qml83
-rw-r--r--pkg/backend/api.go25
-rw-r--r--pkg/backend/status.go6
-rw-r--r--pkg/bitmask/bitmask.go3
-rw-r--r--pkg/vpn/bonafide/bonafide.go7
-rw-r--r--pkg/vpn/bonafide/gateways.go4
-rw-r--r--pkg/vpn/openvpn.go6
-rw-r--r--pkg/vpn/status.go8
12 files changed, 149 insertions, 45 deletions
diff --git a/gui/backend.go b/gui/backend.go
index 064bd94..f693118 100644
--- a/gui/backend.go
+++ b/gui/backend.go
@@ -35,6 +35,11 @@ func UseLocation(label string) {
backend.UseLocation(label)
}
+//export UseAutomaticGateway
+func UseAutomaticGateway() {
+ backend.UseAutomaticGateway()
+}
+
//export UseTransport
func UseTransport(transport string) {
backend.UseTransport(transport)
diff --git a/gui/handlers.cpp b/gui/handlers.cpp
index 558c288..9f68834 100644
--- a/gui/handlers.cpp
+++ b/gui/handlers.cpp
@@ -47,6 +47,11 @@ void Backend::useLocation(QString label)
UseLocation(toGoStr(label));
}
+void Backend::useAutomaticGateway()
+{
+ UseAutomaticGateway();
+}
+
void Backend::login(QString username, QString password)
{
Login(toGoStr(username), toGoStr(password));
diff --git a/gui/handlers.h b/gui/handlers.h
index 9d949fc..3415b7e 100644
--- a/gui/handlers.h
+++ b/gui/handlers.h
@@ -37,6 +37,7 @@ public slots:
void donateAccepted();
void donateSeen();
void useLocation(QString username);
+ void useAutomaticGateway();
void login(QString username, QString password);
void resetError(QString errlabel);
void resetNotification(QString label);
diff --git a/gui/qml/VpnState.qml b/gui/qml/VpnState.qml
index 886868f..7ec6695 100644
--- a/gui/qml/VpnState.qml
+++ b/gui/qml/VpnState.qml
@@ -25,6 +25,10 @@ StateGroup {
text: toHuman("off")
}
PropertyChanges {
+ target: autoSelectionItem
+ text: qsTr("Best")
+ }
+ PropertyChanges {
target: mainStatus
text: toHuman("off")
}
@@ -46,7 +50,18 @@ StateGroup {
}
PropertyChanges {
target: statusItem
- text: toHumanWithLocation("on")
+ text: toHuman("on")
+ }
+ PropertyChanges {
+ target: autoSelectionItem
+ text: {
+ if (autoSelectionButton.checked) {
+ //: %1 -> location to which the client is connected to
+ qsTr("Best (%1)").arg(locationStr())
+ } else {
+ qsTr("Best")
+ }
+ }
}
PropertyChanges {
target: mainStatus
@@ -54,7 +69,8 @@ StateGroup {
}
PropertyChanges {
target: mainCurrentGateway
- text: qsTr("Connected to ") + ctx.currentLocation
+ //: %1 -> location to which the client is connected to
+ text: qsTr("Connected to %1").arg(locationStr())
}
},
State {
@@ -66,7 +82,18 @@ StateGroup {
}
PropertyChanges {
target: statusItem
- text: toHumanWithLocation("connecting")
+ text: toHuman("connecting")
+ }
+ PropertyChanges {
+ target: autoSelectionItem
+ text: {
+ if (autoSelectionButton.checked) {
+ //: %1 -> location to which the client is connected to
+ qsTr("Best (%1)").arg(locationStr())
+ } else {
+ qsTr("Best")
+ }
+ }
}
PropertyChanges {
target: mainStatus
@@ -89,6 +116,10 @@ StateGroup {
text: toHuman("stopping")
}
PropertyChanges {
+ target: autoSelectionItem
+ text: qsTr("Best")
+ }
+ PropertyChanges {
target: mainStatus
text: toHuman("stopping")
}
@@ -109,6 +140,10 @@ StateGroup {
text: toHuman("failed")
}
PropertyChanges {
+ target: autoSelectionItem
+ text: qsTr("Best")
+ }
+ PropertyChanges {
target: mainStatus
text: toHuman("failed")
}
diff --git a/gui/qml/main.qml b/gui/qml/main.qml
index 211dbe5..ddd049d 100644
--- a/gui/qml/main.qml
+++ b/gui/qml/main.qml
@@ -32,7 +32,7 @@ Window {
text: qsTr("Info")
}
TabButton {
- text: qsTr("Gateways")
+ text: qsTr("Location")
}
}
@@ -128,7 +128,7 @@ Window {
color: "grey"
text: qsTr("Location has been manually set.")
anchors.horizontalCenter: parent.horizontalCenter
- visible: manualSelectionButton.checked
+ visible: isManualLocation()
}
}
}
@@ -145,14 +145,15 @@ Window {
RadioButton {
id: autoSelectionButton
- checked: true
- text: qsTr("Automatic")
- // TODO still needs to change to automatic on the backend, and maybe note
- // that the change will be effective on the next reconnect.
+ checked: !isManualLocation()
+ text: qsTr("Best")
+ onClicked: backend.useAutomaticGateway()
}
RadioButton {
id: manualSelectionButton
+ checked: isManualLocation()
text: qsTr("Manual")
+ onClicked: setGwSelection()
}
ComboBox {
id: gwSelector
@@ -160,7 +161,7 @@ Window {
visible: manualSelectionButton.checked
anchors.horizontalCenter: parent.horizontalCenter
- model: [qsTr("Automatic")]
+ model: [qsTr("Best")]
onActivated: {
console.debug("Selected gateway:", currentText)
backend.useLocation(currentText.toString())
@@ -249,6 +250,24 @@ Window {
return false
}
+ function isManualLocation() {
+ if (!ctx) {
+ return false
+ }
+ return ctx.manualLocation == "true"
+ }
+
+ function setGwSelection() {
+ if (!ctx.currentLocation) {
+ return
+ }
+
+ const location = ctx.currentLocation.toLowerCase()
+ const idx = gwSelector.model.indexOf(location)
+ gwSelector.currentIndex = idx
+ backend.useLocation(location)
+ }
+
Component.onCompleted: {
loginDone = false
console.debug("Platform:", Qt.platform.os)
@@ -282,30 +301,8 @@ Window {
}
}
- /* TODO change this!!! automatic: Paris (FR) */
-
- function toHumanWithLocation(st) {
- switch (st) {
- case "off":
- //: %1 -> application name
- return qsTr("%1 off").arg(ctx.appName)
- case "on":
- //: %1 -> application name
- //: %2 -> current gateway
- return qsTr("%1 on - %2").arg(ctx.appName).arg(ctx.currentLocation)
- case "connecting":
- //: %1 -> application name
- //: %2 -> current gateway
- return qsTr("Connecting to %1 - %2").arg(ctx.appName).arg(
- ctx.currentLocation)
- case "stopping":
- //: %1 -> application name
- return qsTr("Stopping %1").arg(ctx.appName)
- case "failed":
- //: %1 -> application name
- return qsTr("%1 blocking internet").arg(
- ctx.appName) // TODO failed is not handed yet
- }
+ function locationStr() {
+ return ctx.currentLocation + ", " + ctx.currentCountry
}
property var icons: {
@@ -355,26 +352,34 @@ Window {
enabled: false
}
+ MenuSeparator {}
+
MenuItem {
id: autoSelectionItem
- text: qsTr("automatic")
+ text: qsTr("Best")
checkable: true
- checked: true
- enabled: false
+ checked: !isManualLocation()
+ onTriggered: {
+ backend.useAutomaticGateway()
+ }
}
/* a minimal segfault for submenu */
// Menu {}
- MenuSeparator {}
-
MenuItem {
id: manualSelectionItem
- text: qsTr("Pick gateway…")
+ text: {
+ if (isManualLocation()) {
+ locationStr()
+ } else {
+ qsTr("Pick location…")
+ }
+ }
checkable: true
- checked: false
- enabled: true
+ checked: isManualLocation()
+ onTriggered: setGwSelection()
}
MenuSeparator {}
diff --git a/pkg/backend/api.go b/pkg/backend/api.go
index f1fed57..d43751b 100644
--- a/pkg/backend/api.go
+++ b/pkg/backend/api.go
@@ -55,10 +55,31 @@ func SwitchOff() {
go stopVPN()
}
-// TODO implement Reconnect - do not tear whole fw down in between
-
func UseLocation(label string) {
+ if ctx.ManualLocation && label == ctx.CurrentLocation {
+ return
+ }
+
ctx.bm.UseGateway(label)
+ go trigger(OnStatusChanged)
+ if label != ctx.CurrentLocation {
+ reconnect()
+ }
+}
+
+func UseAutomaticGateway() {
+ if !ctx.ManualLocation {
+ return
+ }
+
+ ctx.bm.UseAutomaticGateway()
+ go trigger(OnStatusChanged)
+ reconnect()
+}
+
+// TODO implement Reconnect - do not tear whole fw down in between
+
+func reconnect() {
time.Sleep(200 * time.Millisecond)
SwitchOff()
time.Sleep(500 * time.Millisecond)
diff --git a/pkg/backend/status.go b/pkg/backend/status.go
index 0e92253..bdbdd35 100644
--- a/pkg/backend/status.go
+++ b/pkg/backend/status.go
@@ -47,17 +47,21 @@ type connectionCtx struct {
Locations map[string]float64 `json:"locations"`
CurrentGateway string `json:"currentGateway"`
CurrentLocation string `json:"currentLocation"`
+ CurrentCountry string `json:"currentCountry"`
+ ManualLocation bool `json:"manualLocation"`
bm bitmask.Bitmask
autostart bitmask.Autostart
cfg *config.Config
}
-func (c connectionCtx) toJson() ([]byte, error) {
+func (c *connectionCtx) toJson() ([]byte, error) {
statusMutex.Lock()
if c.bm != nil {
c.Locations = c.bm.ListLocationFullness("openvpn")
c.CurrentGateway = c.bm.GetCurrentGateway()
c.CurrentLocation = c.bm.GetCurrentLocation()
+ c.CurrentCountry = c.bm.GetCurrentCountry()
+ c.ManualLocation = c.bm.IsManualLocation()
}
defer statusMutex.Unlock()
b, err := json.Marshal(c)
diff --git a/pkg/bitmask/bitmask.go b/pkg/bitmask/bitmask.go
index eb2a833..d4c1c3f 100644
--- a/pkg/bitmask/bitmask.go
+++ b/pkg/bitmask/bitmask.go
@@ -28,8 +28,11 @@ type Bitmask interface {
VPNCheck() (helpers bool, priviledge bool, err error)
ListLocationFullness(protocol string) map[string]float64
UseGateway(name string)
+ UseAutomaticGateway()
GetCurrentGateway() string
GetCurrentLocation() string
+ GetCurrentCountry() string
+ IsManualLocation() bool
UseTransport(transport string) error
NeedsCredentials() bool
DoLogin(username, password string) (bool, error)
diff --git a/pkg/vpn/bonafide/bonafide.go b/pkg/vpn/bonafide/bonafide.go
index e0d9c9c..8387873 100644
--- a/pkg/vpn/bonafide/bonafide.go
+++ b/pkg/vpn/bonafide/bonafide.go
@@ -236,6 +236,13 @@ func (b *Bonafide) SetAutomaticGateway() {
b.gateways.setAutomaticChoice()
}
+func (b *Bonafide) IsManualLocation() bool {
+ if b.gateways == nil {
+ return false
+ }
+ return b.gateways.isManualLocation()
+}
+
func (b *Bonafide) GetGatewayByIP(ip string) (Gateway, error) {
return b.gateways.getGatewayByIP(ip)
}
diff --git a/pkg/vpn/bonafide/gateways.go b/pkg/vpn/bonafide/gateways.go
index 5474a2f..c848d77 100644
--- a/pkg/vpn/bonafide/gateways.go
+++ b/pkg/vpn/bonafide/gateways.go
@@ -164,6 +164,10 @@ func (p *gatewayPool) setUserChoice(city []byte) error {
return nil
}
+func (p *gatewayPool) isManualLocation() bool {
+ return len(p.userChoice) != 0
+}
+
/* set the recommended field from an ordered array. needs to be modified if menshen passed an array of Loads */
func (p *gatewayPool) setRecommendedGateways(hostnames []string) {
hosts := make([]string, 0)
diff --git a/pkg/vpn/openvpn.go b/pkg/vpn/openvpn.go
index e4d2781..2304dbd 100644
--- a/pkg/vpn/openvpn.go
+++ b/pkg/vpn/openvpn.go
@@ -239,6 +239,12 @@ func (b *Bitmask) UseGateway(label string) {
b.bonafide.SetManualGateway(label)
}
+// UseAutomaticGateway sets the gateway to be selected automatically
+// best gateway will be used
+func (b *Bitmask) UseAutomaticGateway() {
+ b.bonafide.SetAutomaticGateway()
+}
+
// UseTransport selects an obfuscation transport to use
func (b *Bitmask) UseTransport(transport string) error {
if transport != "obfs4" {
diff --git a/pkg/vpn/status.go b/pkg/vpn/status.go
index c812a9a..647cf27 100644
--- a/pkg/vpn/status.go
+++ b/pkg/vpn/status.go
@@ -94,6 +94,14 @@ func (b *Bitmask) GetCurrentLocation() string {
return b.onGateway.LocationName
}
+func (b *Bitmask) GetCurrentCountry() string {
+ return b.onGateway.CountryCode
+}
+
+func (b *Bitmask) IsManualLocation() bool {
+ return b.bonafide.IsManualLocation()
+}
+
func (b *Bitmask) getOpenvpnState() (string, error) {
if b.managementClient == nil {
return "", fmt.Errorf("No management connected")