Browse Source

peer update for host

Abhishek Kondur 2 years ago
parent
commit
d99526fd54
4 changed files with 135 additions and 0 deletions
  1. 117 0
      logic/peers.go
  2. 3 0
      models/metrics.go
  3. 14 0
      models/mqtt.go
  4. 1 0
      models/node.go

+ 117 - 0
logic/peers.go

@@ -192,6 +192,123 @@ func GetPeersForProxy(node *models.Node, onlyPeers bool) (proxy_models.ProxyMana
 	return proxyPayload, nil
 	return proxyPayload, nil
 }
 }
 
 
+func GetPeerUpdateForHost(host *models.Host) (models.HostPeerUpdate, error) {
+	hostPeerUpdate := models.HostPeerUpdate{
+		Network: make(map[string]models.NetworkInfo),
+		PeerIDs: make(models.HostPeerMap),
+	}
+	peerIndexMap := make(map[string]int)
+	for _, nodeID := range host.Nodes {
+		node, err := GetNodeByID(nodeID)
+		if err != nil {
+			continue
+		}
+		log.Println("peer update for node ", node.ID)
+		hostPeerUpdate.Network[node.Network] = models.NetworkInfo{
+			ServerVersion: servercfg.GetVersion(),
+			ServerAddr:    node.Server,
+			DNS:           getPeerDNS(node.Network),
+		}
+		currentPeers, err := GetNetworkNodes(node.Network)
+		if err != nil {
+			log.Println("no network nodes")
+			return models.HostPeerUpdate{}, err
+		}
+		for _, peer := range currentPeers {
+			var peerConfig wgtypes.PeerConfig
+			peerHost, err := GetHost(peer.HostID.String())
+			if err != nil {
+				log.Println("no peer host", err)
+				return models.HostPeerUpdate{}, err
+			}
+			if peer.ID == node.ID {
+				log.Println("peer update, skipping self")
+				//skip yourself
+
+				continue
+			}
+			if !peer.Connected {
+				log.Println("peer update, skipping unconnected node")
+				//skip unconnected nodes
+				continue
+			}
+			if !nodeacls.AreNodesAllowed(nodeacls.NetworkID(node.Network), nodeacls.NodeID(node.ID.String()), nodeacls.NodeID(peer.ID.String())) {
+				log.Println("peer update, skipping node for acl")
+				//skip if not permitted by acl
+				continue
+			}
+			peerConfig.PublicKey = peerHost.PublicKey
+			peerConfig.PersistentKeepaliveInterval = &peer.PersistentKeepalive
+			peerConfig.ReplaceAllowedIPs = true
+			uselocal := false
+			if host.EndpointIP.String() == peerHost.EndpointIP.String() {
+				//peer is on same network
+				// set to localaddress
+				uselocal = true
+				if node.LocalAddress.IP == nil {
+					// use public endpint
+					uselocal = false
+				}
+				if node.LocalAddress.String() == peer.LocalAddress.String() {
+					uselocal = false
+				}
+			}
+			peerConfig.Endpoint = &net.UDPAddr{
+				IP:   peerHost.EndpointIP,
+				Port: peerHost.ListenPort,
+			}
+			if !host.ProxyEnabled && peerHost.ProxyEnabled {
+				peerConfig.Endpoint.Port = peerHost.ProxyListenPort
+			}
+			if uselocal {
+				peerConfig.Endpoint.IP = peer.LocalAddress.IP
+			}
+			allowedips := getNodeAllowedIPs(&peer, &node)
+			if peer.IsIngressGateway {
+				for _, entry := range peer.IngressGatewayRange {
+					_, cidr, err := net.ParseCIDR(string(entry))
+					if err == nil {
+						allowedips = append(allowedips, *cidr)
+					}
+				}
+			}
+			if peer.IsRelay {
+				allowedips = append(allowedips, getRelayAllowedIPs(&node, &peer)...)
+			}
+			if peer.IsEgressGateway {
+				allowedips = append(allowedips, getEgressIPs(&node, &peer)...)
+			}
+			peerConfig.AllowedIPs = allowedips
+			if _, ok := hostPeerUpdate.PeerIDs[peerHost.PublicKey.String()]; !ok {
+				hostPeerUpdate.PeerIDs[peerHost.PublicKey.String()] = make(map[string]models.IDandAddr)
+			}
+			if _, ok := hostPeerUpdate.PeerIDs[peerHost.PublicKey.String()]; !ok {
+				hostPeerUpdate.Peers = append(hostPeerUpdate.Peers, peerConfig)
+				peerIndexMap[peerHost.PublicKey.String()] = len(hostPeerUpdate.Peers) - 1
+				hostPeerUpdate.PeerIDs[peerHost.PublicKey.String()][peer.ID.String()] = models.IDandAddr{
+					ID:      peer.ID.String(),
+					Address: peer.PrimaryAddress(),
+					Name:    peer.Name,
+					Network: peer.Network,
+				}
+			} else {
+				peerAllowedIPs := hostPeerUpdate.Peers[peerIndexMap[peerHost.PublicKey.String()]].AllowedIPs
+				peerAllowedIPs = append(peerAllowedIPs, allowedips...)
+				hostPeerUpdate.Peers[peerIndexMap[peerHost.PublicKey.String()]].AllowedIPs = peerAllowedIPs
+				hostPeerUpdate.PeerIDs[peerHost.PublicKey.String()][peer.ID.String()] = models.IDandAddr{
+					ID:      peer.ID.String(),
+					Address: peer.PrimaryAddress(),
+					Name:    peer.Name,
+					Network: peer.Network,
+				}
+			}
+
+		}
+	}
+
+	return hostPeerUpdate, nil
+}
+
 // GetPeerUpdate - gets a wireguard peer config for each peer of a node
 // GetPeerUpdate - gets a wireguard peer config for each peer of a node
 func GetPeerUpdate(node *models.Node, host *models.Host) (models.PeerUpdate, error) {
 func GetPeerUpdate(node *models.Node, host *models.Host) (models.PeerUpdate, error) {
 	log.Println("peer update for node ", node.ID)
 	log.Println("peer update for node ", node.ID)

+ 3 - 0
models/metrics.go

@@ -37,11 +37,14 @@ type IDandAddr struct {
 	Address  string `json:"address" bson:"address" yaml:"address"`
 	Address  string `json:"address" bson:"address" yaml:"address"`
 	Name     string `json:"name" bson:"name" yaml:"name"`
 	Name     string `json:"name" bson:"name" yaml:"name"`
 	IsServer string `json:"isserver" bson:"isserver" yaml:"isserver" validate:"checkyesorno"`
 	IsServer string `json:"isserver" bson:"isserver" yaml:"isserver" validate:"checkyesorno"`
+	Network  string `json:"network" bson:"network" yaml:"network" validate:"network"`
 }
 }
 
 
 // PeerMap - peer map for ids and addresses in metrics
 // PeerMap - peer map for ids and addresses in metrics
 type PeerMap map[string]IDandAddr
 type PeerMap map[string]IDandAddr
 
 
+type HostPeerMap map[string]map[string]IDandAddr
+
 // MetricsMap - map for holding multiple metrics in memory
 // MetricsMap - map for holding multiple metrics in memory
 type MetricsMap map[string]Metrics
 type MetricsMap map[string]Metrics
 
 

+ 14 - 0
models/mqtt.go

@@ -16,6 +16,20 @@ type PeerUpdate struct {
 	ProxyUpdate   proxy_models.ProxyManagerPayload `json:"proxy_update" bson:"proxy_update" yaml:"proxy_update"`
 	ProxyUpdate   proxy_models.ProxyManagerPayload `json:"proxy_update" bson:"proxy_update" yaml:"proxy_update"`
 }
 }
 
 
