Skip to content

Commit

Permalink
control/controlclient: fix panic regression from earlier load balance…
Browse files Browse the repository at this point in the history
…r hint header

In the recent 20e9f33 we made HealthChangeRequest machine requests
include a NodeKey, as it was the oddball machine request that didn't
include one. Unfortunately, that code was sometimes being called (at
least in some of our integration tests) without a node key due to its
registration with health.RegisterWatcher(direct.ReportHealthChange).

Fortunately tests in corp caught this before we cut a release. It's
possible this only affects this particular integration test's
environment, but still worth fixing.

Updates tailscale/corp#1297

Change-Id: I84046779955105763dc1be5121c69fec3c138672
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
  • Loading branch information
bradfitz authored and maisem committed Mar 21, 2024
1 parent 85febda commit 8444937
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 1 deletion.
5 changes: 4 additions & 1 deletion control/controlclient/direct.go
Original file line number Diff line number Diff line change
Expand Up @@ -1709,7 +1709,10 @@ func (c *Direct) ReportHealthChange(sys health.Subsystem, sysErr error) {
// Don't report errors to control if the server doesn't support noise.
return
}
nodeKey := c.GetPersist().PublicNodeKey()
nodeKey, ok := c.GetPersist().PublicNodeKeyOK()
if !ok {
return
}
req := &tailcfg.HealthChangeRequest{
Subsys: string(sys),
NodeKey: nodeKey,
Expand Down
21 changes: 21 additions & 0 deletions types/persist/persist.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,32 @@ func (p *Persist) PublicNodeKey() key.NodePublic {
return p.PrivateNodeKey.Public()
}

// PublicNodeKeyOK returns the public key for the node key.
//
// Unlike PublicNodeKey, it returns ok=false if there is no node private key
// instead of panicking.
func (p *Persist) PublicNodeKeyOK() (pub key.NodePublic, ok bool) {
if p.PrivateNodeKey.IsZero() {
return
}
return p.PrivateNodeKey.Public(), true
}

// PublicNodeKey returns the public key for the node key.
//
// It panics if there is no node private key. See PublicNodeKeyOK.
func (p PersistView) PublicNodeKey() key.NodePublic {
return p.ж.PublicNodeKey()
}

// PublicNodeKeyOK returns the public key for the node key.
//
// Unlike PublicNodeKey, it returns ok=false if there is no node private key
// instead of panicking.
func (p PersistView) PublicNodeKeyOK() (_ key.NodePublic, ok bool) {
return p.ж.PublicNodeKeyOK()
}

func (p PersistView) Equals(p2 PersistView) bool {
return p.ж.Equals(p2.ж)
}
Expand Down

0 comments on commit 8444937

Please sign in to comment.