mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-11 21:27:31 +00:00
health, controlclient, ipn, magicsock: tell health package state of things
Not yet checking anything. Just plumbing states into the health package. Updates #1505 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
100
health/health.go
100
health/health.go
@@ -8,12 +8,28 @@ package health
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"tailscale.com/tailcfg"
|
||||
)
|
||||
|
||||
var (
|
||||
mu sync.Mutex
|
||||
// mu guards everything in this var block.
|
||||
mu sync.Mutex
|
||||
|
||||
m = map[string]error{} // error key => err (or nil for no error)
|
||||
watchers = map[*watchHandle]func(string, error){} // opt func to run if error state changes
|
||||
|
||||
inMapPoll bool
|
||||
inMapPollSince time.Time
|
||||
lastMapPollEndedAt time.Time
|
||||
lastStreamedMapResponse time.Time
|
||||
derpHomeRegion int
|
||||
derpRegionConnected = map[int]bool{}
|
||||
derpRegionLastFrame = map[int]time.Time{}
|
||||
lastMapRequestHeard time.Time // time we got a 200 from control for a MapRequest
|
||||
ipnState string
|
||||
ipnWantRunning bool
|
||||
)
|
||||
|
||||
type watchHandle byte
|
||||
@@ -53,6 +69,7 @@ func set(key string, err error) {
|
||||
if !ok && err == nil {
|
||||
// Initial happy path.
|
||||
m[key] = nil
|
||||
selfCheckLocked()
|
||||
return
|
||||
}
|
||||
if ok && (old == nil) == (err == nil) {
|
||||
@@ -65,7 +82,88 @@ func set(key string, err error) {
|
||||
return
|
||||
}
|
||||
m[key] = err
|
||||
selfCheckLocked()
|
||||
for _, cb := range watchers {
|
||||
go cb(key, err)
|
||||
}
|
||||
}
|
||||
|
||||
// GotStreamedMapResponse notes that we got a tailcfg.MapResponse
|
||||
// message in streaming mode, even if it's just a keep-alive message.
|
||||
func GotStreamedMapResponse() {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
lastStreamedMapResponse = time.Now()
|
||||
selfCheckLocked()
|
||||
}
|
||||
|
||||
// SetInPollNetMap records that we're in
|
||||
func SetInPollNetMap(v bool) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
if v == inMapPoll {
|
||||
return
|
||||
}
|
||||
inMapPoll = v
|
||||
if v {
|
||||
inMapPollSince = time.Now()
|
||||
} else {
|
||||
lastMapPollEndedAt = time.Now()
|
||||
}
|
||||
}
|
||||
|
||||
// SetMagicSockDERPHome notes what magicsock's view of its home DERP is.
|
||||
func SetMagicSockDERPHome(region int) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
derpHomeRegion = region
|
||||
selfCheckLocked()
|
||||
}
|
||||
|
||||
// NoteMapRequestHeard notes whenever we successfully sent a map request
|
||||
// to control for which we received a 200 response.
|
||||
func NoteMapRequestHeard(mr *tailcfg.MapRequest) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
// TODO: extract mr.HostInfo.NetInfo.PreferredDERP, compare
|
||||
// against SetMagicSockDERPHome and
|
||||
// SetDERPRegionConnectedState
|
||||
|
||||
lastMapRequestHeard = time.Now()
|
||||
selfCheckLocked()
|
||||
}
|
||||
|
||||
func SetDERPRegionConnectedState(region int, connected bool) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
derpRegionConnected[region] = connected
|
||||
selfCheckLocked()
|
||||
}
|
||||
|
||||
func NoteDERPRegionReceivedFrame(region int) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
derpRegionLastFrame[region] = time.Now()
|
||||
selfCheckLocked()
|
||||
}
|
||||
|
||||
// state is an ipn.State.String() value: "Running", "Stopped", "NeedsLogin", etc.
|
||||
func SetIPNState(state string, wantRunning bool) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
ipnState = state
|
||||
ipnWantRunning = wantRunning
|
||||
selfCheckLocked()
|
||||
}
|
||||
|
||||
func selfCheckLocked() {
|
||||
// TODO: check states against each other.
|
||||
// For staticcheck for now:
|
||||
_ = inMapPollSince
|
||||
_ = lastMapPollEndedAt
|
||||
_ = lastStreamedMapResponse
|
||||
_ = derpHomeRegion
|
||||
_ = lastMapRequestHeard
|
||||
_ = ipnState
|
||||
_ = ipnWantRunning
|
||||
}
|
||||
|
Reference in New Issue
Block a user