+// HostPeerUpdate
+type HostPeerUpdate struct {
+	Network     map[string]NetworkInfo           `json:"network" bson:"network" yaml:"network"`
+	Peers       []wgtypes.PeerConfig             `json:"peers" bson:"peers" yaml:"peers"`
+	PeerIDs     HostPeerMap                      `json:"peerids" bson:"peerids" yaml:"peerids"`
+	ProxyUpdate proxy_models.ProxyManagerPayload `json:"proxy_update" bson:"proxy_update" yaml:"proxy_update"`
+}
+
+type NetworkInfo struct {
+	ServerVersion string `json:"serverversion" bson:"serverversion" yaml:"serverversion"`
+	ServerAddr    string `json:"serveraddr" bson:"serveraddr" yaml:"serveraddr"`
+	DNS           string `json:"dns" bson:"dns" yaml:"dns"`
+}
+
 // KeyUpdate - key update struct
 // KeyUpdate - key update struct
 type KeyUpdate struct {
 type KeyUpdate struct {
 	Network   string `json:"network" bson:"network"`
 	Network   string `json:"network" bson:"network"`

+ 1 - 0
models/node.go

@@ -58,6 +58,7 @@ type Iface struct {
 type CommonNode struct {
 type CommonNode struct {
 	ID                  uuid.UUID            `json:"id" yaml:"id"`
 	ID                  uuid.UUID            `json:"id" yaml:"id"`
 	HostID              uuid.UUID            `json:"hostid" yaml:"hostid"`
 	HostID              uuid.UUID            `json:"hostid" yaml:"hostid"`
+	Name                string               `json:"name" yaml:"name"`
 	Network             string               `json:"network" yaml:"network"`
 	Network             string               `json:"network" yaml:"network"`
 	NetworkRange        net.IPNet            `json:"networkrange" yaml:"networkrange"`
 	NetworkRange        net.IPNet            `json:"networkrange" yaml:"networkrange"`
 	NetworkRange6       net.IPNet            `json:"networkrange6" yaml:"networkrange6"`
 	NetworkRange6       net.IPNet            `json:"networkrange6" yaml:"networkrange6"`