ipn/ipnlocal: protect populatePeerStatusLocked from nil Hostinfo (#20150)
ipnlocal.LocalBackend.populatePeerStatusLocked assumed that Hostinfo was always valid, but that’s not always true, especially in tests. ipnlocal.peerAPIPorts suffered from a similar assumption. This patch checks for NodeView.Valid and Hostinfo.Valid; assuming the zero value as a safe default. Updates #8948 Updates #12542 Signed-off-by: Simon Law <sfllaw@tailscale.com>
This commit is contained in:
+13
-5
@@ -1611,6 +1611,7 @@ func (b *LocalBackend) populatePeerStatusLocked(sb *ipnstate.StatusBuilder) {
|
|||||||
sb.AddUser(id, up)
|
sb.AddUser(id, up)
|
||||||
}
|
}
|
||||||
exitNodeID := b.pm.CurrentPrefs().ExitNodeID()
|
exitNodeID := b.pm.CurrentPrefs().ExitNodeID()
|
||||||
|
blankHostinfo := new(tailcfg.Hostinfo).View()
|
||||||
for _, p := range cn.Peers() {
|
for _, p := range cn.Peers() {
|
||||||
tailscaleIPs := make([]netip.Addr, 0, p.Addresses().Len())
|
tailscaleIPs := make([]netip.Addr, 0, p.Addresses().Len())
|
||||||
for i := range p.Addresses().Len() {
|
for i := range p.Addresses().Len() {
|
||||||
@@ -1619,20 +1620,24 @@ func (b *LocalBackend) populatePeerStatusLocked(sb *ipnstate.StatusBuilder) {
|
|||||||
tailscaleIPs = append(tailscaleIPs, addr.Addr())
|
tailscaleIPs = append(tailscaleIPs, addr.Addr())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
hostinfo := p.Hostinfo()
|
||||||
|
if !hostinfo.Valid() {
|
||||||
|
hostinfo = blankHostinfo
|
||||||
|
}
|
||||||
ps := &ipnstate.PeerStatus{
|
ps := &ipnstate.PeerStatus{
|
||||||
InNetworkMap: true,
|
InNetworkMap: true,
|
||||||
UserID: p.User(),
|
UserID: p.User(),
|
||||||
AltSharerUserID: p.Sharer(),
|
AltSharerUserID: p.Sharer(),
|
||||||
TailscaleIPs: tailscaleIPs,
|
TailscaleIPs: tailscaleIPs,
|
||||||
HostName: p.Hostinfo().Hostname(),
|
HostName: hostinfo.Hostname(),
|
||||||
DNSName: p.Name(),
|
DNSName: p.Name(),
|
||||||
OS: p.Hostinfo().OS(),
|
OS: hostinfo.OS(),
|
||||||
LastSeen: p.LastSeen().Get(),
|
LastSeen: p.LastSeen().Get(),
|
||||||
Online: p.Online().Get(),
|
Online: p.Online().Get(),
|
||||||
ShareeNode: p.Hostinfo().ShareeNode(),
|
ShareeNode: hostinfo.ShareeNode(),
|
||||||
ExitNode: p.StableID() != "" && p.StableID() == exitNodeID,
|
ExitNode: p.StableID() != "" && p.StableID() == exitNodeID,
|
||||||
SSH_HostKeys: p.Hostinfo().SSH_HostKeys().AsSlice(),
|
SSH_HostKeys: hostinfo.SSH_HostKeys().AsSlice(),
|
||||||
Location: p.Hostinfo().Location().AsStruct(),
|
Location: hostinfo.Location().AsStruct(),
|
||||||
Capabilities: p.Capabilities().AsSlice(),
|
Capabilities: p.Capabilities().AsSlice(),
|
||||||
}
|
}
|
||||||
for _, f := range b.extHost.Hooks().SetPeerStatus {
|
for _, f := range b.extHost.Hooks().SetPeerStatus {
|
||||||
@@ -7654,6 +7659,9 @@ func (b *LocalBackend) SetDNS(ctx context.Context, name, value string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func peerAPIPorts(peer tailcfg.NodeView) (p4, p6 uint16) {
|
func peerAPIPorts(peer tailcfg.NodeView) (p4, p6 uint16) {
|
||||||
|
if !peer.Valid() || !peer.Hostinfo().Valid() {
|
||||||
|
return
|
||||||
|
}
|
||||||
svcs := peer.Hostinfo().Services()
|
svcs := peer.Hostinfo().Services()
|
||||||
for _, s := range svcs.All() {
|
for _, s := range svcs.All() {
|
||||||
switch s.Proto {
|
switch s.Proto {
|
||||||
|
|||||||
Reference in New Issue
Block a user