@@ -55,12 +55,15 @@ type Topology struct {
5555 // the IP is the 0th address in the subnet, i.e. the CIDR
5656 // is equal to the Kilo subnet.
5757 wireGuardCIDR * net.IPNet
58+ // discoveredEndpoints is the updated map of valid discovered Endpoints
59+ discoveredEndpoints map [string ]* wireguard.Endpoint
5860}
5961
6062type segment struct {
61- allowedIPs []* net.IPNet
62- endpoint * wireguard.Endpoint
63- key []byte
63+ allowedIPs []* net.IPNet
64+ endpoint * wireguard.Endpoint
65+ key []byte
66+ persistentKeepalive int
6467 // Location is the logical location of this segment.
6568 location string
6669
@@ -106,7 +109,7 @@ func NewTopology(nodes map[string]*Node, peers map[string]*Peer, granularity Gra
106109 localLocation = nodeLocationPrefix + hostname
107110 }
108111
109- t := Topology {key : key , port : port , hostname : hostname , location : localLocation , persistentKeepalive : persistentKeepalive , privateIP : nodes [hostname ].InternalIP , subnet : nodes [hostname ].Subnet , wireGuardCIDR : subnet }
112+ t := Topology {key : key , port : port , hostname : hostname , location : localLocation , persistentKeepalive : persistentKeepalive , privateIP : nodes [hostname ].InternalIP , subnet : nodes [hostname ].Subnet , wireGuardCIDR : subnet , discoveredEndpoints : make ( map [ string ] * wireguard. Endpoint ) }
110113 for location := range topoMap {
111114 // Sort the location so the result is stable.
112115 sort .Slice (topoMap [location ], func (i , j int ) bool {
@@ -134,14 +137,15 @@ func NewTopology(nodes map[string]*Node, peers map[string]*Peer, granularity Gra
134137 hostnames = append (hostnames , node .Name )
135138 }
136139 t .segments = append (t .segments , & segment {
137- allowedIPs : allowedIPs ,
138- endpoint : topoMap [location ][leader ].Endpoint ,
139- key : topoMap [location ][leader ].Key ,
140- location : location ,
141- cidrs : cidrs ,
142- hostnames : hostnames ,
143- leader : leader ,
144- privateIPs : privateIPs ,
140+ allowedIPs : allowedIPs ,
141+ endpoint : topoMap [location ][leader ].Endpoint ,
142+ key : topoMap [location ][leader ].Key ,
143+ persistentKeepalive : topoMap [location ][leader ].PersistentKeepalive ,
144+ location : location ,
145+ cidrs : cidrs ,
146+ hostnames : hostnames ,
147+ leader : leader ,
148+ privateIPs : privateIPs ,
145149 })
146150 }
147151 // Sort the Topology segments so the result is stable.
@@ -173,9 +177,37 @@ func NewTopology(nodes map[string]*Node, peers map[string]*Peer, granularity Gra
173177 }
174178 }
175179
180+ // Copy the host node DiscoveredEndpoints first.
181+ for key := range nodes [hostname ].DiscoveredEndpoints {
182+ t .discoveredEndpoints [key ] = nodes [hostname ].DiscoveredEndpoints [key ]
183+ }
184+ // Now that the topology is ordered, update the discoveredEndpoints map
185+ // add new ones by going through the ordered topology: segments, nodes
186+ for _ , segment := range t .segments {
187+ for _ , node := range topoMap [segment .location ] {
188+ for key := range node .DiscoveredEndpoints {
189+ if _ , ok := t .discoveredEndpoints [key ]; ! ok {
190+ t .discoveredEndpoints [key ] = node .DiscoveredEndpoints [key ]
191+ }
192+ }
193+ }
194+ }
195+
176196 return & t , nil
177197}
178198
199+ func (t * Topology ) updateEndpoint (endpoint * wireguard.Endpoint , key []byte , persistentKeepalive int ) * wireguard.Endpoint {
200+ // Do not update non-nat peers
201+ if persistentKeepalive == 0 {
202+ return endpoint
203+ }
204+ e , ok := t .discoveredEndpoints [string (key )]
205+ if ok {
206+ return e
207+ }
208+ return endpoint
209+ }
210+
179211// Conf generates a WireGuard configuration file for a given Topology.
180212func (t * Topology ) Conf () * wireguard.Conf {
181213 c := & wireguard.Conf {
@@ -190,7 +222,7 @@ func (t *Topology) Conf() *wireguard.Conf {
190222 }
191223 peer := & wireguard.Peer {
192224 AllowedIPs : s .allowedIPs ,
193- Endpoint : s .endpoint ,
225+ Endpoint : t . updateEndpoint ( s .endpoint , s . key , s . persistentKeepalive ) ,
194226 PersistentKeepalive : t .persistentKeepalive ,
195227 PublicKey : s .key ,
196228 }
@@ -199,7 +231,7 @@ func (t *Topology) Conf() *wireguard.Conf {
199231 for _ , p := range t .peers {
200232 peer := & wireguard.Peer {
201233 AllowedIPs : p .AllowedIPs ,
202- Endpoint : p .Endpoint ,
234+ Endpoint : t . updateEndpoint ( p .Endpoint , p . PublicKey , p . PersistentKeepalive ) ,
203235 PersistentKeepalive : t .persistentKeepalive ,
204236 PresharedKey : p .PresharedKey ,
205237 PublicKey : p .PublicKey ,
0 commit comments