ipn/ipnstate: add PeerStatus.TailscaleIPs slice, deprecate TailAddr

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
pull/1706/head
Brad Fitzpatrick 2021-04-14 07:20:27 -07:00
parent c2ca2ac8c4
commit 762180595d
5 changed files with 63 additions and 31 deletions

View File

@ -154,7 +154,10 @@ func tailscaleIPFromArg(ctx context.Context, hostOrIP string) (ip string, err er
} }
for _, ps := range st.Peer { for _, ps := range st.Peer {
if hostOrIP == dnsOrQuoteHostname(st, ps) || hostOrIP == ps.DNSName { if hostOrIP == dnsOrQuoteHostname(st, ps) || hostOrIP == ps.DNSName {
return ps.TailAddr, nil if len(ps.TailscaleIPs) == 0 {
return "", errors.New("node found but lacks an IP")
}
return ps.TailscaleIPs[0].String(), nil
} }
} }

View File

@ -18,6 +18,7 @@ import (
"github.com/peterbourgon/ff/v2/ffcli" "github.com/peterbourgon/ff/v2/ffcli"
"github.com/toqueteos/webbrowser" "github.com/toqueteos/webbrowser"
"inet.af/netaddr"
"tailscale.com/client/tailscale" "tailscale.com/client/tailscale"
"tailscale.com/ipn" "tailscale.com/ipn"
"tailscale.com/ipn/ipnstate" "tailscale.com/ipn/ipnstate"
@ -131,7 +132,7 @@ func runStatus(ctx context.Context, args []string) error {
printPS := func(ps *ipnstate.PeerStatus) { printPS := func(ps *ipnstate.PeerStatus) {
active := peerActive(ps) active := peerActive(ps)
f("%-15s %-20s %-12s %-7s ", f("%-15s %-20s %-12s %-7s ",
ps.TailAddr, firstIPString(ps.TailscaleIPs),
dnsOrQuoteHostname(st, ps), dnsOrQuoteHostname(st, ps),
ownerLogin(st, ps), ownerLogin(st, ps),
ps.OS, ps.OS,
@ -216,3 +217,10 @@ func ownerLogin(st *ipnstate.Status, ps *ipnstate.PeerStatus) string {
} }
return u.LoginName return u.LoginName
} }
func firstIPString(v []netaddr.IP) string {
if len(v) == 0 {
return ""
}
return v[0].String()
}

View File

@ -339,20 +339,24 @@ func (b *LocalBackend) populatePeerStatusLocked(sb *ipnstate.StatusBuilder) {
if p.LastSeen != nil { if p.LastSeen != nil {
lastSeen = *p.LastSeen lastSeen = *p.LastSeen
} }
var tailAddr string var tailAddr4 string
var tailscaleIPs = make([]netaddr.IP, 0, len(p.Addresses))
for _, addr := range p.Addresses { for _, addr := range p.Addresses {
// The peer struct currently only allows a single if addr.IsSingleIP() && tsaddr.IsTailscaleIP(addr.IP) {
// Tailscale IP address. For compatibility with the if addr.IP.Is4() && tailAddr4 == "" {
// old display, make sure it's the IPv4 address. // The peer struct previously only allowed a single
if addr.IP.Is4() && addr.IsSingleIP() && tsaddr.IsTailscaleIP(addr.IP) { // Tailscale IP address. For compatibility for a few releases starting
tailAddr = addr.IP.String() // with 1.8, keep it pulled out as IPv4-only for a bit.
break tailAddr4 = addr.IP.String()
}
tailscaleIPs = append(tailscaleIPs, addr.IP)
} }
} }
sb.AddPeer(key.Public(p.Key), &ipnstate.PeerStatus{ sb.AddPeer(key.Public(p.Key), &ipnstate.PeerStatus{
InNetworkMap: true, InNetworkMap: true,
UserID: p.User, UserID: p.User,
TailAddr: tailAddr, TailAddrDeprecated: tailAddr4,
TailscaleIPs: tailscaleIPs,
HostName: p.Hostinfo.Hostname, HostName: p.Hostinfo.Hostname,
DNSName: p.Name, DNSName: p.Name,
OS: p.Hostinfo.OS, OS: p.Hostinfo.OS,

View File

@ -71,7 +71,8 @@ type PeerStatus struct {
OS string // HostInfo.OS OS string // HostInfo.OS
UserID tailcfg.UserID UserID tailcfg.UserID
TailAddr string // Tailscale IP TailAddrDeprecated string `json:"TailAddr"` // Tailscale IP
TailscaleIPs []netaddr.IP // Tailscale IP(s) assigned to this node
// Endpoints: // Endpoints:
Addrs []string Addrs []string
@ -213,8 +214,11 @@ func (sb *StatusBuilder) AddPeer(peer key.Public, st *PeerStatus) {
if v := st.UserID; v != 0 { if v := st.UserID; v != 0 {
e.UserID = v e.UserID = v
} }
if v := st.TailAddr; v != "" { if v := st.TailAddrDeprecated; v != "" {
e.TailAddr = v e.TailAddrDeprecated = v
}
if v := st.TailscaleIPs; v != nil {
e.TailscaleIPs = v
} }
if v := st.OS; v != "" { if v := st.OS; v != "" {
e.OS = st.OS e.OS = st.OS
@ -343,13 +347,17 @@ table tbody tr:nth-child(even) td { background-color: #f5f5f5; }
hostNameHTML = "<br>" + html.EscapeString(hostName) hostNameHTML = "<br>" + html.EscapeString(hostName)
} }
var tailAddr string
if len(ps.TailscaleIPs) > 0 {
tailAddr = ps.TailscaleIPs[0].String()
}
f("<tr><td>%s</td><td class=acenter>%s</td>"+ f("<tr><td>%s</td><td class=acenter>%s</td>"+
"<td><b>%s</b>%s<div class=\"tailaddr\">%s</div></td><td class=\"acenter owner\">%s</td><td class=\"aright\">%v</td><td class=\"aright\">%v</td><td class=\"aright\">%v</td>", "<td><b>%s</b>%s<div class=\"tailaddr\">%s</div></td><td class=\"acenter owner\">%s</td><td class=\"aright\">%v</td><td class=\"aright\">%v</td><td class=\"aright\">%v</td>",
ps.PublicKey.ShortString(), ps.PublicKey.ShortString(),
osEmoji(ps.OS), osEmoji(ps.OS),
html.EscapeString(dnsName), html.EscapeString(dnsName),
hostNameHTML, hostNameHTML,
ps.TailAddr, tailAddr,
html.EscapeString(owner), html.EscapeString(owner),
ps.RxBytes, ps.RxBytes,
ps.TxBytes, ps.TxBytes,
@ -437,5 +445,9 @@ func sortKey(ps *PeerStatus) string {
if ps.HostName != "" { if ps.HostName != "" {
return ps.HostName return ps.HostName
} }
return ps.TailAddr // TODO(bradfitz): add PeerStatus.Less and avoid these allocs in a Less func.
if len(ps.TailscaleIPs) > 0 {
return ps.TailscaleIPs[0].String()
}
return string(ps.PublicKey[:])
} }

View File

@ -2953,19 +2953,23 @@ func (c *Conn) UpdateStatus(sb *ipnstate.StatusBuilder) {
c.mu.Lock() c.mu.Lock()
defer c.mu.Unlock() defer c.mu.Unlock()
var tailAddr string var tailAddr4 string
var tailscaleIPs []netaddr.IP
if c.netMap != nil { if c.netMap != nil {
tailscaleIPs = make([]netaddr.IP, 0, len(c.netMap.Addresses))
for _, addr := range c.netMap.Addresses { for _, addr := range c.netMap.Addresses {
if !addr.IsSingleIP() { if !addr.IsSingleIP() {
continue continue
} }
sb.AddTailscaleIP(addr.IP) sb.AddTailscaleIP(addr.IP)
// TailAddr only allows for a single Tailscale IP. For // TailAddr previously only allowed for a
// readability of `tailscale status`, make it the IPv4 // single Tailscale IP. For compatibility for
// address. // a couple releases starting with 1.8, keep
// that field pulled out separately.
if addr.IP.Is4() { if addr.IP.Is4() {
tailAddr = addr.IP.String() tailAddr4 = addr.IP.String()
} }
tailscaleIPs = append(tailscaleIPs, addr.IP)
} }
} }
@ -2989,7 +2993,8 @@ func (c *Conn) UpdateStatus(sb *ipnstate.StatusBuilder) {
ss.Relay = derpRegion.RegionCode ss.Relay = derpRegion.RegionCode
} }
} }
ss.TailAddr = tailAddr ss.TailscaleIPs = tailscaleIPs
ss.TailAddrDeprecated = tailAddr4
}) })
for dk, n := range c.nodeOfDisco { for dk, n := range c.nodeOfDisco {