2020-02-05 22:16:58 +00:00
|
|
|
// Copyright (c) 2020 Tailscale Inc & AUTHORS All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
package ipn
|
|
|
|
|
|
|
|
import (
|
|
|
|
"sync"
|
|
|
|
"time"
|
|
|
|
|
2020-12-24 20:33:55 +00:00
|
|
|
"inet.af/netaddr"
|
2021-03-19 17:21:33 +00:00
|
|
|
"tailscale.com/tailcfg"
|
2020-02-15 03:23:16 +00:00
|
|
|
"tailscale.com/types/logger"
|
2021-02-05 23:44:46 +00:00
|
|
|
"tailscale.com/types/netmap"
|
2020-02-05 22:16:58 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type Handle struct {
|
2021-04-07 05:11:50 +00:00
|
|
|
b Backend
|
|
|
|
logf logger.Logf
|
2020-02-05 22:16:58 +00:00
|
|
|
|
|
|
|
// Mutex protects everything below
|
|
|
|
mu sync.Mutex
|
2021-04-07 05:11:50 +00:00
|
|
|
xnotify func(Notify)
|
|
|
|
frontendLogID string
|
2021-02-05 23:44:46 +00:00
|
|
|
netmapCache *netmap.NetworkMap
|
2020-02-05 22:16:58 +00:00
|
|
|
engineStatusCache EngineStatus
|
|
|
|
stateCache State
|
2020-02-20 19:07:00 +00:00
|
|
|
prefsCache *Prefs
|
2020-02-05 22:16:58 +00:00
|
|
|
}
|
|
|
|
|
2021-04-07 05:11:50 +00:00
|
|
|
func NewHandle(b Backend, logf logger.Logf, notify func(Notify), opts Options) (*Handle, error) {
|
2020-02-05 22:16:58 +00:00
|
|
|
h := &Handle{
|
|
|
|
b: b,
|
|
|
|
logf: logf,
|
|
|
|
}
|
|
|
|
|
2021-04-07 05:11:50 +00:00
|
|
|
h.SetNotifyCallback(notify)
|
2020-02-05 22:16:58 +00:00
|
|
|
err := h.Start(opts)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return h, nil
|
|
|
|
}
|
|
|
|
|
2021-04-07 05:11:50 +00:00
|
|
|
func (h *Handle) SetNotifyCallback(notify func(Notify)) {
|
|
|
|
h.mu.Lock()
|
|
|
|
h.xnotify = notify
|
|
|
|
h.mu.Unlock()
|
|
|
|
|
|
|
|
h.b.SetNotifyCallback(h.notify)
|
|
|
|
}
|
|
|
|
|
2020-02-05 22:16:58 +00:00
|
|
|
func (h *Handle) Start(opts Options) error {
|
2021-04-07 05:11:50 +00:00
|
|
|
h.mu.Lock()
|
2020-02-05 22:16:58 +00:00
|
|
|
h.frontendLogID = opts.FrontendLogID
|
|
|
|
h.netmapCache = nil
|
|
|
|
h.engineStatusCache = EngineStatus{}
|
|
|
|
h.stateCache = NoState
|
2020-02-03 23:58:40 +00:00
|
|
|
if opts.Prefs != nil {
|
2020-02-27 20:20:29 +00:00
|
|
|
h.prefsCache = opts.Prefs.Clone()
|
2020-02-03 23:58:40 +00:00
|
|
|
}
|
2021-04-07 05:11:50 +00:00
|
|
|
h.mu.Unlock()
|
|
|
|
return h.b.Start(opts)
|
2020-02-05 22:16:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (h *Handle) Reset() {
|
|
|
|
st := NoState
|
|
|
|
h.notify(Notify{State: &st})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h *Handle) notify(n Notify) {
|
|
|
|
h.mu.Lock()
|
|
|
|
if n.BackendLogID != nil {
|
2020-04-11 15:35:34 +00:00
|
|
|
h.logf("Handle: logs: be:%v fe:%v",
|
2020-02-05 22:16:58 +00:00
|
|
|
*n.BackendLogID, h.frontendLogID)
|
|
|
|
}
|
|
|
|
if n.State != nil {
|
|
|
|
h.stateCache = *n.State
|
|
|
|
}
|
|
|
|
if n.Prefs != nil {
|
2020-02-27 20:20:29 +00:00
|
|
|
h.prefsCache = n.Prefs.Clone()
|
2020-02-05 22:16:58 +00:00
|
|
|
}
|
|
|
|
if n.NetMap != nil {
|
|
|
|
h.netmapCache = n.NetMap
|
|
|
|
}
|
|
|
|
if n.Engine != nil {
|
|
|
|
h.engineStatusCache = *n.Engine
|
|
|
|
}
|
|
|
|
h.mu.Unlock()
|
|
|
|
|
|
|
|
if h.xnotify != nil {
|
|
|
|
// Forward onward to our parent's notifier
|
|
|
|
h.xnotify(n)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-20 19:07:00 +00:00
|
|
|
func (h *Handle) Prefs() *Prefs {
|
2020-02-05 22:16:58 +00:00
|
|
|
h.mu.Lock()
|
|
|
|
defer h.mu.Unlock()
|
|
|
|
|
2020-02-27 20:20:29 +00:00
|
|
|
return h.prefsCache.Clone()
|
2020-02-05 22:16:58 +00:00
|
|
|
}
|
|
|
|
|
2020-02-20 19:07:00 +00:00
|
|
|
func (h *Handle) UpdatePrefs(updateFn func(p *Prefs)) {
|
2020-02-05 22:16:58 +00:00
|
|
|
h.mu.Lock()
|
|
|
|
defer h.mu.Unlock()
|
|
|
|
|
2020-02-27 20:20:29 +00:00
|
|
|
new := h.prefsCache.Clone()
|
2020-02-20 19:07:00 +00:00
|
|
|
updateFn(new)
|
2020-02-05 22:16:58 +00:00
|
|
|
h.prefsCache = new
|
|
|
|
h.b.SetPrefs(new)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h *Handle) State() State {
|
|
|
|
h.mu.Lock()
|
|
|
|
defer h.mu.Unlock()
|
|
|
|
|
|
|
|
return h.stateCache
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h *Handle) EngineStatus() EngineStatus {
|
|
|
|
h.mu.Lock()
|
|
|
|
defer h.mu.Unlock()
|
|
|
|
|
|
|
|
return h.engineStatusCache
|
|
|
|
}
|
|
|
|
|
2020-12-24 20:33:55 +00:00
|
|
|
func (h *Handle) LocalAddrs() []netaddr.IPPrefix {
|
2020-02-05 22:16:58 +00:00
|
|
|
h.mu.Lock()
|
|
|
|
defer h.mu.Unlock()
|
|
|
|
|
|
|
|
nm := h.netmapCache
|
|
|
|
if nm != nil {
|
|
|
|
return nm.Addresses
|
|
|
|
}
|
2020-12-24 20:33:55 +00:00
|
|
|
return []netaddr.IPPrefix{}
|
2020-02-05 22:16:58 +00:00
|
|
|
}
|
|
|
|
|
2021-02-05 23:44:46 +00:00
|
|
|
func (h *Handle) NetMap() *netmap.NetworkMap {
|
2020-02-05 22:16:58 +00:00
|
|
|
h.mu.Lock()
|
|
|
|
defer h.mu.Unlock()
|
|
|
|
|
|
|
|
return h.netmapCache
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h *Handle) Expiry() time.Time {
|
|
|
|
h.mu.Lock()
|
|
|
|
defer h.mu.Unlock()
|
|
|
|
|
|
|
|
nm := h.netmapCache
|
|
|
|
if nm != nil {
|
|
|
|
return nm.Expiry
|
|
|
|
}
|
|
|
|
return time.Time{}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h *Handle) AdminPageURL() string {
|
2021-07-12 04:46:50 +00:00
|
|
|
return h.prefsCache.AdminPageURL()
|
2020-02-05 22:16:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (h *Handle) StartLoginInteractive() {
|
|
|
|
h.b.StartLoginInteractive()
|
|
|
|
}
|
|
|
|
|
2021-03-19 17:21:33 +00:00
|
|
|
func (h *Handle) Login(token *tailcfg.Oauth2Token) {
|
2020-07-13 20:13:11 +00:00
|
|
|
h.b.Login(token)
|
|
|
|
}
|
|
|
|
|
2020-02-05 22:16:58 +00:00
|
|
|
func (h *Handle) Logout() {
|
|
|
|
h.b.Logout()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h *Handle) RequestEngineStatus() {
|
|
|
|
h.b.RequestEngineStatus()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h *Handle) FakeExpireAfter(x time.Duration) {
|
|
|
|
h.b.FakeExpireAfter(x)
|
|
|
|
}
|