From 25797c8c2a5f202c4991e2d983d648b5eb68dd27 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Thu, 27 Feb 2020 12:20:29 -0800 Subject: [PATCH] all: rename deep "Copy" methods to conventional Go name "Clone" --- control/controlclient/direct.go | 2 +- ipn/fake.go | 2 +- ipn/handle.go | 8 +++---- ipn/local.go | 8 +++---- ipn/prefs.go | 5 +++-- ipn/prefs_test.go | 4 ++-- tailcfg/tailcfg.go | 40 ++++++++++++++++++++++----------- 7 files changed, 42 insertions(+), 27 deletions(-) diff --git a/control/controlclient/direct.go b/control/controlclient/direct.go index 98d1196fe..d7aa80ecf 100644 --- a/control/controlclient/direct.go +++ b/control/controlclient/direct.go @@ -174,7 +174,7 @@ func (c *Direct) SetHostinfo(hi *tailcfg.Hostinfo) { defer c.mu.Unlock() c.logf("Hostinfo: %v\n", hi) - c.hostinfo = hi.Copy() + c.hostinfo = hi.Clone() } func (c *Direct) GetPersist() Persist { diff --git a/ipn/fake.go b/ipn/fake.go index bb81385f6..c0191cb00 100644 --- a/ipn/fake.go +++ b/ipn/fake.go @@ -58,7 +58,7 @@ func (b *FakeBackend) SetPrefs(new *Prefs) { panic("FakeBackend.SetPrefs got nil prefs") } - b.notify(Notify{Prefs: new.Copy()}) + b.notify(Notify{Prefs: new.Clone()}) if new.WantRunning && !b.live { b.newState(Starting) b.newState(Running) diff --git a/ipn/handle.go b/ipn/handle.go index b9d39a69d..2d05ee91d 100644 --- a/ipn/handle.go +++ b/ipn/handle.go @@ -47,7 +47,7 @@ func (h *Handle) Start(opts Options) error { h.engineStatusCache = EngineStatus{} h.stateCache = NoState if opts.Prefs != nil { - h.prefsCache = opts.Prefs.Copy() + h.prefsCache = opts.Prefs.Clone() } xopts := opts xopts.Notify = h.notify @@ -69,7 +69,7 @@ func (h *Handle) notify(n Notify) { h.stateCache = *n.State } if n.Prefs != nil { - h.prefsCache = n.Prefs.Copy() + h.prefsCache = n.Prefs.Clone() } if n.NetMap != nil { h.netmapCache = n.NetMap @@ -89,14 +89,14 @@ func (h *Handle) Prefs() *Prefs { h.mu.Lock() defer h.mu.Unlock() - return h.prefsCache.Copy() + return h.prefsCache.Clone() } func (h *Handle) UpdatePrefs(updateFn func(p *Prefs)) { h.mu.Lock() defer h.mu.Unlock() - new := h.prefsCache.Copy() + new := h.prefsCache.Clone() updateFn(new) h.prefsCache = new h.b.SetPrefs(new) diff --git a/ipn/local.go b/ipn/local.go index b1c5cfcdd..5ec867388 100644 --- a/ipn/local.go +++ b/ipn/local.go @@ -212,7 +212,7 @@ func (b *LocalBackend) Start(opts Options) error { b.logf("Failed to save new controlclient state: %v", err) } } - b.send(Notify{Prefs: b.prefs.Copy()}) + b.send(Notify{Prefs: b.prefs.Clone()}) } if newSt.NetMap != nil { if b.netMapCache != nil && b.cmpDiff != nil { @@ -282,7 +282,7 @@ func (b *LocalBackend) Start(opts Options) error { blid := b.backendLogID b.logf("Backend: logs: be:%v fe:%v\n", blid, opts.FrontendLogID) b.send(Notify{BackendLogID: &blid}) - b.send(Notify{Prefs: b.prefs.Copy()}) + b.send(Notify{Prefs: b.prefs.Clone()}) cli.Login(nil, controlclient.LoginDefault) return nil @@ -383,7 +383,7 @@ func (b *LocalBackend) loadStateLocked(key StateKey, prefs *Prefs, legacyPath st if key == "" { // Frontend fully owns the state, we just need to obey it. b.logf("Using frontend prefs") - b.prefs = prefs.Copy() + b.prefs = prefs.Clone() b.stateKey = "" return nil } @@ -535,7 +535,7 @@ func (b *LocalBackend) SetPrefs(new *Prefs) { } } oldHi := b.hiCache - newHi := oldHi.Copy() + newHi := oldHi.Clone() newHi.RoutableIPs = append([]wgcfg.CIDR(nil), b.prefs.AdvertiseRoutes...) b.hiCache = newHi cli := b.c diff --git a/ipn/prefs.go b/ipn/prefs.go index 5da0685c0..3bd05384d 100644 --- a/ipn/prefs.go +++ b/ipn/prefs.go @@ -156,8 +156,9 @@ func PrefsFromBytes(b []byte, enforceDefaults bool) (*Prefs, error) { return p, err } -// Copy returns a deep copy of p. -func (p *Prefs) Copy() *Prefs { +// Clone returns a deep copy of p. +func (p *Prefs) Clone() *Prefs { + // TODO: write a faster/non-Fatal-y Clone implementation? p2, err := PrefsFromBytes(p.ToBytes(), false) if err != nil { log.Fatalf("Prefs was uncopyable: %v\n", err) diff --git a/ipn/prefs_test.go b/ipn/prefs_test.go index cc29a023a..4c4e88d4a 100644 --- a/ipn/prefs_test.go +++ b/ipn/prefs_test.go @@ -195,7 +195,7 @@ func checkPrefs(t *testing.T, p Prefs) { if !p.Equals(&p) { t.Fatalf("p != p\n") } - p2 = p.Copy() + p2 = p.Clone() p2.RouteAll = true if p.Equals(p2) { t.Fatalf("p == p2\n") @@ -213,7 +213,7 @@ func checkPrefs(t *testing.T, p Prefs) { if !p2.Equals(p2b) { t.Fatalf("p2 != p2b\n%#v\n%#v\n", p2, p2b) } - p2c = p2.Copy() + p2c = p2.Clone() if !p2b.Equals(p2c) { t.Fatalf("p2b != p2c\n") } diff --git a/tailcfg/tailcfg.go b/tailcfg/tailcfg.go index 06412fe7f..bd4bd0186 100644 --- a/tailcfg/tailcfg.go +++ b/tailcfg/tailcfg.go @@ -83,6 +83,20 @@ type User struct { Logins []LoginID Roles []RoleID Created time.Time + + // Note: be sure to update Clone when adding new fields +} + +// Clone returns a copy of u that aliases no memory with the original. +func (u *User) Clone() *User { + if u == nil { + return nil + } + u2 := new(User) + *u2 = *u + u2.Logins = append([]LoginID(nil), u.Logins...) + u2.Roles = append([]RoleID(nil), u.Roles...) + return u2 } type Login struct { @@ -122,12 +136,12 @@ type Node struct { MachineAuthorized bool // TODO(crawshaw): replace with MachineStatus // NOTE: any new fields containing pointers in this type - // require changes to Node.Copy. + // require changes to Node.Clone. } -// Copy makes a deep copy of Node. +// Clone makes a deep copy of Node. // The result aliases no memory with the original. -func (n *Node) Copy() (res *Node) { +func (n *Node) Clone() (res *Node) { res = new(Node) *res = *n @@ -138,7 +152,7 @@ func (n *Node) Copy() (res *Node) { lastSeen := *res.LastSeen res.LastSeen = &lastSeen } - res.Hostinfo = *res.Hostinfo.Copy() + res.Hostinfo = *res.Hostinfo.Clone() return res } @@ -206,7 +220,7 @@ type Service struct { // TODO(apenwarr): add "tags" here for each service? // NOTE: any new fields containing pointers in this type - // require changes to Hostinfo.Copy. + // require changes to Hostinfo.Clone. } // Hostinfo contains a summary of a Tailscale host. @@ -226,7 +240,7 @@ type Hostinfo struct { NetInfo *NetInfo `json:",omitempty"` // NOTE: any new fields containing pointers in this type - // require changes to Hostinfo.Copy and Hostinfo.Equal. + // require changes to Hostinfo.Clone and Hostinfo.Equal. } // NetInfo contains information about the host's network state. @@ -251,7 +265,7 @@ type NetInfo struct { DERPLatency map[string]float64 `json:",omitempty"` } -func (ni *NetInfo) Copy() (res *NetInfo) { +func (ni *NetInfo) Clone() (res *NetInfo) { if ni == nil { return nil } @@ -266,15 +280,15 @@ func (ni *NetInfo) Copy() (res *NetInfo) { return res } -// Copy makes a deep copy of Hostinfo. +// Clone makes a deep copy of Hostinfo. // The result aliases no memory with the original. -func (h *Hostinfo) Copy() (res *Hostinfo) { +func (h *Hostinfo) Clone() (res *Hostinfo) { res = new(Hostinfo) *res = *h res.RoutableIPs = append([]wgcfg.CIDR{}, h.RoutableIPs...) res.Services = append([]Service{}, h.Services...) - res.NetInfo = h.NetInfo.Copy() + res.NetInfo = h.NetInfo.Clone() return res } @@ -302,13 +316,13 @@ type RegisterRequest struct { Hostinfo *Hostinfo } -// Copy makes a deep copy of RegisterRequest. +// Clone makes a deep copy of RegisterRequest. // The result aliases no memory with the original. -func (req *RegisterRequest) Copy() *RegisterRequest { +func (req *RegisterRequest) Clone() *RegisterRequest { res := new(RegisterRequest) *res = *req if res.Hostinfo != nil { - res.Hostinfo = res.Hostinfo.Copy() + res.Hostinfo = res.Hostinfo.Clone() } if res.Auth.Oauth2Token != nil { tok := *res.Auth.Oauth2Token