Update
This commit is contained in:
1 parent
3530afb854
commit
6903fcff27
2146 files changed
+112256
-190703
No files matched your search
+76
-16
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
// Package health is a registry for other packages to report & check
|
||||
@@ -115,11 +115,11 @@ type Tracker struct {
|
||||
lastMapPollEndedAt time.Time
|
||||
lastStreamedMapResponse time.Time
|
||||
lastNoiseDial time.Time
|
||||
derpHomeRegion int
|
||||
derpHomeRegion tailcfg.DERPRegionID
|
||||
derpHomeless bool
|
||||
derpRegionConnected map[int]bool
|
||||
derpRegionHealthProblem map[int]string
|
||||
derpRegionLastFrame map[int]time.Time
|
||||
derpRegionConnected map[tailcfg.DERPRegionID]bool
|
||||
derpRegionHealthProblem map[tailcfg.DERPRegionID]string
|
||||
derpRegionLastFrame map[tailcfg.DERPRegionID]time.Time
|
||||
derpMap *tailcfg.DERPMap // last DERP map from control, could be nil if never received one
|
||||
lastMapRequestHeard time.Time // time we got a 200 from control for a MapRequest
|
||||
ipnState string
|
||||
@@ -132,6 +132,11 @@ type Tracker struct {
|
||||
localLogConfigErr error
|
||||
tlsConnectionErrors map[string]error // map[ServerName]error
|
||||
metricHealthMessage any // nil or *metrics.MultiLabelMap[metricHealthMessageLabel]
|
||||
|
||||
// IP forwarding check
|
||||
// If non-nil, called periodically to check if IP forwarding is broken.
|
||||
// Should return true if broken, false if healthy.
|
||||
isIPForwardingBroken func() bool
|
||||
}
|
||||
|
||||
// NewTracker contructs a new [Tracker] and attaches the given eventbus.
|
||||
@@ -348,6 +353,15 @@ func (t *Tracker) nil() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// ProbeLocks acquires and releases the tracker's internal mutex.
|
||||
func (t *Tracker) ProbeLocks() {
|
||||
if t.nil() {
|
||||
return
|
||||
}
|
||||
t.mu.Lock()
|
||||
t.mu.Unlock()
|
||||
}
|
||||
|
||||
// Severity represents how serious an error is. Each GUI interprets this severity value in different ways,
|
||||
// to surface the error in a more or less visible way. For instance, the macOS GUI could change its menubar
|
||||
// icon to display an exclamation mark and present a modal notification for SeverityHigh warnings, but not
|
||||
@@ -487,7 +501,12 @@ func (t *Tracker) SetHealthy(w *Warnable) {
|
||||
}
|
||||
|
||||
func (t *Tracker) setHealthyLocked(w *Warnable) {
|
||||
if !buildfeatures.HasHealth || t.warnableVal[w] == nil {
|
||||
if !buildfeatures.HasHealth {
|
||||
return
|
||||
}
|
||||
|
||||
ws := t.warnableVal[w]
|
||||
if ws == nil {
|
||||
// Nothing to remove
|
||||
return
|
||||
}
|
||||
@@ -496,15 +515,28 @@ func (t *Tracker) setHealthyLocked(w *Warnable) {
|
||||
|
||||
// Stop any pending visiblity timers for this Warnable
|
||||
if canc, ok := t.pendingVisibleTimers[w]; ok {
|
||||
// We removed the warningState for this Warnable,
|
||||
// and we hold the lock, so even if the timer callback
|
||||
// has already started, it won't find a warningState
|
||||
// for this Warnable and won't publish any changes.
|
||||
canc.Stop()
|
||||
delete(t.pendingVisibleTimers, w)
|
||||
}
|
||||
|
||||
change := Change{
|
||||
WarnableChanged: true,
|
||||
Warnable: w,
|
||||
// Only publish a change if the Warnable was unhealthy long
|
||||
// enough to become visible to the user. Otherwise, it would
|
||||
// not have been published as unhealthy, so there is no need
|
||||
// to publish it as healthy. This prevents eventbus (and by
|
||||
// extension the IPN bus) churn for Warnables that are marked
|
||||
// unhealthy and then healthy again. Notably, this includes
|
||||
// warnables touched by [Tracker.updateBuiltinWarnablesLocked].
|
||||
if w.IsVisible(ws, t.now) {
|
||||
change := Change{
|
||||
WarnableChanged: true,
|
||||
Warnable: w,
|
||||
}
|
||||
t.changePub.Publish(change)
|
||||
}
|
||||
t.changePub.Publish(change)
|
||||
}
|
||||
|
||||
// notifyWatchersControlChangedLocked calls each watcher to signal that control
|
||||
@@ -750,7 +782,7 @@ func (t *Tracker) GetInPollNetMap() bool {
|
||||
//
|
||||
// The homeless parameter is whether magicsock is running in DERP-disconnected
|
||||
// mode, without discovering and maintaining a connection to its home DERP.
|
||||
func (t *Tracker) SetMagicSockDERPHome(region int, homeless bool) {
|
||||
func (t *Tracker) SetMagicSockDERPHome(region tailcfg.DERPRegionID, homeless bool) {
|
||||
if t.nil() {
|
||||
return
|
||||
}
|
||||
@@ -777,7 +809,7 @@ func (t *Tracker) NoteMapRequestHeard(mr *tailcfg.MapRequest) {
|
||||
t.selfCheckLocked()
|
||||
}
|
||||
|
||||
func (t *Tracker) SetDERPRegionConnectedState(region int, connected bool) {
|
||||
func (t *Tracker) SetDERPRegionConnectedState(region tailcfg.DERPRegionID, connected bool) {
|
||||
if t.nil() {
|
||||
return
|
||||
}
|
||||
@@ -789,7 +821,7 @@ func (t *Tracker) SetDERPRegionConnectedState(region int, connected bool) {
|
||||
|
||||
// SetDERPRegionHealth sets or clears any problem associated with the
|
||||
// provided DERP region.
|
||||
func (t *Tracker) SetDERPRegionHealth(region int, problem string) {
|
||||
func (t *Tracker) SetDERPRegionHealth(region tailcfg.DERPRegionID, problem string) {
|
||||
if t.nil() {
|
||||
return
|
||||
}
|
||||
@@ -805,7 +837,7 @@ func (t *Tracker) SetDERPRegionHealth(region int, problem string) {
|
||||
|
||||
// NoteDERPRegionReceivedFrame is called to note that a frame was received from
|
||||
// the given DERP region at the current time.
|
||||
func (t *Tracker) NoteDERPRegionReceivedFrame(region int) {
|
||||
func (t *Tracker) NoteDERPRegionReceivedFrame(region tailcfg.DERPRegionID) {
|
||||
if t.nil() {
|
||||
return
|
||||
}
|
||||
@@ -818,7 +850,7 @@ func (t *Tracker) NoteDERPRegionReceivedFrame(region int) {
|
||||
// GetDERPRegionReceivedTime returns the last time that a frame was received
|
||||
// from the given DERP region, or the zero time if no communication with that
|
||||
// region has occurred.
|
||||
func (t *Tracker) GetDERPRegionReceivedTime(region int) time.Time {
|
||||
func (t *Tracker) GetDERPRegionReceivedTime(region tailcfg.DERPRegionID) time.Time {
|
||||
if t.nil() {
|
||||
return time.Time{}
|
||||
}
|
||||
@@ -841,7 +873,7 @@ func (t *Tracker) SetDERPMap(dm *tailcfg.DERPMap) {
|
||||
|
||||
// derpRegionNameLocked returns the name of the DERP region with the given ID
|
||||
// or the empty string if unknown.
|
||||
func (t *Tracker) derpRegionNameLocked(regID int) string {
|
||||
func (t *Tracker) derpRegionNameLocked(regID tailcfg.DERPRegionID) string {
|
||||
if t.derpMap == nil {
|
||||
return ""
|
||||
}
|
||||
@@ -1097,6 +1129,8 @@ func (t *Tracker) updateBuiltinWarnablesLocked() {
|
||||
t.setHealthyLocked(NetworkStatusWarnable)
|
||||
}
|
||||
|
||||
t.updateIPForwardingWarnableLocked()
|
||||
|
||||
if t.localLogConfigErr != nil {
|
||||
t.setUnhealthyLocked(localLogWarnable, Args{
|
||||
ArgError: t.localLogConfigErr.Error(),
|
||||
@@ -1389,3 +1423,29 @@ func (t *Tracker) LastNoiseDialWasRecent() bool {
|
||||
t.lastNoiseDial = now
|
||||
return dur < 2*time.Minute
|
||||
}
|
||||
|
||||
// SetIPForwardingCheck sets the function to check if IP forwarding is broken.
|
||||
// The function should return true if IP forwarding is broken, false if healthy.
|
||||
// Pass nil to disable IP forwarding checks.
|
||||
func (t *Tracker) SetIPForwardingCheck(checkFunc func() bool) {
|
||||
if t.nil() {
|
||||
return
|
||||
}
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
|
||||
t.isIPForwardingBroken = checkFunc
|
||||
|
||||
// Run an immediate check to set initial state
|
||||
t.updateIPForwardingWarnableLocked()
|
||||
}
|
||||
|
||||
// updateIPForwardingWarnableLocked checks the IP forwarding state and
|
||||
// sets or clears the ipForwardingWarnable accordingly.
|
||||
func (t *Tracker) updateIPForwardingWarnableLocked() {
|
||||
if t.isIPForwardingBroken != nil && t.isIPForwardingBroken() {
|
||||
t.setUnhealthyLocked(ipForwardingWarnable, Args{})
|
||||
} else {
|
||||
t.setHealthyLocked(ipForwardingWarnable)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user