tailcfg: make Node.Hostinfo a HostinfoView

Signed-off-by: Maisem Ali <maisem@tailscale.com>
pull/3959/head
Maisem Ali 2 years ago committed by Maisem Ali
parent 53998e26a6
commit 72d8672ef7

@ -172,9 +172,15 @@ func gen(buf *bytes.Buffer, imports map[string]struct{}, typ *types.Named, thisP
if !codegen.ContainsPointers(ft) { if !codegen.ContainsPointers(ft) {
continue continue
} }
if named, _ := ft.(*types.Named); named != nil && !hasBasicUnderlying(ft) { if named, _ := ft.(*types.Named); named != nil {
writef("dst.%s = *src.%s.Clone()", fname, fname) if isViewType(ft) {
continue writef("dst.%s = src.%s", fname, fname)
continue
}
if !hasBasicUnderlying(ft) {
writef("dst.%s = *src.%s.Clone()", fname, fname)
continue
}
} }
switch ft := ft.Underlying().(type) { switch ft := ft.Underlying().(type) {
case *types.Slice: case *types.Slice:
@ -234,6 +240,17 @@ func gen(buf *bytes.Buffer, imports map[string]struct{}, typ *types.Named, thisP
buf.Write(codegen.AssertStructUnchanged(t, thisPkg, name, "Clone", imports)) buf.Write(codegen.AssertStructUnchanged(t, thisPkg, name, "Clone", imports))
} }
func isViewType(typ types.Type) bool {
t, ok := typ.Underlying().(*types.Struct)
if !ok {
return false
}
if t.NumFields() != 1 {
return false
}
return t.Field(0).Name() == "ж"
}
func hasBasicUnderlying(typ types.Type) bool { func hasBasicUnderlying(typ types.Type) bool {
switch typ.Underlying().(type) { switch typ.Underlying().(type) {
case *types.Slice, *types.Map: case *types.Slice, *types.Map:

@ -196,7 +196,7 @@ func root(w http.ResponseWriter, r *http.Request) {
LoginName: who.UserProfile.LoginName, LoginName: who.UserProfile.LoginName,
ProfilePicURL: who.UserProfile.ProfilePicURL, ProfilePicURL: who.UserProfile.ProfilePicURL,
MachineName: firstLabel(who.Node.ComputedName), MachineName: firstLabel(who.Node.ComputedName),
MachineOS: who.Node.Hostinfo.OS, MachineOS: who.Node.Hostinfo.OS(),
IP: tailscaleIP(who), IP: tailscaleIP(who),
} }
} }

@ -75,6 +75,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep
tailscale.com/types/persist from tailscale.com/ipn tailscale.com/types/persist from tailscale.com/ipn
tailscale.com/types/preftype from tailscale.com/cmd/tailscale/cli+ tailscale.com/types/preftype from tailscale.com/cmd/tailscale/cli+
tailscale.com/types/structs from tailscale.com/ipn+ tailscale.com/types/structs from tailscale.com/ipn+
tailscale.com/types/views from tailscale.com/tailcfg
tailscale.com/util/clientmetric from tailscale.com/net/netcheck+ tailscale.com/util/clientmetric from tailscale.com/net/netcheck+
tailscale.com/util/dnsname from tailscale.com/cmd/tailscale/cli+ tailscale.com/util/dnsname from tailscale.com/cmd/tailscale/cli+
W tailscale.com/util/endian from tailscale.com/net/netns W tailscale.com/util/endian from tailscale.com/net/netns

@ -240,6 +240,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
tailscale.com/types/persist from tailscale.com/control/controlclient+ tailscale.com/types/persist from tailscale.com/control/controlclient+
tailscale.com/types/preftype from tailscale.com/ipn+ tailscale.com/types/preftype from tailscale.com/ipn+
tailscale.com/types/structs from tailscale.com/control/controlclient+ tailscale.com/types/structs from tailscale.com/control/controlclient+
tailscale.com/types/views from tailscale.com/tailcfg
tailscale.com/util/clientmetric from tailscale.com/ipn/localapi+ tailscale.com/util/clientmetric from tailscale.com/ipn/localapi+
L tailscale.com/util/cmpver from tailscale.com/net/dns L tailscale.com/util/cmpver from tailscale.com/net/dns
💣 tailscale.com/util/deephash from tailscale.com/ipn/ipnlocal+ 💣 tailscale.com/util/deephash from tailscale.com/ipn/ipnlocal+

@ -138,7 +138,9 @@ func (ms *mapSession) netmapForResponse(resp *tailcfg.MapResponse) *netmap.Netwo
nm.Name = node.Name nm.Name = node.Name
nm.Addresses = filterSelfAddresses(node.Addresses) nm.Addresses = filterSelfAddresses(node.Addresses)
nm.User = node.User nm.User = node.User
nm.Hostinfo = node.Hostinfo if node.Hostinfo.Valid() {
nm.Hostinfo = *node.Hostinfo.AsStruct()
}
if node.MachineAuthorized { if node.MachineAuthorized {
nm.MachineStatus = tailcfg.MachineAuthorized nm.MachineStatus = tailcfg.MachineAuthorized
} else { } else {

@ -446,14 +446,14 @@ func (b *LocalBackend) populatePeerStatusLocked(sb *ipnstate.StatusBuilder) {
ID: p.StableID, ID: p.StableID,
UserID: p.User, UserID: p.User,
TailscaleIPs: tailscaleIPs, TailscaleIPs: tailscaleIPs,
HostName: p.Hostinfo.Hostname, HostName: p.Hostinfo.Hostname(),
DNSName: p.Name, DNSName: p.Name,
OS: p.Hostinfo.OS, OS: p.Hostinfo.OS(),
KeepAlive: p.KeepAlive, KeepAlive: p.KeepAlive,
Created: p.Created, Created: p.Created,
LastSeen: lastSeen, LastSeen: lastSeen,
Online: p.Online != nil && *p.Online, Online: p.Online != nil && *p.Online,
ShareeNode: p.Hostinfo.ShareeNode, ShareeNode: p.Hostinfo.ShareeNode(),
ExitNode: p.StableID != "" && p.StableID == b.prefs.ExitNodeID, ExitNode: p.StableID != "" && p.StableID == b.prefs.ExitNodeID,
ExitNodeOption: exitNodeOption, ExitNodeOption: exitNodeOption,
}) })
@ -2956,9 +2956,10 @@ func (b *LocalBackend) registerIncomingFile(inf *incomingFile, active bool) {
// It returns the empty string if the peer doesn't support the 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. // or there's no matching address family based on the netmap's own addresses.
func peerAPIBase(nm *netmap.NetworkMap, peer *tailcfg.Node) string { func peerAPIBase(nm *netmap.NetworkMap, peer *tailcfg.Node) string {
if nm == nil || peer == nil { if nm == nil || peer == nil || !peer.Hostinfo.Valid() {
return "" return ""
} }
var have4, have6 bool var have4, have6 bool
for _, a := range nm.Addresses { for _, a := range nm.Addresses {
if !a.IsSingleIP() { if !a.IsSingleIP() {
@ -2972,7 +2973,9 @@ func peerAPIBase(nm *netmap.NetworkMap, peer *tailcfg.Node) string {
} }
} }
var p4, p6 uint16 var p4, p6 uint16
for _, s := range peer.Hostinfo.Services { svcs := peer.Hostinfo.Services()
for i, n := 0, svcs.Len(); i < n; i++ {
s := svcs.At(i)
switch s.Proto { switch s.Proto {
case tailcfg.PeerAPI4: case tailcfg.PeerAPI4:
p4 = s.Port p4 = s.Port
@ -3178,7 +3181,9 @@ func exitNodeCanProxyDNS(nm *netmap.NetworkMap, exitNodeID tailcfg.StableNodeID)
if p.StableID != exitNodeID { if p.StableID != exitNodeID {
continue continue
} }
for _, s := range p.Hostinfo.Services { services := p.Hostinfo.Services()
for i, n := 0, services.Len(); i < n; i++ {
s := services.At(i)
if s.Proto == tailcfg.PeerAPIDNS && s.Port >= 1 { if s.Proto == tailcfg.PeerAPIDNS && s.Port >= 1 {
return peerAPIBase(nm, p) + "/dns-query", true return peerAPIBase(nm, p) + "/dns-query", true
} }

@ -346,12 +346,12 @@ func TestPeerAPIBase(t *testing.T) {
netaddr.MustParseIPPrefix("100.64.1.2/32"), netaddr.MustParseIPPrefix("100.64.1.2/32"),
netaddr.MustParseIPPrefix("fe70::2/128"), netaddr.MustParseIPPrefix("fe70::2/128"),
}, },
Hostinfo: tailcfg.Hostinfo{ Hostinfo: (&tailcfg.Hostinfo{
Services: []tailcfg.Service{ Services: []tailcfg.Service{
{Proto: "peerapi4", Port: 444}, {Proto: "peerapi4", Port: 444},
{Proto: "peerapi6", Port: 666}, {Proto: "peerapi6", Port: 666},
}, },
}, }).View(),
}, },
want: "http://100.64.1.2:444", want: "http://100.64.1.2:444",
}, },
@ -367,12 +367,12 @@ func TestPeerAPIBase(t *testing.T) {
netaddr.MustParseIPPrefix("100.64.1.2/32"), netaddr.MustParseIPPrefix("100.64.1.2/32"),
netaddr.MustParseIPPrefix("fe70::2/128"), netaddr.MustParseIPPrefix("fe70::2/128"),
}, },
Hostinfo: tailcfg.Hostinfo{ Hostinfo: (&tailcfg.Hostinfo{
Services: []tailcfg.Service{ Services: []tailcfg.Service{
{Proto: "peerapi4", Port: 444}, {Proto: "peerapi4", Port: 444},
{Proto: "peerapi6", Port: 666}, {Proto: "peerapi6", Port: 666},
}, },
}, }).View(),
}, },
want: "http://[fe70::2]:666", want: "http://[fe70::2]:666",
}, },
@ -389,11 +389,11 @@ func TestPeerAPIBase(t *testing.T) {
netaddr.MustParseIPPrefix("100.64.1.2/32"), netaddr.MustParseIPPrefix("100.64.1.2/32"),
netaddr.MustParseIPPrefix("fe70::2/128"), netaddr.MustParseIPPrefix("fe70::2/128"),
}, },
Hostinfo: tailcfg.Hostinfo{ Hostinfo: (&tailcfg.Hostinfo{
Services: []tailcfg.Service{ Services: []tailcfg.Service{
{Proto: "peerapi4", Port: 444}, {Proto: "peerapi4", Port: 444},
}, },
}, }).View(),
}, },
want: "http://100.64.1.2:444", want: "http://100.64.1.2:444",
}, },
@ -410,11 +410,11 @@ func TestPeerAPIBase(t *testing.T) {
netaddr.MustParseIPPrefix("100.64.1.2/32"), netaddr.MustParseIPPrefix("100.64.1.2/32"),
netaddr.MustParseIPPrefix("fe70::2/128"), netaddr.MustParseIPPrefix("fe70::2/128"),
}, },
Hostinfo: tailcfg.Hostinfo{ Hostinfo: (&tailcfg.Hostinfo{
Services: []tailcfg.Service{ Services: []tailcfg.Service{
{Proto: "peerapi6", Port: 666}, {Proto: "peerapi6", Port: 666},
}, },
}, }).View(),
}, },
want: "http://[fe70::2]:666", want: "http://[fe70::2]:666",
}, },

