Kaynağa Gözat

pkg/mesh: fix panic in graph

Commit 4d00bc56fea264940195562affb23c31378800fe introduced a bug in the
Kilo graph generation logic. This commit used the WireGuard CIDR from
the topology struct as the graph title, however this field is nil
whenever the selected node is not a leader, causing the program to
panic.

This commit changes the meaning of the topology struct's wireGuardCIDR
field so that the field is always defined and the normalized value will
always be equal to the Kilo subnet CIDR. When the selected node is a
leader node, then the field's IP will be the IP allocated to the node
within the subnet. This effectively prevents the program from panicking.

Signed-off-by: Lucas Servén Marín <lserven@gmail.com>
Lucas Servén Marín 5 yıl önce
ebeveyn
işleme
d1948acd77
4 değiştirilmiş dosya ile 12 ekleme ve 6 silme
  1. 1 1
      pkg/mesh/graph.go
  2. 5 1
      pkg/mesh/mesh.go
  3. 5 3
      pkg/mesh/topology.go
  4. 1 1
      pkg/mesh/topology_test.go

+ 1 - 1
pkg/mesh/graph.go

@@ -27,7 +27,7 @@ import (
 func (t *Topology) Dot() (string, error) {
 func (t *Topology) Dot() (string, error) {
 	g := gographviz.NewGraph()
 	g := gographviz.NewGraph()
 	g.Name = "kilo"
 	g.Name = "kilo"
-	if err := g.AddAttr("kilo", string(gographviz.Label), graphEscape(t.wireGuardCIDR.String())); err != nil {
+	if err := g.AddAttr("kilo", string(gographviz.Label), graphEscape((&net.IPNet{IP: t.wireGuardCIDR.IP.Mask(t.wireGuardCIDR.Mask), Mask: t.wireGuardCIDR.Mask}).String())); err != nil {
 		return "", fmt.Errorf("failed to add label to graph")
 		return "", fmt.Errorf("failed to add label to graph")
 	}
 	}
 	if err := g.AddAttr("kilo", string(gographviz.LabelLOC), "t"); err != nil {
 	if err := g.AddAttr("kilo", string(gographviz.LabelLOC), "t"); err != nil {

+ 5 - 1
pkg/mesh/mesh.go

@@ -477,7 +477,11 @@ func (m *Mesh) applyTopology() {
 		return
 		return
 	}
 	}
 	// Update the node's WireGuard IP.
 	// Update the node's WireGuard IP.
-	m.wireGuardIP = t.wireGuardCIDR
+	if t.leader {
+		m.wireGuardIP = t.wireGuardCIDR
+	} else {
+		m.wireGuardIP = nil
+	}
 	conf := t.Conf()
 	conf := t.Conf()
 	buf, err := conf.Bytes()
 	buf, err := conf.Bytes()
 	if err != nil {
 	if err != nil {

+ 5 - 3
pkg/mesh/topology.go

@@ -50,8 +50,10 @@ type Topology struct {
 	// subnet is the Pod subnet of the local node.
 	// subnet is the Pod subnet of the local node.
 	subnet *net.IPNet
 	subnet *net.IPNet
 	// wireGuardCIDR is the allocated CIDR of the WireGuard
 	// wireGuardCIDR is the allocated CIDR of the WireGuard
-	// interface of the local node. If the local node is not
-	// the leader, then it is nil.
+	// interface of the local node within the Kilo subnet.
+	// If the local node is not the leader of a location, then
+	// the IP is the 0th address in the subnet, i.e. the CIDR
+	// is equal to the Kilo subnet.
 	wireGuardCIDR *net.IPNet
 	wireGuardCIDR *net.IPNet
 }
 }
 
 
@@ -104,7 +106,7 @@ func NewTopology(nodes map[string]*Node, peers map[string]*Peer, granularity Gra
 		localLocation = nodeLocationPrefix + hostname
 		localLocation = nodeLocationPrefix + hostname
 	}
 	}
 
 
-	t := Topology{key: key, port: port, hostname: hostname, location: localLocation, persistentKeepalive: persistentKeepalive, privateIP: nodes[hostname].InternalIP, subnet: nodes[hostname].Subnet}
+	t := Topology{key: key, port: port, hostname: hostname, location: localLocation, persistentKeepalive: persistentKeepalive, privateIP: nodes[hostname].InternalIP, subnet: nodes[hostname].Subnet, wireGuardCIDR: subnet}
 	for location := range topoMap {
 	for location := range topoMap {
 		// Sort the location so the result is stable.
 		// Sort the location so the result is stable.
 		sort.Slice(topoMap[location], func(i, j int) bool {
 		sort.Slice(topoMap[location], func(i, j int) bool {

+ 1 - 1
pkg/mesh/topology_test.go

@@ -215,7 +215,7 @@ func TestNewTopology(t *testing.T) {
 				location:      logicalLocationPrefix + nodes["b"].Location,
 				location:      logicalLocationPrefix + nodes["b"].Location,
 				subnet:        nodes["c"].Subnet,
 				subnet:        nodes["c"].Subnet,
 				privateIP:     nodes["c"].InternalIP,
 				privateIP:     nodes["c"].InternalIP,
-				wireGuardCIDR: nil,
+				wireGuardCIDR: DefaultKiloSubnet,
 				segments: []*segment{
 				segments: []*segment{
 					{
 					{
 						allowedIPs:  []*net.IPNet{nodes["a"].Subnet, nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},
 						allowedIPs:  []*net.IPNet{nodes["a"].Subnet, nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},