|
|
@@ -355,7 +355,6 @@ func (m *Mesh) Run() error {
|
|
|
if m.cni {
|
|
|
m.updateCNIConfig()
|
|
|
}
|
|
|
- m.syncEndpoints()
|
|
|
m.applyTopology()
|
|
|
t.Reset(resyncPeriod)
|
|
|
case <-m.stop:
|
|
|
@@ -364,47 +363,6 @@ func (m *Mesh) Run() error {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// WireGuard updates the endpoints of peers to match the
|
|
|
-// last place a valid packet was received from.
|
|
|
-// Periodically we need to syncronize the endpoints
|
|
|
-// of peers in the backend to match the WireGuard configuration.
|
|
|
-func (m *Mesh) syncEndpoints() {
|
|
|
- link, err := linkByIndex(m.kiloIface)
|
|
|
- if err != nil {
|
|
|
- level.Error(m.logger).Log("error", err)
|
|
|
- m.errorCounter.WithLabelValues("endpoints").Inc()
|
|
|
- return
|
|
|
- }
|
|
|
- conf, err := wireguard.ShowConf(link.Attrs().Name)
|
|
|
- if err != nil {
|
|
|
- level.Error(m.logger).Log("error", err)
|
|
|
- m.errorCounter.WithLabelValues("endpoints").Inc()
|
|
|
- return
|
|
|
- }
|
|
|
- m.mu.Lock()
|
|
|
- defer m.mu.Unlock()
|
|
|
- c := wireguard.Parse(conf)
|
|
|
- var key string
|
|
|
- var tmp *Peer
|
|
|
- for i := range c.Peers {
|
|
|
- // Peers are indexed by public key.
|
|
|
- key = string(c.Peers[i].PublicKey)
|
|
|
- if p, ok := m.peers[key]; ok {
|
|
|
- tmp = &Peer{
|
|
|
- Name: p.Name,
|
|
|
- Peer: *c.Peers[i],
|
|
|
- }
|
|
|
- if !peersAreEqual(tmp, p) {
|
|
|
- p.Endpoint = tmp.Endpoint
|
|
|
- if err := m.Peers().Set(p.Name, p); err != nil {
|
|
|
- level.Error(m.logger).Log("error", err)
|
|
|
- m.errorCounter.WithLabelValues("endpoints").Inc()
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
func (m *Mesh) syncNodes(e *NodeEvent) {
|
|
|
logger := log.With(m.logger, "event", e.Type)
|
|
|
level.Debug(logger).Log("msg", "syncing nodes", "event", e.Type)
|
|
|
@@ -659,7 +617,7 @@ func (m *Mesh) applyTopology() {
|
|
|
}
|
|
|
// Setting the WireGuard configuration interrupts existing connections
|
|
|
// so only set the configuration if it has changed.
|
|
|
- equal := conf.Equal(wireguard.Parse(oldConf))
|
|
|
+ equal := conf.EqualWithPeerCheck(wireguard.Parse(oldConf), peersAreEqualIgnoreNAT)
|
|
|
if !equal {
|
|
|
level.Info(m.logger).Log("msg", "WireGuard configurations are different")
|
|
|
if err := wireguard.SetConf(link.Attrs().Name, ConfPath); err != nil {
|
|
|
@@ -856,6 +814,41 @@ func peersAreEqual(a, b *Peer) bool {
|
|
|
return string(a.PublicKey) == string(b.PublicKey) && a.PersistentKeepalive == b.PersistentKeepalive
|
|
|
}
|
|
|
|
|
|
+// Basic nil checks and checking the lengths of the allowed IPs is
|
|
|
+// done by the WireGuard package.
|
|
|
+func peersAreEqualIgnoreNAT(a, b *wireguard.Peer) bool {
|
|
|
+ for j := range a.AllowedIPs {
|
|
|
+ if a.AllowedIPs[j].String() != b.AllowedIPs[j].String() {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if a.PersistentKeepalive != b.PersistentKeepalive || !bytes.Equal(a.PublicKey, b.PublicKey) {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ // If a persistent keepalive is set, then the peer is behind NAT
|
|
|
+ // and we want to ignore changes in endpoints, since it may roam.
|
|
|
+ if a.PersistentKeepalive != 0 {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ if (a.Endpoint == nil) != (b.Endpoint == nil) {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ if a.Endpoint != nil {
|
|
|
+ if a.Endpoint.Port != b.Endpoint.Port {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ // IPs take priority, so check them first.
|
|
|
+ if !a.Endpoint.IP.Equal(b.Endpoint.IP) {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ // Only check the DNS name if the IP is empty.
|
|
|
+ if a.Endpoint.IP == nil && a.Endpoint.DNS != b.Endpoint.DNS {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true
|
|
|
+}
|
|
|
+
|
|
|
func ipNetsEqual(a, b *net.IPNet) bool {
|
|
|
if a == nil && b == nil {
|
|
|
return true
|