diff --git a/cmd/cloner/cloner.go b/cmd/cloner/cloner.go index c5be5279e..6784f9dc4 100644 --- a/cmd/cloner/cloner.go +++ b/cmd/cloner/cloner.go @@ -246,7 +246,9 @@ func gen(buf *bytes.Buffer, imports map[string]struct{}, name string, typ *types writef("\t\tdst.%s[k] = append([]%s{}, src.%s[k]...)", fname, n, fname) writef("\t}") } else if containsPointers(ft.Elem()) { - writef("\t\t" + `panic("TODO map value pointers")`) + writef("\tfor k, v := range src.%s {", fname) + writef("\t\tdst.%s[k] = v.Clone()", fname) + writef("\t}") } else { writef("\tfor k, v := range src.%s {", fname) writef("\t\tdst.%s[k] = v", fname) diff --git a/tailcfg/tailcfg.go b/tailcfg/tailcfg.go index 1da0f643b..f4175cb59 100644 --- a/tailcfg/tailcfg.go +++ b/tailcfg/tailcfg.go @@ -4,7 +4,7 @@ package tailcfg -//go:generate go run tailscale.com/cmd/cloner --type=User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse --clonefunc=true --output=tailcfg_clone.go +//go:generate go run tailscale.com/cmd/cloner --type=User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode --clonefunc=true --output=tailcfg_clone.go import ( "encoding/hex" diff --git a/tailcfg/tailcfg_clone.go b/tailcfg/tailcfg_clone.go index 706ac2981..c4701eaf2 100644 --- a/tailcfg/tailcfg_clone.go +++ b/tailcfg/tailcfg_clone.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Code generated by tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse; DO NOT EDIT. +// Code generated by tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode; DO NOT EDIT. package tailcfg @@ -26,7 +26,7 @@ func (src *User) Clone() *User { } // A compilation failure here means this code must be regenerated, with command: -// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse +// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode var _UserNeedsRegeneration = User(struct { ID UserID LoginName string @@ -62,7 +62,7 @@ func (src *Node) Clone() *Node { } // A compilation failure here means this code must be regenerated, with command: -// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse +// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode var _NodeNeedsRegeneration = Node(struct { ID NodeID StableID StableNodeID @@ -105,7 +105,7 @@ func (src *Hostinfo) Clone() *Hostinfo { } // A compilation failure here means this code must be regenerated, with command: -// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse +// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode var _HostinfoNeedsRegeneration = Hostinfo(struct { IPNVersion string FrontendLogID string @@ -142,7 +142,7 @@ func (src *NetInfo) Clone() *NetInfo { } // A compilation failure here means this code must be regenerated, with command: -// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse +// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode var _NetInfoNeedsRegeneration = NetInfo(struct { MappingVariesByDestIP opt.Bool HairPinning opt.Bool @@ -169,7 +169,7 @@ func (src *Login) Clone() *Login { } // A compilation failure here means this code must be regenerated, with command: -// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse +// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode var _LoginNeedsRegeneration = Login(struct { _ structs.Incomparable ID LoginID @@ -210,7 +210,7 @@ func (src *DNSConfig) Clone() *DNSConfig { } // A compilation failure here means this code must be regenerated, with command: -// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse +// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode var _DNSConfigNeedsRegeneration = DNSConfig(struct { Resolvers []DNSResolver Routes map[string][]DNSResolver @@ -236,7 +236,7 @@ func (src *DNSResolver) Clone() *DNSResolver { } // A compilation failure here means this code must be regenerated, with command: -// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse +// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode var _DNSResolverNeedsRegeneration = DNSResolver(struct { Addr string BootstrapResolution []netaddr.IP @@ -255,7 +255,7 @@ func (src *RegisterResponse) Clone() *RegisterResponse { } // A compilation failure here means this code must be regenerated, with command: -// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse +// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode var _RegisterResponseNeedsRegeneration = RegisterResponse(struct { User User Login Login @@ -264,9 +264,83 @@ var _RegisterResponseNeedsRegeneration = RegisterResponse(struct { AuthURL string }{}) +// Clone makes a deep copy of DERPRegion. +// The result aliases no memory with the original. +func (src *DERPRegion) Clone() *DERPRegion { + if src == nil { + return nil + } + dst := new(DERPRegion) + *dst = *src + dst.Nodes = make([]*DERPNode, len(src.Nodes)) + for i := range dst.Nodes { + dst.Nodes[i] = src.Nodes[i].Clone() + } + return dst +} + +// A compilation failure here means this code must be regenerated, with command: +// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode +var _DERPRegionNeedsRegeneration = DERPRegion(struct { + RegionID int + RegionCode string + RegionName string + Avoid bool + Nodes []*DERPNode +}{}) + +// Clone makes a deep copy of DERPMap. +// The result aliases no memory with the original. +func (src *DERPMap) Clone() *DERPMap { + if src == nil { + return nil + } + dst := new(DERPMap) + *dst = *src + if dst.Regions != nil { + dst.Regions = map[int]*DERPRegion{} + for k, v := range src.Regions { + dst.Regions[k] = v.Clone() + } + } + return dst +} + +// A compilation failure here means this code must be regenerated, with command: +// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode +var _DERPMapNeedsRegeneration = DERPMap(struct { + Regions map[int]*DERPRegion +}{}) + +// Clone makes a deep copy of DERPNode. +// The result aliases no memory with the original. +func (src *DERPNode) Clone() *DERPNode { + if src == nil { + return nil + } + dst := new(DERPNode) + *dst = *src + return dst +} + +// A compilation failure here means this code must be regenerated, with command: +// tailscale.com/cmd/cloner -type User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode +var _DERPNodeNeedsRegeneration = DERPNode(struct { + Name string + RegionID int + HostName string + CertName string + IPv4 string + IPv6 string + STUNPort int + STUNOnly bool + DERPTestPort int + STUNTestIP string +}{}) + // Clone duplicates src into dst and reports whether it succeeded. // To succeed, must be of types <*T, *T> or <*T, **T>, -// where T is one of User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse. +// where T is one of User,Node,Hostinfo,NetInfo,Login,DNSConfig,DNSResolver,RegisterResponse,DERPRegion,DERPMap,DERPNode. func Clone(dst, src interface{}) bool { switch src := src.(type) { case *User: @@ -341,6 +415,33 @@ func Clone(dst, src interface{}) bool { *dst = src.Clone() return true } + case *DERPRegion: + switch dst := dst.(type) { + case *DERPRegion: + *dst = *src.Clone() + return true + case **DERPRegion: + *dst = src.Clone() + return true + } + case *DERPMap: + switch dst := dst.(type) { + case *DERPMap: + *dst = *src.Clone() + return true + case **DERPMap: + *dst = src.Clone() + return true + } + case *DERPNode: + switch dst := dst.(type) { + case *DERPNode: + *dst = *src.Clone() + return true + case **DERPNode: + *dst = src.Clone() + return true + } } return false }