diff --git a/ipn/ipnlocal/local.go b/ipn/ipnlocal/local.go index 6449aed95..1e6625655 100644 --- a/ipn/ipnlocal/local.go +++ b/ipn/ipnlocal/local.go @@ -669,6 +669,16 @@ func (b *LocalBackend) populatePeerStatusLocked(sb *ipnstate.StatusBuilder) { SSH_HostKeys: p.Hostinfo.SSH_HostKeys().AsSlice(), } peerStatusFromNode(ps, p) + + p4, p6 := peerAPIPorts(p) + ip4 := nodeIP(p, netip.Addr.Is4) + ip6 := nodeIP(p, netip.Addr.Is6) + if p4 != 0 && ip4.IsValid() { + ps.PeerAPIURL = append(ps.PeerAPIURL, peerAPIURL(ip4, p4)) + } + if p6 != 0 && ip6.IsValid() { + ps.PeerAPIURL = append(ps.PeerAPIURL, peerAPIURL(ip6, p6)) + } sb.AddPeer(p.Key, ps) } } @@ -3660,6 +3670,27 @@ func (b *LocalBackend) registerIncomingFile(inf *incomingFile, active bool) { } } +func peerAPIPorts(peer *tailcfg.Node) (p4, p6 uint16) { + svcs := peer.Hostinfo.Services() + for i, n := 0, svcs.Len(); i < n; i++ { + s := svcs.At(i) + switch s.Proto { + case tailcfg.PeerAPI4: + p4 = s.Port + case tailcfg.PeerAPI6: + p6 = s.Port + } + } + return +} + +func peerAPIURL(ip netip.Addr, port uint16) string { + if port == 0 || !ip.IsValid() { + return "" + } + return fmt.Sprintf("http://%v", netip.AddrPortFrom(ip, port)) +} + // peerAPIBase returns the "http://ip:port" URL base to reach peer's peerAPI. // It returns the empty string if the peer doesn't support the peerapi // or there's no matching address family based on the netmap's own addresses. @@ -3680,28 +3711,14 @@ func peerAPIBase(nm *netmap.NetworkMap, peer *tailcfg.Node) string { have6 = true } } - var p4, p6 uint16 - svcs := peer.Hostinfo.Services() - for i, n := 0, svcs.Len(); i < n; i++ { - s := svcs.At(i) - switch s.Proto { - case tailcfg.PeerAPI4: - p4 = s.Port - case tailcfg.PeerAPI6: - p6 = s.Port - } - } - var ipp netip.AddrPort + p4, p6 := peerAPIPorts(peer) switch { case have4 && p4 != 0: - ipp = netip.AddrPortFrom(nodeIP(peer, netip.Addr.Is4), p4) + return peerAPIURL(nodeIP(peer, netip.Addr.Is4), p4) case have6 && p6 != 0: - ipp = netip.AddrPortFrom(nodeIP(peer, netip.Addr.Is6), p6) - } - if !ipp.Addr().IsValid() { - return "" + return peerAPIURL(nodeIP(peer, netip.Addr.Is6), p6) } - return fmt.Sprintf("http://%v", ipp) + return "" } func nodeIP(n *tailcfg.Node, pred func(netip.Addr) bool) netip.Addr {