diff --git a/wgengine/userspace.go b/wgengine/userspace.go index a3dd75375..d90cb8533 100644 --- a/wgengine/userspace.go +++ b/wgengine/userspace.go @@ -816,7 +816,7 @@ func (e *userspaceEngine) Reconfig(cfg *wgcfg.Config, routerCfg *router.Config, } } - e.lastCfgFull = cfg.Copy() + e.lastCfgFull = *cfg.Clone() // Tell magicsock about the new (or initial) private key // (which is needed by DERP) before wgdev gets it, as wgdev diff --git a/wgengine/wgcfg/clone.go b/wgengine/wgcfg/clone.go new file mode 100644 index 000000000..1b35a5d95 --- /dev/null +++ b/wgengine/wgcfg/clone.go @@ -0,0 +1,61 @@ +// Copyright (c) 2020 Tailscale Inc & AUTHORS All rights reserved. +// 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 Config,Peer; DO NOT EDIT. + +package wgcfg + +import ( + "inet.af/netaddr" + "tailscale.com/types/wgkey" +) + +// Clone makes a deep copy of Config. +// The result aliases no memory with the original. +func (src *Config) Clone() *Config { + if src == nil { + return nil + } + dst := new(Config) + *dst = *src + dst.Addresses = append(src.Addresses[:0:0], src.Addresses...) + dst.DNS = append(src.DNS[:0:0], src.DNS...) + dst.Peers = make([]Peer, len(src.Peers)) + for i := range dst.Peers { + dst.Peers[i] = *src.Peers[i].Clone() + } + return dst +} + +// A compilation failure here means this code must be regenerated, with command: +// tailscale.com/cmd/cloner -type Config,Peer +var _ConfigNeedsRegeneration = Config(struct { + Name string + PrivateKey wgkey.Private + Addresses []netaddr.IPPrefix + MTU uint16 + DNS []netaddr.IP + Peers []Peer +}{}) + +// Clone makes a deep copy of Peer. +// The result aliases no memory with the original. +func (src *Peer) Clone() *Peer { + if src == nil { + return nil + } + dst := new(Peer) + *dst = *src + dst.AllowedIPs = append(src.AllowedIPs[:0:0], src.AllowedIPs...) + return dst +} + +// A compilation failure here means this code must be regenerated, with command: +// tailscale.com/cmd/cloner -type Config,Peer +var _PeerNeedsRegeneration = Peer(struct { + PublicKey wgkey.Key + AllowedIPs []netaddr.IPPrefix + Endpoints string + PersistentKeepalive uint16 +}{}) diff --git a/wgengine/wgcfg/config.go b/wgengine/wgcfg/config.go index aa8850e5d..15b66cee4 100644 --- a/wgengine/wgcfg/config.go +++ b/wgengine/wgcfg/config.go @@ -10,6 +10,8 @@ import ( "tailscale.com/types/wgkey" ) +//go:generate go run tailscale.com/cmd/cloner -type=Config,Peer -output=clone.go + // EndpointDiscoSuffix is appended to the hex representation of a peer's discovery key // and is then the sole wireguard endpoint for peers with a non-zero discovery key. // This form is then recognize by magicsock's CreateEndpoint. @@ -33,34 +35,6 @@ type Peer struct { PersistentKeepalive uint16 } -// Copy makes a deep copy of Config. -// The result aliases no memory with the original. -func (cfg Config) Copy() Config { - res := cfg - if res.Addresses != nil { - res.Addresses = append([]netaddr.IPPrefix{}, res.Addresses...) - } - if res.DNS != nil { - res.DNS = append([]netaddr.IP{}, res.DNS...) - } - peers := make([]Peer, 0, len(res.Peers)) - for _, peer := range res.Peers { - peers = append(peers, peer.Copy()) - } - res.Peers = peers - return res -} - -// Copy makes a deep copy of Peer. -// The result aliases no memory with the original. -func (peer Peer) Copy() Peer { - res := peer - if res.AllowedIPs != nil { - res.AllowedIPs = append([]netaddr.IPPrefix{}, res.AllowedIPs...) - } - return res -} - // PeerWithKey returns the Peer with key k and reports whether it was found. func (config Config) PeerWithKey(k wgkey.Key) (Peer, bool) { for _, p := range config.Peers {