diff --git a/control/controlclient/direct.go b/control/controlclient/direct.go index a5a9cff79..977de8c57 100644 --- a/control/controlclient/direct.go +++ b/control/controlclient/direct.go @@ -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, diff --git a/types/persist/persist.go b/types/persist/persist.go index 19df45dcb..60c9438e5 100644 --- a/types/persist/persist.go +++ b/types/persist/persist.go @@ -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.ж) }