cmd/tailscale: close Tailscale when user cancels system VPN dialog

Fixes tailscale/tailscale#904

Signed-off-by: Elias Naur <mail@eliasnaur.com>
pull/4/head
Elias Naur 4 years ago
parent 21037e6d67
commit 129abdb13f

@ -17,7 +17,11 @@ import (
import "C" import "C"
var ( var (
vpnPrepared = make(chan struct{}, 1) // onVPNPrepared is notified when VpnService.prepare succeeds.
onVPNPrepared = make(chan struct{}, 1)
// onVPNClosed is notified when VpnService.prepare fails, or when
// the a running VPN connection is closed.
onVPNClosed = make(chan struct{}, 1)
// onConnect receives global IPNService references when // onConnect receives global IPNService references when
// a VPN connection is requested. // a VPN connection is requested.
@ -55,12 +59,19 @@ const resultOK = -1
//export Java_com_tailscale_ipn_App_onVPNPrepared //export Java_com_tailscale_ipn_App_onVPNPrepared
func Java_com_tailscale_ipn_App_onVPNPrepared(env *C.JNIEnv, class C.jclass) { func Java_com_tailscale_ipn_App_onVPNPrepared(env *C.JNIEnv, class C.jclass) {
onVPNPrepared() notifyVPNPrepared()
} }
func onVPNPrepared() { func notifyVPNPrepared() {
select { select {
case vpnPrepared <- struct{}{}: case onVPNPrepared <- struct{}{}:
default:
}
}
func notifyVPNClosed() {
select {
case onVPNClosed <- struct{}{}:
default: default:
} }
} }
@ -110,9 +121,10 @@ func Java_com_tailscale_ipn_Peer_onActivityResult0(env *C.JNIEnv, cls C.jclass,
tok := jni.GoString(jenv, jni.String(idToken)) tok := jni.GoString(jenv, jni.String(idToken))
onGoogleToken <- tok onGoogleToken <- tok
case requestPrepareVPN: case requestPrepareVPN:
if resCode != resultOK { if resCode == resultOK {
break notifyVPNPrepared()
} else {
notifyVPNClosed()
} }
onVPNPrepared()
} }
} }

@ -35,9 +35,6 @@ type App struct {
// updates is notifies whenever netState or browseURL changes. // updates is notifies whenever netState or browseURL changes.
updates chan struct{} updates chan struct{}
// vpnClosed is notified when the VPNService is closed while
// logged in.
vpnClosed chan struct{}
// backend is the channel for events from the frontend to the // backend is the channel for events from the frontend to the
// backend. // backend.
@ -113,10 +110,9 @@ var backendEvents = make(chan UIEvent)
func main() { func main() {
a := &App{ a := &App{
jvm: jni.JVMFor(app.JavaVM()), jvm: jni.JVMFor(app.JavaVM()),
appCtx: jni.Object(app.AppContext()), appCtx: jni.Object(app.AppContext()),
updates: make(chan struct{}, 1), updates: make(chan struct{}, 1),
vpnClosed: make(chan struct{}, 1),
} }
err := jni.Do(a.jvm, func(env jni.Env) error { err := jni.Do(a.jvm, func(env jni.Env) error {
loader := jni.ClassLoaderFor(env, a.appCtx) loader := jni.ClassLoaderFor(env, a.appCtx)
@ -231,7 +227,7 @@ func (a *App) runBackend() error {
if cfg != nil && state.State >= ipn.Starting { if cfg != nil && state.State >= ipn.Starting {
if err := b.updateTUN(service, cfg); err != nil { if err := b.updateTUN(service, cfg); err != nil {
log.Printf("VPN update failed: %v", err) log.Printf("VPN update failed: %v", err)
a.notifyVPNClosed() notifyVPNClosed()
} }
} else { } else {
b.CloseTUNs() b.CloseTUNs()
@ -298,7 +294,7 @@ func (a *App) runBackend() error {
if cfg != nil && state.State >= ipn.Starting { if cfg != nil && state.State >= ipn.Starting {
if err := b.updateTUN(service, cfg); err != nil { if err := b.updateTUN(service, cfg); err != nil {
log.Printf("VPN update failed: %v", err) log.Printf("VPN update failed: %v", err)
a.notifyVPNClosed() notifyVPNClosed()
} }
} }
case <-onConnectivityChange: case <-onConnectivityChange:
@ -318,7 +314,7 @@ func (a *App) runBackend() error {
return nil return nil
}) })
if state.State >= ipn.Starting { if state.State >= ipn.Starting {
a.notifyVPNClosed() notifyVPNClosed()
} }
} }
} }
@ -457,13 +453,6 @@ func (a *App) notifyExpiry(service jni.Object, expiry time.Time) *time.Timer {
return t return t
} }
func (a *App) notifyVPNClosed() {
select {
case a.vpnClosed <- struct{}{}:
default:
}
}
func (a *App) notify(state BackendState) { func (a *App) notify(state BackendState) {
a.mu.Lock() a.mu.Lock()
a.netState = state a.netState = state
@ -527,7 +516,7 @@ func (a *App) runUI() error {
defer deleteActivityRef() defer deleteActivityRef()
for { for {
select { select {
case <-a.vpnClosed: case <-onVPNClosed:
requestBackend(ConnectEvent{Enable: false}) requestBackend(ConnectEvent{Enable: false})
case tok := <-onGoogleToken: case tok := <-onGoogleToken:
ui.signinType = noSignin ui.signinType = noSignin
@ -564,7 +553,7 @@ func (a *App) runUI() error {
} }
} }
} }
case <-vpnPrepared: case <-onVPNPrepared:
if state.backend.State > ipn.Stopped { if state.backend.State > ipn.Stopped {
if err := a.callVoidMethod(a.appCtx, "startVPN", "()V"); err != nil { if err := a.callVoidMethod(a.appCtx, "startVPN", "()V"); err != nil {
return err return err

Loading…
Cancel
Save