@ -157,7 +157,7 @@ type Node struct {
AllowedIPs []netaddr.IPPrefix // range of IP addresses to route to this node AllowedIPs []netaddr.IPPrefix // range of IP addresses to route to this node
Endpoints []string `json:",omitempty"` // IP+port (public via STUN, and local LANs) Endpoints []string `json:",omitempty"` // IP+port (public via STUN, and local LANs)
DERP string `json:",omitempty"` // DERP-in-IP:port ("127.3.3.40:N") endpoint DERP string `json:",omitempty"` // DERP-in-IP:port ("127.3.3.40:N") endpoint
Hostinfo Hostinfo Hostinfo HostinfoView
Created time.Time Created time.Time
// Tags are the list of ACL tags applied to this node. // Tags are the list of ACL tags applied to this node.
@ -256,7 +256,10 @@ func (n *Node) DisplayNames(forOwner bool) (name, hostIfDifferent string) {
// n.ComputedNameWithHost. // n.ComputedNameWithHost.
func (n *Node) InitDisplayNames(networkMagicDNSSuffix string) { func (n *Node) InitDisplayNames(networkMagicDNSSuffix string) {
name := dnsname.TrimSuffix(n.Name, networkMagicDNSSuffix) name := dnsname.TrimSuffix(n.Name, networkMagicDNSSuffix)
hostIfDifferent := dnsname.SanitizeHostname(n.Hostinfo.Hostname) var hostIfDifferent string
if n.Hostinfo.Valid() {
hostIfDifferent = dnsname.SanitizeHostname(n.Hostinfo.Hostname())
}
if strings.EqualFold(name, hostIfDifferent) { if strings.EqualFold(name, hostIfDifferent) {
hostIfDifferent = "" hostIfDifferent = ""
@ -456,7 +459,7 @@ type Hostinfo struct {
// require changes to Hostinfo.Equal. // require changes to Hostinfo.Equal.
} }
// View returns a read-only accessor for the Hostinfo object. // View returns a read-only accessor for hi.
func (hi *Hostinfo) View() HostinfoView { return HostinfoView{hi} } func (hi *Hostinfo) View() HostinfoView { return HostinfoView{hi} }
// HostinfoView is a read-only accessor for Hostinfo. // HostinfoView is a read-only accessor for Hostinfo.
@ -503,7 +506,7 @@ func (v HostinfoView) Hostname() string { return v.ж.Hostname }
func (v HostinfoView) ShieldsUp() bool { return v.ж.ShieldsUp } func (v HostinfoView) ShieldsUp() bool { return v.ж.ShieldsUp }
func (v HostinfoView) ShareeNode() bool { return v.ж.ShareeNode } func (v HostinfoView) ShareeNode() bool { return v.ж.ShareeNode }
func (v HostinfoView) GoArch() string { return v.ж.GoArch } func (v HostinfoView) GoArch() string { return v.ж.GoArch }
func (v HostinfoView) Equal(h2 HostinfoView) bool { return v.ж.Equal(h2.ж) } func (v HostinfoView) Equal(v2 HostinfoView) bool { return v.ж.Equal(v2.ж) }
func (v HostinfoView) RoutableIPs() views.IPPrefixSlice { func (v HostinfoView) RoutableIPs() views.IPPrefixSlice {
return views.IPPrefixSliceOf(v.ж.RoutableIPs) return views.IPPrefixSliceOf(v.ж.RoutableIPs)
@ -656,7 +659,7 @@ func (ni *NetInfo) portMapSummary() string {
return prefix + conciseOptBool(ni.UPnP, "U") + conciseOptBool(ni.PMP, "M") + conciseOptBool(ni.PCP, "C") return prefix + conciseOptBool(ni.UPnP, "U") + conciseOptBool(ni.PMP, "M") + conciseOptBool(ni.PCP, "C")
} }
// View returns a read-only accessor for the NetInfo object. // View returns a read-only accessor for ni.
func (ni *NetInfo) View() NetInfoView { return NetInfoView{ni} } func (ni *NetInfo) View() NetInfoView { return NetInfoView{ni} }
func conciseOptBool(b opt.Bool, trueVal string) string { func conciseOptBool(b opt.Bool, trueVal string) string {
@ -1390,7 +1393,7 @@ func (n *Node) Equal(n2 *Node) bool {
eqCIDRs(n.PrimaryRoutes, n2.PrimaryRoutes) && eqCIDRs(n.PrimaryRoutes, n2.PrimaryRoutes) &&
eqStrings(n.Endpoints, n2.Endpoints) && eqStrings(n.Endpoints, n2.Endpoints) &&
n.DERP == n2.DERP && n.DERP == n2.DERP &&
n.Hostinfo.Equal(&n2.Hostinfo) && n.Hostinfo.Equal(n2.Hostinfo) &&
n.Created.Equal(n2.Created) && n.Created.Equal(n2.Created) &&
eqTimePtr(n.LastSeen, n2.LastSeen) && eqTimePtr(n.LastSeen, n2.LastSeen) &&
n.MachineAuthorized == n2.MachineAuthorized && n.MachineAuthorized == n2.MachineAuthorized &&

@ -50,7 +50,7 @@ func (src *Node) Clone() *Node {
dst.Addresses = append(src.Addresses[:0:0], src.Addresses...) dst.Addresses = append(src.Addresses[:0:0], src.Addresses...)
dst.AllowedIPs = append(src.AllowedIPs[:0:0], src.AllowedIPs...) dst.AllowedIPs = append(src.AllowedIPs[:0:0], src.AllowedIPs...)
dst.Endpoints = append(src.Endpoints[:0:0], src.Endpoints...) dst.Endpoints = append(src.Endpoints[:0:0], src.Endpoints...)
dst.Hostinfo = *src.Hostinfo.Clone() dst.Hostinfo = src.Hostinfo
dst.Tags = append(src.Tags[:0:0], src.Tags...) dst.Tags = append(src.Tags[:0:0], src.Tags...)
dst.PrimaryRoutes = append(src.PrimaryRoutes[:0:0], src.PrimaryRoutes...) dst.PrimaryRoutes = append(src.PrimaryRoutes[:0:0], src.PrimaryRoutes...)
if dst.LastSeen != nil { if dst.LastSeen != nil {
@ -80,7 +80,7 @@ var _NodeCloneNeedsRegeneration = Node(struct {
AllowedIPs []netaddr.IPPrefix AllowedIPs []netaddr.IPPrefix
Endpoints []string Endpoints []string
DERP string DERP string
Hostinfo Hostinfo Hostinfo HostinfoView
Created time.Time Created time.Time
Tags []string Tags []string
PrimaryRoutes []netaddr.IPPrefix PrimaryRoutes []netaddr.IPPrefix

@ -400,13 +400,13 @@ func TestNodeEqual(t *testing.T) {
true, true,
}, },
{ {
&Node{Hostinfo: Hostinfo{Hostname: "alice"}}, &Node{Hostinfo: (&Hostinfo{Hostname: "alice"}).View()},
&Node{Hostinfo: Hostinfo{Hostname: "bob"}}, &Node{Hostinfo: (&Hostinfo{Hostname: "bob"}).View()},
false, false,
}, },
{ {
&Node{Hostinfo: Hostinfo{}}, &Node{Hostinfo: (&Hostinfo{}).View()},
&Node{Hostinfo: Hostinfo{}}, &Node{Hostinfo: (&Hostinfo{}).View()},
true, true,
}, },
{ {

@ -474,7 +474,7 @@ func (s *Server) serveRegister(w http.ResponseWriter, r *http.Request, mkey key.
MachineAuthorized: machineAuthorized, MachineAuthorized: machineAuthorized,
Addresses: allowedIPs, Addresses: allowedIPs,
AllowedIPs: allowedIPs, AllowedIPs: allowedIPs,
Hostinfo: *req.Hostinfo, Hostinfo: req.Hostinfo.View(),
} }
requireAuth := s.RequireAuth requireAuth := s.RequireAuth
if requireAuth && s.nodeKeyAuthed[nk] { if requireAuth && s.nodeKeyAuthed[nk] {
@ -611,10 +611,10 @@ func (s *Server) serveMap(w http.ResponseWriter, r *http.Request, mkey key.Machi
node.Endpoints = endpoints node.Endpoints = endpoints
node.DiscoKey = req.DiscoKey node.DiscoKey = req.DiscoKey
if req.Hostinfo != nil { if req.Hostinfo != nil {
node.Hostinfo = *req.Hostinfo.Clone() node.Hostinfo = req.Hostinfo.View()
if ni := node.Hostinfo.NetInfo; ni != nil { if ni := node.Hostinfo.NetInfo(); ni.Valid() {
if ni.PreferredDERP != 0 { if ni.PreferredDERP() != 0 {
node.DERP = fmt.Sprintf("127.3.3.40:%d", ni.PreferredDERP) node.DERP = fmt.Sprintf("127.3.3.40:%d", ni.PreferredDERP())
} }
} }
} }

@ -37,9 +37,10 @@ type NetworkMap struct {
MachineKey key.MachinePublic MachineKey key.MachinePublic
Peers []*tailcfg.Node // sorted by Node.ID Peers []*tailcfg.Node // sorted by Node.ID
DNS tailcfg.DNSConfig DNS tailcfg.DNSConfig
Hostinfo tailcfg.Hostinfo // TODO(maisem) : replace with View.
PacketFilter []filter.Match Hostinfo tailcfg.Hostinfo
SSHPolicy *tailcfg.SSHPolicy // or nil, if not enabled/allowed PacketFilter []filter.Match
SSHPolicy *tailcfg.SSHPolicy // or nil, if not enabled/allowed
// CollectServices reports whether this node's Tailnet has // CollectServices reports whether this node's Tailnet has
// requested that info about services be included in HostInfo. // requested that info about services be included in HostInfo.

@ -191,7 +191,7 @@ func peerDebugName(p *tailcfg.Node) string {
if i := strings.Index(n, "."); i != -1 { if i := strings.Index(n, "."); i != -1 {
return n[:i] return n[:i]
} }
return p.Hostinfo.Hostname return p.Hostinfo.Hostname()
} }
func ipPortLess(a, b netaddr.IPPort) bool { func ipPortLess(a, b netaddr.IPPort) bool {

@ -901,7 +901,7 @@ func (c *Conn) Ping(peer *tailcfg.Node, res *ipnstate.PingResult, cb func(*ipnst
} }
res.NodeName = peer.Name // prefer DNS name res.NodeName = peer.Name // prefer DNS name
if res.NodeName == "" { if res.NodeName == "" {
res.NodeName = peer.Hostinfo.Hostname // else hostname res.NodeName = peer.Hostinfo.Hostname() // else hostname
} else { } else {
if i := strings.Index(res.NodeName, "."); i != -1 { if i := strings.Index(res.NodeName, "."); i != -1 {
res.NodeName = res.NodeName[:i] res.NodeName = res.NodeName[:i]

@ -21,7 +21,7 @@ import (
func nodeDebugName(n *tailcfg.Node) string { func nodeDebugName(n *tailcfg.Node) string {
name := n.Name name := n.Name
if name == "" { if name == "" {
name = n.Hostinfo.Hostname name = n.Hostinfo.Hostname()
} }
if i := strings.Index(name, "."); i != -1 { if i := strings.Index(name, "."); i != -1 {
name = name[:i] name = name[:i]

Loading…
Cancel
Save