metropolis/clusternet: fix race condition

This gives the wireguard backend a copy of the peer data instead of a
pointer into mutable memory.

Change-Id: I47ee83f3d484cc809c35d2e1779b519ec60c7c78
Reviewed-on: https://review.monogon.dev/c/monogon/+/1825
Tested-by: Jenkins CI
Reviewed-by: Lorenz Brun <lorenz@monogon.tech>
diff --git a/metropolis/node/core/clusternet/clusternet.go b/metropolis/node/core/clusternet/clusternet.go
index dc2de00..dea0f89 100644
--- a/metropolis/node/core/clusternet/clusternet.go
+++ b/metropolis/node/core/clusternet/clusternet.go
@@ -175,14 +175,14 @@
 
 		for _, n := range removed {
 			supervisor.Logger(ctx).Infof("Node %s removed, unconfiguring", n.id)
-			if err := s.wg.unconfigurePeer(n); err != nil {
+			if err := s.wg.unconfigurePeer(n.copy()); err != nil {
 				// Do nothing and hope whatever caused this will go away at some point.
 				supervisor.Logger(ctx).Errorf("Node %s couldn't be unconfigured: %v", n.id, err)
 			}
 		}
 		var newNodes []*node
 		for _, n := range updated {
-			newNodes = append(newNodes, n)
+			newNodes = append(newNodes, n.copy())
 			supervisor.Logger(ctx).Infof("Node %s updated: pk %s, address %s, prefixes %v", n.id, n.pubkey, n.address, n.prefixes)
 		}
 		succeeded := 0
diff --git a/metropolis/node/core/clusternet/types.go b/metropolis/node/core/clusternet/types.go
index 80adec9..0d776f2 100644
--- a/metropolis/node/core/clusternet/types.go
+++ b/metropolis/node/core/clusternet/types.go
@@ -59,6 +59,11 @@
 	prefixes []string
 }
 
+func (n *node) copy() *node {
+	n2 := *n
+	return &n2
+}
+
 // update mutates this node to whatever data is held in the given proto Node, and
 // returns true if any data changed.
 func (n *node) update(p *apb.Node) (changed bool) {