diff options
-rw-r--r-- | gui/backend.go | 5 | ||||
-rw-r--r-- | gui/handlers.cpp | 5 | ||||
-rw-r--r-- | gui/handlers.h | 1 | ||||
-rw-r--r-- | gui/qml/VpnState.qml | 41 | ||||
-rw-r--r-- | gui/qml/main.qml | 83 | ||||
-rw-r--r-- | pkg/backend/api.go | 25 | ||||
-rw-r--r-- | pkg/backend/status.go | 6 | ||||
-rw-r--r-- | pkg/bitmask/bitmask.go | 3 | ||||
-rw-r--r-- | pkg/vpn/bonafide/bonafide.go | 7 | ||||
-rw-r--r-- | pkg/vpn/bonafide/gateways.go | 4 | ||||
-rw-r--r-- | pkg/vpn/openvpn.go | 6 | ||||
-rw-r--r-- | pkg/vpn/status.go | 8 |
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") |