|
|
@ -116,16 +116,14 @@ func main() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (a *App) runBackend() error {
|
|
|
|
func (a *App) runBackend() error {
|
|
|
|
var cfg *router.Config
|
|
|
|
configs := make(chan *router.Config)
|
|
|
|
var state NetworkState
|
|
|
|
configErrs := make(chan error)
|
|
|
|
var service jni.Object
|
|
|
|
|
|
|
|
var b *backend
|
|
|
|
|
|
|
|
b, err := newBackend(a.appDir, a.jvm, a.store, func(s *router.Config) error {
|
|
|
|
b, err := newBackend(a.appDir, a.jvm, a.store, func(s *router.Config) error {
|
|
|
|
cfg = s
|
|
|
|
if s == nil {
|
|
|
|
if b == nil || service == 0 || cfg == nil {
|
|
|
|
|
|
|
|
return nil
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return b.updateTUN(service, cfg)
|
|
|
|
configs <- s
|
|
|
|
|
|
|
|
return <-configErrs
|
|
|
|
})
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
return err
|
|
|
@ -143,62 +141,82 @@ func (a *App) runBackend() error {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var prefs struct {
|
|
|
|
var prefs struct {
|
|
|
|
|
|
|
|
once sync.Once
|
|
|
|
mu sync.Mutex
|
|
|
|
mu sync.Mutex
|
|
|
|
prefs *ipn.Prefs
|
|
|
|
prefs *ipn.Prefs
|
|
|
|
}
|
|
|
|
}
|
|
|
|
err = b.Start(func(n ipn.Notify) {
|
|
|
|
notifications := make(chan ipn.Notify, 1)
|
|
|
|
if p := n.Prefs; p != nil {
|
|
|
|
startErr := make(chan error)
|
|
|
|
prefs.mu.Lock()
|
|
|
|
// Start from a goroutine to avoid deadlock when Start
|
|
|
|
prefs.prefs = p.Clone()
|
|
|
|
// calls the callback.
|
|
|
|
prefs.mu.Unlock()
|
|
|
|
go func() {
|
|
|
|
a.setPrefs(prefs.prefs)
|
|
|
|
startErr <- b.Start(func(n ipn.Notify) {
|
|
|
|
}
|
|
|
|
notifications <- n
|
|
|
|
if s := n.State; s != nil {
|
|
|
|
})
|
|
|
|
oldState := state.State
|
|
|
|
}()
|
|
|
|
state.State = *s
|
|
|
|
var cfg *router.Config
|
|
|
|
if service != 0 {
|
|
|
|
var state NetworkState
|
|
|
|
a.updateNotification(service, state.State)
|
|
|
|
var service jni.Object
|
|
|
|
|
|
|
|
for {
|
|
|
|
|
|
|
|
select {
|
|
|
|
|
|
|
|
case err := <-startErr:
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
case s := <-configs:
|
|
|
|
|
|
|
|
cfg = s
|
|
|
|
|
|
|
|
if b == nil || service == 0 || cfg == nil {
|
|
|
|
|
|
|
|
configErrs <- nil
|
|
|
|
|
|
|
|
break
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
configErrs <- b.updateTUN(service, cfg)
|
|
|
|
|
|
|
|
case n := <-notifications:
|
|
|
|
|
|
|
|
if p := n.Prefs; p != nil {
|
|
|
|
|
|
|
|
prefs.mu.Lock()
|
|
|
|
|
|
|
|
prefs.prefs = p.Clone()
|
|
|
|
|
|
|
|
prefs.mu.Unlock()
|
|
|
|
|
|
|
|
a.setPrefs(prefs.prefs)
|
|
|
|
|
|
|
|
prefs.once.Do(func() {
|
|
|
|
|
|
|
|
prefs.mu.Lock()
|
|
|
|
|
|
|
|
prefs.prefs.Hostname = a.hostname()
|
|
|
|
|
|
|
|
p := prefs.prefs
|
|
|
|
|
|
|
|
prefs.mu.Unlock()
|
|
|
|
|
|
|
|
b.backend.SetPrefs(p)
|
|
|
|
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if service != 0 {
|
|
|
|
if s := n.State; s != nil {
|
|
|
|
if cfg != nil && state.State >= ipn.Starting {
|
|
|
|
oldState := state.State
|
|
|
|
if err := b.updateTUN(service, cfg); err != nil {
|
|
|
|
state.State = *s
|
|
|
|
a.notifyVPNClosed()
|
|
|
|
if service != 0 {
|
|
|
|
|
|
|
|
a.updateNotification(service, state.State)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if service != 0 {
|
|
|
|
|
|
|
|
if cfg != nil && state.State >= ipn.Starting {
|
|
|
|
|
|
|
|
if err := b.updateTUN(service, cfg); err != nil {
|
|
|
|
|
|
|
|
a.notifyVPNClosed()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
b.CloseTUNs()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
|
|
|
|
b.CloseTUNs()
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Stop VPN if we logged out.
|
|
|
|
// Stop VPN if we logged out.
|
|
|
|
if oldState > ipn.Stopped && state.State <= ipn.Stopped {
|
|
|
|
if oldState > ipn.Stopped && state.State <= ipn.Stopped {
|
|
|
|
if err := a.callVoidMethod(a.appCtx, "stopVPN", "()V"); err != nil {
|
|
|
|
if err := a.callVoidMethod(a.appCtx, "stopVPN", "()V"); err != nil {
|
|
|
|
fatalErr(err)
|
|
|
|
fatalErr(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
a.notify(state)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
a.notify(state)
|
|
|
|
if u := n.BrowseToURL; u != nil {
|
|
|
|
}
|
|
|
|
a.setURL(*u)
|
|
|
|
if u := n.BrowseToURL; u != nil {
|
|
|
|
}
|
|
|
|
a.setURL(*u)
|
|
|
|
if m := n.NetMap; m != nil {
|
|
|
|
}
|
|
|
|
state.NetworkMap = m
|
|
|
|
if m := n.NetMap; m != nil {
|
|
|
|
a.notify(state)
|
|
|
|
state.NetworkMap = m
|
|
|
|
if service != 0 {
|
|
|
|
a.notify(state)
|
|
|
|
alarm(a.notifyExpiry(service, m.Expiry))
|
|
|
|
if service != 0 {
|
|
|
|
}
|
|
|
|
alarm(a.notifyExpiry(service, m.Expiry))
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
prefs.mu.Lock()
|
|
|
|
|
|
|
|
prefs.prefs.Hostname = a.hostname()
|
|
|
|
|
|
|
|
p := prefs.prefs
|
|
|
|
|
|
|
|
prefs.mu.Unlock()
|
|
|
|
|
|
|
|
b.backend.SetPrefs(p)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
for {
|
|
|
|
|
|
|
|
select {
|
|
|
|
|
|
|
|
case <-alarmChan:
|
|
|
|
case <-alarmChan:
|
|
|
|
if m := state.NetworkMap; m != nil && service != 0 {
|
|
|
|
if m := state.NetworkMap; m != nil && service != 0 {
|
|
|
|
alarm(a.notifyExpiry(service, m.Expiry))
|
|
|
|
alarm(a.notifyExpiry(service, m.Expiry))
|
|
|
|