control/controlclient: bound ReportHealthChange context lifetime to Direct client's

Fixes #13651

Change-Id: I8154d3cc0ca40fe7a0223b26ae2e77e8d6ba874b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick 2024-10-02 08:16:43 -07:00 committed by Brad Fitzpatrick
parent ed1ac799c8
commit 30f0fa95d9

View File

@ -82,6 +82,8 @@ type Direct struct {
onControlTime func(time.Time) // or nil onControlTime func(time.Time) // or nil
onTailnetDefaultAutoUpdate func(bool) // or nil onTailnetDefaultAutoUpdate func(bool) // or nil
panicOnUse bool // if true, panic if client is used (for testing) panicOnUse bool // if true, panic if client is used (for testing)
closedCtx context.Context // alive until Direct.Close is called
closeCtx context.CancelFunc // cancels closedCtx
dialPlan ControlDialPlanner // can be nil dialPlan ControlDialPlanner // can be nil
@ -303,6 +305,8 @@ func NewDirect(opts Options) (*Direct, error) {
dnsCache: dnsCache, dnsCache: dnsCache,
dialPlan: opts.DialPlan, dialPlan: opts.DialPlan,
} }
c.closedCtx, c.closeCtx = context.WithCancel(context.Background())
if opts.Hostinfo == nil { if opts.Hostinfo == nil {
c.SetHostinfo(hostinfo.New()) c.SetHostinfo(hostinfo.New())
} else { } else {
@ -325,6 +329,8 @@ func NewDirect(opts Options) (*Direct, error) {
// Close closes the underlying Noise connection(s). // Close closes the underlying Noise connection(s).
func (c *Direct) Close() error { func (c *Direct) Close() error {
c.closeCtx()
c.mu.Lock() c.mu.Lock()
defer c.mu.Unlock() defer c.mu.Unlock()
if c.noiseClient != nil { if c.noiseClient != nil {
@ -1628,7 +1634,7 @@ func (c *Direct) ReportHealthChange(w *health.Warnable, us *health.UnhealthyStat
} }
// Best effort, no logging: // Best effort, no logging:
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) ctx, cancel := context.WithTimeout(c.closedCtx, 5*time.Second)
defer cancel() defer cancel()
res, err := np.post(ctx, "/machine/update-health", nodeKey, req) res, err := np.post(ctx, "/machine/update-health", nodeKey, req)
if err != nil { if err != nil {